From: Simon McVittie Date: Fri, 7 Oct 2016 23:14:40 +0100 Subject: Retrieve some missing test files from upstream git These were missing from "make dist". --- tests/glib.supp | 562 +++++++++++++++++++++++++++++++++++++++++++++++ tests/ostree.supp | 1 + tests/test-core.js | 55 +++++ tests/test-corruption.sh | 43 ++++ tests/test-sizes.js | 82 +++++++ tests/test-sysroot.js | 147 +++++++++++++ 6 files changed, 890 insertions(+) create mode 100644 tests/glib.supp create mode 100644 tests/ostree.supp create mode 100644 tests/test-core.js create mode 100755 tests/test-corruption.sh create mode 100644 tests/test-sizes.js create mode 100644 tests/test-sysroot.js diff --git a/tests/glib.supp b/tests/glib.supp new file mode 100644 index 0000000..7ac6ed8 --- /dev/null +++ b/tests/glib.supp @@ -0,0 +1,562 @@ +# This GLib suppressions file is known to be used at least by: +# +# - rpm-software-management/libhif +# +# Please use the upstream verison in libhif for changes. +{ + gobject_init_1 + Memcheck:Leak + ... + fun:gobject_init +} +{ + g_type_register_static_1 + Memcheck:Leak + ... + fun:g_type_register_static +} +{ + g_type_register_dynamic + Memcheck:Leak + ... + fun:g_type_register_dynamic +} +{ + g_type_register_fundamental + Memcheck:Leak + ... + fun:g_type_register_fundamental +} +{ + g_type_init_with_debug_flags + Memcheck:Leak + ... + fun:g_type_init_with_debug_flags +} +{ + g_type_class_ref_1 + Memcheck:Leak + ... + fun:type_iface_vtable_base_init_Wm + ... + fun:g_type_class_ref +} +{ + g_type_class_ref_2 + Memcheck:Leak + ... + fun:type_class_init_Wm + ... + fun:g_type_class_ref +} +{ + g_type_add_interface_static + Memcheck:Leak + ... + fun:g_type_add_interface_static +} +{ + g_type_add_interface_dynamic + Memcheck:Leak + ... + fun:g_type_add_interface_dynamic +} +{ + g_param_spec_internal + Memcheck:Leak + ... + fun:g_type_class_ref + fun:g_type_create_instance + fun:g_param_spec_internal +} +{ + g_param_spec_enum + Memcheck:Leak + ... + fun:g_type_class_ref + fun:g_param_spec_enum +} +{ + g_param_spec_flags + Memcheck:Leak + ... + fun:g_type_class_ref + fun:g_param_spec_flags +} +{ + g_quark_from_static_string + Memcheck:Leak + ... + fun:g_quark_from_static_string +} +{ + g_quark_from_string + Memcheck:Leak + ... + fun:g_quark_from_string +} +{ + g_value_register_transform_func + Memcheck:Leak + ... + fun:g_value_register_transform_func +} +{ + test_run_seed + Memcheck:Leak + ... + fun:g_rand_new_with_seed_array + fun:test_run_seed + ... + fun:g_test_run_suite +} +{ + g_test_init + Memcheck:Leak + ... + fun:g_rand_new_with_seed_array + ... + fun:g_test_init +} +{ + g_intern_static_string + Memcheck:Leak + ... + fun:g_intern_static_string +} +{ + g_main_context_push_thread_default + Memcheck:Leak + ... + fun:g_queue_new + fun:g_main_context_push_thread_default +} +{ + g_main_context_push_thread_default_inlined + Memcheck:Leak + ... + fun:g_slice_alloc0 + fun:g_main_context_push_thread_default +} +{ + g_dbus_error_register_error + Memcheck:Leak + ... + fun:g_dbus_error_register_error +} +{ + g_param_spec_pool_insert + Memcheck:Leak + ... + fun:g_param_spec_pool_insert +} +{ + g_main_context_default + Memcheck:Leak + ... + fun:g_main_context_default +} +{ + g_main_context_check + Memcheck:Leak + ... + fun:g_ptr_array_add + fun:g_main_context_check +} +{ + g_test_run_suite + Memcheck:Leak + ... + fun:g_slist_copy + fun:g_test_run_suite_internal + fun:g_test_run_suite +} +{ + g_dbus_interface_info_cache_build + Memcheck:Leak + ... + fun:g_dbus_interface_info_cache_build +} +{ + g_cancellable_push_current + Memcheck:Leak + ... + fun:thread_memory_from_self + ... + fun:g_cancellable_push_current +} +{ + _g_io_module_get_default + Memcheck:Leak + ... + fun:g_io_module_new + fun:g_io_modules_scan_all_in_directory_with_scope + fun:_g_io_modules_ensure_loaded + fun:_g_io_module_get_default +} +{ + g_io_scheduler_push_job + Memcheck:Leak + ... + fun:init_scheduler + fun:g_once_impl + fun:g_io_scheduler_push_job +} +{ + g_io_scheduler_push_job_2 + Memcheck:Leak + ... + fun:g_system_thread_new + ... + fun:g_io_scheduler_push_job +} +{ + g_bus_get_sync__available_connections + Memcheck:Leak + ... + fun:g_hash_table_new + fun:initable_init + fun:g_initable_init + fun:g_bus_get_sync +} +{ + g_socket_connection_factory_register_type + Memcheck:Leak + ... + fun:g_socket_connection_factory_register_type +} +{ + g_test_add_vtable + Memcheck:Leak + ... + fun:g_test_add_vtable +} +{ + g_mutex_lock + Memcheck:Leak + ... + fun:g_mutex_impl_new + fun:g_mutex_get_impl + fun:g_mutex_lock +} +{ + g_thread_self + Memcheck:Leak + ... + fun:g_thread_self +} +{ + g_rec_mutex_lock + Memcheck:Leak + ... + fun:g_rec_mutex_impl_new + fun:g_rec_mutex_get_impl + fun:g_rec_mutex_lock +} +{ + test_case_run + Memcheck:Leak + ... + fun:g_malloc0 + fun:test_case_run + ... + fun:g_test_run_suite +} +{ + g_get_charset + Memcheck:Leak + ... + fun:g_get_charset +} +{ + g_test_run_suite__timer_new + Memcheck:Leak + ... + fun:g_timer_new + fun:test_case_run + ... + fun:g_test_run_suite +} +{ + g_test_run_suite__timer_new2 + Memcheck:Leak + ... + fun:g_timer_new + fun:test_case_run_suite_internal + ... + fun:g_test_run_suite +} +{ + g_test_run_suite__strconcat + Memcheck:Leak + ... + fun:g_strconcat + fun:test_case_run + ... + fun:g_test_run_suite + fun:g_test_run +} +{ + g_type_interface_add_prerequisite + Memcheck:Leak + ... + fun:g_type_interface_add_prerequisite +} +{ + + Memcheck:Leak + ... + fun:g_slist_copy + fun:g_test_run_suite_internal + ... + fun:g_test_run_suite +} +{ + g_set_prgname + Memcheck:Leak + ... + fun:g_set_prgname +} +{ + g_test_run_suite__strconcat_2 + Memcheck:Leak + ... + fun:g_strconcat + fun:g_test_run_suite_internal +} +{ + g_test_run_suite__strdup + Memcheck:Leak + ... + fun:g_strdup + fun:g_test_run_suite_internal +} +{ + g_private_get + Memcheck:Leak + ... + fun:g_private_get +} +{ + g_private_set + Memcheck:Leak + ... + fun:g_private_set +} +{ + g_static_mutex_get_mutex_impl + Memcheck:Leak + ... + fun:g_static_mutex_get_mutex_impl +} +{ + g_variant_type_info_unref + Memcheck:Leak + ... + fun:g_hash_table_remove + fun:g_variant_type_info_unref +} +{ + g_rw_lock_reader_lock + Memcheck:Leak + ... + fun:g_rw_lock_impl_new + fun:g_rw_lock_get_impl + fun:g_rw_lock_reader_lock +} +{ + g_child_watch_finalize__rt_sigaction + Memcheck:Param + rt_sigaction(act->sa_flags) + fun:__libc_sigaction + ... + fun:g_child_watch_finalize +} +{ + g_dbus_worker_new + Memcheck:Leak + fun:calloc + ... + fun:_g_dbus_worker_new +} +{ + gdbus_shared_thread_func + Memcheck:Leak + match-leak-kinds: definite + ... + fun:g_malloc + ... + fun:gdbus_shared_thread_func +} +{ + g_task_start_task_thread + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + fun:g_slice_alloc + fun:g_slice_alloc0 + ... + fun:g_thread_pool_push + fun:g_task_start_task_thread +} +{ + g_task_to_pool + Memcheck:Leak + ... + fun:g_thread_pool_start_thread + ... + fun:g_task_run_in_thread +} +{ + g_get_language_names + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:g_malloc0 + fun:g_get_language_names +} +{ + g_get_filename_charsets + Memcheck:Leak + match-leak-kinds: definite + ... + fun:g_get_filename_charsets + fun:g_filename_display_name +} +{ + g_main_current_source + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + ... + fun:g_main_current_source + fun:g_task_return + fun:g_task_thread_pool_thread +} +{ + g_once_init_enter + Memcheck:Leak + match-leak-kinds: definite + ... + fun:g_once_init_enter +} +{ + g_child_watch_source_new + Memcheck:Leak + match-leak-kinds: definite + ... + fun:g_thread_new + ... + fun:g_child_watch_source_new +} +{ + continue_writing_in_idle_cb + Memcheck:Leak + match-leak-kinds: definite + ... + fun:g_task_new + ... + fun:continue_writing_in_idle_cb + fun:g_main_context_dispatch +} +{ + g_main_current_source + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + ... + fun:g_main_current_source +} +{ + g_thread_pool_push + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + ... + fun:g_thread_pool_push +} +{ + leak_test_dbus_dispose + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + ... + fun:g_main_loop_run + fun:g_test_dbus_down +} +{ + leak_test_dbus_down + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:g_malloc0 + fun:g_main_loop_new + fun:g_test_dbus_down +} +{ + leak_socket_client_connect + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + fun:g_slice_alloc + fun:g_slice_alloc0 + fun:g_socket_client_connect_async + fun:g_socket_client_connect_to_uri_async +} +{ + leak_signal_handlers_disconnect_matched + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:g_malloc0 + ... + fun:g_slice_alloc + ... + fun:g_signal_handlers_disconnect_matched +} +{ + g_tls_connection_gnutls_init_priorities + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + fun:g_strdup + fun:g_tls_connection_gnutls_init_priorities +} +{ + g_tls_connection_gnutls_heisenbug_likely_same_as_above + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + fun:g_strdup + ... + fun:g_tls_client_connection_new +} +{ + g_unix_signal_add_full + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + ... + fun:g_thread_new + ... + fun:g_unix_signal_add_full +} +{ + glib_worker_1 + Memcheck:Leak + ... + fun:glib_worker_main +} +{ + glib_worker_2 + Memcheck:Leak + ... + fun:g_thread_new + fun:g_get_worker_context +} diff --git a/tests/ostree.supp b/tests/ostree.supp new file mode 100644 index 0000000..b81ea51 --- /dev/null +++ b/tests/ostree.supp @@ -0,0 +1 @@ +# Use this to suppress "possibly lost" for global statics diff --git a/tests/test-core.js b/tests/test-core.js new file mode 100644 index 0000000..e9ace6e --- /dev/null +++ b/tests/test-core.js @@ -0,0 +1,55 @@ +#!/usr/bin/env gjs +// +// Copyright (C) 2013 Colin Walters +// +// 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 Gio = imports.gi.Gio; +const OSTree = imports.gi.OSTree; + +function assertEquals(a, b) { + if (a != b) + throw new Error("assertion failed " + JSON.stringify(a) + " == " + JSON.stringify(b)); +} + +let testDataDir = Gio.File.new_for_path('test-data'); +testDataDir.make_directory(null); +testDataDir.get_child('some-file').replace_contents("hello world!", null, false, 0, null); + +let repoPath = Gio.File.new_for_path('repo'); +let repo = OSTree.Repo.new(repoPath); +repo.create(OSTree.RepoMode.ARCHIVE_Z2, null); + +repo.open(null); + +assertEquals(repo.get_mode(), OSTree.RepoMode.ARCHIVE_Z2); + +repo.prepare_transaction(null); + +let mtree = OSTree.MutableTree.new(); +repo.write_directory_to_mtree(testDataDir, mtree, null, null); +let [,dirTree] = repo.write_mtree(mtree, null); +let [,commit] = repo.write_commit(null, 'Some subject', 'Some body', null, dirTree, null); +print("commit => " + commit); + +repo.commit_transaction(null, null); + +let [,root,checksum] = repo.read_commit(commit, null); +let child = root.get_child('some-file'); +let info = child.query_info("standard::name,standard::type,standard::size", 0, null); +assertEquals(info.get_size(), 12); + +print("test-core complete"); diff --git a/tests/test-corruption.sh b/tests/test-corruption.sh new file mode 100755 index 0000000..ef0e94e --- /dev/null +++ b/tests/test-corruption.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# +# Copyright (C) 2011 Colin Walters +# +# 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. + +set -euo pipefail + +echo "1..2" + +. $(dirname $0)/libtest.sh + +setup_test_repository "bare" +$OSTREE checkout test2 checkout-test2 +cd checkout-test2 +chmod o+x firstfile +$OSTREE fsck -q && (echo 1>&2 "fsck unexpectedly succeeded"; exit 1) +chmod o-x firstfile +$OSTREE fsck -q + +echo "ok chmod" + +cd ${test_tmpdir} +rm checkout-test2 -rf +$OSTREE checkout test2 checkout-test2 +cd checkout-test2 +chmod o+x firstfile +$OSTREE fsck -q --delete && (echo 1>&2 "fsck unexpectedly succeeded"; exit 1) + +echo "ok chmod" diff --git a/tests/test-sizes.js b/tests/test-sizes.js new file mode 100644 index 0000000..5cf765f --- /dev/null +++ b/tests/test-sizes.js @@ -0,0 +1,82 @@ +#!/usr/bin/env gjs +// +// Copyright (C) 2013 Colin Walters +// +// 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; + +function assertEquals(a, b) { + if (a != b) + throw new Error("assertion failed " + JSON.stringify(a) + " == " + JSON.stringify(b)); +} + +let testDataDir = Gio.File.new_for_path('test-data'); +testDataDir.make_directory(null); +testDataDir.get_child('some-file').replace_contents("hello world!", null, false, 0, null); +testDataDir.get_child('another-file').replace_contents("hello world again!", null, false, 0, null); + +let repoPath = Gio.File.new_for_path('repo'); +let repo = OSTree.Repo.new(repoPath); +repo.create(OSTree.RepoMode.ARCHIVE_Z2, null); + +repo.open(null); + +let commitModifier = OSTree.RepoCommitModifier.new(OSTree.RepoCommitModifierFlags.GENERATE_SIZES, null); + +assertEquals(repo.get_mode(), OSTree.RepoMode.ARCHIVE_Z2); + +repo.prepare_transaction(null); + +let mtree = OSTree.MutableTree.new(); +repo.write_directory_to_mtree(testDataDir, mtree, commitModifier, null); +let [,dirTree] = repo.write_mtree(mtree, null); +let [,commit] = repo.write_commit(null, 'Some subject', 'Some body', null, dirTree, null); +print("commit => " + commit); + +repo.commit_transaction(null, null); + +// Test the sizes metadata +let [,commitVariant] = repo.load_variant(OSTree.ObjectType.COMMIT, commit); +let metadata = commitVariant.get_child_value(0); +let sizes = metadata.lookup_value('ostree.sizes', GLib.VariantType.new('aay')); +let nSizes = sizes.n_children(); +assertEquals(nSizes, 2); +let expectedUncompressedSizes = [12, 18]; +let foundExpectedUncompressedSizes = 0; +for (let i = 0; i < nSizes; i++) { + let sizeEntry = sizes.get_child_value(i).deep_unpack(); + assertEquals(sizeEntry.length, 34); + let compressedSize = sizeEntry[32]; + let uncompressedSize = sizeEntry[33]; + print("compressed = " + compressedSize); + print("uncompressed = " + uncompressedSize); + for (let j = 0; j < expectedUncompressedSizes.length; j++) { + let expected = expectedUncompressedSizes[j]; + if (expected == uncompressedSize) { + print("Matched expected uncompressed size " + expected); + expectedUncompressedSizes.splice(j, 1); + break; + } + } +} +if (expectedUncompressedSizes.length > 0) { + throw new Error("Failed to match expectedUncompressedSizes: " + JSON.stringify(expectedUncompressedSizes)); +} + +print("test-sizes complete"); diff --git a/tests/test-sysroot.js b/tests/test-sysroot.js new file mode 100644 index 0000000..7e8fcf7 --- /dev/null +++ b/tests/test-sysroot.js @@ -0,0 +1,147 @@ +#!/usr/bin/env gjs +// +// Copyright (C) 2013 Colin Walters +// +// 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; + +function assertEquals(a, b) { + if (a != b) + throw new Error("assertion failed " + JSON.stringify(a) + " == " + JSON.stringify(b)); +} + +function assertNotEquals(a, b) { + if (a == b) + throw new Error("assertion failed " + JSON.stringify(a) + " != " + JSON.stringify(b)); +} + +function libtestExec(shellCode) { + let testdatadir = GLib.getenv("G_TEST_SRCDIR"); + let libtestPath = GLib.build_filenamev([testdatadir, 'libtest.sh']) + let proc = Gio.Subprocess.new(['bash', '-c', 'set -xeuo pipefail; . ' + GLib.shell_quote(libtestPath) + '; ' + shellCode], 0); + proc.wait_check(null); +} + +libtestExec('setup_os_repository archive-z2 syslinux'); + +let upstreamRepo = OSTree.Repo.new(Gio.File.new_for_path('testos-repo')); +upstreamRepo.open(null); + +let runtimeRef = 'testos/buildmaster/x86_64-runtime'; +let [,rev] = upstreamRepo.resolve_rev(runtimeRef, false); + +print("testos => " + rev); + +//// TEST: We should have no deployments + +let sysroot = OSTree.Sysroot.new(Gio.File.new_for_path('sysroot')); +sysroot.load(null); +let deployments = sysroot.get_deployments(); +assertEquals(deployments.length, 0); + +//// Add the remote, and do a pull + +let [,sysrootRepo] = sysroot.get_repo(null); +sysrootRepo.remote_add('testos', 'file://' + upstreamRepo.get_path().get_path(), + GLib.Variant.new('a{sv}', {'gpg-verify': GLib.Variant.new('b', false), + 'branches': GLib.Variant.new('as', [runtimeRef])}), null); +sysrootRepo.pull('testos', null, 0, null, null); + +//// TEST: We can deploy one tree + +let mergeDeployment = sysroot.get_merge_deployment('testos'); + +let origin = sysroot.origin_new_from_refspec(runtimeRef); +let [,deployment] = sysroot.deploy_tree('testos', rev, origin, + mergeDeployment, null, + null); +let newDeployments = deployments; +deployments = null; +newDeployments.unshift(deployment); +sysroot.write_deployments(newDeployments, null); +deployments = sysroot.get_deployments(); +assertEquals(deployments.length, newDeployments.length); +assertEquals(deployments[0].get_csum(), deployment.get_csum()); + +let deploymentPath = sysroot.get_deployment_directory(deployment); +assertEquals(deploymentPath.query_exists(null), true); + +print("OK one deployment"); + +/// TEST: We can delete the deployment, going back to empty +sysroot.write_deployments([], null); + +print("OK empty deployments"); + +assertEquals(deploymentPath.query_exists(null), false); + +//// Ok, redeploy, then add a new revision upstream and pull it + +let [,deployment] = sysroot.deploy_tree('testos', rev, origin, + mergeDeployment, null, + null); +newDeployments = deployments; +deployments = null; +newDeployments.unshift(deployment); +print(JSON.stringify(newDeployments)); +sysroot.write_deployments(newDeployments, null); + +libtestExec('os_repository_new_commit'); + +sysrootRepo.pull('testos', null, 0, null, null); + +let [,newRev] = upstreamRepo.resolve_rev(runtimeRef, false); + +print("testos => " + newRev); +assertNotEquals(rev, newRev); + +mergeDeployment = sysroot.get_merge_deployment('testos'); +assertEquals(mergeDeployment.get_csum(), deployment.get_csum()); +let [,newDeployment] = sysroot.deploy_tree('testos', newRev, origin, + mergeDeployment, null, + null); +newDeployments = [newDeployment, mergeDeployment]; +assertNotEquals(mergeDeployment.get_bootcsum(), newDeployment.get_bootcsum()); +assertNotEquals(mergeDeployment.get_csum(), newDeployment.get_csum()); +sysroot.write_deployments(newDeployments, null); +deployments = sysroot.get_deployments(); +assertEquals(deployments.length, 2); +assertEquals(deploymentPath.query_exists(null), true); +let newDeploymentPath = sysroot.get_deployment_directory(newDeployment); +assertEquals(newDeploymentPath.query_exists(null), true); + +print("OK two deployments"); + +libtestExec('os_repository_new_commit 0 1'); + +sysrootRepo.pull('testos', null, 0, null, null); + +let [,thirdRev] = sysrootRepo.resolve_rev(runtimeRef, false); +assertNotEquals(newRev, thirdRev); + +mergeDeployment = sysroot.get_merge_deployment('testos'); +let [,thirdDeployment] = sysroot.deploy_tree('testos', thirdRev, origin, + mergeDeployment, null, + null); +assertEquals(mergeDeployment.get_bootcsum(), thirdDeployment.get_bootcsum()); +assertNotEquals(mergeDeployment.get_csum(), thirdDeployment.get_csum()); +newDeployments = [deployment, newDeployment, thirdDeployment]; +sysroot.write_deployments(newDeployments, null); +deployments = sysroot.get_deployments(); +assertEquals(deployments.length, 3);