1 /*
2  * This file is part of libmodulemd
3  * Copyright (C) 2018-2020 Red Hat, Inc.
4  *
5  * Fedora-License-Identifier: MIT
6  * SPDX-2.0-License-Identifier: MIT
7  * SPDX-3.0-License-Identifier: MIT
8  *
9  * This program is free software.
10  * For more information on the license, see COPYING.
11  * For more information on free software, see <https://www.gnu.org/philosophy/free-sw.en.html>.
12  */
13 
14 #include <glib.h>
15 #include <glib/gstdio.h>
16 #include <inttypes.h>
17 #include <locale.h>
18 #include <signal.h>
19 
20 #include "modulemd-module-index.h"
21 #include "modulemd-module-stream.h"
22 #include "private/glib-extensions.h"
23 #include "private/modulemd-build-config-private.h"
24 #include "private/modulemd-module-stream-private.h"
25 #include "private/modulemd-module-stream-v1-private.h"
26 #include "private/modulemd-module-stream-v2-private.h"
27 #include "private/modulemd-subdocument-info-private.h"
28 #include "private/modulemd-obsoletes-private.h"
29 #include "private/modulemd-util.h"
30 #include "private/modulemd-yaml.h"
31 #include "private/test-utils.h"
32 
33 #define MMD_TEST_DOC_TEXT "http://example.com"
34 #define MMD_TEST_DOC_TEXT2 "http://redhat.com"
35 #define MMD_TEST_DOC_PROP "documentation"
36 #define MMD_TEST_COM_PROP "community"
37 #define MMD_TEST_DOC_UNICODE_TEXT                                             \
38   "À϶¥��∮⇒⇔¬β∀₂⌀ıəˈ⍳⍴V)"                           \
39   "═€ίζησθლბშიнстемองจึองታሽ።ደለᚢᛞᚦᚹ⠳⠞⠊⠎▉▒▒▓��"
40 #define MMD_TEST_TRACKER_PROP "tracker"
41 #define MMD_TEST_DESC_TEXT "A different description"
42 #define MMD_TEST_SUM_TEXT "A different summary"
43 
44 
45 static void
module_stream_test_construct(void)46 module_stream_test_construct (void)
47 {
48   g_autoptr (ModulemdModuleStream) stream = NULL;
49   guint64 version;
50 
51   for (version = MD_MODULESTREAM_VERSION_ONE;
52        version <= MD_MODULESTREAM_VERSION_LATEST;
53        version++)
54     {
55       /* Test that the new() function works */
56       stream = modulemd_module_stream_new (version, "foo", "latest");
57       g_assert_nonnull (stream);
58       g_assert_true (MODULEMD_IS_MODULE_STREAM (stream));
59 
60       g_assert_cmpint (
61         modulemd_module_stream_get_mdversion (stream), ==, version);
62       g_assert_cmpstr (
63         modulemd_module_stream_get_module_name (stream), ==, "foo");
64       g_assert_cmpstr (
65         modulemd_module_stream_get_stream_name (stream), ==, "latest");
66 
67       g_clear_object (&stream);
68 
69       /* Test that the new() function works without a stream name */
70       stream = modulemd_module_stream_new (version, "foo", NULL);
71       g_assert_nonnull (stream);
72       g_assert_true (MODULEMD_IS_MODULE_STREAM (stream));
73 
74       g_assert_cmpint (
75         modulemd_module_stream_get_mdversion (stream), ==, version);
76       g_assert_cmpstr (
77         modulemd_module_stream_get_module_name (stream), ==, "foo");
78       g_assert_null (modulemd_module_stream_get_stream_name (stream));
79 
80       g_clear_object (&stream);
81 
82       /* Test with no module name */
83       stream = modulemd_module_stream_new (version, NULL, NULL);
84       g_assert_nonnull (stream);
85       g_assert_true (MODULEMD_IS_MODULE_STREAM (stream));
86 
87       g_assert_cmpint (
88         modulemd_module_stream_get_mdversion (stream), ==, version);
89       g_assert_null (modulemd_module_stream_get_module_name (stream));
90       g_assert_null (modulemd_module_stream_get_stream_name (stream));
91 
92       g_clear_object (&stream);
93     }
94 
95   /* Test with a zero mdversion */
96   stream = modulemd_module_stream_new (0, "foo", "latest");
97   g_assert_null (stream);
98   g_clear_object (&stream);
99 
100 
101   /* Test with an unknown mdversion */
102   stream = modulemd_module_stream_new (
103     MD_MODULESTREAM_VERSION_LATEST + 1, "foo", "latest");
104   g_assert_null (stream);
105   g_clear_object (&stream);
106 }
107 
108 
109 static void
module_stream_test_arch(void)110 module_stream_test_arch (void)
111 {
112   g_autoptr (ModulemdModuleStream) stream = NULL;
113   guint64 version;
114   g_autofree gchar *arch = NULL;
115 
116   for (version = MD_MODULESTREAM_VERSION_ONE;
117        version <= MD_MODULESTREAM_VERSION_LATEST;
118        version++)
119     {
120       /* Test the parent class set_arch() and get_arch() */
121       stream = modulemd_module_stream_new (version, "foo", "latest");
122       g_assert_nonnull (stream);
123 
124       g_assert_null (modulemd_module_stream_get_arch (stream));
125 
126       // clang-format off
127       g_object_get (stream,
128                     "arch", &arch,
129                     NULL);
130       // clang-format on
131       g_assert_null (arch);
132 
133       modulemd_module_stream_set_arch (stream, "x86_64");
134       g_assert_cmpstr (modulemd_module_stream_get_arch (stream), ==, "x86_64");
135 
136       // clang-format off
137       g_object_set (stream,
138                     "arch", "aarch64",
139                     NULL);
140       g_object_get (stream,
141                     "arch", &arch,
142                     NULL);
143       // clang-format on
144       g_assert_cmpstr (arch, ==, "aarch64");
145       g_clear_pointer (&arch, g_free);
146 
147       g_clear_object (&stream);
148     }
149 }
150 
151 
152 static void
module_stream_v1_test_licenses(void)153 module_stream_v1_test_licenses (void)
154 {
155   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
156   g_auto (GStrv) licenses = NULL;
157 
158   stream = modulemd_module_stream_v1_new (NULL, NULL);
159 
160   modulemd_module_stream_v1_add_content_license (stream, "GPLv2+");
161   licenses = modulemd_module_stream_v1_get_content_licenses_as_strv (stream);
162   g_assert_true (g_strv_contains ((const gchar *const *)licenses, "GPLv2+"));
163   g_assert_cmpint (g_strv_length (licenses), ==, 1);
164 
165   g_clear_pointer (&licenses, g_strfreev);
166 
167   modulemd_module_stream_v1_add_module_license (stream, "MIT");
168   licenses = modulemd_module_stream_v1_get_module_licenses_as_strv (stream);
169   g_assert_true (g_strv_contains ((const gchar *const *)licenses, "MIT"));
170   g_assert_cmpint (g_strv_length (licenses), ==, 1);
171 
172   g_clear_pointer (&licenses, g_strfreev);
173 
174   modulemd_module_stream_v1_remove_content_license (stream, "GPLv2+");
175   licenses = modulemd_module_stream_v1_get_content_licenses_as_strv (stream);
176   g_assert_cmpint (g_strv_length (licenses), ==, 0);
177 
178   g_clear_pointer (&licenses, g_strfreev);
179 
180   modulemd_module_stream_v1_remove_module_license (stream, "MIT");
181   licenses = modulemd_module_stream_v1_get_module_licenses_as_strv (stream);
182   g_assert_cmpint (g_strv_length (licenses), ==, 0);
183 
184   g_clear_pointer (&licenses, g_strfreev);
185   g_clear_object (&stream);
186 }
187 
188 static void
module_stream_v2_test_licenses(void)189 module_stream_v2_test_licenses (void)
190 {
191   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
192   g_auto (GStrv) licenses = NULL;
193 
194   stream = modulemd_module_stream_v2_new (NULL, NULL);
195 
196   modulemd_module_stream_v2_add_content_license (stream, "GPLv2+");
197   licenses = modulemd_module_stream_v2_get_content_licenses_as_strv (stream);
198   g_assert_true (g_strv_contains ((const gchar *const *)licenses, "GPLv2+"));
199   g_assert_cmpint (g_strv_length (licenses), ==, 1);
200 
201   g_clear_pointer (&licenses, g_strfreev);
202 
203   modulemd_module_stream_v2_add_module_license (stream, "MIT");
204   licenses = modulemd_module_stream_v2_get_module_licenses_as_strv (stream);
205   g_assert_true (g_strv_contains ((const gchar *const *)licenses, "MIT"));
206   g_assert_cmpint (g_strv_length (licenses), ==, 1);
207 
208   g_clear_pointer (&licenses, g_strfreev);
209 
210   modulemd_module_stream_v2_remove_content_license (stream, "GPLv2+");
211   licenses = modulemd_module_stream_v2_get_content_licenses_as_strv (stream);
212   g_assert_cmpint (g_strv_length (licenses), ==, 0);
213 
214   g_clear_pointer (&licenses, g_strfreev);
215 
216   modulemd_module_stream_v2_remove_module_license (stream, "MIT");
217   licenses = modulemd_module_stream_v2_get_module_licenses_as_strv (stream);
218   g_assert_cmpint (g_strv_length (licenses), ==, 0);
219 
220   g_clear_pointer (&licenses, g_strfreev);
221   g_clear_object (&stream);
222 }
223 
224 
225 static void
module_stream_v1_test_profiles(void)226 module_stream_v1_test_profiles (void)
227 {
228   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
229   g_autoptr (ModulemdProfile) profile = NULL;
230   g_auto (GStrv) profiles = NULL;
231   g_auto (GStrv) rpms = NULL;
232 
233   stream = modulemd_module_stream_v1_new ("sssd", NULL);
234 
235   profile = modulemd_profile_new ("client");
236   modulemd_profile_add_rpm (profile, "sssd-client");
237 
238   modulemd_module_stream_v1_add_profile (stream, profile);
239   profiles = modulemd_module_stream_v1_get_profile_names_as_strv (stream);
240   g_assert_cmpint (g_strv_length (profiles), ==, 1);
241   g_assert_true (g_strv_contains ((const gchar *const *)profiles, "client"));
242 
243   g_clear_pointer (&profiles, g_strfreev);
244 
245   rpms = modulemd_profile_get_rpms_as_strv (
246     modulemd_module_stream_v1_get_profile (stream, "client"));
247   g_assert_true (g_strv_contains ((const gchar *const *)rpms, "sssd-client"));
248 
249   modulemd_module_stream_v1_clear_profiles (stream);
250   profiles = modulemd_module_stream_v1_get_profile_names_as_strv (stream);
251   g_assert_cmpint (g_strv_length (profiles), ==, 0);
252 
253   g_clear_object (&stream);
254   g_clear_object (&profile);
255   g_clear_pointer (&profiles, g_strfreev);
256   g_clear_pointer (&rpms, g_strfreev);
257 }
258 
259 static void
module_stream_v2_test_profiles(void)260 module_stream_v2_test_profiles (void)
261 {
262   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
263   g_autoptr (ModulemdProfile) profile = NULL;
264   g_auto (GStrv) profiles = NULL;
265   g_auto (GStrv) rpms = NULL;
266 
267   stream = modulemd_module_stream_v2_new ("sssd", NULL);
268 
269   profile = modulemd_profile_new ("client");
270   modulemd_profile_add_rpm (profile, "sssd-client");
271 
272   modulemd_module_stream_v2_add_profile (stream, profile);
273   profiles = modulemd_module_stream_v2_get_profile_names_as_strv (stream);
274   g_assert_cmpint (g_strv_length (profiles), ==, 1);
275   g_assert_true (g_strv_contains ((const gchar *const *)profiles, "client"));
276 
277   g_clear_pointer (&profiles, g_strfreev);
278 
279   rpms = modulemd_profile_get_rpms_as_strv (
280     modulemd_module_stream_v2_get_profile (stream, "client"));
281   g_assert_true (g_strv_contains ((const gchar *const *)rpms, "sssd-client"));
282 
283   modulemd_module_stream_v2_clear_profiles (stream);
284   profiles = modulemd_module_stream_v2_get_profile_names_as_strv (stream);
285   g_assert_cmpint (g_strv_length (profiles), ==, 0);
286 
287   g_clear_object (&stream);
288   g_clear_object (&profile);
289   g_clear_pointer (&profiles, g_strfreev);
290   g_clear_pointer (&rpms, g_strfreev);
291 }
292 
293 
294 static void
module_stream_v1_test_summary(void)295 module_stream_v1_test_summary (void)
296 {
297   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
298   const gchar *summary = NULL;
299 
300   stream = modulemd_module_stream_v1_new (NULL, NULL);
301 
302   // Check the defaults
303   summary = modulemd_module_stream_v1_get_summary (stream, "C");
304   g_assert_null (summary);
305 
306   // Test setting summary
307   modulemd_module_stream_v1_set_summary (stream, MMD_TEST_SUM_TEXT);
308   summary = modulemd_module_stream_v1_get_summary (stream, "C");
309   g_assert_cmpstr (summary, ==, MMD_TEST_SUM_TEXT);
310 
311   // Test setting it back to NULL
312   modulemd_module_stream_v1_set_summary (stream, NULL);
313   summary = modulemd_module_stream_v1_get_summary (stream, "C");
314   g_assert_null (summary);
315 
316   // Test setting unicode characters
317   modulemd_module_stream_v1_set_summary (stream, MMD_TEST_DOC_UNICODE_TEXT);
318   summary = modulemd_module_stream_v1_get_summary (stream, "C");
319   g_assert_cmpstr (summary, ==, MMD_TEST_DOC_UNICODE_TEXT);
320 }
321 
322 static void
module_stream_v2_test_summary(void)323 module_stream_v2_test_summary (void)
324 {
325   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
326   const gchar *summary = NULL;
327 
328   stream = modulemd_module_stream_v2_new (NULL, NULL);
329 
330   // Check the defaults
331   summary = modulemd_module_stream_v2_get_summary (stream, "C");
332   g_assert_null (summary);
333 
334   // Test setting summary
335   modulemd_module_stream_v2_set_summary (stream, MMD_TEST_SUM_TEXT);
336   summary = modulemd_module_stream_v2_get_summary (stream, "C");
337   g_assert_cmpstr (summary, ==, MMD_TEST_SUM_TEXT);
338 
339   // Test setting it back to NULL
340   modulemd_module_stream_v2_set_summary (stream, NULL);
341   summary = modulemd_module_stream_v2_get_summary (stream, "C");
342   g_assert_null (summary);
343 
344   // Test setting unicode characters
345   modulemd_module_stream_v2_set_summary (stream, MMD_TEST_DOC_UNICODE_TEXT);
346   summary = modulemd_module_stream_v2_get_summary (stream, "C");
347   g_assert_cmpstr (summary, ==, MMD_TEST_DOC_UNICODE_TEXT);
348 }
349 
350 
351 static void
module_stream_v1_test_description(void)352 module_stream_v1_test_description (void)
353 {
354   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
355   const gchar *description = NULL;
356 
357   stream = modulemd_module_stream_v1_new (NULL, NULL);
358 
359   // Check the defaults
360   description = modulemd_module_stream_v1_get_description (stream, "C");
361   g_assert_null (description);
362 
363   // Test setting description
364   modulemd_module_stream_v1_set_description (stream, MMD_TEST_DESC_TEXT);
365   description = modulemd_module_stream_v1_get_description (stream, "C");
366   g_assert_cmpstr (description, ==, MMD_TEST_DESC_TEXT);
367 
368   // Test setting it back to NULL
369   modulemd_module_stream_v1_set_description (stream, NULL);
370   description = modulemd_module_stream_v1_get_description (stream, "C");
371   g_assert_null (description);
372 
373   // Test unicode characters
374   modulemd_module_stream_v1_set_description (stream,
375                                              MMD_TEST_DOC_UNICODE_TEXT);
376   description = modulemd_module_stream_v1_get_description (stream, "C");
377   g_assert_cmpstr (description, ==, MMD_TEST_DOC_UNICODE_TEXT);
378 
379   g_clear_object (&stream);
380 }
381 
382 static void
module_stream_v2_test_description(void)383 module_stream_v2_test_description (void)
384 {
385   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
386   const gchar *description = NULL;
387 
388   stream = modulemd_module_stream_v2_new (NULL, NULL);
389 
390   // Check the defaults
391   description = modulemd_module_stream_v2_get_description (stream, "C");
392   g_assert_null (description);
393 
394   // Test setting description
395   modulemd_module_stream_v2_set_description (stream, MMD_TEST_DESC_TEXT);
396   description = modulemd_module_stream_v2_get_description (stream, "C");
397   g_assert_cmpstr (description, ==, MMD_TEST_DESC_TEXT);
398 
399   // Test setting it back to NULL
400   modulemd_module_stream_v2_set_description (stream, NULL);
401   description = modulemd_module_stream_v2_get_description (stream, "C");
402   g_assert_null (description);
403 
404   // Test unicode characters
405   modulemd_module_stream_v2_set_description (stream,
406                                              MMD_TEST_DOC_UNICODE_TEXT);
407   description = modulemd_module_stream_v2_get_description (stream, "C");
408   g_assert_cmpstr (description, ==, MMD_TEST_DOC_UNICODE_TEXT);
409 
410   g_clear_object (&stream);
411 }
412 
413 
414 static void
module_stream_v1_test_rpm_api(void)415 module_stream_v1_test_rpm_api (void)
416 {
417   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
418   g_auto (GStrv) rpm_apis = NULL;
419 
420   stream = modulemd_module_stream_v1_new ("sssd", NULL);
421 
422   modulemd_module_stream_v1_add_rpm_api (stream, "sssd-common");
423   rpm_apis = modulemd_module_stream_v1_get_rpm_api_as_strv (stream);
424 
425   g_assert_true (
426     g_strv_contains ((const gchar *const *)rpm_apis, "sssd-common"));
427   g_assert_cmpint (g_strv_length (rpm_apis), ==, 1);
428 
429   g_clear_pointer (&rpm_apis, g_strfreev);
430 
431   modulemd_module_stream_v1_remove_rpm_api (stream, "sssd-common");
432   rpm_apis = modulemd_module_stream_v1_get_rpm_api_as_strv (stream);
433 
434   g_assert_cmpint (g_strv_length (rpm_apis), ==, 0);
435 
436   g_clear_pointer (&rpm_apis, g_strfreev);
437   g_clear_object (&stream);
438 }
439 
440 static void
module_stream_v2_test_rpm_api(void)441 module_stream_v2_test_rpm_api (void)
442 {
443   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
444   g_auto (GStrv) rpm_apis = NULL;
445 
446   stream = modulemd_module_stream_v2_new ("sssd", NULL);
447 
448   modulemd_module_stream_v2_add_rpm_api (stream, "sssd-common");
449   rpm_apis = modulemd_module_stream_v2_get_rpm_api_as_strv (stream);
450 
451   g_assert_true (
452     g_strv_contains ((const gchar *const *)rpm_apis, "sssd-common"));
453   g_assert_cmpint (g_strv_length (rpm_apis), ==, 1);
454 
455   g_clear_pointer (&rpm_apis, g_strfreev);
456 
457   modulemd_module_stream_v2_remove_rpm_api (stream, "sssd-common");
458   rpm_apis = modulemd_module_stream_v2_get_rpm_api_as_strv (stream);
459 
460   g_assert_cmpint (g_strv_length (rpm_apis), ==, 0);
461 
462   g_clear_pointer (&rpm_apis, g_strfreev);
463   g_clear_object (&stream);
464 }
465 
466 
467 static void
module_stream_v1_test_rpm_filters(void)468 module_stream_v1_test_rpm_filters (void)
469 {
470   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
471   g_auto (GStrv) filters = NULL;
472 
473   stream = modulemd_module_stream_v1_new ("sssd", NULL);
474 
475   // Test add_rpm_filter
476   modulemd_module_stream_v1_add_rpm_filter (stream, "foo");
477   modulemd_module_stream_v1_add_rpm_filter (stream, "bar");
478   filters = modulemd_module_stream_v1_get_rpm_filters_as_strv (stream);
479 
480   g_assert_true (g_strv_contains ((const gchar *const *)filters, "foo"));
481   g_assert_true (g_strv_contains ((const gchar *const *)filters, "bar"));
482   g_assert_cmpint (g_strv_length (filters), ==, 2);
483   g_clear_pointer (&filters, g_strfreev);
484 
485   // Test remove_rpm_filter
486   modulemd_module_stream_v1_remove_rpm_filter (stream, "foo");
487   filters = modulemd_module_stream_v1_get_rpm_filters_as_strv (stream);
488 
489   g_assert_true (g_strv_contains ((const gchar *const *)filters, "bar"));
490   g_assert_cmpint (g_strv_length (filters), ==, 1);
491   g_clear_pointer (&filters, g_strfreev);
492 
493   // Test clear_rpm_filters
494   modulemd_module_stream_v1_clear_rpm_filters (stream);
495   filters = modulemd_module_stream_v1_get_rpm_filters_as_strv (stream);
496   g_assert_cmpint (g_strv_length (filters), ==, 0);
497 
498   g_clear_pointer (&filters, g_strfreev);
499   g_clear_object (&stream);
500 }
501 
502 static void
module_stream_v2_test_rpm_filters(void)503 module_stream_v2_test_rpm_filters (void)
504 {
505   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
506   g_auto (GStrv) filters = NULL;
507 
508   stream = modulemd_module_stream_v2_new ("sssd", NULL);
509 
510   // Test add_rpm_filter
511   modulemd_module_stream_v2_add_rpm_filter (stream, "foo");
512   modulemd_module_stream_v2_add_rpm_filter (stream, "bar");
513   filters = modulemd_module_stream_v2_get_rpm_filters_as_strv (stream);
514 
515   g_assert_true (g_strv_contains ((const gchar *const *)filters, "foo"));
516   g_assert_true (g_strv_contains ((const gchar *const *)filters, "bar"));
517   g_assert_cmpint (g_strv_length (filters), ==, 2);
518   g_clear_pointer (&filters, g_strfreev);
519 
520   // Test remove_rpm_filter
521   modulemd_module_stream_v2_remove_rpm_filter (stream, "foo");
522   filters = modulemd_module_stream_v2_get_rpm_filters_as_strv (stream);
523 
524   g_assert_true (g_strv_contains ((const gchar *const *)filters, "bar"));
525   g_assert_cmpint (g_strv_length (filters), ==, 1);
526   g_clear_pointer (&filters, g_strfreev);
527 
528   // Test clear_rpm_filters
529   modulemd_module_stream_v2_clear_rpm_filters (stream);
530   filters = modulemd_module_stream_v2_get_rpm_filters_as_strv (stream);
531   g_assert_cmpint (g_strv_length (filters), ==, 0);
532 
533   g_clear_pointer (&filters, g_strfreev);
534   g_clear_object (&stream);
535 }
536 
537 
538 static void
module_stream_v2_test_demodularized_rpms(void)539 module_stream_v2_test_demodularized_rpms (void)
540 {
541   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
542   g_auto (GStrv) demodularized = NULL;
543 
544   stream = modulemd_module_stream_v2_new ("sssd", NULL);
545 
546   // Test add_demodularized_rpm
547   modulemd_module_stream_v2_add_demodularized_rpm (stream, "foo");
548   modulemd_module_stream_v2_add_demodularized_rpm (stream, "bar");
549   demodularized = modulemd_module_stream_v2_get_demodularized_rpms (stream);
550 
551   g_assert_true (g_strv_contains ((const gchar *const *)demodularized, "foo"));
552   g_assert_true (g_strv_contains ((const gchar *const *)demodularized, "bar"));
553   g_assert_cmpint (g_strv_length (demodularized), ==, 2);
554   g_clear_pointer (&demodularized, g_strfreev);
555 
556   // Test remove_demodularized_rpm
557   modulemd_module_stream_v2_remove_demodularized_rpm (stream, "foo");
558   demodularized = modulemd_module_stream_v2_get_demodularized_rpms (stream);
559 
560   g_assert_true (g_strv_contains ((const gchar *const *)demodularized, "bar"));
561   g_assert_cmpint (g_strv_length (demodularized), ==, 1);
562   g_clear_pointer (&demodularized, g_strfreev);
563 
564   // Test clear_demodularized_rpms
565   modulemd_module_stream_v2_clear_demodularized_rpms (stream);
566   demodularized = modulemd_module_stream_v2_get_demodularized_rpms (stream);
567   g_assert_cmpint (g_strv_length (demodularized), ==, 0);
568 
569   g_clear_pointer (&demodularized, g_strfreev);
570   g_clear_object (&stream);
571 }
572 
573 
574 static void
module_stream_test_upgrade_v1_to_v2(void)575 module_stream_test_upgrade_v1_to_v2 (void)
576 {
577   gboolean ret;
578   g_autoptr (ModulemdModuleStreamV1) streamV1 = NULL;
579   g_autoptr (ModulemdModuleStream) updated_stream = NULL;
580   g_autoptr (ModulemdModuleIndex) index = NULL;
581   g_autoptr (GError) error = NULL;
582   g_autofree gchar *yaml_str = NULL;
583 
584   streamV1 = modulemd_module_stream_v1_new ("SuperModule", "latest");
585 
586   modulemd_module_stream_v1_set_summary (streamV1, "Summary");
587   modulemd_module_stream_v1_set_description (streamV1, "Description");
588   modulemd_module_stream_v1_add_module_license (streamV1, "BSD");
589 
590   modulemd_module_stream_v1_add_buildtime_requirement (
591     streamV1, "ModuleA", "streamZ");
592   modulemd_module_stream_v1_add_buildtime_requirement (
593     streamV1, "ModuleB", "streamY");
594   modulemd_module_stream_v1_add_runtime_requirement (
595     streamV1, "ModuleA", "streamZ");
596   modulemd_module_stream_v1_add_runtime_requirement (
597     streamV1, "ModuleB", "streamY");
598 
599   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
600   updated_stream = modulemd_module_stream_upgrade (
601     MODULEMD_MODULE_STREAM (streamV1), MD_MODULESTREAM_VERSION_TWO, &error);
602   G_GNUC_END_IGNORE_DEPRECATIONS
603 
604   g_assert_no_error (error);
605   g_assert_nonnull (updated_stream);
606 
607   index = modulemd_module_index_new ();
608   ret = modulemd_module_index_add_module_stream (
609     index, MODULEMD_MODULE_STREAM (updated_stream), &error);
610 
611   g_assert_no_error (error);
612   g_assert_true (ret);
613 
614   yaml_str = modulemd_module_index_dump_to_string (index, &error);
615 
616   g_assert_no_error (error);
617   g_assert_cmpstr (yaml_str,
618                    ==,
619                    "---\n"
620                    "document: modulemd\n"
621                    "version: 2\n"
622                    "data:\n"
623                    "  name: SuperModule\n"
624                    "  stream: \"latest\"\n"
625                    "  summary: Summary\n"
626                    "  description: >-\n"
627                    "    Description\n"
628                    "  license:\n"
629                    "    module:\n"
630                    "    - BSD\n"
631                    "  dependencies:\n"
632                    "  - buildrequires:\n"
633                    "      ModuleA: [streamZ]\n"
634                    "      ModuleB: [streamY]\n"
635                    "    requires:\n"
636                    "      ModuleA: [streamZ]\n"
637                    "      ModuleB: [streamY]\n"
638                    "...\n");
639 
640   g_clear_object (&streamV1);
641   g_clear_object (&updated_stream);
642   g_clear_object (&index);
643   g_clear_object (&error);
644   g_clear_pointer (&yaml_str, g_free);
645 }
646 
647 
648 static void
module_stream_test_v2_yaml(void)649 module_stream_test_v2_yaml (void)
650 {
651   g_autoptr (ModulemdModuleStream) stream = NULL;
652   ModulemdModuleStreamV2 *streamV2 = NULL;
653   g_autofree gchar *module_name_prop = NULL;
654   g_autofree gchar *stream_name_prop = NULL;
655   g_autofree gchar *context_prop = NULL;
656   g_autofree gchar *arch_prop = NULL;
657   guint64 version_prop = 0;
658   g_autoptr (GError) error = NULL;
659 
660   g_auto (GStrv) rpm_apis = NULL;
661   g_auto (GStrv) rpm_filters = NULL;
662   g_auto (GStrv) demodularized_rpms = NULL;
663   g_auto (GStrv) rpm_artifacts = NULL;
664   g_auto (GStrv) servicelevel_names = NULL;
665 
666   ModulemdServiceLevel *sl = NULL;
667   g_autofree gchar *sl_name_prop = NULL;
668   g_autofree gchar *sl_eol_string = NULL;
669 
670   g_auto (GStrv) content_licenses = NULL;
671   g_auto (GStrv) module_licenses = NULL;
672   g_auto (GStrv) stream_dependencies = NULL;
673 
674   g_autofree gchar *community_prop = NULL;
675   g_autofree gchar *documentation_prop = NULL;
676   g_autofree gchar *tracker_prop = NULL;
677   g_auto (GStrv) profile_names = NULL;
678 
679   ModulemdBuildopts *buildopts = NULL;
680   g_autofree gchar *buildopts_rpm_macros_prop = NULL;
681   g_auto (GStrv) buildopts_rpm_whitelist = NULL;
682   g_auto (GStrv) buildopts_arches = NULL;
683 
684   GVariant *tmp_variant = NULL;
685   GVariantDict *xmd_dict = NULL;
686   GVariantDict *tmp_dict = NULL;
687   gchar *tmp_str = NULL;
688   gboolean *tmp_bool = NULL;
689 
690   GPtrArray *dependencies = NULL;
691 
692   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
693   stream = modulemd_module_stream_read_string (
694     "---\n"
695     "document: modulemd\n"
696     "version: 2\n"
697     "data:\n"
698     "  name: modulename\n"
699     "  stream: \"streamname\"\n"
700     "  version: 1\n"
701     "  context: c0ffe3\n"
702     "  arch: x86_64\n"
703     "  summary: Module Summary\n"
704     "  description: >-\n"
705     "    Module Description\n"
706     "  api:\n"
707     "    rpms:\n"
708     "      - rpm_a\n"
709     "      - rpm_b\n"
710     "  filter:\n"
711     "    rpms: rpm_c\n"
712 
713     "  demodularized:\n"
714     "    rpms:\n"
715     "      - rpm_d\n"
716 
717     "  artifacts:\n"
718     "    rpms:\n"
719     "      - bar-0:1.23-1.module_deadbeef.x86_64\n"
720 
721     "  servicelevels:\n"
722     "    rawhide: {}\n"
723     "    production:\n"
724     "      eol: 2099-12-31\n"
725 
726     "  license:\n"
727     "    content:\n"
728     "      - BSD\n"
729     "      - GPLv2+\n"
730     "    module: MIT\n"
731 
732     "  dependencies:\n"
733     "    - buildrequires:\n"
734     "          platform: [-f27, -f28, -epel7]\n"
735     "      requires:\n"
736     "          platform: [-f27, -f28, -epel7]\n"
737     "    - buildrequires:\n"
738     "          platform: [f27]\n"
739     "          buildtools: [v1, v2]\n"
740     "          compatible: [v3]\n"
741     "      requires:\n"
742     "          platform: [f27]\n"
743     "          compatible: [v3, v4]\n"
744     "    - buildrequires:\n"
745     "          platform: [f28]\n"
746     "      requires:\n"
747     "          platform: [f28]\n"
748     "          runtime: [a, b]\n"
749     "    - buildrequires:\n"
750     "          platform: [epel7]\n"
751     "          extras: []\n"
752     "          moreextras: [foo, bar]\n"
753     "      requires:\n"
754     "          platform: [epel7]\n"
755     "          extras: []\n"
756     "          moreextras: [foo, bar]\n"
757     "  references:\n"
758     "        community: http://www.example.com/\n"
759     "        documentation: http://www.example.com/\n"
760     "        tracker: http://www.example.com/\n"
761     "  profiles:\n"
762     "        default:\n"
763     "            rpms:\n"
764     "                - bar\n"
765     "                - bar-extras\n"
766     "                - baz\n"
767     "        container:\n"
768     "            rpms:\n"
769     "                - bar\n"
770     "                - bar-devel\n"
771     "        minimal:\n"
772     "            description: Minimal profile installing only the bar "
773     "package.\n"
774     "            rpms:\n"
775     "                - bar\n"
776     "        buildroot:\n"
777     "            rpms:\n"
778     "                - bar-devel\n"
779     "        srpm-buildroot:\n"
780     "            rpms:\n"
781     "                - bar-extras\n"
782     "  buildopts:\n"
783     "        rpms:\n"
784     "            macros: |\n"
785     "                %demomacro 1\n"
786     "                %demomacro2 %{demomacro}23\n"
787     "            whitelist:\n"
788     "                - fooscl-1-bar\n"
789     "                - fooscl-1-baz\n"
790     "                - xxx\n"
791     "                - xyz\n"
792     "        arches: [i686, x86_64]\n"
793     "  components:\n"
794     "        rpms:\n"
795     "            bar:\n"
796     "                rationale: We need this to demonstrate stuff.\n"
797     "                repository: https://pagure.io/bar.git\n"
798     "                cache: https://example.com/cache\n"
799     "                ref: 26ca0c0\n"
800     "            baz:\n"
801     "                rationale: This one is here to demonstrate other stuff.\n"
802     "            xxx:\n"
803     "                rationale: xxx demonstrates arches and multilib.\n"
804     "                arches: [i686, x86_64]\n"
805     "                multilib: [x86_64]\n"
806     "            xyz:\n"
807     "                rationale: xyz is a bundled dependency of xxx.\n"
808     "                buildorder: 10\n"
809     "        modules:\n"
810     "            includedmodule:\n"
811     "                rationale: Included in the stack, just because.\n"
812     "                repository: https://pagure.io/includedmodule.git\n"
813     "                ref: somecoolbranchname\n"
814     "                buildorder: 100\n"
815     "  xmd:\n"
816     "        some_key: some_data\n"
817     "        some_list:\n"
818     "            - a\n"
819     "            - b\n"
820     "        some_dict:\n"
821     "            a: alpha\n"
822     "            b: beta\n"
823     "            some_other_list:\n"
824     "                - c\n"
825     "                - d\n"
826     "            some_other_dict:\n"
827     "                another_key: more_data\n"
828     "                yet_another_key:\n"
829     "                    - this\n"
830     "                    - is\n"
831     "                    - getting\n"
832     "                    - silly\n"
833     "        can_bool: TRUE\n"
834     "...\n",
835     TRUE,
836     NULL,
837     NULL,
838     &error);
839   G_GNUC_END_IGNORE_DEPRECATIONS
840 
841   g_assert_no_error (error);
842 
843   g_assert_nonnull (stream);
844   streamV2 = MODULEMD_MODULE_STREAM_V2 (stream);
845 
846   g_object_get (streamV2, "module-name", &module_name_prop, NULL);
847   g_object_get (streamV2, "stream-name", &stream_name_prop, NULL);
848   g_object_get (streamV2, "version", &version_prop, NULL);
849   g_object_get (streamV2, "context", &context_prop, NULL);
850   g_object_get (streamV2, "arch", &arch_prop, NULL);
851 
852   g_assert_cmpstr (module_name_prop, ==, "modulename");
853   g_assert_cmpstr (stream_name_prop, ==, "streamname");
854   g_assert_cmpuint (version_prop, ==, 1);
855   g_assert_cmpstr (context_prop, ==, "c0ffe3");
856   g_assert_cmpstr (arch_prop, ==, "x86_64");
857   g_assert_cmpstr (modulemd_module_stream_v2_get_summary (streamV2, "C"),
858                    ==,
859                    "Module Summary");
860   g_assert_cmpstr (modulemd_module_stream_v2_get_description (streamV2, "C"),
861                    ==,
862                    "Module Description");
863 
864   rpm_apis = modulemd_module_stream_v2_get_rpm_api_as_strv (streamV2);
865   rpm_filters = modulemd_module_stream_v2_get_rpm_filters_as_strv (streamV2);
866   demodularized_rpms =
867     modulemd_module_stream_v2_get_demodularized_rpms (streamV2);
868   rpm_artifacts =
869     modulemd_module_stream_v2_get_rpm_artifacts_as_strv (streamV2);
870   servicelevel_names =
871     modulemd_module_stream_v2_get_servicelevel_names_as_strv (streamV2);
872 
873   g_assert_true (g_strv_contains ((const gchar *const *)rpm_apis, "rpm_a"));
874   g_assert_true (g_strv_contains ((const gchar *const *)rpm_apis, "rpm_b"));
875 
876   g_assert_true (g_strv_contains ((const gchar *const *)rpm_filters, "rpm_c"));
877 
878   g_assert_true (
879     g_strv_contains ((const gchar *const *)demodularized_rpms, "rpm_d"));
880 
881   g_assert_true (g_strv_contains ((const gchar *const *)rpm_artifacts,
882                                   "bar-0:1.23-1.module_deadbeef.x86_64"));
883 
884   g_assert_true (
885     g_strv_contains ((const gchar *const *)servicelevel_names, "rawhide"));
886   g_assert_true (
887     g_strv_contains ((const gchar *const *)servicelevel_names, "production"));
888 
889   sl = modulemd_module_stream_v2_get_servicelevel (streamV2, "rawhide");
890   g_assert_nonnull (sl);
891   g_object_get (sl, "name", &sl_name_prop, NULL);
892   g_assert_cmpstr (sl_name_prop, ==, "rawhide");
893   g_assert_null (modulemd_service_level_get_eol (sl));
894 
895   g_clear_pointer (&sl_name_prop, g_free);
896 
897   sl = modulemd_module_stream_v2_get_servicelevel (streamV2, "production");
898   g_assert_nonnull (sl);
899   g_object_get (sl, "name", &sl_name_prop, NULL);
900   g_assert_cmpstr (sl_name_prop, ==, "production");
901   g_assert_nonnull (modulemd_service_level_get_eol (sl));
902   sl_eol_string = modulemd_service_level_get_eol_as_string (sl);
903   g_assert_cmpstr (sl_eol_string, ==, "2099-12-31");
904 
905   g_clear_pointer (&sl_name_prop, g_free);
906   g_clear_pointer (&sl_eol_string, g_free);
907 
908   content_licenses =
909     modulemd_module_stream_v2_get_content_licenses_as_strv (streamV2);
910   module_licenses =
911     modulemd_module_stream_v2_get_module_licenses_as_strv (streamV2);
912 
913   g_assert_true (
914     g_strv_contains ((const gchar *const *)content_licenses, "BSD"));
915   g_assert_true (
916     g_strv_contains ((const gchar *const *)content_licenses, "GPLv2+"));
917   g_assert_true (
918     g_strv_contains ((const gchar *const *)module_licenses, "MIT"));
919 
920   dependencies = modulemd_module_stream_v2_get_dependencies (streamV2);
921   g_assert_cmpint (dependencies->len, ==, 4);
922 
923   g_object_get (streamV2, "community", &community_prop, NULL);
924   g_object_get (streamV2, "documentation", &documentation_prop, NULL);
925   g_object_get (streamV2, "tracker", &tracker_prop, NULL);
926 
927   g_assert_cmpstr (community_prop, ==, "http://www.example.com/");
928   g_assert_cmpstr (documentation_prop, ==, "http://www.example.com/");
929   g_assert_cmpstr (tracker_prop, ==, "http://www.example.com/");
930 
931   profile_names =
932     modulemd_module_stream_v2_get_profile_names_as_strv (streamV2);
933   g_assert_cmpint (g_strv_length (profile_names), ==, 5);
934 
935   buildopts = modulemd_module_stream_v2_get_buildopts (streamV2);
936   g_assert_nonnull (buildopts);
937 
938   g_object_get (buildopts, "rpm_macros", &buildopts_rpm_macros_prop, NULL);
939   g_assert_cmpstr (buildopts_rpm_macros_prop,
940                    ==,
941                    "%demomacro 1\n%demomacro2 %{demomacro}23\n");
942 
943   buildopts_rpm_whitelist =
944     modulemd_buildopts_get_rpm_whitelist_as_strv (buildopts);
945   buildopts_arches = modulemd_buildopts_get_arches_as_strv (buildopts);
946 
947   g_assert_true (g_strv_contains (
948     (const gchar *const *)buildopts_rpm_whitelist, "fooscl-1-bar"));
949   g_assert_true (g_strv_contains (
950     (const gchar *const *)buildopts_rpm_whitelist, "fooscl-1-baz"));
951   g_assert_true (
952     g_strv_contains ((const gchar *const *)buildopts_rpm_whitelist, "xxx"));
953   g_assert_true (
954     g_strv_contains ((const gchar *const *)buildopts_rpm_whitelist, "xyz"));
955   g_assert_true (
956     g_strv_contains ((const gchar *const *)buildopts_arches, "i686"));
957   g_assert_true (
958     g_strv_contains ((const gchar *const *)buildopts_arches, "x86_64"));
959 
960 
961   // Load XMD into dictionary
962   tmp_variant = modulemd_module_stream_v2_get_xmd (streamV2);
963   g_assert_nonnull (tmp_variant);
964   xmd_dict = g_variant_dict_new (tmp_variant);
965 
966   // Check xmd["some_key"] == "some_data"
967   g_assert_true (g_variant_dict_contains (xmd_dict, "some_key"));
968   g_assert_true (g_variant_dict_lookup (xmd_dict, "some_key", "&s", &tmp_str));
969   g_assert_cmpstr (tmp_str, ==, "some_data");
970 
971   // Check xmd["some_list"][0] == "a" and xmd["some_list"][1] == "b"
972   g_assert_true (g_variant_dict_contains (xmd_dict, "some_list"));
973   g_assert_true (
974     g_variant_dict_lookup (xmd_dict, "some_list", "@as", &tmp_variant));
975 
976   g_variant_get_child (tmp_variant, 0, "&s", &tmp_str);
977   g_assert_cmpstr (tmp_str, ==, "a");
978 
979   g_variant_get_child (tmp_variant, 1, "&s", &tmp_str);
980   g_assert_cmpstr (tmp_str, ==, "b");
981 
982   g_clear_pointer (&tmp_variant, g_variant_unref);
983 
984   // Check xmd["some_dict"]["a"] == "alpha"
985   g_assert_true (g_variant_dict_contains (xmd_dict, "some_dict"));
986   g_assert_true (
987     g_variant_dict_lookup (xmd_dict, "some_dict", "@a{sv}", &tmp_variant));
988   tmp_dict = g_variant_dict_new (tmp_variant);
989 
990   g_assert_true (g_variant_dict_contains (tmp_dict, "a"));
991   g_assert_true (g_variant_dict_lookup (tmp_dict, "a", "&s", &tmp_str));
992   g_assert_cmpstr (tmp_str, ==, "alpha");
993 
994   g_clear_pointer (&tmp_variant, g_variant_unref);
995 
996   // Check xmd["some_dict"]["some_other_dict"]["another_key"] == "more_data"
997   g_assert_true (g_variant_dict_contains (tmp_dict, "some_other_dict"));
998   g_assert_true (g_variant_dict_lookup (
999     tmp_dict, "some_other_dict", "@a{sv}", &tmp_variant));
1000   g_clear_pointer (&tmp_dict, g_variant_dict_unref);
1001   tmp_dict = g_variant_dict_new (tmp_variant);
1002 
1003   g_assert_true (g_variant_dict_contains (tmp_dict, "another_key"));
1004   g_assert_true (
1005     g_variant_dict_lookup (tmp_dict, "another_key", "&s", &tmp_str));
1006   g_assert_cmpstr (tmp_str, ==, "more_data");
1007 
1008   g_clear_pointer (&tmp_variant, g_variant_unref);
1009 
1010   // Check xmd["some_dict"]["some_other_dict"]["yet_another_key"][3] == "silly"
1011   g_assert_true (
1012     g_variant_dict_lookup (tmp_dict, "yet_another_key", "@as", &tmp_variant));
1013 
1014   g_variant_get_child (tmp_variant, 3, "&s", &tmp_str);
1015   g_assert_cmpstr (tmp_str, ==, "silly");
1016 
1017   g_clear_pointer (&tmp_variant, g_variant_unref);
1018   g_clear_pointer (&tmp_dict, g_variant_dict_unref);
1019 
1020   // Check xmd["can_bool"] == TRUE
1021   g_assert_true (g_variant_dict_lookup (xmd_dict, "can_bool", "b", &tmp_bool));
1022   g_assert_true (tmp_bool);
1023 
1024   g_clear_pointer (&xmd_dict, g_variant_dict_unref);
1025 
1026 
1027   // Cleanup
1028   g_clear_object (&stream);
1029   g_clear_pointer (&module_name_prop, g_free);
1030   g_clear_pointer (&stream_name_prop, g_free);
1031   g_clear_pointer (&context_prop, g_free);
1032   g_clear_pointer (&arch_prop, g_free);
1033   g_clear_pointer (&error, g_error_free);
1034 
1035   g_clear_pointer (&rpm_apis, g_strfreev);
1036   g_clear_pointer (&rpm_filters, g_strfreev);
1037   g_clear_pointer (&demodularized_rpms, g_strfreev);
1038   g_clear_pointer (&rpm_artifacts, g_strfreev);
1039   g_clear_pointer (&servicelevel_names, g_strfreev);
1040 
1041   g_clear_pointer (&sl_name_prop, g_free);
1042   g_clear_pointer (&sl_eol_string, g_free);
1043 
1044   g_clear_pointer (&content_licenses, g_strfreev);
1045   g_clear_pointer (&module_licenses, g_strfreev);
1046   g_clear_pointer (&stream_dependencies, g_strfreev);
1047 
1048   g_clear_pointer (&community_prop, g_free);
1049   g_clear_pointer (&documentation_prop, g_free);
1050   g_clear_pointer (&tracker_prop, g_free);
1051   g_clear_pointer (&profile_names, g_strfreev);
1052 
1053   g_clear_pointer (&buildopts_rpm_macros_prop, g_free);
1054   g_clear_pointer (&buildopts_rpm_whitelist, g_strfreev);
1055   g_clear_pointer (&buildopts_arches, g_strfreev);
1056 
1057 
1058   // Validate a trivial modulemd
1059   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1060   stream = modulemd_module_stream_read_string (
1061     "---\n"
1062     "document: modulemd\n"
1063     "version: 2\n"
1064     "data:\n"
1065     "  summary: Trivial Summary\n"
1066     "  description: >-\n"
1067     "    Trivial Description\n"
1068     "  license:\n"
1069     "    module: MIT\n"
1070     "...\n",
1071     TRUE,
1072     NULL,
1073     NULL,
1074     &error);
1075   G_GNUC_END_IGNORE_DEPRECATIONS
1076 
1077   g_assert_no_error (error);
1078   g_assert_nonnull (stream);
1079 
1080   g_clear_object (&stream);
1081 
1082 
1083   // Sanity check spec.v2.yaml
1084   gchar *specV2Path = g_strdup_printf ("%s/yaml_specs/modulemd_stream_v2.yaml",
1085                                        g_getenv ("MESON_SOURCE_ROOT"));
1086   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1087   stream =
1088     modulemd_module_stream_read_file (specV2Path, TRUE, NULL, NULL, &error);
1089   G_GNUC_END_IGNORE_DEPRECATIONS
1090 
1091   g_assert_no_error (error);
1092   g_assert_nonnull (stream);
1093 
1094   g_clear_object (&stream);
1095   g_clear_pointer (&specV2Path, g_free);
1096 }
1097 
1098 
1099 static void
module_packager_v2_sanity(void)1100 module_packager_v2_sanity (void)
1101 {
1102   g_autoptr (ModulemdModuleStream) stream = NULL;
1103   g_autoptr (GError) error = NULL;
1104 
1105   g_autofree gchar *specV2Path = g_strdup_printf (
1106     "%s/yaml_specs/modulemd_packager_v2.yaml", g_getenv ("MESON_SOURCE_ROOT"));
1107   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1108   stream =
1109     modulemd_module_stream_read_file (specV2Path, TRUE, NULL, NULL, &error);
1110   G_GNUC_END_IGNORE_DEPRECATIONS
1111   g_assert_no_error (error);
1112   g_assert_nonnull (stream);
1113 
1114   g_clear_object (&stream);
1115   g_clear_pointer (&specV2Path, g_free);
1116 }
1117 
1118 
1119 static void
module_packager_v3_sanity(void)1120 module_packager_v3_sanity (void)
1121 {
1122   g_autoptr (ModulemdModuleStream) stream = NULL;
1123   g_autoptr (GError) error = NULL;
1124 
1125   g_autofree gchar *packagerV3Path = g_strdup_printf (
1126     "%s/yaml_specs/modulemd_packager_v3.yaml", g_getenv ("MESON_SOURCE_ROOT"));
1127   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1128   stream = modulemd_module_stream_read_file (
1129     packagerV3Path, TRUE, NULL, NULL, &error);
1130   G_GNUC_END_IGNORE_DEPRECATIONS
1131   g_assert_no_error (error);
1132   g_assert_nonnull (stream);
1133 
1134   /* confirm packager v3 document was returned as stream v2 */
1135   g_assert_true (MODULEMD_IS_MODULE_STREAM_V2 (stream));
1136 
1137   g_clear_object (&stream);
1138   g_clear_pointer (&packagerV3Path, g_free);
1139 }
1140 
1141 
1142 static void
module_stream_v1_test_rpm_artifacts(void)1143 module_stream_v1_test_rpm_artifacts (void)
1144 {
1145   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
1146   g_auto (GStrv) artifacts = NULL;
1147 
1148   stream = modulemd_module_stream_v1_new (NULL, NULL);
1149 
1150   modulemd_module_stream_v1_add_rpm_artifact (
1151     stream, "bar-0:1.23-1.module_deadbeef.x86_64");
1152   artifacts = modulemd_module_stream_v1_get_rpm_artifacts_as_strv (stream);
1153   g_assert_true (g_strv_contains ((const gchar *const *)artifacts,
1154                                   "bar-0:1.23-1.module_deadbeef.x86_64"));
1155   g_assert_cmpint (g_strv_length (artifacts), ==, 1);
1156 
1157   g_clear_pointer (&artifacts, g_strfreev);
1158 
1159   modulemd_module_stream_v1_remove_rpm_artifact (
1160     stream, "bar-0:1.23-1.module_deadbeef.x86_64");
1161   artifacts = modulemd_module_stream_v1_get_rpm_artifacts_as_strv (stream);
1162   g_assert_cmpint (g_strv_length (artifacts), ==, 0);
1163 
1164   g_clear_pointer (&artifacts, g_strfreev);
1165   g_clear_object (&stream);
1166 }
1167 
1168 static void
module_stream_v2_test_rpm_artifacts(void)1169 module_stream_v2_test_rpm_artifacts (void)
1170 {
1171   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
1172   g_auto (GStrv) artifacts = NULL;
1173 
1174   stream = modulemd_module_stream_v2_new (NULL, NULL);
1175 
1176   modulemd_module_stream_v2_add_rpm_artifact (
1177     stream, "bar-0:1.23-1.module_deadbeef.x86_64");
1178   artifacts = modulemd_module_stream_v2_get_rpm_artifacts_as_strv (stream);
1179   g_assert_true (g_strv_contains ((const gchar *const *)artifacts,
1180                                   "bar-0:1.23-1.module_deadbeef.x86_64"));
1181   g_assert_cmpint (g_strv_length (artifacts), ==, 1);
1182 
1183   g_clear_pointer (&artifacts, g_strfreev);
1184 
1185   modulemd_module_stream_v2_remove_rpm_artifact (
1186     stream, "bar-0:1.23-1.module_deadbeef.x86_64");
1187   artifacts = modulemd_module_stream_v2_get_rpm_artifacts_as_strv (stream);
1188   g_assert_cmpint (g_strv_length (artifacts), ==, 0);
1189 
1190   g_clear_pointer (&artifacts, g_strfreev);
1191   g_clear_object (&stream);
1192 }
1193 
1194 
1195 static void
module_stream_v1_test_servicelevels(void)1196 module_stream_v1_test_servicelevels (void)
1197 {
1198   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
1199   g_auto (GStrv) servicelevel_names = NULL;
1200   g_autoptr (ModulemdServiceLevel) sl = NULL;
1201   ModulemdServiceLevel *sl_retrieved = NULL;
1202   g_autofree gchar *name_prop = NULL;
1203   g_autofree gchar *eol_str = NULL;
1204 
1205   stream = modulemd_module_stream_v1_new (NULL, NULL);
1206   sl = modulemd_service_level_new ("rawhide");
1207   modulemd_service_level_set_eol_ymd (sl, 1980, 3, 2);
1208 
1209   modulemd_module_stream_v1_add_servicelevel (stream, sl);
1210 
1211   servicelevel_names =
1212     modulemd_module_stream_v1_get_servicelevel_names_as_strv (stream);
1213   g_assert_true (
1214     g_strv_contains ((const gchar *const *)servicelevel_names, "rawhide"));
1215   g_assert_cmpint (g_strv_length (servicelevel_names), ==, 1);
1216 
1217   sl_retrieved =
1218     modulemd_module_stream_v1_get_servicelevel (stream, "rawhide");
1219   g_object_get (sl_retrieved, "name", &name_prop, NULL);
1220   eol_str = modulemd_service_level_get_eol_as_string (sl_retrieved);
1221 
1222   g_assert_cmpstr (name_prop, ==, "rawhide");
1223   g_assert_cmpstr (eol_str, ==, "1980-03-02");
1224 
1225   g_clear_object (&sl);
1226   g_clear_object (&stream);
1227   g_clear_pointer (&name_prop, g_free);
1228   g_clear_pointer (&eol_str, g_free);
1229   g_clear_pointer (&servicelevel_names, g_strfreev);
1230 }
1231 
1232 
1233 static void
module_stream_v2_test_servicelevels(void)1234 module_stream_v2_test_servicelevels (void)
1235 {
1236   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
1237   g_auto (GStrv) servicelevel_names = NULL;
1238   g_autoptr (ModulemdServiceLevel) sl = NULL;
1239   ModulemdServiceLevel *sl_retrieved = NULL;
1240   g_autofree gchar *name_prop = NULL;
1241   g_autofree gchar *eol_str = NULL;
1242 
1243   stream = modulemd_module_stream_v2_new (NULL, NULL);
1244   sl = modulemd_service_level_new ("rawhide");
1245   modulemd_service_level_set_eol_ymd (sl, 1980, 3, 2);
1246 
1247   modulemd_module_stream_v2_add_servicelevel (stream, sl);
1248 
1249   servicelevel_names =
1250     modulemd_module_stream_v2_get_servicelevel_names_as_strv (stream);
1251   g_assert_true (
1252     g_strv_contains ((const gchar *const *)servicelevel_names, "rawhide"));
1253   g_assert_cmpint (g_strv_length (servicelevel_names), ==, 1);
1254 
1255   sl_retrieved =
1256     modulemd_module_stream_v2_get_servicelevel (stream, "rawhide");
1257   g_object_get (sl_retrieved, "name", &name_prop, NULL);
1258   eol_str = modulemd_service_level_get_eol_as_string (sl_retrieved);
1259 
1260   g_assert_cmpstr (name_prop, ==, "rawhide");
1261   g_assert_cmpstr (eol_str, ==, "1980-03-02");
1262 
1263   g_clear_object (&sl);
1264   g_clear_object (&stream);
1265   g_clear_pointer (&name_prop, g_free);
1266   g_clear_pointer (&eol_str, g_free);
1267   g_clear_pointer (&servicelevel_names, g_strfreev);
1268 }
1269 
1270 
1271 static void
module_stream_v1_test_documentation(void)1272 module_stream_v1_test_documentation (void)
1273 {
1274   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
1275   const gchar *documentation = NULL;
1276   g_autofree gchar *documentation_prop = NULL;
1277 
1278   stream = modulemd_module_stream_v1_new (NULL, NULL);
1279 
1280   // Check the defaults
1281   documentation = modulemd_module_stream_v1_get_documentation (stream);
1282   g_object_get (stream, MMD_TEST_DOC_PROP, &documentation_prop, NULL);
1283   g_assert_null (documentation);
1284   g_assert_null (documentation_prop);
1285 
1286   g_clear_pointer (&documentation_prop, g_free);
1287 
1288   // Test property setting
1289   g_object_set (stream, MMD_TEST_DOC_PROP, MMD_TEST_DOC_TEXT, NULL);
1290 
1291   documentation = modulemd_module_stream_v1_get_documentation (stream);
1292   g_object_get (stream, MMD_TEST_DOC_PROP, &documentation_prop, NULL);
1293   g_assert_cmpstr (documentation_prop, ==, MMD_TEST_DOC_TEXT);
1294   g_assert_cmpstr (documentation, ==, MMD_TEST_DOC_TEXT);
1295 
1296   g_clear_pointer (&documentation_prop, g_free);
1297 
1298   // Test set_documentation()
1299   modulemd_module_stream_v1_set_documentation (stream, MMD_TEST_DOC_TEXT2);
1300 
1301   documentation = modulemd_module_stream_v1_get_documentation (stream);
1302   g_object_get (stream, MMD_TEST_DOC_PROP, &documentation_prop, NULL);
1303   g_assert_cmpstr (documentation_prop, ==, MMD_TEST_DOC_TEXT2);
1304   g_assert_cmpstr (documentation, ==, MMD_TEST_DOC_TEXT2);
1305 
1306   g_clear_pointer (&documentation_prop, g_free);
1307 
1308   // Test setting to NULL
1309   g_object_set (stream, MMD_TEST_DOC_PROP, NULL, NULL);
1310 
1311   documentation = modulemd_module_stream_v1_get_documentation (stream);
1312   g_object_get (stream, MMD_TEST_DOC_PROP, &documentation_prop, NULL);
1313   g_assert_null (documentation);
1314   g_assert_null (documentation_prop);
1315 
1316   g_clear_pointer (&documentation_prop, g_free);
1317 
1318   // Test unicode characters
1319   modulemd_module_stream_v1_set_documentation (stream,
1320                                                MMD_TEST_DOC_UNICODE_TEXT);
1321 
1322   documentation = modulemd_module_stream_v1_get_documentation (stream);
1323   g_object_get (stream, MMD_TEST_DOC_PROP, &documentation_prop, NULL);
1324   g_assert_cmpstr (documentation_prop, ==, MMD_TEST_DOC_UNICODE_TEXT);
1325   g_assert_cmpstr (documentation, ==, MMD_TEST_DOC_UNICODE_TEXT);
1326 
1327   g_clear_pointer (&documentation_prop, g_free);
1328 
1329   g_clear_object (&stream);
1330 }
1331 
1332 static void
module_stream_v2_test_documentation(void)1333 module_stream_v2_test_documentation (void)
1334 {
1335   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
1336   const gchar *documentation = NULL;
1337   g_autofree gchar *documentation_prop = NULL;
1338 
1339   stream = modulemd_module_stream_v2_new (NULL, NULL);
1340 
1341   // Check the defaults
1342   documentation = modulemd_module_stream_v2_get_documentation (stream);
1343   g_object_get (stream, MMD_TEST_DOC_PROP, &documentation_prop, NULL);
1344   g_assert_null (documentation);
1345   g_assert_null (documentation_prop);
1346 
1347   g_clear_pointer (&documentation_prop, g_free);
1348 
1349   // Test property setting
1350   g_object_set (stream, MMD_TEST_DOC_PROP, MMD_TEST_DOC_TEXT, NULL);
1351 
1352   documentation = modulemd_module_stream_v2_get_documentation (stream);
1353   g_object_get (stream, MMD_TEST_DOC_PROP, &documentation_prop, NULL);
1354   g_assert_cmpstr (documentation_prop, ==, MMD_TEST_DOC_TEXT);
1355   g_assert_cmpstr (documentation, ==, MMD_TEST_DOC_TEXT);
1356 
1357   g_clear_pointer (&documentation_prop, g_free);
1358 
1359   // Test set_documentation()
1360   modulemd_module_stream_v2_set_documentation (stream, MMD_TEST_DOC_TEXT2);
1361 
1362   documentation = modulemd_module_stream_v2_get_documentation (stream);
1363   g_object_get (stream, MMD_TEST_DOC_PROP, &documentation_prop, NULL);
1364   g_assert_cmpstr (documentation_prop, ==, MMD_TEST_DOC_TEXT2);
1365   g_assert_cmpstr (documentation, ==, MMD_TEST_DOC_TEXT2);
1366 
1367   g_clear_pointer (&documentation_prop, g_free);
1368 
1369   // Test setting to NULL
1370   g_object_set (stream, MMD_TEST_DOC_PROP, NULL, NULL);
1371 
1372   documentation = modulemd_module_stream_v2_get_documentation (stream);
1373   g_object_get (stream, MMD_TEST_DOC_PROP, &documentation_prop, NULL);
1374   g_assert_null (documentation);
1375   g_assert_null (documentation_prop);
1376 
1377   g_clear_pointer (&documentation_prop, g_free);
1378 
1379   // Test unicode characters
1380   modulemd_module_stream_v2_set_documentation (stream,
1381                                                MMD_TEST_DOC_UNICODE_TEXT);
1382 
1383   documentation = modulemd_module_stream_v2_get_documentation (stream);
1384   g_object_get (stream, MMD_TEST_DOC_PROP, &documentation_prop, NULL);
1385   g_assert_cmpstr (documentation_prop, ==, MMD_TEST_DOC_UNICODE_TEXT);
1386   g_assert_cmpstr (documentation, ==, MMD_TEST_DOC_UNICODE_TEXT);
1387 
1388   g_clear_pointer (&documentation_prop, g_free);
1389 
1390   g_clear_object (&stream);
1391 }
1392 
1393 
1394 static void
module_stream_v1_test_tracker(void)1395 module_stream_v1_test_tracker (void)
1396 {
1397   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
1398   g_autofree gchar *tracker_prop = NULL;
1399   const gchar *tracker = NULL;
1400 
1401   stream = modulemd_module_stream_v1_new (NULL, NULL);
1402 
1403   // Check the defaults
1404   g_object_get (stream, MMD_TEST_TRACKER_PROP, &tracker_prop, NULL);
1405   tracker = modulemd_module_stream_v1_get_tracker (stream);
1406 
1407   g_assert_null (tracker);
1408   g_assert_null (tracker_prop);
1409 
1410   g_clear_pointer (&tracker_prop, g_free);
1411 
1412   // Test property setting
1413   g_object_set (stream, MMD_TEST_TRACKER_PROP, MMD_TEST_DOC_TEXT, NULL);
1414 
1415   g_object_get (stream, MMD_TEST_TRACKER_PROP, &tracker_prop, NULL);
1416   tracker = modulemd_module_stream_v1_get_tracker (stream);
1417 
1418   g_assert_cmpstr (tracker, ==, MMD_TEST_DOC_TEXT);
1419   g_assert_cmpstr (tracker_prop, ==, MMD_TEST_DOC_TEXT);
1420 
1421   g_clear_pointer (&tracker_prop, g_free);
1422 
1423   // Test set_tracker
1424   modulemd_module_stream_v1_set_tracker (stream, MMD_TEST_DOC_TEXT2);
1425 
1426   g_object_get (stream, MMD_TEST_TRACKER_PROP, &tracker_prop, NULL);
1427   tracker = modulemd_module_stream_v1_get_tracker (stream);
1428 
1429   g_assert_cmpstr (tracker, ==, MMD_TEST_DOC_TEXT2);
1430   g_assert_cmpstr (tracker_prop, ==, MMD_TEST_DOC_TEXT2);
1431 
1432   g_clear_pointer (&tracker_prop, g_free);
1433 
1434   // Test setting it to NULL
1435   g_object_set (stream, MMD_TEST_TRACKER_PROP, NULL, NULL);
1436 
1437   g_object_get (stream, MMD_TEST_TRACKER_PROP, &tracker_prop, NULL);
1438   tracker = modulemd_module_stream_v1_get_tracker (stream);
1439 
1440   g_assert_null (tracker);
1441   g_assert_null (tracker_prop);
1442 
1443   g_clear_pointer (&tracker_prop, g_free);
1444 
1445   // Test Unicode values
1446   modulemd_module_stream_v1_set_tracker (stream, MMD_TEST_DOC_UNICODE_TEXT);
1447 
1448   g_object_get (stream, MMD_TEST_TRACKER_PROP, &tracker_prop, NULL);
1449   tracker = modulemd_module_stream_v1_get_tracker (stream);
1450 
1451   g_assert_cmpstr (tracker, ==, MMD_TEST_DOC_UNICODE_TEXT);
1452   g_assert_cmpstr (tracker_prop, ==, MMD_TEST_DOC_UNICODE_TEXT);
1453 
1454   g_clear_pointer (&tracker_prop, g_free);
1455   g_clear_object (&stream);
1456 }
1457 
1458 static void
module_stream_v2_test_tracker(void)1459 module_stream_v2_test_tracker (void)
1460 {
1461   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
1462   g_autofree gchar *tracker_prop = NULL;
1463   const gchar *tracker = NULL;
1464 
1465   stream = modulemd_module_stream_v2_new (NULL, NULL);
1466 
1467   // Check the defaults
1468   g_object_get (stream, MMD_TEST_TRACKER_PROP, &tracker_prop, NULL);
1469   tracker = modulemd_module_stream_v2_get_tracker (stream);
1470 
1471   g_assert_null (tracker);
1472   g_assert_null (tracker_prop);
1473 
1474   g_clear_pointer (&tracker_prop, g_free);
1475 
1476   // Test property setting
1477   g_object_set (stream, MMD_TEST_TRACKER_PROP, MMD_TEST_DOC_TEXT, NULL);
1478 
1479   g_object_get (stream, MMD_TEST_TRACKER_PROP, &tracker_prop, NULL);
1480   tracker = modulemd_module_stream_v2_get_tracker (stream);
1481 
1482   g_assert_cmpstr (tracker, ==, MMD_TEST_DOC_TEXT);
1483   g_assert_cmpstr (tracker_prop, ==, MMD_TEST_DOC_TEXT);
1484 
1485   g_clear_pointer (&tracker_prop, g_free);
1486 
1487   // Test set_tracker
1488   modulemd_module_stream_v2_set_tracker (stream, MMD_TEST_DOC_TEXT2);
1489 
1490   g_object_get (stream, MMD_TEST_TRACKER_PROP, &tracker_prop, NULL);
1491   tracker = modulemd_module_stream_v2_get_tracker (stream);
1492 
1493   g_assert_cmpstr (tracker, ==, MMD_TEST_DOC_TEXT2);
1494   g_assert_cmpstr (tracker_prop, ==, MMD_TEST_DOC_TEXT2);
1495 
1496   g_clear_pointer (&tracker_prop, g_free);
1497 
1498   // Test setting it to NULL
1499   g_object_set (stream, MMD_TEST_TRACKER_PROP, NULL, NULL);
1500 
1501   g_object_get (stream, MMD_TEST_TRACKER_PROP, &tracker_prop, NULL);
1502   tracker = modulemd_module_stream_v2_get_tracker (stream);
1503 
1504   g_assert_null (tracker);
1505   g_assert_null (tracker_prop);
1506 
1507   g_clear_pointer (&tracker_prop, g_free);
1508 
1509   // Test Unicode values
1510   modulemd_module_stream_v2_set_tracker (stream, MMD_TEST_DOC_UNICODE_TEXT);
1511 
1512   g_object_get (stream, MMD_TEST_TRACKER_PROP, &tracker_prop, NULL);
1513   tracker = modulemd_module_stream_v2_get_tracker (stream);
1514 
1515   g_assert_cmpstr (tracker, ==, MMD_TEST_DOC_UNICODE_TEXT);
1516   g_assert_cmpstr (tracker_prop, ==, MMD_TEST_DOC_UNICODE_TEXT);
1517 
1518   g_clear_pointer (&tracker_prop, g_free);
1519   g_clear_object (&stream);
1520 }
1521 
1522 
1523 static void
module_stream_v1_test_components(void)1524 module_stream_v1_test_components (void)
1525 {
1526   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
1527   g_autoptr (ModulemdComponentRpm) rpm_component = NULL;
1528   g_autoptr (ModulemdComponentModule) module_component = NULL;
1529   ModulemdComponent *retrieved_component = NULL;
1530   g_auto (GStrv) component_names = NULL;
1531 
1532   stream = modulemd_module_stream_v1_new (NULL, NULL);
1533 
1534   // Add a RPM component to a stream
1535   rpm_component = modulemd_component_rpm_new ("rpmcomponent");
1536   modulemd_module_stream_v1_add_component (stream,
1537                                            (ModulemdComponent *)rpm_component);
1538   component_names =
1539     modulemd_module_stream_v1_get_rpm_component_names_as_strv (stream);
1540   g_assert_true (
1541     g_strv_contains ((const gchar *const *)component_names, "rpmcomponent"));
1542   g_assert_cmpint (g_strv_length (component_names), ==, 1);
1543 
1544   retrieved_component =
1545     (ModulemdComponent *)modulemd_module_stream_v1_get_rpm_component (
1546       stream, "rpmcomponent");
1547   g_assert_nonnull (retrieved_component);
1548   g_assert_true (modulemd_component_equals (
1549     retrieved_component, (ModulemdComponent *)rpm_component));
1550 
1551   g_clear_pointer (&component_names, g_strfreev);
1552 
1553   // Add a Module component to a stream
1554   module_component = modulemd_component_module_new ("modulecomponent");
1555   modulemd_module_stream_v1_add_component (
1556     stream, (ModulemdComponent *)module_component);
1557   component_names =
1558     modulemd_module_stream_v1_get_module_component_names_as_strv (stream);
1559   g_assert_true (g_strv_contains ((const gchar *const *)component_names,
1560                                   "modulecomponent"));
1561   g_assert_cmpint (g_strv_length (component_names), ==, 1);
1562 
1563   retrieved_component =
1564     (ModulemdComponent *)modulemd_module_stream_v1_get_module_component (
1565       stream, "modulecomponent");
1566   g_assert_nonnull (retrieved_component);
1567   g_assert_true (modulemd_component_equals (
1568     retrieved_component, (ModulemdComponent *)module_component));
1569 
1570   g_clear_pointer (&component_names, g_strfreev);
1571 
1572   // Remove an RPM component from a stream
1573   modulemd_module_stream_v1_remove_rpm_component (stream, "rpmcomponent");
1574   component_names =
1575     modulemd_module_stream_v1_get_rpm_component_names_as_strv (stream);
1576   g_assert_cmpint (g_strv_length (component_names), ==, 0);
1577 
1578   g_clear_pointer (&component_names, g_strfreev);
1579 
1580   // Remove a Module component from a stream
1581   modulemd_module_stream_v1_remove_module_component (stream,
1582                                                      "modulecomponent");
1583   component_names =
1584     modulemd_module_stream_v1_get_module_component_names_as_strv (stream);
1585   g_assert_cmpint (g_strv_length (component_names), ==, 0);
1586 
1587   g_clear_pointer (&component_names, g_strfreev);
1588 
1589   g_clear_object (&module_component);
1590   g_clear_object (&rpm_component);
1591   g_clear_object (&stream);
1592 }
1593 
1594 static void
module_stream_v2_test_components(void)1595 module_stream_v2_test_components (void)
1596 {
1597   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
1598   g_autoptr (ModulemdComponentRpm) rpm_component = NULL;
1599   g_autoptr (ModulemdComponentModule) module_component = NULL;
1600   ModulemdComponent *retrieved_component = NULL;
1601   g_auto (GStrv) component_names = NULL;
1602 
1603   stream = modulemd_module_stream_v2_new (NULL, NULL);
1604 
1605   // Add a RPM component to a stream
1606   rpm_component = modulemd_component_rpm_new ("rpmcomponent");
1607   modulemd_module_stream_v2_add_component (stream,
1608                                            (ModulemdComponent *)rpm_component);
1609   component_names =
1610     modulemd_module_stream_v2_get_rpm_component_names_as_strv (stream);
1611   g_assert_true (
1612     g_strv_contains ((const gchar *const *)component_names, "rpmcomponent"));
1613   g_assert_cmpint (g_strv_length (component_names), ==, 1);
1614 
1615   retrieved_component =
1616     (ModulemdComponent *)modulemd_module_stream_v2_get_rpm_component (
1617       stream, "rpmcomponent");
1618   g_assert_nonnull (retrieved_component);
1619   g_assert_true (modulemd_component_equals (
1620     retrieved_component, (ModulemdComponent *)rpm_component));
1621 
1622   g_clear_pointer (&component_names, g_strfreev);
1623 
1624   // Add a Module component to a stream
1625   module_component = modulemd_component_module_new ("modulecomponent");
1626   modulemd_module_stream_v2_add_component (
1627     stream, (ModulemdComponent *)module_component);
1628   component_names =
1629     modulemd_module_stream_v2_get_module_component_names_as_strv (stream);
1630   g_assert_true (g_strv_contains ((const gchar *const *)component_names,
1631                                   "modulecomponent"));
1632   g_assert_cmpint (g_strv_length (component_names), ==, 1);
1633 
1634   retrieved_component =
1635     (ModulemdComponent *)modulemd_module_stream_v2_get_module_component (
1636       stream, "modulecomponent");
1637   g_assert_nonnull (retrieved_component);
1638   g_assert_true (modulemd_component_equals (
1639     retrieved_component, (ModulemdComponent *)module_component));
1640 
1641   g_clear_pointer (&component_names, g_strfreev);
1642 
1643   // Remove an RPM component from a stream
1644   modulemd_module_stream_v2_remove_rpm_component (stream, "rpmcomponent");
1645   component_names =
1646     modulemd_module_stream_v2_get_rpm_component_names_as_strv (stream);
1647   g_assert_cmpint (g_strv_length (component_names), ==, 0);
1648 
1649   g_clear_pointer (&component_names, g_strfreev);
1650 
1651   // Remove a Module component from a stream
1652   modulemd_module_stream_v2_remove_module_component (stream,
1653                                                      "modulecomponent");
1654   component_names =
1655     modulemd_module_stream_v2_get_module_component_names_as_strv (stream);
1656   g_assert_cmpint (g_strv_length (component_names), ==, 0);
1657 
1658   g_clear_pointer (&component_names, g_strfreev);
1659 
1660   g_clear_object (&module_component);
1661   g_clear_object (&rpm_component);
1662   g_clear_object (&stream);
1663 }
1664 
1665 
1666 static void
module_stream_test_copy(void)1667 module_stream_test_copy (void)
1668 {
1669   g_autoptr (ModulemdModuleStream) stream = NULL;
1670   g_autoptr (ModulemdModuleStream) copied_stream = NULL;
1671   guint64 version;
1672 
1673   for (version = MD_MODULESTREAM_VERSION_ONE;
1674        version <= MD_MODULESTREAM_VERSION_LATEST;
1675        version++)
1676     {
1677       /* Test copying with a stream name */
1678       stream = modulemd_module_stream_new (version, "foo", "latest");
1679       copied_stream = modulemd_module_stream_copy (stream, NULL, NULL);
1680       g_assert_nonnull (copied_stream);
1681       g_assert_true (MODULEMD_IS_MODULE_STREAM (copied_stream));
1682       g_assert_cmpstr (modulemd_module_stream_get_module_name (stream),
1683                        ==,
1684                        modulemd_module_stream_get_module_name (copied_stream));
1685       g_assert_cmpstr (modulemd_module_stream_get_stream_name (stream),
1686                        ==,
1687                        modulemd_module_stream_get_stream_name (copied_stream));
1688       g_clear_object (&stream);
1689       g_clear_object (&copied_stream);
1690 
1691 
1692       /* Test copying without a stream name */
1693       stream = modulemd_module_stream_new (version, "foo", NULL);
1694       copied_stream = modulemd_module_stream_copy (stream, NULL, NULL);
1695       g_assert_nonnull (copied_stream);
1696       g_assert_true (MODULEMD_IS_MODULE_STREAM (copied_stream));
1697       g_assert_cmpstr (modulemd_module_stream_get_module_name (stream),
1698                        ==,
1699                        modulemd_module_stream_get_module_name (copied_stream));
1700       g_assert_cmpstr (modulemd_module_stream_get_stream_name (stream),
1701                        ==,
1702                        modulemd_module_stream_get_stream_name (copied_stream));
1703       g_clear_object (&stream);
1704       g_clear_object (&copied_stream);
1705 
1706       /* Test copying with and renaming the stream name */
1707       stream = modulemd_module_stream_new (version, "foo", "latest");
1708       copied_stream = modulemd_module_stream_copy (stream, NULL, "earliest");
1709       g_assert_nonnull (copied_stream);
1710       g_assert_true (MODULEMD_IS_MODULE_STREAM (copied_stream));
1711       g_assert_cmpstr (modulemd_module_stream_get_module_name (stream),
1712                        ==,
1713                        modulemd_module_stream_get_module_name (copied_stream));
1714       g_assert_cmpstr (
1715         modulemd_module_stream_get_stream_name (stream), ==, "latest");
1716       g_assert_cmpstr (modulemd_module_stream_get_stream_name (copied_stream),
1717                        ==,
1718                        "earliest");
1719       g_clear_object (&stream);
1720       g_clear_object (&copied_stream);
1721     }
1722 }
1723 
1724 
1725 static void
module_stream_test_equals(void)1726 module_stream_test_equals (void)
1727 {
1728   g_autoptr (ModulemdModuleStream) stream_1 = NULL;
1729   g_autoptr (ModulemdModuleStream) stream_2 = NULL;
1730   guint64 version;
1731 
1732   for (version = MD_MODULESTREAM_VERSION_ONE;
1733        version <= MD_MODULESTREAM_VERSION_LATEST;
1734        version++)
1735     {
1736       /* Test equality with same stream and module names */
1737       stream_1 = modulemd_module_stream_new (version, "foo", "latest");
1738       stream_2 = modulemd_module_stream_new (version, "foo", "latest");
1739 
1740       g_assert_true (modulemd_module_stream_equals (stream_1, stream_2));
1741       g_clear_object (&stream_1);
1742       g_clear_object (&stream_2);
1743 
1744 
1745       /* Test equality with different stream names*/
1746       stream_1 = modulemd_module_stream_new (version, "foo", NULL);
1747       stream_2 = modulemd_module_stream_new (version, "bar", NULL);
1748 
1749       g_assert_false (modulemd_module_stream_equals (stream_1, stream_2));
1750       g_clear_object (&stream_1);
1751       g_clear_object (&stream_2);
1752 
1753       /* Test equality with different module name */
1754       stream_1 = modulemd_module_stream_new (version, "bar", "thor");
1755       stream_2 = modulemd_module_stream_new (version, "bar", "loki");
1756 
1757       g_assert_false (modulemd_module_stream_equals (stream_1, stream_2));
1758       g_clear_object (&stream_1);
1759       g_clear_object (&stream_2);
1760 
1761       /* Test equality with same arch */
1762       stream_1 = modulemd_module_stream_new (version, "bar", "thor");
1763       modulemd_module_stream_set_arch (stream_1, "x86_64");
1764       stream_2 = modulemd_module_stream_new (version, "bar", "thor");
1765       modulemd_module_stream_set_arch (stream_2, "x86_64");
1766 
1767       g_assert_true (modulemd_module_stream_equals (stream_1, stream_2));
1768       g_clear_object (&stream_1);
1769       g_clear_object (&stream_2);
1770 
1771       /* Test equality with different arch */
1772       stream_1 = modulemd_module_stream_new (version, "bar", "thor");
1773       modulemd_module_stream_set_arch (stream_1, "x86_64");
1774       stream_2 = modulemd_module_stream_new (version, "bar", "thor");
1775       modulemd_module_stream_set_arch (stream_2, "x86_25");
1776 
1777       g_assert_false (modulemd_module_stream_equals (stream_1, stream_2));
1778       g_clear_object (&stream_1);
1779       g_clear_object (&stream_2);
1780     }
1781 }
1782 
1783 
1784 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1785 static void
module_stream_test_nsvc(void)1786 module_stream_test_nsvc (void)
1787 {
1788   g_autoptr (ModulemdModuleStream) stream = NULL;
1789   g_autofree gchar *s_nsvc = NULL;
1790   guint64 version;
1791 
1792   for (version = MD_MODULESTREAM_VERSION_ONE;
1793        version <= MD_MODULESTREAM_VERSION_LATEST;
1794        version++)
1795     {
1796       // First test that nsvc is None for a module with no name
1797       stream = modulemd_module_stream_new (version, NULL, NULL);
1798       s_nsvc = modulemd_module_stream_get_nsvc_as_string (stream);
1799       g_assert_null (s_nsvc);
1800       g_clear_pointer (&s_nsvc, g_free);
1801       g_clear_object (&stream);
1802 
1803       // Now with valid module and stream names
1804       stream = modulemd_module_stream_new (version, "modulename", NULL);
1805       s_nsvc = modulemd_module_stream_get_nsvc_as_string (stream);
1806       g_assert_null (s_nsvc);
1807       g_clear_pointer (&s_nsvc, g_free);
1808       g_clear_object (&stream);
1809 
1810       // Now with valid module and stream names
1811       stream =
1812         modulemd_module_stream_new (version, "modulename", "streamname");
1813       s_nsvc = modulemd_module_stream_get_nsvc_as_string (stream);
1814       g_assert_cmpstr (s_nsvc, ==, "modulename:streamname:0");
1815       g_clear_pointer (&s_nsvc, g_free);
1816 
1817       //# Add a version number
1818       modulemd_module_stream_set_version (stream, 42);
1819       s_nsvc = modulemd_module_stream_get_nsvc_as_string (stream);
1820       g_assert_cmpstr (s_nsvc, ==, "modulename:streamname:42");
1821       g_clear_pointer (&s_nsvc, g_free);
1822 
1823       // Add a context
1824       modulemd_module_stream_set_context (stream, "deadbeef");
1825       s_nsvc = modulemd_module_stream_get_nsvc_as_string (stream);
1826       g_assert_cmpstr (s_nsvc, ==, "modulename:streamname:42:deadbeef");
1827       g_clear_pointer (&s_nsvc, g_free);
1828       g_clear_object (&stream);
1829     }
1830 }
1831 G_GNUC_END_IGNORE_DEPRECATIONS
1832 
1833 
1834 static void
module_stream_test_nsvca(void)1835 module_stream_test_nsvca (void)
1836 {
1837   g_autoptr (ModulemdModuleStream) stream = NULL;
1838   g_autofree gchar *s_nsvca = NULL;
1839   guint64 version;
1840 
1841   for (version = MD_MODULESTREAM_VERSION_ONE;
1842        version <= MD_MODULESTREAM_VERSION_LATEST;
1843        version++)
1844     {
1845       // First test that NSVCA is None for a module with no name
1846       stream = modulemd_module_stream_new (version, NULL, NULL);
1847       s_nsvca = modulemd_module_stream_get_NSVCA_as_string (stream);
1848       g_assert_null (s_nsvca);
1849       g_clear_pointer (&s_nsvca, g_free);
1850       g_clear_object (&stream);
1851 
1852       // Now with valid module and stream names
1853       stream = modulemd_module_stream_new (version, "modulename", NULL);
1854       s_nsvca = modulemd_module_stream_get_NSVCA_as_string (stream);
1855       g_assert_cmpstr (s_nsvca, ==, "modulename");
1856       g_clear_pointer (&s_nsvca, g_free);
1857       g_clear_object (&stream);
1858 
1859       // Now with valid module and stream names
1860       stream =
1861         modulemd_module_stream_new (version, "modulename", "streamname");
1862       s_nsvca = modulemd_module_stream_get_NSVCA_as_string (stream);
1863       g_assert_cmpstr (s_nsvca, ==, "modulename:streamname");
1864       g_clear_pointer (&s_nsvca, g_free);
1865 
1866       //# Add a version number
1867       modulemd_module_stream_set_version (stream, 42);
1868       s_nsvca = modulemd_module_stream_get_NSVCA_as_string (stream);
1869       g_assert_cmpstr (s_nsvca, ==, "modulename:streamname:42");
1870       g_clear_pointer (&s_nsvca, g_free);
1871 
1872       // Add a context
1873       modulemd_module_stream_set_context (stream, "deadbeef");
1874       s_nsvca = modulemd_module_stream_get_NSVCA_as_string (stream);
1875       g_assert_cmpstr (s_nsvca, ==, "modulename:streamname:42:deadbeef");
1876       g_clear_pointer (&s_nsvca, g_free);
1877 
1878       // Add an architecture
1879       modulemd_module_stream_set_arch (stream, "x86_64");
1880       s_nsvca = modulemd_module_stream_get_NSVCA_as_string (stream);
1881       g_assert_cmpstr (
1882         s_nsvca, ==, "modulename:streamname:42:deadbeef:x86_64");
1883       g_clear_pointer (&s_nsvca, g_free);
1884 
1885       // Now try removing some of the bits in the middle
1886       modulemd_module_stream_set_context (stream, NULL);
1887       s_nsvca = modulemd_module_stream_get_NSVCA_as_string (stream);
1888       g_assert_cmpstr (s_nsvca, ==, "modulename:streamname:42::x86_64");
1889       g_clear_pointer (&s_nsvca, g_free);
1890       g_clear_object (&stream);
1891 
1892       stream = modulemd_module_stream_new (version, "modulename", NULL);
1893       modulemd_module_stream_set_arch (stream, "x86_64");
1894       s_nsvca = modulemd_module_stream_get_NSVCA_as_string (stream);
1895       g_assert_cmpstr (s_nsvca, ==, "modulename::::x86_64");
1896       g_clear_pointer (&s_nsvca, g_free);
1897 
1898       modulemd_module_stream_set_version (stream, 2019);
1899       s_nsvca = modulemd_module_stream_get_NSVCA_as_string (stream);
1900       g_assert_cmpstr (s_nsvca, ==, "modulename::2019::x86_64");
1901       g_clear_pointer (&s_nsvca, g_free);
1902 
1903       // Add a context
1904       modulemd_module_stream_set_context (stream, "feedfeed");
1905       s_nsvca = modulemd_module_stream_get_NSVCA_as_string (stream);
1906       g_assert_cmpstr (s_nsvca, ==, "modulename::2019:feedfeed:x86_64");
1907       g_clear_pointer (&s_nsvca, g_free);
1908       g_clear_object (&stream);
1909     }
1910 }
1911 
1912 
1913 static void
module_stream_v1_test_equals(void)1914 module_stream_v1_test_equals (void)
1915 {
1916   g_autoptr (ModulemdModuleStreamV1) stream_1 = NULL;
1917   g_autoptr (ModulemdModuleStreamV1) stream_2 = NULL;
1918   g_autoptr (ModulemdProfile) profile_1 = NULL;
1919   g_autoptr (ModulemdServiceLevel) servicelevel_1 = NULL;
1920   g_autoptr (ModulemdServiceLevel) servicelevel_2 = NULL;
1921   g_autoptr (ModulemdComponentModule) component_1 = NULL;
1922   g_autoptr (ModulemdComponentRpm) component_2 = NULL;
1923 
1924   /*Test equality of 2 streams with same string constants*/
1925   stream_1 = modulemd_module_stream_v1_new (NULL, NULL);
1926   modulemd_module_stream_v1_set_community (stream_1, "community_1");
1927   modulemd_module_stream_v1_set_description (stream_1, "description_1");
1928   modulemd_module_stream_v1_set_documentation (stream_1, "documentation_1");
1929   modulemd_module_stream_v1_set_summary (stream_1, "summary_1");
1930   modulemd_module_stream_v1_set_tracker (stream_1, "tracker_1");
1931 
1932   stream_2 = modulemd_module_stream_v1_new (NULL, NULL);
1933   modulemd_module_stream_v1_set_community (stream_2, "community_1");
1934   modulemd_module_stream_v1_set_description (stream_2, "description_1");
1935   modulemd_module_stream_v1_set_documentation (stream_2, "documentation_1");
1936   modulemd_module_stream_v1_set_summary (stream_2, "summary_1");
1937   modulemd_module_stream_v1_set_tracker (stream_2, "tracker_1");
1938 
1939   g_assert_true (modulemd_module_stream_equals (
1940     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
1941   g_clear_object (&stream_1);
1942   g_clear_object (&stream_2);
1943 
1944   /*Test equality of 2 streams with certain different string constants*/
1945   stream_1 = modulemd_module_stream_v1_new (NULL, NULL);
1946   modulemd_module_stream_v1_set_community (stream_1, "community_1");
1947   modulemd_module_stream_v1_set_description (stream_1, "description_1");
1948   modulemd_module_stream_v1_set_documentation (stream_1, "documentation_1");
1949   modulemd_module_stream_v1_set_summary (stream_1, "summary_1");
1950   modulemd_module_stream_v1_set_tracker (stream_1, "tracker_1");
1951 
1952   stream_2 = modulemd_module_stream_v1_new (NULL, NULL);
1953   modulemd_module_stream_v1_set_community (stream_2, "community_1");
1954   modulemd_module_stream_v1_set_description (stream_2, "description_2");
1955   modulemd_module_stream_v1_set_documentation (stream_2, "documentation_1");
1956   modulemd_module_stream_v1_set_summary (stream_2, "summary_2");
1957   modulemd_module_stream_v1_set_tracker (stream_2, "tracker_2");
1958 
1959   g_assert_false (modulemd_module_stream_equals (
1960     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
1961   g_clear_object (&stream_1);
1962   g_clear_object (&stream_2);
1963 
1964   /*Test equality of 2 streams with same hashtable sets*/
1965   stream_1 = modulemd_module_stream_v1_new (NULL, NULL);
1966   modulemd_module_stream_v1_add_rpm_api (stream_1, "rpm_1");
1967   modulemd_module_stream_v1_add_rpm_api (stream_1, "rpm_2");
1968   modulemd_module_stream_v1_add_module_license (stream_1, "module_a");
1969   modulemd_module_stream_v1_add_module_license (stream_1, "module_b");
1970   modulemd_module_stream_v1_add_content_license (stream_1, "content_a");
1971   modulemd_module_stream_v1_add_content_license (stream_1, "content_b");
1972   modulemd_module_stream_v1_add_rpm_artifact (stream_1, "artifact_a");
1973   modulemd_module_stream_v1_add_rpm_artifact (stream_1, "artifact_b");
1974   modulemd_module_stream_v1_add_rpm_filter (stream_1, "filter_a");
1975   modulemd_module_stream_v1_add_rpm_filter (stream_1, "filter_b");
1976 
1977   stream_2 = modulemd_module_stream_v1_new (NULL, NULL);
1978   modulemd_module_stream_v1_add_rpm_api (stream_2, "rpm_1");
1979   modulemd_module_stream_v1_add_rpm_api (stream_2, "rpm_2");
1980   modulemd_module_stream_v1_add_module_license (stream_2, "module_a");
1981   modulemd_module_stream_v1_add_module_license (stream_2, "module_b");
1982   modulemd_module_stream_v1_add_content_license (stream_2, "content_a");
1983   modulemd_module_stream_v1_add_content_license (stream_2, "content_b");
1984   modulemd_module_stream_v1_add_rpm_artifact (stream_2, "artifact_a");
1985   modulemd_module_stream_v1_add_rpm_artifact (stream_2, "artifact_b");
1986   modulemd_module_stream_v1_add_rpm_filter (stream_2, "filter_a");
1987   modulemd_module_stream_v1_add_rpm_filter (stream_2, "filter_b");
1988 
1989   g_assert_true (modulemd_module_stream_equals (
1990     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
1991   g_clear_object (&stream_1);
1992   g_clear_object (&stream_2);
1993 
1994   /*Test equality of 2 streams with different hashtable sets*/
1995   stream_1 = modulemd_module_stream_v1_new (NULL, NULL);
1996   modulemd_module_stream_v1_add_rpm_api (stream_1, "rpm_1");
1997   modulemd_module_stream_v1_add_rpm_api (stream_1, "rpm_2");
1998   modulemd_module_stream_v1_add_module_license (stream_1, "module_a");
1999   modulemd_module_stream_v1_add_module_license (stream_1, "module_b");
2000   modulemd_module_stream_v1_add_content_license (stream_1, "content_a");
2001   modulemd_module_stream_v1_add_content_license (stream_1, "content_b");
2002   modulemd_module_stream_v1_add_rpm_artifact (stream_1, "artifact_a");
2003   modulemd_module_stream_v1_add_rpm_artifact (stream_1, "artifact_b");
2004   modulemd_module_stream_v1_add_rpm_artifact (stream_1, "artifact_c");
2005   modulemd_module_stream_v1_add_rpm_filter (stream_1, "filter_a");
2006   modulemd_module_stream_v1_add_rpm_filter (stream_1, "filter_b");
2007 
2008   stream_2 = modulemd_module_stream_v1_new (NULL, NULL);
2009   modulemd_module_stream_v1_add_rpm_api (stream_2, "rpm_1");
2010   modulemd_module_stream_v1_add_module_license (stream_2, "module_a");
2011   modulemd_module_stream_v1_add_module_license (stream_2, "module_b");
2012   modulemd_module_stream_v1_add_content_license (stream_2, "content_a");
2013   modulemd_module_stream_v1_add_content_license (stream_2, "content_b");
2014   modulemd_module_stream_v1_add_rpm_artifact (stream_2, "artifact_a");
2015   modulemd_module_stream_v1_add_rpm_artifact (stream_2, "artifact_b");
2016   modulemd_module_stream_v1_add_rpm_filter (stream_2, "filter_a");
2017   modulemd_module_stream_v1_add_rpm_filter (stream_2, "filter_b");
2018 
2019   g_assert_false (modulemd_module_stream_equals (
2020     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2021   g_clear_object (&stream_1);
2022   g_clear_object (&stream_2);
2023 
2024   /*Test equality of 2 streams with same dependencies*/
2025   stream_1 = modulemd_module_stream_v1_new (NULL, NULL);
2026   modulemd_module_stream_v1_add_buildtime_requirement (
2027     stream_1, "testmodule", "stable");
2028   modulemd_module_stream_v1_add_runtime_requirement (
2029     stream_1, "testmodule", "latest");
2030   stream_2 = modulemd_module_stream_v1_new (NULL, NULL);
2031   modulemd_module_stream_v1_add_buildtime_requirement (
2032     stream_2, "testmodule", "stable");
2033   modulemd_module_stream_v1_add_runtime_requirement (
2034     stream_2, "testmodule", "latest");
2035 
2036   g_assert_true (modulemd_module_stream_equals (
2037     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2038   g_clear_object (&stream_1);
2039   g_clear_object (&stream_2);
2040 
2041   /*Test equality of 2 streams with different dependencies*/
2042   stream_1 = modulemd_module_stream_v1_new (NULL, NULL);
2043   modulemd_module_stream_v1_add_buildtime_requirement (
2044     stream_1, "test", "stable");
2045   modulemd_module_stream_v1_add_runtime_requirement (
2046     stream_1, "testmodule", "latest");
2047   stream_2 = modulemd_module_stream_v1_new (NULL, NULL);
2048   modulemd_module_stream_v1_add_buildtime_requirement (
2049     stream_2, "testmodule", "stable");
2050   modulemd_module_stream_v1_add_runtime_requirement (
2051     stream_2, "testmodule", "not_latest");
2052 
2053   g_assert_false (modulemd_module_stream_equals (
2054     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2055   g_clear_object (&stream_1);
2056   g_clear_object (&stream_2);
2057 
2058   /*Test equality of 2 streams with same hashtables*/
2059   profile_1 = modulemd_profile_new ("testprofile");
2060   component_1 = modulemd_component_module_new ("testmodule");
2061   servicelevel_1 = modulemd_service_level_new ("foo");
2062 
2063   stream_1 = modulemd_module_stream_v1_new (NULL, NULL);
2064   modulemd_module_stream_v1_add_profile (stream_1, profile_1);
2065   modulemd_module_stream_v1_add_component (stream_1,
2066                                            (ModulemdComponent *)component_1);
2067   modulemd_module_stream_v1_add_servicelevel (stream_1, servicelevel_1);
2068   stream_2 = modulemd_module_stream_v1_new (NULL, NULL);
2069   modulemd_module_stream_v1_add_profile (stream_2, profile_1);
2070   modulemd_module_stream_v1_add_component (stream_2,
2071                                            (ModulemdComponent *)component_1);
2072   modulemd_module_stream_v1_add_servicelevel (stream_2, servicelevel_1);
2073 
2074   g_assert_true (modulemd_module_stream_equals (
2075     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2076   g_clear_object (&stream_1);
2077   g_clear_object (&stream_2);
2078   g_clear_object (&profile_1);
2079   g_clear_object (&component_1);
2080   g_clear_object (&servicelevel_1);
2081 
2082   /*Test equality of 2 streams with different hashtables*/
2083   profile_1 = modulemd_profile_new ("testprofile");
2084   component_1 = modulemd_component_module_new ("testmodule");
2085   component_2 = modulemd_component_rpm_new ("something");
2086   servicelevel_1 = modulemd_service_level_new ("foo");
2087   servicelevel_2 = modulemd_service_level_new ("bar");
2088 
2089   stream_1 = modulemd_module_stream_v1_new (NULL, NULL);
2090   modulemd_module_stream_v1_add_profile (stream_1, profile_1);
2091   modulemd_module_stream_v1_add_component (stream_1,
2092                                            (ModulemdComponent *)component_1);
2093   modulemd_module_stream_v1_add_servicelevel (stream_1, servicelevel_1);
2094   stream_2 = modulemd_module_stream_v1_new (NULL, NULL);
2095   modulemd_module_stream_v1_add_profile (stream_2, profile_1);
2096   modulemd_module_stream_v1_add_component (stream_2,
2097                                            (ModulemdComponent *)component_2);
2098   modulemd_module_stream_v1_add_servicelevel (stream_2, servicelevel_2);
2099 
2100   g_assert_false (modulemd_module_stream_equals (
2101     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2102   g_clear_object (&stream_1);
2103   g_clear_object (&stream_2);
2104   g_clear_object (&profile_1);
2105   g_clear_object (&component_1);
2106   g_clear_object (&component_2);
2107   g_clear_object (&servicelevel_1);
2108   g_clear_object (&servicelevel_2);
2109 }
2110 
2111 static void
module_stream_v2_test_equals(void)2112 module_stream_v2_test_equals (void)
2113 {
2114   g_autoptr (ModulemdModuleStreamV2) stream_1 = NULL;
2115   g_autoptr (ModulemdModuleStreamV2) stream_2 = NULL;
2116   g_autoptr (ModulemdProfile) profile_1 = NULL;
2117   g_autoptr (ModulemdServiceLevel) servicelevel_1 = NULL;
2118   g_autoptr (ModulemdServiceLevel) servicelevel_2 = NULL;
2119   g_autoptr (ModulemdComponentModule) component_1 = NULL;
2120   g_autoptr (ModulemdComponentRpm) component_2 = NULL;
2121   g_autoptr (ModulemdDependencies) dep_1 = NULL;
2122   g_autoptr (ModulemdDependencies) dep_2 = NULL;
2123   g_autoptr (ModulemdRpmMapEntry) entry_1 = NULL;
2124 
2125   /*Test equality of 2 streams with same string constants*/
2126   stream_1 = modulemd_module_stream_v2_new (NULL, NULL);
2127   modulemd_module_stream_v2_set_community (stream_1, "community_1");
2128   modulemd_module_stream_v2_set_description (stream_1, "description_1");
2129   modulemd_module_stream_v2_set_documentation (stream_1, "documentation_1");
2130   modulemd_module_stream_v2_set_summary (stream_1, "summary_1");
2131   modulemd_module_stream_v2_set_tracker (stream_1, "tracker_1");
2132 
2133   stream_2 = modulemd_module_stream_v2_new (NULL, NULL);
2134   modulemd_module_stream_v2_set_community (stream_2, "community_1");
2135   modulemd_module_stream_v2_set_description (stream_2, "description_1");
2136   modulemd_module_stream_v2_set_documentation (stream_2, "documentation_1");
2137   modulemd_module_stream_v2_set_summary (stream_2, "summary_1");
2138   modulemd_module_stream_v2_set_tracker (stream_2, "tracker_1");
2139 
2140   g_assert_true (modulemd_module_stream_equals (
2141     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2142   g_clear_object (&stream_1);
2143   g_clear_object (&stream_2);
2144 
2145   /*Test equality of 2 streams with certain different string constants*/
2146   stream_1 = modulemd_module_stream_v2_new (NULL, NULL);
2147   modulemd_module_stream_v2_set_community (stream_1, "community_1");
2148   modulemd_module_stream_v2_set_description (stream_1, "description_1");
2149   modulemd_module_stream_v2_set_documentation (stream_1, "documentation_1");
2150   modulemd_module_stream_v2_set_summary (stream_1, "summary_1");
2151   modulemd_module_stream_v2_set_tracker (stream_1, "tracker_1");
2152 
2153   stream_2 = modulemd_module_stream_v2_new (NULL, NULL);
2154   modulemd_module_stream_v2_set_community (stream_2, "community_1");
2155   modulemd_module_stream_v2_set_description (stream_2, "description_2");
2156   modulemd_module_stream_v2_set_documentation (stream_2, "documentation_1");
2157   modulemd_module_stream_v2_set_summary (stream_2, "summary_2");
2158   modulemd_module_stream_v2_set_tracker (stream_2, "tracker_2");
2159 
2160   g_assert_false (modulemd_module_stream_equals (
2161     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2162   g_clear_object (&stream_1);
2163   g_clear_object (&stream_2);
2164 
2165   /*Test equality of 2 streams with same hashtable sets*/
2166   stream_1 = modulemd_module_stream_v2_new (NULL, NULL);
2167   modulemd_module_stream_v2_add_rpm_api (stream_1, "rpm_1");
2168   modulemd_module_stream_v2_add_rpm_api (stream_1, "rpm_2");
2169   modulemd_module_stream_v2_add_module_license (stream_1, "module_a");
2170   modulemd_module_stream_v2_add_module_license (stream_1, "module_b");
2171   modulemd_module_stream_v2_add_content_license (stream_1, "content_a");
2172   modulemd_module_stream_v2_add_content_license (stream_1, "content_b");
2173   modulemd_module_stream_v2_add_rpm_artifact (stream_1, "artifact_a");
2174   modulemd_module_stream_v2_add_rpm_artifact (stream_1, "artifact_b");
2175   modulemd_module_stream_v2_add_rpm_filter (stream_1, "filter_a");
2176   modulemd_module_stream_v2_add_rpm_filter (stream_1, "filter_b");
2177   modulemd_module_stream_v2_add_demodularized_rpm (stream_1, "rpm_3");
2178   modulemd_module_stream_v2_add_demodularized_rpm (stream_1, "rpm_4");
2179 
2180   stream_2 = modulemd_module_stream_v2_new (NULL, NULL);
2181   modulemd_module_stream_v2_add_rpm_api (stream_2, "rpm_1");
2182   modulemd_module_stream_v2_add_rpm_api (stream_2, "rpm_2");
2183   modulemd_module_stream_v2_add_module_license (stream_2, "module_a");
2184   modulemd_module_stream_v2_add_module_license (stream_2, "module_b");
2185   modulemd_module_stream_v2_add_content_license (stream_2, "content_a");
2186   modulemd_module_stream_v2_add_content_license (stream_2, "content_b");
2187   modulemd_module_stream_v2_add_rpm_artifact (stream_2, "artifact_a");
2188   modulemd_module_stream_v2_add_rpm_artifact (stream_2, "artifact_b");
2189   modulemd_module_stream_v2_add_rpm_filter (stream_2, "filter_a");
2190   modulemd_module_stream_v2_add_rpm_filter (stream_2, "filter_b");
2191   modulemd_module_stream_v2_add_demodularized_rpm (stream_2, "rpm_3");
2192   modulemd_module_stream_v2_add_demodularized_rpm (stream_2, "rpm_4");
2193 
2194   g_assert_true (modulemd_module_stream_equals (
2195     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2196   g_clear_object (&stream_1);
2197   g_clear_object (&stream_2);
2198 
2199   /*Test equality of 2 streams with different hashtable sets*/
2200   stream_1 = modulemd_module_stream_v2_new (NULL, NULL);
2201   modulemd_module_stream_v2_add_rpm_api (stream_1, "rpm_1");
2202   modulemd_module_stream_v2_add_rpm_api (stream_1, "rpm_2");
2203   modulemd_module_stream_v2_add_module_license (stream_1, "module_a");
2204   modulemd_module_stream_v2_add_module_license (stream_1, "module_b");
2205   modulemd_module_stream_v2_add_content_license (stream_1, "content_a");
2206   modulemd_module_stream_v2_add_content_license (stream_1, "content_b");
2207   modulemd_module_stream_v2_add_rpm_artifact (stream_1, "artifact_a");
2208   modulemd_module_stream_v2_add_rpm_artifact (stream_1, "artifact_b");
2209   modulemd_module_stream_v2_add_rpm_artifact (stream_1, "artifact_c");
2210   modulemd_module_stream_v2_add_rpm_filter (stream_1, "filter_a");
2211   modulemd_module_stream_v2_add_rpm_filter (stream_1, "filter_b");
2212   modulemd_module_stream_v2_add_demodularized_rpm (stream_1, "rpm_3");
2213   modulemd_module_stream_v2_add_demodularized_rpm (stream_1, "rpm_4");
2214 
2215   stream_2 = modulemd_module_stream_v2_new (NULL, NULL);
2216   modulemd_module_stream_v2_add_rpm_api (stream_2, "rpm_1");
2217   modulemd_module_stream_v2_add_module_license (stream_2, "module_a");
2218   modulemd_module_stream_v2_add_module_license (stream_2, "module_b");
2219   modulemd_module_stream_v2_add_content_license (stream_2, "content_a");
2220   modulemd_module_stream_v2_add_content_license (stream_2, "content_b");
2221   modulemd_module_stream_v2_add_rpm_artifact (stream_2, "artifact_a");
2222   modulemd_module_stream_v2_add_rpm_artifact (stream_2, "artifact_b");
2223   modulemd_module_stream_v2_add_rpm_filter (stream_2, "filter_a");
2224   modulemd_module_stream_v2_add_rpm_filter (stream_2, "filter_b");
2225   modulemd_module_stream_v2_add_demodularized_rpm (stream_2, "rpm_3");
2226   modulemd_module_stream_v2_add_demodularized_rpm (stream_2, "rpm_4");
2227 
2228   g_assert_false (modulemd_module_stream_equals (
2229     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2230   g_clear_object (&stream_1);
2231   g_clear_object (&stream_2);
2232 
2233   /*Test equality of 2 streams with same hashtables*/
2234   profile_1 = modulemd_profile_new ("testprofile");
2235   component_1 = modulemd_component_module_new ("testmodule");
2236   servicelevel_1 = modulemd_service_level_new ("foo");
2237 
2238   stream_1 = modulemd_module_stream_v2_new (NULL, NULL);
2239   modulemd_module_stream_v2_add_profile (stream_1, profile_1);
2240   modulemd_module_stream_v2_add_component (stream_1,
2241                                            (ModulemdComponent *)component_1);
2242   modulemd_module_stream_v2_add_servicelevel (stream_1, servicelevel_1);
2243   stream_2 = modulemd_module_stream_v2_new (NULL, NULL);
2244   modulemd_module_stream_v2_add_profile (stream_2, profile_1);
2245   modulemd_module_stream_v2_add_component (stream_2,
2246                                            (ModulemdComponent *)component_1);
2247   modulemd_module_stream_v2_add_servicelevel (stream_2, servicelevel_1);
2248 
2249   g_assert_true (modulemd_module_stream_equals (
2250     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2251   g_clear_object (&stream_1);
2252   g_clear_object (&stream_2);
2253   g_clear_object (&profile_1);
2254   g_clear_object (&component_1);
2255   g_clear_object (&servicelevel_1);
2256 
2257   /*Test equality of 2 streams with different hashtables*/
2258   profile_1 = modulemd_profile_new ("testprofile");
2259   component_1 = modulemd_component_module_new ("testmodule");
2260   component_2 = modulemd_component_rpm_new ("something");
2261   servicelevel_1 = modulemd_service_level_new ("foo");
2262   servicelevel_2 = modulemd_service_level_new ("bar");
2263 
2264   stream_1 = modulemd_module_stream_v2_new (NULL, NULL);
2265   modulemd_module_stream_v2_add_profile (stream_1, profile_1);
2266   modulemd_module_stream_v2_add_component (stream_1,
2267                                            (ModulemdComponent *)component_1);
2268   modulemd_module_stream_v2_add_servicelevel (stream_1, servicelevel_1);
2269   stream_2 = modulemd_module_stream_v2_new (NULL, NULL);
2270   modulemd_module_stream_v2_add_profile (stream_2, profile_1);
2271   modulemd_module_stream_v2_add_component (stream_2,
2272                                            (ModulemdComponent *)component_2);
2273   modulemd_module_stream_v2_add_servicelevel (stream_2, servicelevel_2);
2274 
2275   g_assert_false (modulemd_module_stream_equals (
2276     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2277   g_clear_object (&stream_1);
2278   g_clear_object (&stream_2);
2279   g_clear_object (&profile_1);
2280   g_clear_object (&component_1);
2281   g_clear_object (&component_2);
2282   g_clear_object (&servicelevel_1);
2283   g_clear_object (&servicelevel_2);
2284 
2285   /*Test equality of 2 streams with same dependencies*/
2286   dep_1 = modulemd_dependencies_new ();
2287   modulemd_dependencies_add_buildtime_stream (dep_1, "foo", "stable");
2288 
2289   stream_1 = modulemd_module_stream_v2_new (NULL, NULL);
2290   modulemd_module_stream_v2_add_dependencies (stream_1, dep_1);
2291   stream_2 = modulemd_module_stream_v2_new (NULL, NULL);
2292   modulemd_module_stream_v2_add_dependencies (stream_2, dep_1);
2293 
2294   g_assert_true (modulemd_module_stream_equals (
2295     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2296   g_clear_object (&stream_1);
2297   g_clear_object (&stream_2);
2298   g_clear_object (&dep_1);
2299 
2300   /*Test equality of 2 streams with different dependencies*/
2301   dep_1 = modulemd_dependencies_new ();
2302   modulemd_dependencies_add_buildtime_stream (dep_1, "foo", "stable");
2303   dep_2 = modulemd_dependencies_new ();
2304   modulemd_dependencies_add_buildtime_stream (dep_2, "foo", "latest");
2305 
2306   stream_1 = modulemd_module_stream_v2_new (NULL, NULL);
2307   modulemd_module_stream_v2_add_dependencies (stream_1, dep_1);
2308   stream_2 = modulemd_module_stream_v2_new (NULL, NULL);
2309   modulemd_module_stream_v2_add_dependencies (stream_2, dep_2);
2310 
2311   g_assert_false (modulemd_module_stream_equals (
2312     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2313   g_clear_object (&stream_1);
2314   g_clear_object (&stream_2);
2315   g_clear_object (&dep_1);
2316   g_clear_object (&dep_2);
2317 
2318   /*Test equality of 2 streams with same rpm artifact map entry*/
2319   entry_1 = modulemd_rpm_map_entry_new (
2320     "bar", 0, "1.23", "1.module_deadbeef", "x86_64");
2321 
2322   stream_1 = modulemd_module_stream_v2_new (NULL, NULL);
2323   modulemd_module_stream_v2_set_rpm_artifact_map_entry (
2324     stream_1, entry_1, "sha256", "baddad");
2325   stream_2 = modulemd_module_stream_v2_new (NULL, NULL);
2326   modulemd_module_stream_v2_set_rpm_artifact_map_entry (
2327     stream_2, entry_1, "sha256", "baddad");
2328 
2329   g_assert_true (modulemd_module_stream_equals (
2330     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2331   g_clear_object (&stream_1);
2332   g_clear_object (&stream_2);
2333   g_clear_object (&entry_1);
2334 
2335   /*Test equality of 2 streams with different rpm artifact map entry*/
2336   entry_1 = modulemd_rpm_map_entry_new (
2337     "bar", 0, "1.23", "1.module_deadbeef", "x86_64");
2338 
2339   stream_1 = modulemd_module_stream_v2_new (NULL, NULL);
2340   modulemd_module_stream_v2_set_rpm_artifact_map_entry (
2341     stream_1, entry_1, "sha256", "baddad");
2342   stream_2 = modulemd_module_stream_v2_new (NULL, NULL);
2343   modulemd_module_stream_v2_set_rpm_artifact_map_entry (
2344     stream_2, entry_1, "sha256", "badmom");
2345 
2346   g_assert_false (modulemd_module_stream_equals (
2347     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2348   g_clear_object (&stream_1);
2349   g_clear_object (&stream_2);
2350   g_clear_object (&entry_1);
2351 
2352   /* Test equality of 2 streams with same NSVC and static_context attributes */
2353   stream_1 = modulemd_module_stream_v2_new ("name_1", "stream_1");
2354   modulemd_module_stream_set_version (MODULEMD_MODULE_STREAM (stream_1), 11);
2355   modulemd_module_stream_set_context (MODULEMD_MODULE_STREAM (stream_1),
2356                                       "context_1");
2357   modulemd_module_stream_v2_set_static_context (stream_1);
2358 
2359   stream_2 = modulemd_module_stream_v2_new ("name_1", "stream_1");
2360   modulemd_module_stream_set_version (MODULEMD_MODULE_STREAM (stream_2), 11);
2361   modulemd_module_stream_set_context (MODULEMD_MODULE_STREAM (stream_2),
2362                                       "context_1");
2363   modulemd_module_stream_v2_set_static_context (stream_2);
2364 
2365   g_assert_true (modulemd_module_stream_equals (
2366     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2367   g_clear_object (&stream_1);
2368   g_clear_object (&stream_2);
2369 
2370   /* Test equality of 2 streams with same NSVC but different static_context attributes */
2371   stream_1 = modulemd_module_stream_v2_new ("name_1", "stream_1");
2372   modulemd_module_stream_set_version (MODULEMD_MODULE_STREAM (stream_1), 11);
2373   modulemd_module_stream_set_context (MODULEMD_MODULE_STREAM (stream_1),
2374                                       "context_1");
2375   modulemd_module_stream_v2_set_static_context (stream_1);
2376 
2377   stream_2 = modulemd_module_stream_v2_new ("name_1", "stream_1");
2378   modulemd_module_stream_set_version (MODULEMD_MODULE_STREAM (stream_2), 11);
2379   modulemd_module_stream_set_context (MODULEMD_MODULE_STREAM (stream_2),
2380                                       "context_1");
2381   modulemd_module_stream_v2_unset_static_context (stream_2);
2382 
2383   g_assert_false (modulemd_module_stream_equals (
2384     (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2));
2385   g_clear_object (&stream_1);
2386   g_clear_object (&stream_2);
2387 }
2388 
2389 
2390 static void
module_stream_v1_test_dependencies(void)2391 module_stream_v1_test_dependencies (void)
2392 {
2393   g_auto (GStrv) list = NULL;
2394   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
2395   stream = modulemd_module_stream_v1_new (NULL, NULL);
2396   modulemd_module_stream_v1_add_buildtime_requirement (
2397     stream, "testmodule", "stable");
2398   list = modulemd_module_stream_v1_get_buildtime_modules_as_strv (stream);
2399   g_assert_cmpint (g_strv_length (list), ==, 1);
2400   g_assert_cmpstr (list[0], ==, "testmodule");
2401   g_assert_cmpstr (modulemd_module_stream_v1_get_buildtime_requirement_stream (
2402                      stream, "testmodule"),
2403                    ==,
2404                    "stable");
2405   g_clear_pointer (&list, g_strfreev);
2406 
2407   modulemd_module_stream_v1_add_runtime_requirement (
2408     stream, "testmodule", "latest");
2409   list = modulemd_module_stream_v1_get_runtime_modules_as_strv (stream);
2410   g_assert_cmpint (g_strv_length (list), ==, 1);
2411   g_assert_cmpstr (list[0], ==, "testmodule");
2412   g_assert_cmpstr (modulemd_module_stream_v1_get_runtime_requirement_stream (
2413                      stream, "testmodule"),
2414                    ==,
2415                    "latest");
2416   g_clear_pointer (&list, g_strfreev);
2417   g_clear_object (&stream);
2418 }
2419 
2420 static void
module_stream_v2_test_dependencies(void)2421 module_stream_v2_test_dependencies (void)
2422 {
2423   g_auto (GStrv) list = NULL;
2424   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
2425   g_autoptr (ModulemdDependencies) dep = NULL;
2426   stream = modulemd_module_stream_v2_new (NULL, NULL);
2427   dep = modulemd_dependencies_new ();
2428   modulemd_dependencies_add_buildtime_stream (dep, "foo", "stable");
2429   modulemd_dependencies_set_empty_runtime_dependencies_for_module (dep, "bar");
2430   modulemd_module_stream_v2_add_dependencies (stream, dep);
2431   GPtrArray *deps_list = modulemd_module_stream_v2_get_dependencies (stream);
2432   g_assert_cmpint (deps_list->len, ==, 1);
2433 
2434   list = modulemd_dependencies_get_buildtime_modules_as_strv (
2435     g_ptr_array_index (deps_list, 0));
2436   g_assert_cmpstr (list[0], ==, "foo");
2437   g_clear_pointer (&list, g_strfreev);
2438 
2439   list = modulemd_dependencies_get_buildtime_streams_as_strv (
2440     g_ptr_array_index (deps_list, 0), "foo");
2441   g_assert_nonnull (list);
2442   g_assert_cmpstr (list[0], ==, "stable");
2443   g_assert_null (list[1]);
2444   g_clear_pointer (&list, g_strfreev);
2445 
2446   list = modulemd_dependencies_get_runtime_modules_as_strv (
2447     g_ptr_array_index (deps_list, 0));
2448   g_assert_nonnull (list);
2449   g_assert_cmpstr (list[0], ==, "bar");
2450   g_assert_null (list[1]);
2451 
2452   g_clear_pointer (&list, g_strfreev);
2453   g_clear_object (&dep);
2454   g_clear_object (&stream);
2455 }
2456 
2457 
2458 static void
module_stream_v1_test_parse_dump(void)2459 module_stream_v1_test_parse_dump (void)
2460 {
2461   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
2462   g_autoptr (GError) error = NULL;
2463   gboolean ret;
2464   MMD_INIT_YAML_PARSER (parser);
2465   MMD_INIT_YAML_EVENT (event);
2466   MMD_INIT_YAML_EMITTER (emitter);
2467   MMD_INIT_YAML_STRING (&emitter, yaml_string);
2468   g_autofree gchar *yaml_path = NULL;
2469   g_autoptr (FILE) yaml_stream = NULL;
2470   g_autoptr (ModulemdSubdocumentInfo) subdoc = NULL;
2471   yaml_path = g_strdup_printf ("%s/yaml_specs/modulemd_stream_v1.yaml",
2472                                g_getenv ("MESON_SOURCE_ROOT"));
2473   g_assert_nonnull (yaml_path);
2474 
2475   yaml_stream = g_fopen (yaml_path, "rbe");
2476   g_assert_nonnull (yaml_stream);
2477 
2478   /* First parse it */
2479   yaml_parser_set_input_file (&parser, yaml_stream);
2480   g_assert_true (yaml_parser_parse (&parser, &event));
2481   g_assert_cmpint (event.type, ==, YAML_STREAM_START_EVENT);
2482   yaml_event_delete (&event);
2483   g_assert_true (yaml_parser_parse (&parser, &event));
2484   g_assert_cmpint (event.type, ==, YAML_DOCUMENT_START_EVENT);
2485   yaml_event_delete (&event);
2486 
2487   subdoc = modulemd_yaml_parse_document_type (&parser);
2488   g_assert_nonnull (subdoc);
2489   g_assert_null (modulemd_subdocument_info_get_gerror (subdoc));
2490 
2491   g_assert_cmpint (modulemd_subdocument_info_get_doctype (subdoc),
2492                    ==,
2493                    MODULEMD_YAML_DOC_MODULESTREAM);
2494   g_assert_cmpint (modulemd_subdocument_info_get_mdversion (subdoc), ==, 1);
2495   g_assert_nonnull (modulemd_subdocument_info_get_yaml (subdoc));
2496 
2497   stream = modulemd_module_stream_v1_parse_yaml (subdoc, TRUE, &error);
2498   g_assert_no_error (error);
2499   g_assert_nonnull (stream);
2500 
2501   /* Then dump it */
2502   g_debug ("Starting dumping");
2503   g_assert_true (mmd_emitter_start_stream (&emitter, &error));
2504   ret = modulemd_module_stream_v1_emit_yaml (stream, &emitter, &error);
2505   g_assert_no_error (error);
2506   g_assert_true (ret);
2507   ret = mmd_emitter_end_stream (&emitter, &error);
2508   g_assert_no_error (error);
2509   g_assert_true (ret);
2510   g_assert_nonnull (yaml_string->str);
2511 
2512   g_assert_cmpstr (
2513     yaml_string->str,
2514     ==,
2515     "---\n"
2516     "document: modulemd\n"
2517     "version: 1\n"
2518     "data:\n"
2519     "  name: foo\n"
2520     "  stream: \"stream-name\"\n"
2521     "  version: 20160927144203\n"
2522     "  context: c0ffee43\n"
2523     "  arch: x86_64\n"
2524     "  summary: An example module\n"
2525     "  description: >-\n"
2526     "    A module for the demonstration of the metadata format. Also, the "
2527     "obligatory lorem\n"
2528     "    ipsum dolor sit amet goes right here.\n"
2529     "  servicelevels:\n"
2530     "    bug_fixes:\n"
2531     "      eol: 2077-10-23\n"
2532     "    rawhide:\n"
2533     "      eol: 2077-10-23\n"
2534     "    security_fixes:\n"
2535     "      eol: 2077-10-23\n"
2536     "    stable_api:\n"
2537     "      eol: 2077-10-23\n"
2538     "  license:\n"
2539     "    module:\n"
2540     "    - MIT\n"
2541     "    content:\n"
2542     "    - Beerware\n"
2543     "    - GPLv2+\n"
2544     "    - zlib\n"
2545     "  xmd:\n"
2546     "    some_key: some_data\n"
2547     "  dependencies:\n"
2548     "    buildrequires:\n"
2549     "      extra-build-env: and-its-stream-name-too\n"
2550     "      platform: and-its-stream-name\n"
2551     "    requires:\n"
2552     "      platform: and-its-stream-name\n"
2553     "  references:\n"
2554     "    community: http://www.example.com/\n"
2555     "    documentation: http://www.example.com/\n"
2556     "    tracker: http://www.example.com/\n"
2557     "  profiles:\n"
2558     "    buildroot:\n"
2559     "      rpms:\n"
2560     "      - bar-devel\n"
2561     "    container:\n"
2562     "      rpms:\n"
2563     "      - bar\n"
2564     "      - bar-devel\n"
2565     "    default:\n"
2566     "      rpms:\n"
2567     "      - bar\n"
2568     "      - bar-extras\n"
2569     "      - baz\n"
2570     "    minimal:\n"
2571     "      description: Minimal profile installing only the bar package.\n"
2572     "      rpms:\n"
2573     "      - bar\n"
2574     "    srpm-buildroot:\n"
2575     "      rpms:\n"
2576     "      - bar-extras\n"
2577     "  api:\n"
2578     "    rpms:\n"
2579     "    - bar\n"
2580     "    - bar-devel\n"
2581     "    - bar-extras\n"
2582     "    - baz\n"
2583     "    - xxx\n"
2584     "  filter:\n"
2585     "    rpms:\n"
2586     "    - baz-nonfoo\n"
2587     "  buildopts:\n"
2588     "    rpms:\n"
2589     "      macros: >\n"
2590     "        %demomacro 1\n"
2591     "\n"
2592     "        %demomacro2 %{demomacro}23\n"
2593     "  components:\n"
2594     "    rpms:\n"
2595     "      bar:\n"
2596     "        rationale: We need this to demonstrate stuff.\n"
2597     "        repository: https://pagure.io/bar.git\n"
2598     "        cache: https://example.com/cache\n"
2599     "        ref: 26ca0c0\n"
2600     "      baz:\n"
2601     "        rationale: This one is here to demonstrate other stuff.\n"
2602     "      xxx:\n"
2603     "        rationale: xxx demonstrates arches and multilib.\n"
2604     "        arches: [i686, x86_64]\n"
2605     "        multilib: [x86_64]\n"
2606     "      xyz:\n"
2607     "        rationale: xyz is a bundled dependency of xxx.\n"
2608     "        buildorder: 10\n"
2609     "    modules:\n"
2610     "      includedmodule:\n"
2611     "        rationale: Included in the stack, just because.\n"
2612     "        repository: https://pagure.io/includedmodule.git\n"
2613     "        ref: somecoolbranchname\n"
2614     "        buildorder: 100\n"
2615     "  artifacts:\n"
2616     "    rpms:\n"
2617     "    - bar-0:1.23-1.module_deadbeef.x86_64\n"
2618     "    - bar-devel-0:1.23-1.module_deadbeef.x86_64\n"
2619     "    - bar-extras-0:1.23-1.module_deadbeef.x86_64\n"
2620     "    - baz-0:42-42.module_deadbeef.x86_64\n"
2621     "    - xxx-0:1-1.module_deadbeef.i686\n"
2622     "    - xxx-0:1-1.module_deadbeef.x86_64\n"
2623     "    - xyz-0:1-1.module_deadbeef.x86_64\n"
2624     "...\n");
2625 }
2626 
2627 static void
module_stream_v2_test_parse_dump(void)2628 module_stream_v2_test_parse_dump (void)
2629 {
2630   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
2631   g_autoptr (GError) error = NULL;
2632   gboolean ret;
2633   MMD_INIT_YAML_PARSER (parser);
2634   MMD_INIT_YAML_EVENT (event);
2635   MMD_INIT_YAML_EMITTER (emitter);
2636   MMD_INIT_YAML_STRING (&emitter, yaml_string);
2637   g_autofree gchar *yaml_path = NULL;
2638   g_autoptr (FILE) yaml_stream = NULL;
2639   g_autoptr (ModulemdSubdocumentInfo) subdoc = NULL;
2640   yaml_path = g_strdup_printf ("%s/yaml_specs/modulemd_stream_v2.yaml",
2641                                g_getenv ("MESON_SOURCE_ROOT"));
2642   g_assert_nonnull (yaml_path);
2643 
2644   yaml_stream = g_fopen (yaml_path, "rbe");
2645   g_assert_nonnull (yaml_stream);
2646 
2647   /* First parse it */
2648   yaml_parser_set_input_file (&parser, yaml_stream);
2649   g_assert_true (yaml_parser_parse (&parser, &event));
2650   g_assert_cmpint (event.type, ==, YAML_STREAM_START_EVENT);
2651   yaml_event_delete (&event);
2652   g_assert_true (yaml_parser_parse (&parser, &event));
2653   g_assert_cmpint (event.type, ==, YAML_DOCUMENT_START_EVENT);
2654   yaml_event_delete (&event);
2655 
2656   subdoc = modulemd_yaml_parse_document_type (&parser);
2657   g_assert_nonnull (subdoc);
2658   g_assert_null (modulemd_subdocument_info_get_gerror (subdoc));
2659 
2660   g_assert_cmpint (modulemd_subdocument_info_get_doctype (subdoc),
2661                    ==,
2662                    MODULEMD_YAML_DOC_MODULESTREAM);
2663   g_assert_cmpint (modulemd_subdocument_info_get_mdversion (subdoc), ==, 2);
2664   g_assert_nonnull (modulemd_subdocument_info_get_yaml (subdoc));
2665 
2666   stream = modulemd_module_stream_v2_parse_yaml (subdoc, TRUE, FALSE, &error);
2667   g_assert_no_error (error);
2668   g_assert_nonnull (stream);
2669 
2670   /* Then dump it */
2671   g_debug ("Starting dumping");
2672   g_assert_true (mmd_emitter_start_stream (&emitter, &error));
2673   ret = modulemd_module_stream_v2_emit_yaml (stream, &emitter, &error);
2674   g_assert_no_error (error);
2675   g_assert_true (ret);
2676   ret = mmd_emitter_end_stream (&emitter, &error);
2677   g_assert_no_error (error);
2678   g_assert_true (ret);
2679   g_assert_nonnull (yaml_string->str);
2680 
2681   g_assert_cmpstr (
2682     yaml_string->str,
2683     ==,
2684     "---\n"
2685     "document: modulemd\n"
2686     "version: 2\n"
2687     "data:\n"
2688     "  name: foo\n"
2689     "  stream: \"latest\"\n"
2690     "  version: 20160927144203\n"
2691     "  context: c0ffee43\n"
2692     "  arch: x86_64\n"
2693     "  summary: An example module\n"
2694     "  description: >-\n"
2695     "    A module for the demonstration of the metadata format. Also, the "
2696     "obligatory lorem\n"
2697     "    ipsum dolor sit amet goes right here.\n"
2698     "  servicelevels:\n"
2699     "    bug_fixes:\n"
2700     "      eol: 2077-10-23\n"
2701     "    rawhide:\n"
2702     "      eol: 2077-10-23\n"
2703     "    security_fixes:\n"
2704     "      eol: 2077-10-23\n"
2705     "    stable_api:\n"
2706     "      eol: 2077-10-23\n"
2707     "  license:\n"
2708     "    module:\n"
2709     "    - MIT\n"
2710     "    content:\n"
2711     "    - Beerware\n"
2712     "    - GPLv2+\n"
2713     "    - zlib\n"
2714     "  xmd:\n"
2715     "    some_key: some_data\n"
2716     "  dependencies:\n"
2717     "  - buildrequires:\n"
2718     "      platform: [-epel7, -f27, -f28]\n"
2719     "    requires:\n"
2720     "      platform: [-epel7, -f27, -f28]\n"
2721     "  - buildrequires:\n"
2722     "      buildtools: [v1, v2]\n"
2723     "      compatible: [v3]\n"
2724     "      platform: [f27]\n"
2725     "    requires:\n"
2726     "      compatible: [v3, v4]\n"
2727     "      platform: [f27]\n"
2728     "  - buildrequires:\n"
2729     "      platform: [f28]\n"
2730     "    requires:\n"
2731     "      platform: [f28]\n"
2732     "      runtime: [a, b]\n"
2733     "  - buildrequires:\n"
2734     "      extras: []\n"
2735     "      moreextras: [bar, foo]\n"
2736     "      platform: [epel7]\n"
2737     "    requires:\n"
2738     "      extras: []\n"
2739     "      moreextras: [bar, foo]\n"
2740     "      platform: [epel7]\n"
2741     "  references:\n"
2742     "    community: http://www.example.com/\n"
2743     "    documentation: http://www.example.com/\n"
2744     "    tracker: http://www.example.com/\n"
2745     "  profiles:\n"
2746     "    buildroot:\n"
2747     "      rpms:\n"
2748     "      - bar-devel\n"
2749     "    container:\n"
2750     "      rpms:\n"
2751     "      - bar\n"
2752     "      - bar-devel\n"
2753     "    minimal:\n"
2754     "      description: Minimal profile installing only the bar package.\n"
2755     "      rpms:\n"
2756     "      - bar\n"
2757     "    srpm-buildroot:\n"
2758     "      rpms:\n"
2759     "      - bar-extras\n"
2760     "  api:\n"
2761     "    rpms:\n"
2762     "    - bar\n"
2763     "    - bar-devel\n"
2764     "    - bar-extras\n"
2765     "    - baz\n"
2766     "    - xxx\n"
2767     "  filter:\n"
2768     "    rpms:\n"
2769     "    - baz-nonfoo\n"
2770     "  demodularized:\n"
2771     "    rpms:\n"
2772     "    - bar-old\n"
2773     "  buildopts:\n"
2774     "    rpms:\n"
2775     "      macros: >\n"
2776     "        %demomacro 1\n"
2777     "\n"
2778     "        %demomacro2 %{demomacro}23\n"
2779     "      whitelist:\n"
2780     "      - fooscl-1-bar\n"
2781     "      - fooscl-1-baz\n"
2782     "      - xxx\n"
2783     "      - xyz\n"
2784     "    arches: [i686, x86_64]\n"
2785     "  components:\n"
2786     "    rpms:\n"
2787     "      bar:\n"
2788     "        rationale: We need this to demonstrate stuff.\n"
2789     "        name: bar-real\n"
2790     "        repository: https://pagure.io/bar.git\n"
2791     "        cache: https://example.com/cache\n"
2792     "        ref: 26ca0c0\n"
2793     "      baz:\n"
2794     "        rationale: Demonstrate updating the buildroot contents.\n"
2795     "        buildroot: true\n"
2796     "        srpm-buildroot: true\n"
2797     "        buildorder: -1\n"
2798     "      xxx:\n"
2799     "        rationale: xxx demonstrates arches and multilib.\n"
2800     "        arches: [i686, x86_64]\n"
2801     "        multilib: [x86_64]\n"
2802     "      xyz:\n"
2803     "        rationale: xyz is a bundled dependency of xxx.\n"
2804     "        buildorder: 10\n"
2805     "    modules:\n"
2806     "      includedmodule:\n"
2807     "        rationale: Included in the stack, just because.\n"
2808     "        repository: https://pagure.io/includedmodule.git\n"
2809     "        ref: somecoolbranchname\n"
2810     "        buildorder: 100\n"
2811     "  artifacts:\n"
2812     "    rpms:\n"
2813     "    - bar-0:1.23-1.module_deadbeef.x86_64\n"
2814     "    - bar-devel-0:1.23-1.module_deadbeef.x86_64\n"
2815     "    - bar-extras-0:1.23-1.module_deadbeef.x86_64\n"
2816     "    - baz-0:42-42.module_deadbeef.x86_64\n"
2817     "    - xxx-0:1-1.module_deadbeef.i686\n"
2818     "    - xxx-0:1-1.module_deadbeef.x86_64\n"
2819     "    - xyz-0:1-1.module_deadbeef.x86_64\n"
2820     "    rpm-map:\n"
2821     "      sha256:\n"
2822     "        "
2823     "ee47083ed80146eb2c84e9a94d0836393912185dcda62b9d93ee0c2ea5dc795b:\n"
2824     "          name: bar\n"
2825     "          epoch: 0\n"
2826     "          version: 1.23\n"
2827     "          release: 1.module_deadbeef\n"
2828     "          arch: x86_64\n"
2829     "          nevra: bar-0:1.23-1.module_deadbeef.x86_64\n"
2830     "...\n");
2831 }
2832 
2833 
2834 static void
module_stream_v1_test_depends_on_stream(void)2835 module_stream_v1_test_depends_on_stream (void)
2836 {
2837   g_autoptr (ModulemdModuleStream) stream = NULL;
2838   g_autofree gchar *path = NULL;
2839   g_autoptr (GError) error = NULL;
2840   g_autofree gchar *module_name = NULL;
2841   g_autofree gchar *module_stream = NULL;
2842 
2843   path = g_strdup_printf ("%s/dependson_v1.yaml", g_getenv ("TEST_DATA_PATH"));
2844   g_assert_nonnull (path);
2845   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2846   stream = modulemd_module_stream_read_file (
2847     path, TRUE, module_name, module_stream, &error);
2848   G_GNUC_END_IGNORE_DEPRECATIONS
2849   g_assert_nonnull (stream);
2850 
2851   g_assert_true (
2852     modulemd_module_stream_depends_on_stream (stream, "platform", "f30"));
2853   g_assert_true (modulemd_module_stream_build_depends_on_stream (
2854     stream, "platform", "f30"));
2855 
2856   g_assert_false (
2857     modulemd_module_stream_depends_on_stream (stream, "platform", "f28"));
2858   g_assert_false (modulemd_module_stream_build_depends_on_stream (
2859     stream, "platform", "f28"));
2860 
2861   g_assert_false (
2862     modulemd_module_stream_depends_on_stream (stream, "base", "f30"));
2863   g_assert_false (
2864     modulemd_module_stream_build_depends_on_stream (stream, "base", "f30"));
2865   g_clear_object (&stream);
2866 }
2867 
2868 static void
module_stream_v2_test_depends_on_stream(void)2869 module_stream_v2_test_depends_on_stream (void)
2870 {
2871   g_autoptr (ModulemdModuleStream) stream = NULL;
2872   g_autofree gchar *path = NULL;
2873   g_autoptr (GError) error = NULL;
2874   g_autofree gchar *module_name = NULL;
2875   g_autofree gchar *module_stream = NULL;
2876 
2877   path = g_strdup_printf ("%s/dependson_v2.yaml", g_getenv ("TEST_DATA_PATH"));
2878   g_assert_nonnull (path);
2879   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2880   stream = modulemd_module_stream_read_file (
2881     path, TRUE, module_name, module_stream, &error);
2882   G_GNUC_END_IGNORE_DEPRECATIONS
2883   g_assert_nonnull (stream);
2884 
2885   g_assert_true (
2886     modulemd_module_stream_depends_on_stream (stream, "platform", "f30"));
2887   g_assert_true (modulemd_module_stream_build_depends_on_stream (
2888     stream, "platform", "f30"));
2889 
2890   g_assert_false (
2891     modulemd_module_stream_depends_on_stream (stream, "platform", "f28"));
2892   g_assert_false (modulemd_module_stream_build_depends_on_stream (
2893     stream, "platform", "f28"));
2894 
2895   g_assert_false (
2896     modulemd_module_stream_depends_on_stream (stream, "base", "f30"));
2897   g_assert_false (
2898     modulemd_module_stream_build_depends_on_stream (stream, "base", "f30"));
2899   g_clear_object (&stream);
2900 }
2901 
2902 
2903 static void
module_stream_test_validate_buildafter(void)2904 module_stream_test_validate_buildafter (void)
2905 {
2906   g_autoptr (ModulemdModuleStream) stream = NULL;
2907   g_autofree gchar *path = NULL;
2908   g_autoptr (GError) error = NULL;
2909   guint64 version;
2910 
2911   /* buildafter is supported starting with v2 */
2912   for (version = MD_MODULESTREAM_VERSION_TWO;
2913        version <= MD_MODULESTREAM_VERSION_LATEST;
2914        version++)
2915     {
2916       /* Test a valid module stream with buildafter set */
2917       path =
2918         g_strdup_printf ("%s/buildafter/good_buildafter_v%" PRIu64 ".yaml",
2919                          g_getenv ("TEST_DATA_PATH"),
2920                          version);
2921       g_assert_nonnull (path);
2922       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2923       stream =
2924         modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
2925       G_GNUC_END_IGNORE_DEPRECATIONS
2926       g_assert_nonnull (stream);
2927       g_assert_null (error);
2928       g_clear_pointer (&path, g_free);
2929       g_clear_object (&stream);
2930 
2931       /* Should fail validation if both buildorder and buildafter are set for the
2932        * same component.
2933        */
2934       path =
2935         g_strdup_printf ("%s/buildafter/both_same_component_v%" PRIu64 ".yaml",
2936                          g_getenv ("TEST_DATA_PATH"),
2937                          version);
2938       g_assert_nonnull (path);
2939       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2940       stream =
2941         modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
2942       G_GNUC_END_IGNORE_DEPRECATIONS
2943       g_assert_error (error, MODULEMD_ERROR, MMD_ERROR_VALIDATE);
2944       g_assert_null (stream);
2945       g_clear_error (&error);
2946       g_clear_pointer (&path, g_free);
2947 
2948       /* Should fail validation if both buildorder and buildafter are set in
2949        * different components of the same stream.
2950        */
2951       path =
2952         g_strdup_printf ("%s/buildafter/mixed_buildorder_v%" PRIu64 ".yaml",
2953                          g_getenv ("TEST_DATA_PATH"),
2954                          version);
2955       g_assert_nonnull (path);
2956       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2957       stream =
2958         modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
2959       G_GNUC_END_IGNORE_DEPRECATIONS
2960       g_assert_error (error, MODULEMD_ERROR, MMD_ERROR_VALIDATE);
2961       g_assert_null (stream);
2962       g_clear_error (&error);
2963       g_clear_pointer (&path, g_free);
2964 
2965       /* Should fail if a key specified in a buildafter set does not exist for this
2966        * module stream.
2967        */
2968       path = g_strdup_printf ("%s/buildafter/invalid_key_v%" PRIu64 ".yaml",
2969                               g_getenv ("TEST_DATA_PATH"),
2970                               version);
2971       g_assert_nonnull (path);
2972       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2973       stream =
2974         modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
2975       G_GNUC_END_IGNORE_DEPRECATIONS
2976       g_assert_error (error, MODULEMD_ERROR, MMD_ERROR_VALIDATE);
2977       g_assert_null (stream);
2978       g_clear_error (&error);
2979       g_clear_pointer (&path, g_free);
2980     }
2981 }
2982 
2983 
2984 static void
module_stream_test_validate_buildarches(void)2985 module_stream_test_validate_buildarches (void)
2986 {
2987   g_autoptr (ModulemdModuleStream) stream = NULL;
2988   g_autofree gchar *path = NULL;
2989   g_autoptr (GError) error = NULL;
2990   guint64 version;
2991 
2992   /* skipping v1 because spec does not require build arch validation */
2993   for (version = MD_MODULESTREAM_VERSION_TWO;
2994        version <= MD_MODULESTREAM_VERSION_LATEST;
2995        version++)
2996     {
2997       /* Test a valid module stream with no buildopts or component
2998        * rpm arches set.
2999        */
3000       path =
3001         g_strdup_printf ("%s/buildarches/good_no_arches_v%" PRIu64 ".yaml",
3002                          g_getenv ("TEST_DATA_PATH"),
3003                          version);
3004       g_assert_nonnull (path);
3005       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3006       stream =
3007         modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
3008       G_GNUC_END_IGNORE_DEPRECATIONS
3009       g_assert_nonnull (stream);
3010       g_assert_null (error);
3011       g_clear_pointer (&path, g_free);
3012       g_clear_object (&stream);
3013 
3014       /* Test a valid module stream with buildopts arches but no component rpm
3015        * arches set.
3016        */
3017       path =
3018         g_strdup_printf ("%s/buildarches/only_module_arches_v%" PRIu64 ".yaml",
3019                          g_getenv ("TEST_DATA_PATH"),
3020                          version);
3021       g_assert_nonnull (path);
3022       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3023       stream =
3024         modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
3025       G_GNUC_END_IGNORE_DEPRECATIONS
3026       g_assert_nonnull (stream);
3027       g_assert_null (error);
3028       g_clear_pointer (&path, g_free);
3029       g_clear_object (&stream);
3030 
3031       /* Test a valid module stream with component rpm arches but no buildopts
3032        * arches set.
3033        */
3034       path =
3035         g_strdup_printf ("%s/buildarches/only_rpm_arches_v%" PRIu64 ".yaml",
3036                          g_getenv ("TEST_DATA_PATH"),
3037                          version);
3038       g_assert_nonnull (path);
3039       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3040       stream =
3041         modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
3042       G_GNUC_END_IGNORE_DEPRECATIONS
3043       g_assert_nonnull (stream);
3044       g_assert_null (error);
3045       g_clear_pointer (&path, g_free);
3046       g_clear_object (&stream);
3047 
3048       /* Test a valid module stream with buildopts arches set and a component rpm
3049        * specified containing a subset of archs specified at the module level.
3050        */
3051       path =
3052         g_strdup_printf ("%s/buildarches/good_combo_arches_v%" PRIu64 ".yaml",
3053                          g_getenv ("TEST_DATA_PATH"),
3054                          version);
3055       g_assert_nonnull (path);
3056       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3057       stream =
3058         modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
3059       G_GNUC_END_IGNORE_DEPRECATIONS
3060       g_assert_nonnull (stream);
3061       g_assert_null (error);
3062       g_clear_pointer (&path, g_free);
3063       g_clear_object (&stream);
3064 
3065       /* Should fail validation if buildopts arches is set and a component rpm
3066        * specified an arch not specified at the module level.
3067        */
3068       path =
3069         g_strdup_printf ("%s/buildarches/bad_combo_arches_v%" PRIu64 ".yaml",
3070                          g_getenv ("TEST_DATA_PATH"),
3071                          version);
3072       g_assert_nonnull (path);
3073       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3074       stream =
3075         modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
3076       G_GNUC_END_IGNORE_DEPRECATIONS
3077       g_assert_error (error, MODULEMD_ERROR, MMD_ERROR_VALIDATE);
3078       g_assert_null (stream);
3079       g_clear_error (&error);
3080       g_clear_pointer (&path, g_free);
3081     }
3082 }
3083 
3084 
3085 static void
module_stream_v2_test_rpm_map(void)3086 module_stream_v2_test_rpm_map (void)
3087 {
3088   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
3089   g_autoptr (ModulemdRpmMapEntry) entry = NULL;
3090   ModulemdRpmMapEntry *retrieved_entry = NULL;
3091 
3092   stream = modulemd_module_stream_v2_new ("foo", "bar");
3093   g_assert_nonnull (stream);
3094 
3095   entry = modulemd_rpm_map_entry_new (
3096     "bar", 0, "1.23", "1.module_deadbeef", "x86_64");
3097   g_assert_nonnull (entry);
3098 
3099   modulemd_module_stream_v2_set_rpm_artifact_map_entry (
3100     stream, entry, "sha256", "baddad");
3101 
3102   retrieved_entry = modulemd_module_stream_v2_get_rpm_artifact_map_entry (
3103     stream, "sha256", "baddad");
3104   g_assert_nonnull (retrieved_entry);
3105 
3106   g_assert_true (modulemd_rpm_map_entry_equals (entry, retrieved_entry));
3107 }
3108 
3109 
3110 static void
module_stream_test_unicode_desc(void)3111 module_stream_test_unicode_desc (void)
3112 {
3113   g_autoptr (ModulemdModuleStream) stream = NULL;
3114   g_autofree gchar *path = NULL;
3115   g_autoptr (GError) error = NULL;
3116   guint64 version;
3117 
3118   for (version = MD_MODULESTREAM_VERSION_ONE;
3119        version <= MD_MODULESTREAM_VERSION_LATEST;
3120        version++)
3121     {
3122       /* Test a module stream with unicode in description */
3123       path = g_strdup_printf ("%s/stream_unicode_v%" PRIu64 ".yaml",
3124                               g_getenv ("TEST_DATA_PATH"),
3125                               version);
3126       g_assert_nonnull (path);
3127 
3128       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3129       stream =
3130         modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
3131       G_GNUC_END_IGNORE_DEPRECATIONS
3132       g_assert_nonnull (stream);
3133       g_assert_no_error (error);
3134       g_clear_object (&stream);
3135       g_clear_error (&error);
3136       g_clear_pointer (&path, g_free);
3137     }
3138 }
3139 
3140 
3141 static void
module_stream_v1_test_xmd_issue_274(void)3142 module_stream_v1_test_xmd_issue_274 (void)
3143 {
3144   g_autoptr (ModulemdModuleStream) stream = NULL;
3145   g_autofree gchar *path = NULL;
3146   g_autoptr (GError) error = NULL;
3147   GVariant *xmd1 = NULL;
3148   GVariant *xmd2 = NULL;
3149 
3150   path =
3151     g_strdup_printf ("%s/stream_unicode_v1.yaml", g_getenv ("TEST_DATA_PATH"));
3152   g_assert_nonnull (path);
3153 
3154   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3155   stream = modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
3156   G_GNUC_END_IGNORE_DEPRECATIONS
3157   g_assert_nonnull (stream);
3158   g_assert_no_error (error);
3159   g_assert_cmpint (modulemd_module_stream_get_mdversion (stream),
3160                    ==,
3161                    MD_MODULESTREAM_VERSION_ONE);
3162 
3163   xmd1 =
3164     modulemd_module_stream_v1_get_xmd (MODULEMD_MODULE_STREAM_V1 (stream));
3165   xmd2 =
3166     modulemd_module_stream_v1_get_xmd (MODULEMD_MODULE_STREAM_V1 (stream));
3167 
3168   g_assert_true (xmd1 == xmd2);
3169 }
3170 
3171 
3172 static void
module_stream_v2_test_xmd_issue_290(void)3173 module_stream_v2_test_xmd_issue_290 (void)
3174 {
3175   gboolean ret;
3176   g_auto (GVariantBuilder) builder;
3177   g_autoptr (GVariant) xmd = NULL;
3178   GVariant *xmd_array = NULL;
3179   g_autoptr (GVariantDict) xmd_dict = NULL;
3180   g_autoptr (GError) error = NULL;
3181   g_autoptr (ModulemdModuleIndex) index = modulemd_module_index_new ();
3182   g_autofree gchar *yaml_str = NULL;
3183 
3184   g_autoptr (ModulemdModuleStreamV2) stream =
3185     modulemd_module_stream_v2_new ("foo", "bar");
3186 
3187   modulemd_module_stream_v2_set_summary (stream, "summary");
3188   modulemd_module_stream_v2_set_description (stream, "desc");
3189   modulemd_module_stream_v2_add_module_license (stream, "MIT");
3190 
3191 
3192   g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
3193 
3194   g_variant_builder_add_value (&builder, g_variant_new_string ("foo"));
3195   g_variant_builder_add_value (&builder, g_variant_new_string ("bar"));
3196 
3197   xmd_array = g_variant_builder_end (&builder);
3198 
3199   xmd_dict = g_variant_dict_new (NULL);
3200   g_variant_dict_insert_value (
3201     xmd_dict, "something", g_steal_pointer (&xmd_array));
3202   xmd = g_variant_ref_sink (g_variant_dict_end (xmd_dict));
3203 
3204 
3205   modulemd_module_stream_v2_set_xmd (stream, xmd);
3206 
3207   ret = modulemd_module_index_add_module_stream (
3208     index, MODULEMD_MODULE_STREAM (stream), &error);
3209   g_assert_no_error (error);
3210   g_assert_true (ret);
3211 
3212   yaml_str = modulemd_module_index_dump_to_string (index, &error);
3213 
3214   // clang-format off
3215   g_assert_cmpstr (yaml_str, ==,
3216 "---\n"
3217 "document: modulemd\n"
3218 "version: 2\n"
3219 "data:\n"
3220 "  name: foo\n"
3221 "  stream: \"bar\"\n"
3222 "  summary: summary\n"
3223 "  description: >-\n"
3224 "    desc\n"
3225 "  license:\n"
3226 "    module:\n"
3227 "    - MIT\n"
3228 "  xmd:\n"
3229 "    something:\n"
3230 "    - foo\n"
3231 "    - bar\n"
3232 "...\n");
3233   // clang-format on
3234 
3235   g_assert_no_error (error);
3236 }
3237 
3238 
3239 static void
module_stream_v2_test_xmd_issue_290_with_example(void)3240 module_stream_v2_test_xmd_issue_290_with_example (void)
3241 {
3242   gboolean ret;
3243   g_autoptr (ModulemdModuleStream) stream = NULL;
3244   g_autofree gchar *path = NULL;
3245   g_autoptr (GError) error = NULL;
3246   g_autoptr (ModulemdModuleIndex) index = modulemd_module_index_new ();
3247   g_autofree gchar *output_yaml = NULL;
3248   g_autoptr (GVariant) xmd = NULL;
3249 
3250   path = g_strdup_printf ("%s/290.yaml", g_getenv ("TEST_DATA_PATH"));
3251   g_assert_nonnull (path);
3252   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3253   stream = modulemd_module_stream_read_file (path, TRUE, NULL, NULL, &error);
3254   G_GNUC_END_IGNORE_DEPRECATIONS
3255   g_assert_nonnull (stream);
3256   g_assert_no_error (error);
3257 
3258   xmd = modulemd_variant_deep_copy (
3259     modulemd_module_stream_v1_get_xmd (MODULEMD_MODULE_STREAM_V1 (stream)));
3260   modulemd_module_stream_v1_set_xmd (MODULEMD_MODULE_STREAM_V1 (stream), xmd);
3261 
3262   ret = modulemd_module_index_add_module_stream (index, stream, &error);
3263   g_assert_no_error (error);
3264   g_assert_true (ret);
3265 
3266   output_yaml = modulemd_module_index_dump_to_string (index, &error);
3267   g_assert_no_error (error);
3268   g_assert_nonnull (output_yaml);
3269 }
3270 
3271 
3272 static void
module_stream_v1_test_community(void)3273 module_stream_v1_test_community (void)
3274 {
3275   g_autoptr (ModulemdModuleStreamV1) stream = NULL;
3276   const gchar *community = NULL;
3277   g_autofree gchar *community_prop = NULL;
3278 
3279   stream = modulemd_module_stream_v1_new (NULL, NULL);
3280 
3281   // Check the defaults
3282   community = modulemd_module_stream_v1_get_community (stream);
3283   g_object_get (stream, MMD_TEST_COM_PROP, &community_prop, NULL);
3284   g_assert_null (community);
3285   g_assert_null (community_prop);
3286 
3287   g_clear_pointer (&community_prop, g_free);
3288 
3289   // Test property setting
3290   g_object_set (stream, MMD_TEST_COM_PROP, MMD_TEST_DOC_TEXT, NULL);
3291 
3292   community = modulemd_module_stream_v1_get_community (stream);
3293   g_object_get (stream, MMD_TEST_COM_PROP, &community_prop, NULL);
3294   g_assert_cmpstr (community_prop, ==, MMD_TEST_DOC_TEXT);
3295   g_assert_cmpstr (community, ==, MMD_TEST_DOC_TEXT);
3296 
3297   g_clear_pointer (&community_prop, g_free);
3298 
3299   // Test set_community()
3300   modulemd_module_stream_v1_set_community (stream, MMD_TEST_DOC_TEXT2);
3301 
3302   community = modulemd_module_stream_v1_get_community (stream);
3303   g_object_get (stream, MMD_TEST_COM_PROP, &community_prop, NULL);
3304   g_assert_cmpstr (community_prop, ==, MMD_TEST_DOC_TEXT2);
3305   g_assert_cmpstr (community, ==, MMD_TEST_DOC_TEXT2);
3306 
3307   g_clear_pointer (&community_prop, g_free);
3308 
3309   // Test setting to NULL
3310   g_object_set (stream, MMD_TEST_COM_PROP, NULL, NULL);
3311 
3312   community = modulemd_module_stream_v1_get_community (stream);
3313   g_object_get (stream, MMD_TEST_COM_PROP, &community_prop, NULL);
3314   g_assert_null (community);
3315   g_assert_null (community_prop);
3316 
3317   g_clear_pointer (&community_prop, g_free);
3318   g_clear_object (&stream);
3319 }
3320 
3321 static void
module_stream_v2_test_community(void)3322 module_stream_v2_test_community (void)
3323 {
3324   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
3325   const gchar *community = NULL;
3326   g_autofree gchar *community_prop = NULL;
3327 
3328   stream = modulemd_module_stream_v2_new (NULL, NULL);
3329 
3330   // Check the defaults
3331   community = modulemd_module_stream_v2_get_community (stream);
3332   g_object_get (stream, MMD_TEST_COM_PROP, &community_prop, NULL);
3333   g_assert_null (community);
3334   g_assert_null (community_prop);
3335 
3336   g_clear_pointer (&community_prop, g_free);
3337 
3338   // Test property setting
3339   g_object_set (stream, MMD_TEST_COM_PROP, MMD_TEST_DOC_TEXT, NULL);
3340 
3341   community = modulemd_module_stream_v2_get_community (stream);
3342   g_object_get (stream, MMD_TEST_COM_PROP, &community_prop, NULL);
3343   g_assert_cmpstr (community_prop, ==, MMD_TEST_DOC_TEXT);
3344   g_assert_cmpstr (community, ==, MMD_TEST_DOC_TEXT);
3345 
3346   g_clear_pointer (&community_prop, g_free);
3347 
3348   // Test set_community()
3349   modulemd_module_stream_v2_set_community (stream, MMD_TEST_DOC_TEXT2);
3350 
3351   community = modulemd_module_stream_v2_get_community (stream);
3352   g_object_get (stream, MMD_TEST_COM_PROP, &community_prop, NULL);
3353   g_assert_cmpstr (community_prop, ==, MMD_TEST_DOC_TEXT2);
3354   g_assert_cmpstr (community, ==, MMD_TEST_DOC_TEXT2);
3355 
3356   g_clear_pointer (&community_prop, g_free);
3357 
3358   // Test setting to NULL
3359   g_object_set (stream, MMD_TEST_COM_PROP, NULL, NULL);
3360 
3361   community = modulemd_module_stream_v2_get_community (stream);
3362   g_object_get (stream, MMD_TEST_COM_PROP, &community_prop, NULL);
3363   g_assert_null (community);
3364   g_assert_null (community_prop);
3365 
3366   g_clear_pointer (&community_prop, g_free);
3367   g_clear_object (&stream);
3368 }
3369 
3370 /*
3371  * This is a regression test for a memory leak that occurred when reading a
3372  * v1 ModuleStream YAML document if the `data.license.content` field appeared
3373  * before the `data.license.module` field.
3374  */
3375 static void
module_stream_v1_regression_content_license(void)3376 module_stream_v1_regression_content_license (void)
3377 {
3378   g_autoptr (ModulemdModuleStream) stream = NULL;
3379   g_autoptr (GError) error = NULL;
3380   const char *content_first =
3381     "---\n"
3382     "document: modulemd\n"
3383     "version: 1\n"
3384     "data:\n"
3385     "  summary: summary\n"
3386     "  description: >-\n"
3387     "    desc\n"
3388     "  license:\n"
3389     "    content:\n"
3390     "    - BSD\n"
3391     "    module:\n"
3392     "    - MIT\n"
3393     "  xmd:\n"
3394     "    something:\n"
3395     "    - foo\n"
3396     "    - bar\n"
3397     "...\n";
3398 
3399   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3400   stream = modulemd_module_stream_read_string (
3401     content_first, TRUE, NULL, NULL, &error);
3402   G_GNUC_END_IGNORE_DEPRECATIONS
3403   g_assert_no_error (error);
3404   g_assert_nonnull (stream);
3405   g_assert_true (MODULEMD_IS_MODULE_STREAM_V1 (stream));
3406 }
3407 
3408 
3409 static void
module_stream_v2_test_obsoletes(void)3410 module_stream_v2_test_obsoletes (void)
3411 {
3412   g_autoptr (ModulemdModuleStreamV2) stream = NULL;
3413   g_autoptr (ModulemdObsoletes) o = NULL;
3414 
3415   stream = modulemd_module_stream_v2_new ("foo", "latest");
3416   g_assert_nonnull (stream);
3417   o = modulemd_obsoletes_new (1, 2, "testmodule", "teststream", "testmessage");
3418   g_assert_nonnull (o);
3419 
3420   g_assert_null (modulemd_module_stream_v2_get_obsoletes_resolved (stream));
3421 
3422   modulemd_module_stream_v2_associate_obsoletes (stream, o);
3423   g_clear_object (&o);
3424 
3425   o = modulemd_module_stream_v2_get_obsoletes_resolved (stream);
3426   g_assert_nonnull (o);
3427   g_assert_cmpstr (modulemd_obsoletes_get_module_name (o), ==, "testmodule");
3428   g_assert_cmpstr (modulemd_obsoletes_get_module_stream (o), ==, "teststream");
3429   g_assert_null (modulemd_obsoletes_get_module_context (o));
3430 
3431   o = modulemd_obsoletes_new (1, 2, "testmodule", "teststream", "testmessage");
3432   g_assert_nonnull (o);
3433   modulemd_obsoletes_set_reset (o, TRUE);
3434   modulemd_module_stream_v2_associate_obsoletes (stream, o);
3435   o = modulemd_module_stream_v2_get_obsoletes_resolved (stream);
3436   g_assert_null (o);
3437   g_clear_object (&o);
3438 
3439   o = modulemd_module_stream_v2_get_obsoletes (stream);
3440   g_assert_nonnull (o);
3441   g_assert_cmpstr (modulemd_obsoletes_get_module_name (o), ==, "testmodule");
3442   g_assert_cmpstr (modulemd_obsoletes_get_module_stream (o), ==, "teststream");
3443   g_assert_null (modulemd_obsoletes_get_module_context (o));
3444 
3445   g_clear_object (&o);
3446   g_clear_object (&stream);
3447 }
3448 
3449 
3450 int
main(int argc,char * argv[])3451 main (int argc, char *argv[])
3452 {
3453   setlocale (LC_ALL, "");
3454   g_test_init (&argc, &argv, NULL);
3455   g_test_bug_base ("https://bugzilla.redhat.com/show_bug.cgi?id=");
3456 
3457   // Define the tests.o
3458 
3459   g_test_add_func ("/modulemd/v2/modulestream/construct",
3460                    module_stream_test_construct);
3461 
3462   g_test_add_func ("/modulemd/v2/modulestream/arch", module_stream_test_arch);
3463 
3464   g_test_add_func ("/modulemd/v2/modulestream/v1/documentation",
3465                    module_stream_v1_test_documentation);
3466 
3467   g_test_add_func ("/modulemd/v2/modulestream/v2/documentation",
3468                    module_stream_v2_test_documentation);
3469 
3470   g_test_add_func ("/modulemd/v2/modulestream/v1/summary",
3471                    module_stream_v1_test_summary);
3472 
3473   g_test_add_func ("/modulemd/v2/modulestream/v2/summary",
3474                    module_stream_v2_test_summary);
3475 
3476   g_test_add_func ("/modulemd/v2/modulestream/v1/description",
3477                    module_stream_v1_test_description);
3478 
3479   g_test_add_func ("/modulemd/v2/modulestream/v2/description",
3480                    module_stream_v2_test_description);
3481 
3482   g_test_add_func ("/modulemd/v2/modulestream/v1/licenses",
3483                    module_stream_v1_test_licenses);
3484 
3485   g_test_add_func ("/modulemd/v2/modulestream/v2/licenses",
3486                    module_stream_v2_test_licenses);
3487 
3488   g_test_add_func ("/modulemd/v2/modulestream/v1/tracker",
3489                    module_stream_v1_test_tracker);
3490 
3491   g_test_add_func ("/modulemd/v2/modulestream/v2/tracker",
3492                    module_stream_v2_test_tracker);
3493 
3494   g_test_add_func ("/modulemd/v2/modulestream/v1/profiles",
3495                    module_stream_v1_test_profiles);
3496 
3497   g_test_add_func ("/modulemd/v2/modulestream/v2/profiles",
3498                    module_stream_v2_test_profiles);
3499 
3500   g_test_add_func ("/modulemd/v2/modulestream/v1/rpm_api",
3501                    module_stream_v1_test_rpm_api);
3502 
3503   g_test_add_func ("/modulemd/v2/modulestream/v2/rpm_api",
3504                    module_stream_v2_test_rpm_api);
3505 
3506   g_test_add_func ("/modulemd/v2/modulestream/v1/rpm_filters",
3507                    module_stream_v1_test_rpm_filters);
3508 
3509   g_test_add_func ("/modulemd/v2/modulestream/v2/rpm_filters",
3510                    module_stream_v2_test_rpm_filters);
3511 
3512   g_test_add_func ("/modulemd/v2/modulestream/v2/demodularized_rpms",
3513                    module_stream_v2_test_demodularized_rpms);
3514 
3515   g_test_add_func ("/modulemd/v2/modulestream/v2_yaml",
3516                    module_stream_test_v2_yaml);
3517 
3518   g_test_add_func ("/modulemd/v2/packager/v2_sanity",
3519                    module_packager_v2_sanity);
3520 
3521   g_test_add_func ("/modulemd/v2/packager/v3_sanity",
3522                    module_packager_v3_sanity);
3523 
3524   g_test_add_func ("/modulemd/v2/modulestream/upgrade_v1_to_v2",
3525                    module_stream_test_upgrade_v1_to_v2);
3526 
3527   g_test_add_func ("/modulemd/v2/modulestream/v1/rpm_artifacts",
3528                    module_stream_v1_test_rpm_artifacts);
3529 
3530   g_test_add_func ("/modulemd/v2/modulestream/v2/rpm_artifacts",
3531                    module_stream_v2_test_rpm_artifacts);
3532 
3533   g_test_add_func ("/modulemd/v2/modulestream/v1/servicelevels",
3534                    module_stream_v2_test_servicelevels);
3535 
3536   g_test_add_func ("/modulemd/v2/modulestream/v2/servicelevels",
3537                    module_stream_v1_test_servicelevels);
3538 
3539   g_test_add_func ("/modulemd/v2/modulestream/v1/components",
3540                    module_stream_v1_test_components);
3541 
3542   g_test_add_func ("/modulemd/v2/modulestream/v2/components",
3543                    module_stream_v2_test_components);
3544 
3545   g_test_add_func ("/modulemd/v2/modulestream/copy", module_stream_test_copy);
3546 
3547   g_test_add_func ("/modulemd/v2/modulestream/equals",
3548                    module_stream_test_equals);
3549 
3550   g_test_add_func ("/modulemd/v2/modulestream/nsvc", module_stream_test_nsvc);
3551 
3552   g_test_add_func ("/modulemd/v2/modulestream/nsvca",
3553                    module_stream_test_nsvca);
3554 
3555   g_test_add_func ("/modulemd/v2/modulestream/v1/equals",
3556                    module_stream_v1_test_equals);
3557 
3558   g_test_add_func ("/modulemd/v2/modulestream/v2/equals",
3559                    module_stream_v2_test_equals);
3560 
3561   g_test_add_func ("/modulemd/v2/modulestream/v1/dependencies",
3562                    module_stream_v1_test_dependencies);
3563 
3564   g_test_add_func ("/modulemd/v2/modulestream/v2/dependencies",
3565                    module_stream_v2_test_dependencies);
3566 
3567   g_test_add_func ("/modulemd/v2/modulestream/v1/parse_dump",
3568                    module_stream_v1_test_parse_dump);
3569 
3570   g_test_add_func ("/modulemd/v2/modulestream/v2/parse_dump",
3571                    module_stream_v2_test_parse_dump);
3572 
3573   g_test_add_func ("/modulemd/v2/modulestream/v1/depends_on_stream",
3574                    module_stream_v1_test_depends_on_stream);
3575 
3576   g_test_add_func ("/modulemd/v2/modulestream/v2/depends_on_stream",
3577                    module_stream_v2_test_depends_on_stream);
3578 
3579   g_test_add_func ("/modulemd/v2/modulestream/validate/buildafter",
3580                    module_stream_test_validate_buildafter);
3581 
3582   g_test_add_func ("/modulemd/v2/modulestream/validate/buildarches",
3583                    module_stream_test_validate_buildarches);
3584 
3585   g_test_add_func ("/modulemd/v2/modulestream/v2/rpm_map",
3586                    module_stream_v2_test_rpm_map);
3587 
3588   g_test_add_func ("/modulemd/v2/modulestream/v1/community",
3589                    module_stream_v1_test_community);
3590 
3591   g_test_add_func ("/modulemd/v2/modulestream/v2/community",
3592                    module_stream_v2_test_community);
3593 
3594   g_test_add_func ("/modulemd/v2/modulestream/unicode/description",
3595                    module_stream_test_unicode_desc);
3596 
3597   g_test_add_func ("/modulemd/v2/modulestream/v1/xmd/issue274",
3598                    module_stream_v1_test_xmd_issue_274);
3599 
3600   g_test_add_func ("/modulemd/v2/modulestream/v2/xmd/issue290",
3601                    module_stream_v2_test_xmd_issue_290);
3602 
3603   g_test_add_func ("/modulemd/v2/modulestream/v2/xmd/issue290plus",
3604                    module_stream_v2_test_xmd_issue_290_with_example);
3605 
3606   g_test_add_func ("/modulemd/v2/modulestream/regression/memleak/v1_licenses",
3607                    module_stream_v1_regression_content_license);
3608 
3609   g_test_add_func ("/modulemd/v2/modulestream/v2/obsoletes",
3610                    module_stream_v2_test_obsoletes);
3611 
3612   return g_test_run ();
3613 }
3614