diff --git a/.gitignore b/.gitignore index 011e9f8..8261923 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/modulemd-2.0.0.tar.xz +SOURCES/modulemd-2.5.0.tar.xz diff --git a/.libmodulemd.metadata b/.libmodulemd.metadata index c29b91c..0ea40c8 100644 --- a/.libmodulemd.metadata +++ b/.libmodulemd.metadata @@ -1 +1 @@ -e242f10ac0185da47cc54d0253cb0f8a80633ff4 SOURCES/modulemd-2.0.0.tar.xz +2b6c3443a36ec821fd289ae6605e9dea4c5dbcda SOURCES/modulemd-2.5.0.tar.xz diff --git a/SOURCES/0001-Don-t-fail-merges-when-default-streams-differ.patch b/SOURCES/0001-Don-t-fail-merges-when-default-streams-differ.patch deleted file mode 100644 index 1daa97a..0000000 --- a/SOURCES/0001-Don-t-fail-merges-when-default-streams-differ.patch +++ /dev/null @@ -1,543 +0,0 @@ -From 774f36026f1d3a4215be67845c2873135ceab6e4 Mon Sep 17 00:00:00 2001 -From: Stephen Gallagher -Date: Wed, 16 Jan 2019 13:21:44 -0500 -Subject: [PATCH] Don't fail merges when default streams differ - -Instead of failing the merge on a default stream conflict, we will -instead treat it as having no default set. This is safe because if -the module is not yet installed, then this just means its packages -aren't visible and it needs to be selected explicitly. - -If some packages from it are already installed, then the module -stream is already set, and thus changing the default won't matter. - -Update documentation to reflect modified field in Defaults - -Resolves: rhbz#1666871 - -Signed-off-by: Stephen Gallagher ---- - .../modulemd-1.0/private/modulemd-private.h | 2 + - modulemd/v1/modulemd-defaults.c | 39 +++++++---- - modulemd/v1/tests/test-modulemd-defaults.c | 66 ++++++++++++++++++- - .../modulemd-module-index-merger.h | 18 +++-- - .../private/modulemd-defaults-v1-private.h | 2 + - modulemd/v2/modulemd-defaults-v1.c | 59 +++++++++++------ - modulemd/v2/tests/ModulemdTests/merger.py | 33 +++++++--- - .../v2/tests/test_data/overriding-nodejs.yaml | 11 ++++ - test_data/defaults/overriding-nodejs.yaml | 10 +++ - 9 files changed, 191 insertions(+), 49 deletions(-) - create mode 100644 modulemd/v2/tests/test_data/overriding-nodejs.yaml - create mode 100644 test_data/defaults/overriding-nodejs.yaml - -diff --git a/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h b/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h -index 20604efab843de6ac64cd9e181ce93d7e3a798fe..e9a785aed0d38598ce08d58e7e507d01698788a0 100644 ---- a/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h -+++ b/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h -@@ -24,10 +24,12 @@ enum - MD_VERSION_MAX = G_MAXUINT64 - }; - - #define MD_VERSION_LATEST MD_VERSION_2 - -+#define DEFAULT_MERGE_CONFLICT "__merge_conflict__" -+ - ModulemdModule * - modulemd_module_new_from_modulestream (ModulemdModuleStream *stream); - - ModulemdModuleStream * - modulemd_module_peek_modulestream (ModulemdModule *self); -diff --git a/modulemd/v1/modulemd-defaults.c b/modulemd/v1/modulemd-defaults.c -index 77ce30733945e30ffb8368986fa8c54c45697b5a..d44076eef0ac3bffae05f74b852fb6b51c2aee64 100644 ---- a/modulemd/v1/modulemd-defaults.c -+++ b/modulemd/v1/modulemd-defaults.c -@@ -12,10 +12,11 @@ - */ - - #include "modulemd.h" - #include "modulemd-defaults.h" - #include "modulemd-simpleset.h" -+#include "private/modulemd-private.h" - #include "private/modulemd-yaml.h" - - - GQuark - modulemd_defaults_error_quark (void) -@@ -146,19 +147,38 @@ modulemd_defaults_set_default_stream (ModulemdDefaults *self, - const gchar * - modulemd_defaults_peek_default_stream (ModulemdDefaults *self) - { - g_return_val_if_fail (self, NULL); - -+ if (self->default_stream && -+ g_str_equal (self->default_stream, DEFAULT_MERGE_CONFLICT)) -+ { -+ /* During an index merge, we determined that this was in conflict -+ * with another set of ModulemdDefaults for the same module. If we -+ * see this, treat it as no default stream when querying for it. -+ */ -+ return NULL; -+ } - return self->default_stream; - } - - - gchar * - modulemd_defaults_dup_default_stream (ModulemdDefaults *self) - { - g_return_val_if_fail (self, NULL); - -+ if (self->default_stream && -+ g_str_equal (self->default_stream, DEFAULT_MERGE_CONFLICT)) -+ { -+ /* During an index merge, we determined that this was in conflict -+ * with another set of ModulemdDefaults for the same module. If we -+ * see this, treat it as no default stream when querying for it. -+ */ -+ return NULL; -+ } -+ - return g_strdup (self->default_stream); - } - - - void -@@ -753,28 +773,25 @@ modulemd_defaults_merge (ModulemdDefaults *first, - /* They had the same 'modified' value (such as both zero, for - * backwards-compatibility with 1.7.x and older. - * Merge them as best we can. - */ - -+ defaults = modulemd_defaults_copy (first); -+ - /* First check for incompatibilities with the streams */ -- if (g_strcmp0 (modulemd_defaults_peek_default_stream (first), -- modulemd_defaults_peek_default_stream (second))) -+ if (g_strcmp0 (first->default_stream, second->default_stream)) - { - /* Default streams don't match and override is not set. - * Return an error - */ -- g_set_error ( -- error, -- MODULEMD_DEFAULTS_ERROR, -- MODULEMD_DEFAULTS_ERROR_CONFLICTING_STREAMS, -- "Conflicting default streams when merging defaults for module %s", -- modulemd_defaults_peek_module_name (first)); -- return NULL; -+ /* They have conflicting default streams */ -+ g_info ("Module stream mismatch in merge: %s != %s", -+ first->default_stream, -+ second->default_stream); -+ modulemd_defaults_set_default_stream (defaults, DEFAULT_MERGE_CONFLICT); - } - -- defaults = modulemd_defaults_copy (first); -- - /* Merge the profile defaults */ - profile_defaults = modulemd_defaults_peek_profile_defaults (defaults); - - g_hash_table_iter_init (&iter, - modulemd_defaults_peek_profile_defaults (second)); -diff --git a/modulemd/v1/tests/test-modulemd-defaults.c b/modulemd/v1/tests/test-modulemd-defaults.c -index 5d032d83cbca4046af13719f68bdbc6778d6879e..35142b885b3ec30f5109d53befe17be3e08d7b5a 100644 ---- a/modulemd/v1/tests/test-modulemd-defaults.c -+++ b/modulemd/v1/tests/test-modulemd-defaults.c -@@ -602,10 +602,11 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture, - { - g_autofree gchar *yaml_base_path = NULL; - g_autofree gchar *yaml_override_path = NULL; - g_autoptr (GPtrArray) base_objects = NULL; - g_autoptr (GPtrArray) override_objects = NULL; -+ g_autoptr (GPtrArray) override_nodejs_objects = NULL; - g_autoptr (GPtrArray) merged_objects = NULL; - g_autoptr (ModulemdPrioritizer) prioritizer = NULL; - g_autoptr (GError) error = NULL; - GHashTable *htable = NULL; - gint64 prio; -@@ -618,10 +619,22 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture, - - base_objects = modulemd_objects_from_file (yaml_base_path, &error); - g_assert_nonnull (base_objects); - g_assert_cmpint (base_objects->len, ==, 7); - -+ -+ yaml_override_path = -+ g_strdup_printf ("%s/test_data/defaults/overriding-nodejs.yaml", -+ g_getenv ("MESON_SOURCE_ROOT")); -+ g_assert_nonnull (yaml_override_path); -+ -+ override_nodejs_objects = -+ modulemd_objects_from_file (yaml_override_path, &error); -+ g_clear_pointer (&yaml_override_path, g_free); -+ g_assert_nonnull (override_nodejs_objects); -+ g_assert_cmpint (override_nodejs_objects->len, ==, 1); -+ - yaml_override_path = g_strdup_printf ( - "%s/test_data/defaults/overriding.yaml", g_getenv ("MESON_SOURCE_ROOT")); - g_assert_nonnull (yaml_override_path); - - override_objects = modulemd_objects_from_file (yaml_override_path, &error); -@@ -659,10 +672,52 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture, - fprintf (stderr, "Merge error: %s", error->message); - } - g_assert_true (result); - - -+ /* -+ * Test that importing the nodejs overrides at the same priority level fails. -+ * -+ * This YAML has a conflicting default stream which should be ignored and set -+ * to "no default stream". -+ */ -+ -+ result = modulemd_prioritizer_add ( -+ prioritizer, override_nodejs_objects, prio, &error); -+ g_assert_true (result); -+ -+ merged_objects = modulemd_prioritizer_resolve (prioritizer, &error); -+ g_assert_nonnull (merged_objects); -+ g_assert_cmpint (merged_objects->len, ==, 3); -+ -+ for (gint i = 0; i < merged_objects->len; i++) -+ { -+ if (MODULEMD_IS_DEFAULTS (g_ptr_array_index (merged_objects, i))) -+ { -+ defaults = g_ptr_array_index (merged_objects, i); -+ if (!g_strcmp0 (modulemd_defaults_peek_module_name (defaults), -+ "nodejs")) -+ { -+ g_assert_null (modulemd_defaults_peek_default_stream (defaults)); -+ } -+ } -+ } -+ -+ g_clear_pointer (&merged_objects, g_ptr_array_unref); -+ -+ -+ /* Start over and test profile conflicts */ -+ g_clear_pointer (&prioritizer, g_object_unref); -+ prioritizer = modulemd_prioritizer_new (); -+ result = modulemd_prioritizer_add (prioritizer, base_objects, prio, &error); -+ if (!result) -+ { -+ fprintf (stderr, "Merge error: %s", error->message); -+ } -+ g_assert_true (result); -+ -+ - /* - * Test that importing the overrides at the same priority level fails. - * - * These objects have several conflicts with the base objects that cannot be - * merged. -@@ -671,11 +726,11 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture, - modulemd_prioritizer_add (prioritizer, override_objects, prio, &error); - g_assert_false (result); - g_assert_cmpstr ( - g_quark_to_string (error->domain), ==, "modulemd-defaults-error-quark"); - g_assert_cmpint ( -- error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_STREAMS); -+ error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_PROFILES); - g_clear_pointer (&error, g_error_free); - - /* The object's internal state is undefined after an error, so delete it */ - g_clear_pointer (&prioritizer, g_object_unref); - -@@ -987,11 +1042,11 @@ modulemd_defaults_test_index_prioritizer (DefaultsFixture *fixture, - modulemd_prioritizer_add_index (prioritizer, override_index, prio, &error); - g_assert_false (result); - g_assert_cmpstr ( - g_quark_to_string (error->domain), ==, "modulemd-defaults-error-quark"); - g_assert_cmpint ( -- error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_STREAMS); -+ error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_PROFILES); - g_clear_pointer (&error, g_error_free); - - /* The object's internal state is undefined after an error, so delete it */ - g_clear_pointer (&prioritizer, g_object_unref); - -@@ -1138,10 +1193,15 @@ modulemd_regressions_issue44 (DefaultsFixture *fixture, - g_assert_true (result); - - - /* Add another almost-identical document, except with a conflicting default - * stream set. -+ * -+ * NOTE: when this was written (for issue 44 on GitHub), this was meant to be -+ * a hard error. As of 1.8.1 we expect this to just result in having no -+ * default stream for this module. This test has been slightly modified so -+ * that the expected result is now a pass. - */ - yaml_conflicting_path = g_strdup_printf ( - "%s/test_data/defaults/issue44-2.yaml", g_getenv ("MESON_SOURCE_ROOT")); - g_assert_nonnull (yaml_conflicting_path); - -@@ -1149,11 +1209,11 @@ modulemd_regressions_issue44 (DefaultsFixture *fixture, - modulemd_objects_from_file (yaml_conflicting_path, &error); - g_assert_nonnull (conflicting_objects); - - result = - modulemd_prioritizer_add (prioritizer, conflicting_objects, 0, &error); -- g_assert_false (result); -+ g_assert_true (result); - } - - - static void - modulemd_regressions_issue45 (DefaultsFixture *fixture, -diff --git a/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h b/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h -index 27cccb738dc805724268afa04acc13d4e250eae2..b019f0ed856684a003e9c2f6abefc70e1448246a 100644 ---- a/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h -+++ b/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h -@@ -51,22 +51,30 @@ G_BEGIN_DECLS - * there exists two #ModulemdModuleStream entries that have different content - * for the same NSVC, the behavior is undefined. - * - * Merging #ModulemdDefaults entries behaves as follows: - * -+ * - Within a ModuleIndex, if two or more default entries reference the same -+ * module, the one with the highest modified field will be used and the -+ * others discarded. -+ * - When merging ModuleIndexes, if two or more indexes contain Defaults for -+ * the same module, but different modified values, the one with the highest -+ * modified value will be used and the others discarded. - * - Any module default that is provided by a single repository is - * authoritative. - * - If the repos have different priorities (not common), then the default for - * this module and stream name coming from the repo of higher priority will -- * be used and the default from the lower-priority repo will not be included. -+ * be used and the default from the lower-priority repo will not be included -+ * even if it has a higher modified value. - * - If the repos have the same priority (such as "fedora" and "updates" in the -- * Fedora Project), the entries will be merged as follows: -- * - If both repositories specify a default stream for the module, use it. -+ * Fedora Project) and modified value, the entries will be merged as follows: -+ * - If both repositories specify the same default stream for the module, use -+ * it. - * - If either repository specifies a default stream for the module and the - * other does not, use the one specified. -- * - If both repositories specify different streams, this is an unresolvable -- * merge conflict and the merge resolution will fail and report an error. -+ * - If both repositories specify different default streams, the merge will -+ * unset the default stream and proceed with the merge. - * - If both repositories specify a set of default profiles for a stream and - * the sets are equivalent, use that set. - * - If one repository specifies a set of default profiles for a stream and - * the other does not, use the one specified. - * - If both repositories specify a set of default profiles for a stream and -diff --git a/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h b/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h -index 9cac6cc53175a0eecca986f4fa96a7b7b1070957..de2ede98e6fb49bfd792b5f2913868fad6ff27db 100644 ---- a/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h -+++ b/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h -@@ -26,10 +26,12 @@ G_BEGIN_DECLS - * @stability: private - * @short_description: #ModulemdDefault methods that should only be used by - * internal consumers. - */ - -+#define DEFAULT_MERGE_CONFLICT "__merge_conflict__" -+ - /** - * modulemd_defaults_v1_parse_yaml: - * @subdoc: (in): A #ModulemdSubdocumentInfo representing a defaults document - * of metadata version 1. - * @strict: (in): Whether the parser should return failure if it encounters an -diff --git a/modulemd/v2/modulemd-defaults-v1.c b/modulemd/v2/modulemd-defaults-v1.c -index c8f983105b529519365d0a653d8d07715f610b97..1c1cdd7b1036734a477b72d12f12526af1de777d 100644 ---- a/modulemd/v2/modulemd-defaults-v1.c -+++ b/modulemd/v2/modulemd-defaults-v1.c -@@ -179,11 +179,22 @@ modulemd_defaults_v1_get_default_stream (ModulemdDefaultsV1 *self, - { - const gchar *default_stream = NULL; - g_return_val_if_fail (MODULEMD_IS_DEFAULTS_V1 (self), NULL); - - if (!intent) -- return self->default_stream; -+ { -+ if (self->default_stream && -+ g_str_equal (self->default_stream, DEFAULT_MERGE_CONFLICT)) -+ { -+ /* During an index merge, we determined that this was in conflict -+ * with another set of ModulemdDefaults for the same module. If we -+ * see this, treat it as no default stream when querying for it. -+ */ -+ return NULL; -+ } -+ return self->default_stream; -+ } - - default_stream = g_hash_table_lookup (self->intent_default_streams, intent); - if (default_stream) - { - if (default_stream[0] == '\0') -@@ -1159,12 +1170,10 @@ ModulemdDefaults * - modulemd_defaults_v1_merge (const gchar *module_name, - ModulemdDefaultsV1 *from, - ModulemdDefaultsV1 *into, - GError **error) - { -- const gchar *into_default_stream; -- const gchar *from_default_stream; - g_autoptr (ModulemdDefaultsV1) merged = NULL; - GHashTableIter iter; - gpointer key, value; - GHashTable *intent_profiles = NULL; - GHashTable *merged_intent_profiles = NULL; -@@ -1175,37 +1184,45 @@ modulemd_defaults_v1_merge (const gchar *module_name, - g_autoptr (GError) nested_error = NULL; - - merged = modulemd_defaults_v1_new (module_name); - - /* Merge the default streams */ -- into_default_stream = modulemd_defaults_v1_get_default_stream (into, NULL); -- from_default_stream = modulemd_defaults_v1_get_default_stream (from, NULL); -- -- if (into_default_stream && !from_default_stream) -+ if (into->default_stream && !from->default_stream) - { - modulemd_defaults_v1_set_default_stream ( -- merged, into_default_stream, NULL); -+ merged, into->default_stream, NULL); - } -- else if (from_default_stream && !into_default_stream) -+ else if (from->default_stream && !into->default_stream) - { - modulemd_defaults_v1_set_default_stream ( -- merged, from_default_stream, NULL); -+ merged, from->default_stream, NULL); - } -- else if (into_default_stream && from_default_stream) -+ else if (into->default_stream && from->default_stream) - { -- if (!g_str_equal (into_default_stream, from_default_stream)) -+ if (g_str_equal (into->default_stream, DEFAULT_MERGE_CONFLICT)) - { -- g_set_error (error, -- MODULEMD_ERROR, -- MODULEMD_ERROR_VALIDATE, -- "Module stream mismatch in merge: %s != %s", -- into_default_stream, -- from_default_stream); -- return NULL; -+ /* A previous pass over this same module encountered a merge -+ * conflict, so we need to propagate that. -+ */ -+ modulemd_defaults_v1_set_default_stream ( -+ merged, DEFAULT_MERGE_CONFLICT, NULL); -+ } -+ else if (!g_str_equal (into->default_stream, from->default_stream)) -+ { -+ /* They have conflicting default streams */ -+ g_info ("Module stream mismatch in merge: %s != %s", -+ into->default_stream, -+ from->default_stream); -+ modulemd_defaults_v1_set_default_stream ( -+ merged, DEFAULT_MERGE_CONFLICT, NULL); -+ } -+ else -+ { -+ /* They're the same, so store that */ -+ modulemd_defaults_v1_set_default_stream ( -+ merged, into->default_stream, NULL); - } -- modulemd_defaults_v1_set_default_stream ( -- merged, into_default_stream, NULL); - } - else - { - /* Both values were NULL. - * Nothing to do, leave it blank. -diff --git a/modulemd/v2/tests/ModulemdTests/merger.py b/modulemd/v2/tests/ModulemdTests/merger.py -index e7cbf4214bb111fbc5732fe983ee5ccee134fd83..49c2722959486aeb250d88daf7f068cacc8c3fe7 100644 ---- a/modulemd/v2/tests/ModulemdTests/merger.py -+++ b/modulemd/v2/tests/ModulemdTests/merger.py -@@ -104,26 +104,41 @@ class TestModuleIndexMerger(TestBase): - self.assertEqual( - len(httpd_defaults.get_default_profiles_for_stream('2.4', 'workstation')), 1) - self.assertEqual( - len(httpd_defaults.get_default_profiles_for_stream('2.6', 'workstation')), 3) - -+ # Get another set of objects that will override the default stream for -+ # nodejs -+ override_nodejs_index = Modulemd.ModuleIndex() -+ override_nodejs_index.update_from_file( -+ path.join( -+ self.source_root, -+ "modulemd/v2/tests/test_data/overriding-nodejs.yaml"), True) -+ -+ # Test that adding both of these at the same priority level results in -+ # the no default stream -+ merger = Modulemd.ModuleIndexMerger() -+ merger.associate_index(base_index, 0) -+ merger.associate_index(override_nodejs_index, 0) -+ -+ merged_index = merger.resolve() -+ self.assertIsNotNone(merged_index) -+ -+ nodejs = merged_index.get_module('nodejs') -+ self.assertIsNotNone(nodejs) -+ -+ nodejs_defaults = nodejs.get_defaults() -+ self.assertIsNotNone(nodejs_defaults) -+ self.assertIsNone(nodejs_defaults.get_default_stream()) -+ - # Get another set of objects that will override the above - override_index = Modulemd.ModuleIndex() - override_index.update_from_file( - path.join( - self.source_root, - "modulemd/v2/tests/test_data/overriding.yaml"), True) - -- # Test that adding both of these at the same priority level fails -- # with a merge conflict. -- merger = Modulemd.ModuleIndexMerger() -- merger.associate_index(base_index, 0) -- merger.associate_index(override_index, 0) -- -- with self.assertRaisesRegex(GLib.GError, 'Module stream mismatch in merge'): -- merged_index = merger.resolve() -- - # Test that override_index at a higher priority level succeeds - # Test that adding both of these at the same priority level fails - # with a merge conflict. - # Use randomly-selected high and low values to make sure we don't have - # sorting issues. -diff --git a/modulemd/v2/tests/test_data/overriding-nodejs.yaml b/modulemd/v2/tests/test_data/overriding-nodejs.yaml -new file mode 100644 -index 0000000000000000000000000000000000000000..b588f5f542d84755fa74fc1dbf059c0766d2a712 ---- /dev/null -+++ b/modulemd/v2/tests/test_data/overriding-nodejs.yaml -@@ -0,0 +1,11 @@ -+--- -+# Override the default stream -+document: modulemd-defaults -+version: 1 -+data: -+ module: nodejs -+ stream: '9.0' -+ profiles: -+ '6.0': [default] -+ '8.0': [super] -+ '9.0': [supermegaultra] -\ No newline at end of file -diff --git a/test_data/defaults/overriding-nodejs.yaml b/test_data/defaults/overriding-nodejs.yaml -new file mode 100644 -index 0000000000000000000000000000000000000000..937a2b899afc6b5254fd3b3e61e5b32035a3130a ---- /dev/null -+++ b/test_data/defaults/overriding-nodejs.yaml -@@ -0,0 +1,10 @@ -+--- -+document: modulemd-defaults -+version: 1 -+data: -+ module: nodejs -+ stream: '9.0' -+ profiles: -+ '6.0': [default] -+ '8.0': [super] -+ '9.0': [supermegaultra] -\ No newline at end of file --- -2.20.1 - diff --git a/SOURCES/0001-Double-valgrind-timeout.patch b/SOURCES/0001-Double-valgrind-timeout.patch new file mode 100644 index 0000000..e7f128a --- /dev/null +++ b/SOURCES/0001-Double-valgrind-timeout.patch @@ -0,0 +1,29 @@ +From 1a7bf143761ff8e3f4f6585b82c0be4dbd511fca Mon Sep 17 00:00:00 2001 +From: Stephen Gallagher +Date: Thu, 23 May 2019 14:00:36 -0400 +Subject: [PATCH 1/3] Double valgrind timeout + +On some architectures under heavy load, the valgrind check on v2 +is taking a long time. + +Signed-off-by: Stephen Gallagher +--- + modulemd/meson.build | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/modulemd/meson.build b/modulemd/meson.build +index 47bd1f58e6401d2634d8ff737c2b347f5ebc6bf5..e49c7a9df76dcf37a18ddeba3150d6c914aa4e25 100644 +--- a/modulemd/meson.build ++++ b/modulemd/meson.build +@@ -313,7 +313,7 @@ endif + if valgrind.found() + modulemd_valgrind_scripts = files('common/tests/test-valgrind.py') + test ('valgrind', python3, + env : test_env, + args : modulemd_valgrind_scripts, +- timeout : 600) ++ timeout : 1200) + endif +-- +2.21.0 + diff --git a/SOURCES/0001-Include-modified-value-when-copying-Defaults-objects.patch b/SOURCES/0001-Include-modified-value-when-copying-Defaults-objects.patch deleted file mode 100644 index ad3ee96..0000000 --- a/SOURCES/0001-Include-modified-value-when-copying-Defaults-objects.patch +++ /dev/null @@ -1,106 +0,0 @@ -From f66d185dd5c2c1750b3626c2e0bdfeab63e427b6 Mon Sep 17 00:00:00 2001 -From: Stephen Gallagher -Date: Fri, 11 Jan 2019 08:36:11 -0500 -Subject: [PATCH] Include modified value when copying Defaults objects - -The symptom of this was that any defaults object read from a YAML -stream would end up stored in the ModuleIndex with the a zero for -the modified value. - -Signed-off-by: Stephen Gallagher ---- - modulemd/v2/modulemd-defaults.c | 7 ++++-- - modulemd/v2/tests/ModulemdTests/defaults.py | 25 +++++++++++++++++++++ - 2 files changed, 30 insertions(+), 2 deletions(-) - -diff --git a/modulemd/v2/modulemd-defaults.c b/modulemd/v2/modulemd-defaults.c -index 9e5c31b499704ae7a8543c91b9ea3bbf0dbf981d..c577d4a0c3db45319c8e0582b4cc07f3943836fa 100644 ---- a/modulemd/v2/modulemd-defaults.c -+++ b/modulemd/v2/modulemd-defaults.c -@@ -91,14 +91,18 @@ modulemd_defaults_copy (ModulemdDefaults *self) - - - static ModulemdDefaults * - modulemd_defaults_default_copy (ModulemdDefaults *self) - { -+ g_autoptr (ModulemdDefaults) copy = NULL; - g_return_val_if_fail (MODULEMD_IS_DEFAULTS (self), NULL); - -- return modulemd_defaults_new (modulemd_defaults_get_mdversion (self), -+ copy = modulemd_defaults_new (modulemd_defaults_get_mdversion (self), - modulemd_defaults_get_module_name (self)); -+ modulemd_defaults_set_modified (copy, modulemd_defaults_get_modified (self)); -+ -+ return g_steal_pointer (©); - } - - - gboolean - modulemd_defaults_validate (ModulemdDefaults *self, GError **error) -@@ -214,11 +218,10 @@ modulemd_defaults_set_modified (ModulemdDefaults *self, guint64 modified) - { - g_return_if_fail (MODULEMD_IS_DEFAULTS (self)); - - ModulemdDefaultsPrivate *priv = - modulemd_defaults_get_instance_private (self); -- - priv->modified = modified; - } - - - guint64 -diff --git a/modulemd/v2/tests/ModulemdTests/defaults.py b/modulemd/v2/tests/ModulemdTests/defaults.py -index ddac23bbed573b3725feb8cb0090fb878a1f4f22..9a783d25617fc53f59448bc32a68c6e2755dd034 100644 ---- a/modulemd/v2/tests/ModulemdTests/defaults.py -+++ b/modulemd/v2/tests/ModulemdTests/defaults.py -@@ -10,11 +10,13 @@ - # This program is free software. - # For more information on the license, see COPYING. - # For more information on free software, see - # . - -+import os - import sys -+ - try: - import unittest - import gi - gi.require_version('Modulemd', '2.0') - from gi.repository import Modulemd -@@ -92,10 +94,33 @@ class TestDefaults(TestBase): - - # Ensure we cannot set the module_name - with self.expect_signal(): - defs.props.module_name = None - -+ def test_modified(self): -+ defs = Modulemd.Defaults.new( -+ Modulemd.DefaultsVersionEnum.LATEST, 'foo') -+ self.assertIsNotNone(defs) -+ -+ self.assertEqual(defs.get_modified(), 0) -+ -+ defs.set_modified(201901110830) -+ -+ self.assertEqual(defs.get_modified(), 201901110830) -+ -+ # Load a defaults object into an Index -+ index = Modulemd.ModuleIndex.new() -+ index.update_from_file("%s/mod-defaults/spec.v1.yaml" % ( -+ os.getenv('MESON_SOURCE_ROOT')), True) -+ module_names = index.get_module_names() -+ self.assertEqual(len(module_names), 1) -+ -+ defs = index.get_module(index.get_module_names()[0]).get_defaults() -+ self.assertIsNotNone(defs) -+ -+ self.assertEqual(defs.get_modified(), 201812071200) -+ - def test_validate(self): - defs = Modulemd.Defaults.new( - Modulemd.DefaultsVersionEnum.LATEST, 'foo') - assert defs - --- -2.20.1 - diff --git a/SOURCES/0002-Parallelize-the-valgrind-tests.patch b/SOURCES/0002-Parallelize-the-valgrind-tests.patch new file mode 100644 index 0000000..ba160a5 --- /dev/null +++ b/SOURCES/0002-Parallelize-the-valgrind-tests.patch @@ -0,0 +1,136 @@ +From d9b41f72d4b2d545b2600aff7bd8a27ed0093750 Mon Sep 17 00:00:00 2001 +From: Stephen Gallagher +Date: Wed, 29 May 2019 11:33:57 -0400 +Subject: [PATCH 2/3] Parallelize the valgrind tests + +This considerably reduces the time needed to perform the valgrind +memory tests on systems with multiple available processors. In the +case of my laptop, the duration was reduced from ~200s to 90s. + +Signed-off-by: Stephen Gallagher +--- + modulemd/common/tests/test-valgrind.py | 74 ++++++++++++++------------ + 1 file changed, 41 insertions(+), 33 deletions(-) + +diff --git a/modulemd/common/tests/test-valgrind.py b/modulemd/common/tests/test-valgrind.py +index 9be72c705fde79aa305d831eaa4f31f7e2cc663f..9349749658ccca0529776f3d534664d614c1cb4d 100644 +--- a/modulemd/common/tests/test-valgrind.py ++++ b/modulemd/common/tests/test-valgrind.py +@@ -16,13 +16,16 @@ import os + import sys + import subprocess + import tempfile + import xml.etree.ElementTree as ET + ++from multiprocessing import Pool, TimeoutError ++ + if os.getenv('MMD_SKIP_VALGRIND'): + sys.exit(77) + ++ + failed = False + + # Get the list of tests to run + proc_result = subprocess.run(['meson', 'test', '--list'], + stdout=subprocess.PIPE, +@@ -47,13 +50,13 @@ for test in unfiltered_tests: + test == 'test_dirty_repo' or + test == 'valgrind'): + continue + tests.append(test) + ++ + with tempfile.TemporaryDirectory(prefix="libmodulemd_valgrind_") as tmpdirname: +- for test in tests: +- # TODO: auto-detect the location of the suppression file ++ def exec_valgrind(test): + valgrind_command = "/usr/bin/valgrind " \ + "--leak-check=full " \ + "--suppressions=/usr/share/glib-2.0/valgrind/glib.supp " \ + "--xml=yes " \ + "--xml-file=%s/%s.xml " % (tmpdirname, test) +@@ -64,45 +67,50 @@ with tempfile.TemporaryDirectory(prefix="libmodulemd_valgrind_") as tmpdirname: + '-t', '10', + '--logbase=%s' % test, + '--wrap=%s' % valgrind_command, + test]) + +- if proc_result.returncode != 0: +- print("Valgrind exited with an error on %s" % test, +- file=sys.stderr) +- failed = True +- continue ++ return proc_result.returncode, test + +- # Process the XML for leaks +- tree = ET.parse('%s/%s.xml' % (tmpdirname, test)) +- root = tree.getroot() ++ with Pool() as pool: ++ for returncode, test in pool.map(exec_valgrind, tests): ++ if returncode != 0: ++ print("Valgrind exited with an error on %s" % test, ++ file=sys.stderr) ++ failed = True ++ continue + +- for root_child in root: +- if (root_child.tag == "error"): +- for error_child in root_child: +- if error_child.tag == 'kind': +- if error_child.text == 'Leak_DefinitelyLost': +- print("Memory leak detected in %s" % test, +- file=sys.stderr) +- failed = True ++ # Process the XML for leaks ++ tree = ET.parse('%s/%s.xml' % (tmpdirname, test)) ++ root = tree.getroot() + +- elif error_child.text == 'InvalidFree': +- print("Invalid free() detected in %s" % test, +- file=sys.stderr) +- failed = True ++ for root_child in root: ++ if (root_child.tag == "error"): ++ for error_child in root_child: ++ if error_child.tag == 'kind': ++ if error_child.text == 'Leak_DefinitelyLost': ++ print("Memory leak detected in %s" % test, ++ file=sys.stderr) ++ failed = True + +- elif error_child.text == 'InvalidRead': +- print("Invalid read detected in %s" % test, +- file=sys.stderr) +- failed = True ++ elif error_child.text == 'InvalidFree': ++ print("Invalid free() detected in %s" % test, ++ file=sys.stderr) ++ failed = True + +- elif error_child.text == 'UninitCondition': +- print("Uninitialized usage detected in %s" % test, +- file=sys.stderr) +- failed = True +- if failed: +- with open('%s/%s.xml' % (tmpdirname, test), 'r') as xml: +- print(xml.read()) ++ elif error_child.text == 'InvalidRead': ++ print("Invalid read detected in %s" % test, ++ file=sys.stderr) ++ failed = True ++ ++ elif error_child.text == 'UninitCondition': ++ print( ++ "Uninitialized usage detected in %s" % ++ test, file=sys.stderr) ++ failed = True ++ if failed: ++ with open('%s/%s.xml' % (tmpdirname, test), 'r') as xml: ++ print(xml.read()) + + + if failed: + sys.exit(1) +-- +2.21.0 + diff --git a/SOURCES/0003-Fix-transfer-type-for-Module.search_streams.patch b/SOURCES/0003-Fix-transfer-type-for-Module.search_streams.patch new file mode 100644 index 0000000..40ba286 --- /dev/null +++ b/SOURCES/0003-Fix-transfer-type-for-Module.search_streams.patch @@ -0,0 +1,150 @@ +From 340e316bd6384562086b4e381c8cd42b1ccd0781 Mon Sep 17 00:00:00 2001 +From: Stephen Gallagher +Date: Tue, 28 May 2019 14:28:30 -0400 +Subject: [PATCH 3/3] Fix transfer type for Module.search_streams() + +Technically this is an API-breaking change, but no one is using it +yet and it was always expected to be managed this way. + +Fixes: https://github.com/fedora-modularity/libmodulemd/issues/308 + +Signed-off-by: Stephen Gallagher +--- + modulemd/meson.build | 1 + + .../v2/include/modulemd-2.0/modulemd-module.h | 4 +- + modulemd/v2/meson.build | 17 ++++++- + modulemd/v2/tests/ModulemdTests/module.py | 46 +++++++++++++++++++ + 4 files changed, 65 insertions(+), 3 deletions(-) + create mode 100644 modulemd/v2/tests/ModulemdTests/module.py + +diff --git a/modulemd/meson.build b/modulemd/meson.build +index e49c7a9df76dcf37a18ddeba3150d6c914aa4e25..e5912d4041ba3e427d13b98c0eeca5217d48244b 100644 +--- a/modulemd/meson.build ++++ b/modulemd/meson.build +@@ -229,10 +229,11 @@ test_v2_python_scripts = files( + 'v2/tests/ModulemdTests/componentrpm.py', + 'v2/tests/ModulemdTests/defaults.py', + 'v2/tests/ModulemdTests/defaultsv1.py', + 'v2/tests/ModulemdTests/dependencies.py', + 'v2/tests/ModulemdTests/merger.py', ++ 'v2/tests/ModulemdTests/module.py', + 'v2/tests/ModulemdTests/moduleindex.py', + 'v2/tests/ModulemdTests/modulestream.py', + 'v2/tests/ModulemdTests/profile.py', + 'v2/tests/ModulemdTests/rpmmap.py', + 'v2/tests/ModulemdTests/servicelevel.py', +diff --git a/modulemd/v2/include/modulemd-2.0/modulemd-module.h b/modulemd/v2/include/modulemd-2.0/modulemd-module.h +index 45be9c0ae96e203707da61d84f18c71c4a826035..0219cfe227652813d20bdf736f9033782084c5ad 100644 +--- a/modulemd/v2/include/modulemd-2.0/modulemd-module.h ++++ b/modulemd/v2/include/modulemd-2.0/modulemd-module.h +@@ -129,12 +129,12 @@ modulemd_module_get_stream_by_NSVC (ModulemdModule *self, + * @context: (nullable): The context of the stream to retrieve. If NULL, the + * context is not included in the search. + * @arch: (nullable): The processor architecture of the stream to retrieve. If + * NULL, the architecture is not included in the search. + * +- * Returns: (transfer full) (element-type ModulemdModuleStream): The list of +- * stream objects matching the requested parameters. This function cannot ++ * Returns: (transfer container) (element-type ModulemdModuleStream): The list ++ * of stream objects matching the requested parameters. This function cannot + * fail, but it may return a zero-length list if no matches were found. The + * returned streams will be in a predictable order, sorted first by stream + * name, then by version (highest to lowest), then by context and finally by + * architecture. + * +diff --git a/modulemd/v2/meson.build b/modulemd/v2/meson.build +index 3f45db2c4e0e9a8996c74dffd949d5276082dc6f..e8a5a38f0528c4f860f0b84ef63609ff5fd89caa 100644 +--- a/modulemd/v2/meson.build ++++ b/modulemd/v2/meson.build +@@ -390,20 +390,35 @@ test ('dependencies_python2_debug', python2, + args : dependencies_python_script) + test ('dependencies_python2_release', python2, + env : py_test_release_env, + args : dependencies_python_script) + ++# -- Test Modulemd.Module (Python) -- # ++module_python_script = files('tests/ModulemdTests/module.py') ++test ('module_python3_debug', python3, ++ env : py_test_env, ++ args : module_python_script) ++test ('module_python3_release', python3, ++ env : py_test_release_env, ++ args : module_python_script) ++ ++test ('module_python2_debug', python2, ++ env : py_test_env, ++ args : module_python_script) ++test ('module_python2_release', python2, ++ env : py_test_release_env, ++ args : module_python_script) ++ + # -- Test Modulemd.ModuleIndex (Python) -- # + moduleindex_python_script = files('tests/ModulemdTests/moduleindex.py') + test ('moduleindex_python3_debug', python3, + env : py_test_env, + args : moduleindex_python_script) + test ('moduleindex_python3_release', python3, + env : py_test_release_env, + args : moduleindex_python_script) + +-moduleindex_python_script = files('tests/ModulemdTests/moduleindex.py') + test ('moduleindex_python2_debug', python2, + env : py_test_env, + args : moduleindex_python_script) + test ('moduleindex_python2_release', python2, + env : py_test_release_env, +diff --git a/modulemd/v2/tests/ModulemdTests/module.py b/modulemd/v2/tests/ModulemdTests/module.py +new file mode 100644 +index 0000000000000000000000000000000000000000..b604d9c9b357c4a5211d3ba5b4d0aba08c3a42bd +--- /dev/null ++++ b/modulemd/v2/tests/ModulemdTests/module.py +@@ -0,0 +1,46 @@ ++#!/usr/bin/python3 ++ ++# This file is part of libmodulemd ++# Copyright (C) 2017-2018 Stephen Gallagher ++# ++# Fedora-License-Identifier: MIT ++# SPDX-2.0-License-Identifier: MIT ++# SPDX-3.0-License-Identifier: MIT ++# ++# This program is free software. ++# For more information on the license, see COPYING. ++# For more information on free software, see ++# . ++ ++from os import path ++import sys ++try: ++ import unittest ++ import gi ++ gi.require_version('Modulemd', '2.0') ++ from gi.repository import Modulemd ++ from gi.repository.Modulemd import ModuleIndex ++ from gi.repository import GLib ++except ImportError: ++ # Return error 77 to skip this test on platforms without the necessary ++ # python modules ++ sys.exit(77) ++ ++from base import TestBase ++ ++ ++class TestModule(TestBase): ++ ++ def test_search_streams(self): ++ idx = Modulemd.ModuleIndex.new() ++ idx.update_from_file(path.join(self.source_root, ++ "modulemd/v2/tests/test_data/f29.yaml"), ++ True) ++ module = idx.get_module('nodejs') ++ ++ self.assertEquals(len(module.search_streams('8', 0)), 1) ++ self.assertEquals(len(module.search_streams('10', 0)), 1) ++ ++ ++if __name__ == '__main__': ++ unittest.main() +-- +2.21.0 + diff --git a/SPECS/libmodulemd.spec b/SPECS/libmodulemd.spec index abf46d8..a8a288c 100644 --- a/SPECS/libmodulemd.spec +++ b/SPECS/libmodulemd.spec @@ -1,16 +1,16 @@ -%global libmodulemd_version 2.0.0 -%global libmodulemd_v1_version 1.8.0 +%global libmodulemd_version 2.5.0 +%global libmodulemd_v1_version 1.8.11 Name: libmodulemd Version: %{libmodulemd_version} -Release: 5%{?dist} +Release: 2%{?dist} Summary: Module metadata manipulation library License: MIT URL: https://github.com/fedora-modularity/libmodulemd Source0: %{url}/releases/download/%{name}-%{version}/modulemd-%{version}.tar.xz -BuildRequires: meson >= 0.45.1-3 +BuildRequires: meson >= 0.47 BuildRequires: pkgconfig BuildRequires: gcc BuildRequires: gcc-c++ @@ -24,15 +24,15 @@ BuildRequires: python3-gobject-base BuildRequires: valgrind %endif -Obsoletes: python2-modulemd < 1.3.4 -Obsoletes: python3-modulemd < 1.3.4 - # Make sure we upgrade libmodulemd1 to match Conflicts: libmodulemd1 < %{libmodulemd_v1_version}-%{release} + # Patches -Patch0001: 0001-Include-modified-value-when-copying-Defaults-objects.patch -Patch0002: 0001-Don-t-fail-merges-when-default-streams-differ.patch +Patch0001: 0001-Double-valgrind-timeout.patch +Patch0002: 0002-Parallelize-the-valgrind-tests.patch +Patch0003: 0003-Fix-transfer-type-for-Module.search_streams.patch + %description C Library for manipulating module metadata files. @@ -42,9 +42,9 @@ more details. %package -n python3-%{name} Summary: Python 3 bindings for %{name} -BuildArch: noarch -Requires: libmodulemd = %{version}-%{release} +Requires: %{name}%{?_isa} = %{version}-%{release} Requires: python3-gobject-base +Requires: %{py3_dist six} Obsoletes: python3-modulemd < 1.3.4 %description -n python3-%{name} @@ -88,10 +88,12 @@ Development files for libmodulemd 1.x %package -n python3-libmodulemd1 Summary: Python 3 bindings for %{name}1 Version: %{libmodulemd_v1_version} -BuildArch: noarch Requires: libmodulemd1 = %{libmodulemd_v1_version}-%{release} Requires: python3-gobject-base +Obsoletes: python3-libmodulemd < 2 +Provides: python3-libmodulemd = %{libmodulemd_v1_version}-%{release} + %description -n python3-libmodulemd1 Python 3 bindings for libmodulemd1 @@ -106,7 +108,7 @@ Python 3 bindings for libmodulemd1 %meson_build %define _vpath_builddir api2 -%meson -Ddeveloper_build=false -Dbuild_api_v1=false -Dbuild_api_v2=true +%meson -Ddeveloper_build=false -Dbuild_api_v1=false -Dbuild_api_v2=true -Dwith_py3_overrides=true -Dwith_py2_overrides=false %meson_build @@ -114,7 +116,7 @@ Python 3 bindings for libmodulemd1 export LC_CTYPE=C.utf8 -%ifarch %{power64} +%ifarch %{power64} s390x # Valgrind is broken on ppc64[le] with GCC7: # https://bugs.kde.org/show_bug.cgi?id=386945 export MMD_SKIP_VALGRIND=1 @@ -148,7 +150,6 @@ ln -s libmodulemd.so.%{libmodulemd_v1_version} \ %{_libdir}/%{name}.so.2* %dir %{_libdir}/girepository-1.0 %{_libdir}/girepository-1.0/Modulemd-2.0.typelib -%{python3_sitearch}/gi/overrides/ %files devel @@ -163,6 +164,7 @@ ln -s libmodulemd.so.%{libmodulemd_v1_version} \ %files -n python3-%{name} +%{python3_sitearch}/gi/overrides/ %files -n python3-libmodulemd1 @@ -189,6 +191,19 @@ ln -s libmodulemd.so.%{libmodulemd_v1_version} \ %changelog +* Wed May 29 2019 Stephen Gallagher - 2.5.0-2 +- Fix memory corruption error using Module.search_rpms() from python +- Speed up valgrind tests +- Resolves: rhbz#1714766 + +* Wed May 22 2019 Stephen Gallagher - 2.5.0-1 +- Rebase to 2.5.0 and 1.8.11 +- Related: rhbz#1693680 + +* Mon May 13 2019 Stephen Gallagher - 2.4.0-1 +- Rebase to 2.4.0 and 1.8.10 +- Resolves: rhbz#1693680 + * Fri Jan 18 2019 Stephen Gallagher - 2.0.0-5 - Don't fail merges when default streams differ - Resolves: rhbz#1666871