[ostree] tests/pull-corruption: Ensure we corrupt an object to be pulled



commit 3802a0679b5b0ef7a434c09e2c16b97141fe1cee
Author: Colin Walters <walters verbum org>
Date:   Sun Jan 19 12:39:38 2014 -0500

    tests/pull-corruption: Ensure we corrupt an object to be pulled
    
    This test had some nondeterminism because we chose a random
    object to corrupt, but because there were multiple commits, it
    was possible that we chose an object that was not being pulled.
    
    Fix this by writing some custom GJS code to find an explicitly random
    object that exists in a given ref, an change a random byte offset.
    This adds a lot more randomness to the testing too.

 Makefile-tests.am             |    1 +
 tests/corrupt-repo-ref.js     |   88 +++++++++++++++++++++++++++++++++++++++++
 tests/test-pull-corruption.sh |   22 ++--------
 3 files changed, 94 insertions(+), 17 deletions(-)
---
diff --git a/Makefile-tests.am b/Makefile-tests.am
index ac63d23..75d9d2c 100644
--- a/Makefile-tests.am
+++ b/Makefile-tests.am
@@ -50,6 +50,7 @@ insttest_DATA = tests/archive-test.sh \
        tests/pull-test.sh \
        tests/libtest.sh \
        tests/admin-test.sh \
+       tests/corrupt-repo-ref.js \
        $(NULL)
 
 gpginsttestdir = $(pkglibexecdir)/installed-tests/gpghome
diff --git a/tests/corrupt-repo-ref.js b/tests/corrupt-repo-ref.js
new file mode 100644
index 0000000..b1a797d
--- /dev/null
+++ b/tests/corrupt-repo-ref.js
@@ -0,0 +1,88 @@
+#!/usr/bin/env gjs
+//
+// Copyright (C) 2014 Colin Walters <walters verbum org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+const GLib = imports.gi.GLib;
+const Gio = imports.gi.Gio;
+const OSTree = imports.gi.OSTree;
+
+let repoPathArg = ARGV[0];
+let refToCorrupt = ARGV[1];
+
+let repo = OSTree.Repo.new(Gio.File.new_for_path(repoPathArg));
+
+repo.open(null);
+
+function listObjectChecksumsRecurse(dir, allObjects) {
+    dir.ensure_resolved();
+    allObjects[dir.tree_get_contents_checksum() + '.dirtree'] = true;
+    allObjects[dir.get_checksum() + '.dirmeta'] = true;
+    let e = dir.enumerate_children('standard::name,standard::type', 0, null);
+    let info;
+    while ((info = e.next_file(null)) != null) {
+       let child = e.get_child(info);
+       child.ensure_resolved();
+       print(info.get_name() + " is " + info.get_file_type());
+       if (info.get_file_type() == Gio.FileType.DIRECTORY) {
+           listObjectChecksumsRecurse(child, allObjects);
+       } else {
+           allObjects[child.get_checksum() + '.filez'] = true;
+       }
+    } 
+    e.close(null);
+} 
+
+let [,commit] = repo.resolve_rev(refToCorrupt, false);
+let [,root,commit] = repo.read_commit(refToCorrupt, null);
+let allObjects = {};
+allObjects[commit + '.commit'] = true;
+listObjectChecksumsRecurse(root, allObjects);
+let i = 0;
+for (let v in allObjects) 
+    i++;
+print("commit " + commit + " refers to " + i + " objects");
+let offset = GLib.random_int_range(0, i);
+let objectToCorrupt = null;
+for (let v in allObjects) {
+    if (offset <= 0) {
+       objectToCorrupt = v;
+       break;
+    }
+    offset--;
+}
+print("Choosing " + objectToCorrupt + " to corrupt");
+
+let loosePath = repo.get_path().resolve_relative_path('objects/' + objectToCorrupt.substring(0, 2) + "/" + 
objectToCorrupt.substring(2));
+
+let iostream = loosePath.open_readwrite(null);
+let info = iostream.query_info('standard::size', null);
+let size = info.get_size();
+let byteOffsetToCorrupt = GLib.random_int_range(0, size);
+iostream.seek(byteOffsetToCorrupt, GLib.SeekType.SET, null);
+let datain = Gio.DataInputStream.new(iostream.get_input_stream());
+let dataout = Gio.DataOutputStream.new(iostream.get_output_stream());
+let inbyte = datain.read_byte(null);
+let outbyte = (inbyte + 1) % 255;
+dataout.put_byte(outbyte, null);
+dataout.flush(null);
+iostream.close(null);
+let status = "Changed byte offset " + byteOffsetToCorrupt + " from " + inbyte + " to " + outbyte;
+print(status);
+
+let successFile = Gio.File.new_for_path('corrupted-status.txt');
+successFile.replace_contents(status, null, false, 0, null);
diff --git a/tests/test-pull-corruption.sh b/tests/test-pull-corruption.sh
index b042a0c..9a3cbf5 100755
--- a/tests/test-pull-corruption.sh
+++ b/tests/test-pull-corruption.sh
@@ -47,21 +47,9 @@ do_corrupt_pull_test() {
     fi
 }
 
-# Corrupt .dirmeta
-someobject=$(find ${repopath} -name '*.dirmeta' | head -1)
-echo "garbage garbage garbage" > ${someobject}
+# FIXME - ignore errors here since gjs in RHEL7 has the final
+# unrooting bug
+gjs $(dirname $0)/corrupt-repo-ref.js ${repopath} main || true
+assert_file_has_content corrupted-status.txt 'Changed byte'
 do_corrupt_pull_test
-echo "ok corrupt dirmeta"
-
-# Corrupt .dirtree
-someobject=$(find ${repopath} -name '*.dirtree' | head -1)
-echo "garbage garbage garbage" > ${someobject}
-do_corrupt_pull_test
-echo "ok corrupt dirtree"
-
-# Corrupt .filez
-someobject=$(find ${repopath} -name '*.filez' | head -1)
-otherobject=$(find ${repopath} -name '*.filez' | head -2 | tail -1)
-cp ${someobject} ${otherobject}
-do_corrupt_pull_test
-echo "ok corrupt filez"
+echo "ok corruption $iteration"


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]