1 /*
2  * This file is part of libmodulemd
3  * Copyright (C) 2017-2018 Stephen Gallagher
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 <locale.h>
17 #include <signal.h>
18 
19 #include "modulemd-service-level.h"
20 #include "private/glib-extensions.h"
21 #include "private/modulemd-service-level-private.h"
22 #include "private/modulemd-yaml.h"
23 #include "private/test-utils.h"
24 
25 typedef struct _ServiceLevelFixture
26 {
27 } ServiceLevelFixture;
28 
29 gboolean signaled = FALSE;
30 
31 static void
sigtrap_handler(int sig_num)32 sigtrap_handler (int sig_num)
33 {
34   signaled = TRUE;
35 }
36 
37 static void
service_level_test_construct(void)38 service_level_test_construct (void)
39 {
40   g_autoptr (ModulemdServiceLevel) sl = NULL;
41 
42 
43   /* Test that the new() function works */
44   sl = modulemd_service_level_new ("foo");
45   g_assert_nonnull (sl);
46   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl));
47   g_assert_cmpstr (modulemd_service_level_get_name (sl), ==, "foo");
48   g_assert_null (modulemd_service_level_get_eol (sl));
49   g_clear_object (&sl);
50 
51 
52   /* Test that standard object instantiation works with a name */
53   // clang-format off
54   sl = g_object_new (MODULEMD_TYPE_SERVICE_LEVEL,
55                      "name", "bar",
56                      NULL);
57   // clang-format on
58   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl));
59   g_assert_cmpstr (modulemd_service_level_get_name (sl), ==, "bar");
60   g_assert_null (modulemd_service_level_get_eol (sl));
61   g_clear_object (&sl);
62 
63 
64   /* Test that we abort if we call new() with a NULL name */
65   signaled = FALSE;
66   signal (SIGTRAP, sigtrap_handler);
67   sl = modulemd_service_level_new (NULL);
68   g_assert_true (signaled);
69   g_clear_object (&sl);
70 
71 
72   /* Test that we abort if we instatiate without a name */
73   signaled = FALSE;
74   signal (SIGTRAP, sigtrap_handler);
75   sl = g_object_new (MODULEMD_TYPE_SERVICE_LEVEL, NULL);
76   g_assert_true (signaled);
77   g_clear_object (&sl);
78 
79 
80   /* Test that we abort if we instatiate with a NULL name */
81   signaled = FALSE;
82   signal (SIGTRAP, sigtrap_handler);
83   // clang-format off
84   sl = g_object_new (MODULEMD_TYPE_SERVICE_LEVEL,
85                      "name", NULL,
86                      NULL);
87   // clang-format on
88   g_assert_true (signaled);
89   g_clear_object (&sl);
90 }
91 
92 
93 static void
service_level_test_equals(void)94 service_level_test_equals (void)
95 {
96   g_autoptr (ModulemdServiceLevel) sl_1 = NULL;
97   g_autoptr (ModulemdServiceLevel) sl_2 = NULL;
98 
99   /* Test 2 service levels with same name*/
100   sl_1 = modulemd_service_level_new ("foo");
101   g_assert_nonnull (sl_1);
102   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_1));
103 
104   sl_2 = modulemd_service_level_new ("foo");
105   g_assert_nonnull (sl_2);
106   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_2));
107 
108   g_assert_true (modulemd_service_level_equals (sl_1, sl_2));
109   g_clear_object (&sl_1);
110   g_clear_object (&sl_2);
111 
112   /* Test 2 service levels with different names*/
113   sl_1 = modulemd_service_level_new ("foo");
114   g_assert_nonnull (sl_1);
115   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_1));
116 
117   sl_2 = modulemd_service_level_new ("bar");
118   g_assert_nonnull (sl_2);
119   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_2));
120 
121   g_assert_false (modulemd_service_level_equals (sl_1, sl_2));
122   g_clear_object (&sl_1);
123   g_clear_object (&sl_2);
124 
125   /* Test 2 service levels with same name and same eol*/
126   sl_1 = modulemd_service_level_new ("foo");
127   g_assert_nonnull (sl_1);
128   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_1));
129   modulemd_service_level_set_eol_ymd (sl_1, 2018, 11, 13);
130   g_assert_nonnull (modulemd_service_level_get_eol (sl_1));
131 
132   sl_2 = modulemd_service_level_new ("foo");
133   g_assert_nonnull (sl_2);
134   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_2));
135   modulemd_service_level_set_eol_ymd (sl_2, 2018, 11, 13);
136   g_assert_nonnull (modulemd_service_level_get_eol (sl_2));
137 
138   g_assert_true (modulemd_service_level_equals (sl_1, sl_2));
139   g_clear_object (&sl_1);
140   g_clear_object (&sl_2);
141 
142   /* Test 2 service levels with same name and different eol*/
143   sl_1 = modulemd_service_level_new ("foo");
144   g_assert_nonnull (sl_1);
145   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_1));
146   modulemd_service_level_set_eol_ymd (sl_1, 2018, 11, 13);
147   g_assert_nonnull (modulemd_service_level_get_eol (sl_1));
148 
149   sl_2 = modulemd_service_level_new ("foo");
150   g_assert_nonnull (sl_2);
151   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_2));
152   modulemd_service_level_set_eol_ymd (sl_2, 1998, 05, 25);
153   g_assert_nonnull (modulemd_service_level_get_eol (sl_2));
154 
155   g_assert_false (modulemd_service_level_equals (sl_1, sl_2));
156   g_clear_object (&sl_1);
157   g_clear_object (&sl_2);
158 
159   /* Test 2 service levels with same name and 1 invalid eol*/
160   sl_1 = modulemd_service_level_new ("foo");
161   g_assert_nonnull (sl_1);
162   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_1));
163   modulemd_service_level_set_eol_ymd (sl_1, 9999, 99, 99);
164   g_assert_null (modulemd_service_level_get_eol (sl_1));
165 
166   sl_2 = modulemd_service_level_new ("foo");
167   g_assert_nonnull (sl_2);
168   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_2));
169   modulemd_service_level_set_eol_ymd (sl_2, 1998, 05, 25);
170   g_assert_nonnull (modulemd_service_level_get_eol (sl_2));
171 
172   g_assert_false (modulemd_service_level_equals (sl_1, sl_2));
173   g_clear_object (&sl_1);
174   g_clear_object (&sl_2);
175 
176   /* Test 2 service levels with same name and both invalid eol*/
177   sl_1 = modulemd_service_level_new ("foo");
178   g_assert_nonnull (sl_1);
179   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_1));
180   modulemd_service_level_set_eol_ymd (sl_1, 9999, 99, 99);
181   g_assert_null (modulemd_service_level_get_eol (sl_1));
182 
183   sl_2 = modulemd_service_level_new ("foo");
184   g_assert_nonnull (sl_2);
185   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_2));
186   modulemd_service_level_set_eol_ymd (sl_2, 9999, 99, 98);
187   g_assert_null (modulemd_service_level_get_eol (sl_2));
188 
189   g_assert_true (modulemd_service_level_equals (sl_1, sl_2));
190   g_clear_object (&sl_1);
191   g_clear_object (&sl_2);
192 }
193 
194 
195 static void
service_level_test_copy(void)196 service_level_test_copy (void)
197 {
198   g_autoptr (ModulemdServiceLevel) sl = NULL;
199   g_autoptr (ModulemdServiceLevel) sl_copy = NULL;
200   g_autofree gchar *eol_string = NULL;
201 
202   /* Test copying a service level with no EOL */
203   sl = modulemd_service_level_new ("foo");
204   g_assert_nonnull (sl);
205   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl));
206   g_assert_cmpstr (modulemd_service_level_get_name (sl), ==, "foo");
207   g_assert_null (modulemd_service_level_get_eol (sl));
208 
209   sl_copy = modulemd_service_level_copy (sl);
210   g_assert_nonnull (sl_copy);
211   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_copy));
212   g_assert_cmpstr (modulemd_service_level_get_name (sl_copy), ==, "foo");
213   g_assert_null (modulemd_service_level_get_eol (sl_copy));
214   g_clear_object (&sl_copy);
215 
216   /* Test copying a service level with an EOL */
217   modulemd_service_level_set_eol_ymd (sl, 2018, 11, 13);
218 
219   sl_copy = modulemd_service_level_copy (sl);
220   g_assert_nonnull (sl_copy);
221   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl_copy));
222   g_assert_cmpstr (modulemd_service_level_get_name (sl_copy), ==, "foo");
223   g_assert_nonnull (modulemd_service_level_get_eol (sl_copy));
224   eol_string = modulemd_service_level_get_eol_as_string (sl_copy);
225   g_assert_cmpstr (eol_string, ==, "2018-11-13");
226 }
227 
228 
229 static void
service_level_test_get_name(void)230 service_level_test_get_name (void)
231 {
232   g_autoptr (ModulemdServiceLevel) sl = NULL;
233   g_autofree gchar *name = NULL;
234 
235 
236   /* First create a service level */
237   sl = modulemd_service_level_new ("foo");
238   g_assert_nonnull (sl);
239   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl));
240 
241   /* Test that get_name() returns the correct value */
242   g_assert_cmpstr (modulemd_service_level_get_name (sl), ==, "foo");
243 
244 
245   /* Test looking up the name by object properties */
246   // clang-format off
247   g_object_get (sl,
248                 "name", &name,
249                 NULL);
250   // clang-format on
251   g_assert_cmpstr (name, ==, "foo");
252 
253 
254   /* Test that trying to set the name by object properties fails.
255    * The name must be immutable for the life of the object.
256    */
257   signaled = FALSE;
258   signal (SIGTRAP, sigtrap_handler);
259   // clang-format off
260   g_object_set (sl,
261                 "name", "bar",
262                 NULL);
263   // clang-format on
264   g_assert_true (signaled);
265 }
266 
267 
268 static void
service_level_test_get_set_eol(void)269 service_level_test_get_set_eol (void)
270 {
271   g_autoptr (ModulemdServiceLevel) sl = NULL;
272   g_autoptr (GDate) eol = NULL;
273   GDate *returned_eol = NULL;
274   g_autofree gchar *eol_string = NULL;
275 
276 
277   /* First create a service level */
278   sl = modulemd_service_level_new ("foo");
279   g_assert_nonnull (sl);
280   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl));
281 
282   /* Test that get_eol() returns NULL at first */
283   g_assert_null (modulemd_service_level_get_eol (sl));
284   /* coverity[leaked_storage] */
285   g_assert_null (modulemd_service_level_get_eol_as_string (sl));
286 
287 
288   /* Set the EOL with the set_eol() method */
289   eol = g_date_new_dmy (7, 11, 2018);
290   modulemd_service_level_set_eol (sl, eol);
291 
292   returned_eol = modulemd_service_level_get_eol (sl);
293   g_assert_nonnull (returned_eol);
294   g_assert_true (g_date_valid (returned_eol));
295   g_assert_cmpint (g_date_compare (eol, returned_eol), ==, 0);
296 
297   eol_string = modulemd_service_level_get_eol_as_string (sl);
298   g_assert_nonnull (eol_string);
299   g_assert_cmpstr (eol_string, ==, "2018-11-07");
300   g_clear_pointer (&eol_string, g_free);
301 
302 
303   /* Set the EOL with the set_eol_ymd() method */
304   modulemd_service_level_set_eol_ymd (sl, 2018, 11, 7);
305 
306   returned_eol = modulemd_service_level_get_eol (sl);
307   g_assert_nonnull (returned_eol);
308   g_assert_true (g_date_valid (returned_eol));
309   g_assert_cmpint (g_date_compare (eol, returned_eol), ==, 0);
310 
311   eol_string = modulemd_service_level_get_eol_as_string (sl);
312   g_assert_nonnull (eol_string);
313   g_assert_cmpstr (eol_string, ==, "2018-11-07");
314   g_clear_pointer (&eol_string, g_free);
315 
316 
317   /* Set an invalid date */
318   g_clear_pointer (&eol, g_date_free);
319   eol = g_date_new ();
320   modulemd_service_level_set_eol (sl, eol);
321   g_assert_null (modulemd_service_level_get_eol (sl));
322 
323   modulemd_service_level_set_eol_ymd (sl, 2018, 2, 31);
324   g_assert_null (modulemd_service_level_get_eol (sl));
325 
326   modulemd_service_level_set_eol_ymd (sl, 9999, 99, 99);
327   g_assert_null (modulemd_service_level_get_eol (sl));
328 
329   /* Set the EOL back to something valid */
330   modulemd_service_level_set_eol_ymd (sl, 2018, 11, 7);
331   returned_eol = modulemd_service_level_get_eol (sl);
332   g_assert_nonnull (returned_eol);
333   eol_string = modulemd_service_level_get_eol_as_string (sl);
334   g_assert_nonnull (eol_string);
335   g_assert_cmpstr (eol_string, ==, "2018-11-07");
336   g_clear_pointer (&eol_string, g_free);
337 
338   /* Test the remove_eol() function */
339   modulemd_service_level_remove_eol (sl);
340   g_assert_null (modulemd_service_level_get_eol (sl));
341 }
342 
343 static void
service_level_test_parse_yaml(void)344 service_level_test_parse_yaml (void)
345 {
346   g_autoptr (ModulemdServiceLevel) sl = NULL;
347   g_autoptr (GError) error = NULL;
348   MMD_INIT_YAML_PARSER (parser);
349   g_autofree gchar *yaml_path = NULL;
350   g_autoptr (FILE) yaml_stream = NULL;
351   g_autofree gchar *name = NULL;
352   GDate *eol = NULL;
353   yaml_path =
354     g_strdup_printf ("%s/sl_with_eol.yaml", g_getenv ("TEST_DATA_PATH"));
355   g_assert_nonnull (yaml_path);
356 
357   yaml_stream = g_fopen (yaml_path, "rbe");
358   g_assert_nonnull (yaml_stream);
359 
360   yaml_parser_set_input_file (&parser, yaml_stream);
361 
362   /* Advance the parser past STREAM_START, DOCUMENT_START and MAPPING_START */
363   parser_skip_headers (&parser);
364 
365   /* Read the name */
366   name = modulemd_yaml_parse_string (&parser, &error);
367   g_assert_nonnull (name);
368   g_assert_cmpstr (name, ==, "sl_name");
369 
370   sl = modulemd_service_level_parse_yaml (&parser, name, TRUE, &error);
371   g_assert_nonnull (sl);
372   g_assert_true (MODULEMD_IS_SERVICE_LEVEL (sl));
373   g_assert_cmpstr (modulemd_service_level_get_name (sl), ==, "sl_name");
374   g_assert_nonnull (modulemd_service_level_get_eol (sl));
375 
376   eol = modulemd_service_level_get_eol (sl);
377   g_assert_cmpint (g_date_get_year (eol), ==, 2018);
378   g_assert_cmpint (g_date_get_month (eol), ==, 7);
379   g_assert_cmpint (g_date_get_day (eol), ==, 11);
380 }
381 
382 
383 static void
service_level_test_emit_yaml(void)384 service_level_test_emit_yaml (void)
385 {
386   g_autoptr (ModulemdServiceLevel) sl = NULL;
387   g_autoptr (GError) error = NULL;
388   MMD_INIT_YAML_EMITTER (emitter);
389   MMD_INIT_YAML_STRING (&emitter, yaml_string);
390 
391   /* Service Level without EOL */
392   sl = modulemd_service_level_new ("foo");
393 
394   g_assert_true (mmd_emitter_start_stream (&emitter, &error));
395   g_assert_true (mmd_emitter_start_document (&emitter, &error));
396 
397   g_assert_true (
398     mmd_emitter_start_mapping (&emitter, YAML_BLOCK_MAPPING_STYLE, &error));
399 
400   g_assert_true (modulemd_service_level_emit_yaml (sl, &emitter, &error));
401 
402   g_assert_true (mmd_emitter_end_mapping (&emitter, &error));
403 
404   g_assert_true (mmd_emitter_end_document (&emitter, &error));
405   g_assert_true (mmd_emitter_end_stream (&emitter, &error));
406 
407   g_assert_cmpstr (yaml_string->str, ==, "---\nfoo: {}\n...\n");
408 
409   /* Service Level with EOL */
410   g_clear_pointer (&yaml_string, modulemd_yaml_string_free);
411   yaml_emitter_delete (&emitter);
412   yaml_emitter_initialize (&emitter);
413   yaml_string = g_malloc0_n (1, sizeof (modulemd_yaml_string));
414   yaml_emitter_set_output (&emitter, write_yaml_string, (void *)yaml_string);
415 
416   modulemd_service_level_set_eol_ymd (sl, 2018, 11, 13);
417 
418   g_assert_true (mmd_emitter_start_stream (&emitter, &error));
419   g_assert_true (mmd_emitter_start_document (&emitter, &error));
420 
421   g_assert_true (
422     mmd_emitter_start_mapping (&emitter, YAML_BLOCK_MAPPING_STYLE, &error));
423 
424   g_assert_true (modulemd_service_level_emit_yaml (sl, &emitter, &error));
425 
426   g_assert_true (mmd_emitter_end_mapping (&emitter, &error));
427 
428   g_assert_true (mmd_emitter_end_document (&emitter, &error));
429   g_assert_true (mmd_emitter_end_stream (&emitter, &error));
430 
431   g_assert_cmpstr (yaml_string->str,
432                    ==,
433                    "---\n"
434                    "foo:\n"
435                    "  eol: 2018-11-13\n"
436                    "...\n");
437 }
438 
439 
440 int
main(int argc,char * argv[])441 main (int argc, char *argv[])
442 {
443   setlocale (LC_ALL, "");
444 
445   g_test_init (&argc, &argv, NULL);
446   g_test_bug_base ("https://bugzilla.redhat.com/show_bug.cgi?id=");
447 
448   // Define the tests.
449 
450   g_test_add_func ("/modulemd/v2/servicelevel/construct",
451                    service_level_test_construct);
452 
453   g_test_add_func ("/modulemd/v2/servicelevel/get_set_name",
454                    service_level_test_get_name);
455 
456   g_test_add_func ("/modulemd/v2/servicelevel/equals",
457                    service_level_test_equals);
458 
459   g_test_add_func ("/modulemd/v2/servicelevel/copy", service_level_test_copy);
460 
461   g_test_add_func ("/modulemd/v2/servicelevel/get_set_eol",
462                    service_level_test_get_set_eol);
463 
464   g_test_add_func ("/modulemd/v2/servicelevel/yaml/parse",
465                    service_level_test_parse_yaml);
466 
467   g_test_add_func ("/modulemd/v2/servicelevel/yaml/emit",
468                    service_level_test_emit_yaml);
469 
470   return g_test_run ();
471 }
472