Branch data Line data Source code
1 : : #include "sute.h"
2 : :
3 : : /**
4 : : * Runs precizer with the given arguments and validates output with optional
5 : : * stdout/stderr regex templates.
6 : : */
7 : 90 : static Return assert_compare_output(
8 : : const char *arguments,
9 : : const int expected_return_code,
10 : : const char *stdout_pattern_file,
11 : : const char *stderr_pattern_file)
12 : : {
13 : : /* The status that will be returned before exiting */
14 : : /* By default, assumes the function ran without errors */
15 : 90 : Return status = SUCCESS;
16 : :
17 : 90 : m_create(char,stdout_result,MEMORY_STRING);
18 : 90 : m_create(char,stderr_result,MEMORY_STRING);
19 : 90 : m_create(char,stdout_pattern,MEMORY_STRING);
20 : 90 : m_create(char,stderr_pattern,MEMORY_STRING);
21 : :
22 [ - + ]: 90 : if(arguments == NULL)
23 : : {
24 : 0 : status = FAILURE;
25 : : }
26 : :
27 : 90 : unsigned int capture_policy = ALLOW_BOTH;
28 : :
29 [ + + - + ]: 90 : if(expected_return_code != COMPLETED || stderr_pattern_file != NULL)
30 : : {
31 : 20 : capture_policy = STDERR_ALLOW;
32 : : }
33 : :
34 : 90 : run(runit(arguments,stdout_result,stderr_result,expected_return_code,capture_policy));
35 : :
36 [ + + ]: 90 : if(stdout_pattern_file != NULL)
37 : : {
38 : 84 : run(get_file_content(stdout_pattern_file,stdout_pattern));
39 : 84 : run(match_pattern(stdout_result,stdout_pattern,stdout_pattern_file));
40 : : }
41 : :
42 [ + + ]: 90 : if(stderr_pattern_file != NULL)
43 : : {
44 : 20 : run(get_file_content(stderr_pattern_file,stderr_pattern));
45 : 20 : run(match_pattern(stderr_result,stderr_pattern,stderr_pattern_file));
46 : : }
47 : :
48 : 90 : m_del(stderr_pattern);
49 : 90 : m_del(stdout_pattern);
50 : 90 : m_del(stderr_result);
51 : 90 : m_del(stdout_result);
52 : :
53 : 90 : deliver(status);
54 : : }
55 : :
56 : : /**
57 : : * Prepares two databases with known differences for compare-filter tests.
58 : : */
59 : 6 : static Return prepare_compare_filter_differences_fixture(void)
60 : : {
61 : : /* The status that will be returned before exiting */
62 : : /* By default, assumes the function ran without errors */
63 : 6 : Return status = SUCCESS;
64 : :
65 : 6 : m_create(char,result,MEMORY_STRING);
66 : :
67 : 6 : run(prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
68 : :
69 : 6 : run(set_environment_variable("TESTING","false"));
70 : :
71 : 6 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
72 : 6 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
73 : :
74 [ + - - + ]: 6 : if((SUCCESS & status) && result->length != 0)
75 : : {
76 : 0 : status = FAILURE;
77 : : }
78 : :
79 : 6 : run(delete_path("tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/a.txt"));
80 : 6 : run(add_string_to("AFAKDSJ","tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt"));
81 : 6 : run(replase_to_string("WNEURHGO","tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/b.txt"));
82 : :
83 : 6 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
84 : 6 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
85 : :
86 [ + - - + ]: 6 : if((SUCCESS & status) && result->length != 0)
87 : : {
88 : 0 : status = FAILURE;
89 : : }
90 : :
91 : 6 : m_del(result);
92 : :
93 : 6 : deliver(status);
94 : : }
95 : :
96 : : /**
97 : : * Prepares two databases where only one existence side differs:
98 : : * database2 contains one extra path compared to database1.
99 : : */
100 : 2 : static Return prepare_compare_filter_one_sided_fixture(void)
101 : : {
102 : : /* The status that will be returned before exiting */
103 : : /* By default, assumes the function ran without errors */
104 : 2 : Return status = SUCCESS;
105 : :
106 : 2 : m_create(char,result,MEMORY_STRING);
107 : :
108 : 2 : run(prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
109 : :
110 : 2 : run(set_environment_variable("TESTING","false"));
111 : :
112 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
113 : 2 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
114 : :
115 [ + - - + ]: 2 : if((SUCCESS & status) && result->length != 0)
116 : : {
117 : 0 : status = FAILURE;
118 : : }
119 : :
120 : 2 : run(replase_to_string("ONLY_DB2_FILE","tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/only_db2.txt"));
121 : :
122 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
123 : 2 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
124 : :
125 [ + - - + ]: 2 : if((SUCCESS & status) && result->length != 0)
126 : : {
127 : 0 : status = FAILURE;
128 : : }
129 : :
130 : 2 : m_del(result);
131 : :
132 : 2 : deliver(status);
133 : : }
134 : :
135 : : /**
136 : : * Cleans temporary files created by the "differences" fixture.
137 : : */
138 : 8 : static Return cleanup_compare_filter_differences_fixture(void)
139 : : {
140 : : /* The status that will be returned before exiting */
141 : : /* By default, assumes the function ran without errors */
142 : 8 : Return status = SUCCESS;
143 : :
144 : 8 : run(delete_path("database1.db"));
145 : 8 : run(delete_path("database2.db"));
146 : 8 : run(restore_mutable_fixture("tests/fixtures/diffs/diff1"));
147 : :
148 : 8 : deliver(status);
149 : : }
150 : :
151 : : /**
152 : : * Prepares two equal databases for compare-filter tests.
153 : : */
154 : 8 : static Return prepare_compare_filter_equal_fixture(void)
155 : : {
156 : : /* The status that will be returned before exiting */
157 : : /* By default, assumes the function ran without errors */
158 : 8 : Return status = SUCCESS;
159 : :
160 : 8 : m_create(char,result,MEMORY_STRING);
161 : :
162 : 8 : run(set_environment_variable("TESTING","false"));
163 : :
164 : 8 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
165 : 8 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
166 : :
167 [ + - - + ]: 8 : if((SUCCESS & status) && result->length != 0)
168 : : {
169 : 0 : status = FAILURE;
170 : : }
171 : :
172 : 8 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
173 : 8 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
174 : :
175 [ + - - + ]: 8 : if((SUCCESS & status) && result->length != 0)
176 : : {
177 : 0 : status = FAILURE;
178 : : }
179 : :
180 : 8 : m_del(result);
181 : :
182 : 8 : deliver(status);
183 : : }
184 : :
185 : : /**
186 : : * Cleans temporary files created by the "equal" fixture.
187 : : */
188 : 6 : static Return cleanup_compare_filter_equal_fixture(void)
189 : : {
190 : : /* The status that will be returned before exiting */
191 : : /* By default, assumes the function ran without errors */
192 : 6 : Return status = SUCCESS;
193 : :
194 : 6 : run(delete_path("database1.db"));
195 : 6 : run(delete_path("database2.db"));
196 : :
197 : 6 : deliver(status);
198 : : }
199 : :
200 : : /**
201 : : * One file is removed, updated, and added at a time
202 : : */
203 : 2 : static Return test0028_1(void)
204 : : {
205 : 2 : INITTEST;
206 : :
207 : : // Create memory for the result
208 : 2 : m_create(char,result,MEMORY_STRING);
209 : 2 : m_create(char,pattern,MEMORY_STRING);
210 : :
211 : : // Preparation for tests
212 : 2 : ASSERT(SUCCESS == prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
213 : :
214 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
215 : :
216 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
217 : :
218 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
219 : :
220 : 2 : ASSERT(result->length == 0);
221 : :
222 : 2 : ASSERT(SUCCESS == delete_path("tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/a.txt")); // Remove
223 : 2 : ASSERT(SUCCESS == add_string_to("AFAKDSJ","tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt")); // Modify
224 : 2 : ASSERT(SUCCESS == replase_to_string("WNEURHGO","tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/b.txt")); // New file
225 : :
226 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
227 : :
228 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
229 : :
230 : 2 : ASSERT(result->length == 0);
231 : :
232 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
233 : :
234 : 2 : arguments = "--compare database1.db database2.db";
235 : :
236 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
237 : :
238 : 2 : const char *filename = "templates/0028_001.txt";
239 : :
240 : 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
241 : 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
242 : :
243 : 2 : m_del(pattern);
244 : 2 : m_del(result);
245 : :
246 : : // Clean up test results
247 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
248 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
249 : 2 : ASSERT(SUCCESS == restore_mutable_fixture("tests/fixtures/diffs/diff1"));
250 : :
251 : 2 : RETURN_STATUS;
252 : : }
253 : :
254 : : /**
255 : : * One file is removed. It should be reflected as a change in one of the databases.
256 : : */
257 : 2 : static Return test0028_2(void)
258 : : {
259 : 2 : INITTEST;
260 : :
261 : : // Create memory for the result
262 : 2 : m_create(char,result,MEMORY_STRING);
263 : 2 : m_create(char,pattern,MEMORY_STRING);
264 : :
265 : : // Preparation for tests
266 : 2 : ASSERT(SUCCESS == prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
267 : :
268 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
269 : :
270 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
271 : :
272 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
273 : :
274 : 2 : ASSERT(result->length == 0);
275 : :
276 : 2 : ASSERT(SUCCESS == delete_path("tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/a.txt")); // Remove
277 : :
278 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
279 : :
280 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
281 : :
282 : 2 : ASSERT(result->length == 0);
283 : :
284 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
285 : :
286 : 2 : arguments = "--compare database1.db database2.db";
287 : :
288 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
289 : :
290 : 2 : const char *filename = "templates/0028_002_1.txt";
291 : :
292 : 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
293 : 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
294 : :
295 : 2 : m_del(pattern);
296 : 2 : m_del(result);
297 : :
298 : : // Clean up test results
299 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
300 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
301 : 2 : ASSERT(SUCCESS == restore_mutable_fixture("tests/fixtures/diffs/diff1"));
302 : :
303 : 2 : RETURN_STATUS;
304 : : }
305 : :
306 : : /**
307 : : * One file is added. It should be reflected as a change in one of the databases.
308 : : */
309 : 2 : static Return test0028_3(void)
310 : : {
311 : 2 : INITTEST;
312 : :
313 : : // Create memory for the result
314 : 2 : m_create(char,result,MEMORY_STRING);
315 : 2 : m_create(char,pattern,MEMORY_STRING);
316 : :
317 : : // Preparation for tests
318 : 2 : ASSERT(SUCCESS == prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
319 : :
320 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
321 : :
322 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
323 : :
324 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
325 : :
326 : 2 : ASSERT(result->length == 0);
327 : :
328 : 2 : ASSERT(SUCCESS == replase_to_string("WNEURHGO","tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/b.txt")); // New file
329 : :
330 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
331 : :
332 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
333 : :
334 : 2 : ASSERT(result->length == 0);
335 : :
336 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
337 : :
338 : 2 : arguments = "--compare database1.db database2.db";
339 : :
340 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
341 : :
342 : 2 : const char *filename = "templates/0028_003_1.txt";
343 : :
344 : 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
345 : 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
346 : :
347 : 2 : m_del(pattern);
348 : 2 : m_del(result);
349 : :
350 : : // Clean up test results
351 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
352 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
353 : 2 : ASSERT(SUCCESS == restore_mutable_fixture("tests/fixtures/diffs/diff1"));
354 : :
355 : 2 : RETURN_STATUS;
356 : : }
357 : :
358 : : /**
359 : : * One file is updated and its checksum should change
360 : : */
361 : 2 : static Return test0028_4(void)
362 : : {
363 : 2 : INITTEST;
364 : :
365 : : // Create memory for the result
366 : 2 : m_create(char,result,MEMORY_STRING);
367 : 2 : m_create(char,pattern,MEMORY_STRING);
368 : :
369 : : // Preparation for tests
370 : 2 : ASSERT(SUCCESS == prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
371 : :
372 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
373 : :
374 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
375 : :
376 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
377 : :
378 : 2 : ASSERT(result->length == 0);
379 : :
380 : 2 : ASSERT(SUCCESS == add_string_to("AFAKDSJ","tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt")); // Modify
381 : :
382 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
383 : :
384 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
385 : :
386 : 2 : ASSERT(result->length == 0);
387 : :
388 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
389 : :
390 : 2 : arguments = "--compare database1.db database2.db";
391 : :
392 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
393 : :
394 : 2 : const char *filename = "templates/0028_004.txt";
395 : :
396 : 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
397 : 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
398 : :
399 : 2 : m_del(pattern);
400 : 2 : m_del(result);
401 : :
402 : : // Clean up test results
403 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
404 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
405 : 2 : ASSERT(SUCCESS == restore_mutable_fixture("tests/fixtures/diffs/diff1"));
406 : :
407 : 2 : RETURN_STATUS;
408 : : }
409 : :
410 : : /**
411 : : * Nothing changes. The databases should be equivalent
412 : : */
413 : 2 : static Return test0028_5(void)
414 : : {
415 : 2 : INITTEST;
416 : :
417 : : // Create memory for the result
418 : 2 : m_create(char,result,MEMORY_STRING);
419 : 2 : m_create(char,pattern,MEMORY_STRING);
420 : :
421 : 2 : const char *arguments = "--database=database1.db tests/fixtures/diffs/diff1";
422 : :
423 : 2 : ASSERT(SUCCESS == runit(arguments,NULL,NULL,COMPLETED,ALLOW_BOTH));
424 : :
425 : 2 : arguments = "--database=database2.db tests/fixtures/diffs/diff1";
426 : :
427 : 2 : ASSERT(SUCCESS == runit(arguments,NULL,NULL,COMPLETED,ALLOW_BOTH));
428 : :
429 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
430 : :
431 : 2 : arguments = "--compare database1.db database2.db";
432 : :
433 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
434 : :
435 : 2 : const char *filename = "templates/0028_005.txt";
436 : :
437 : 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
438 : 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
439 : :
440 : 2 : m_del(pattern);
441 : 2 : m_del(result);
442 : :
443 : : // Clean up test results
444 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
445 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
446 : :
447 : 2 : RETURN_STATUS;
448 : : }
449 : :
450 : : /**
451 : : * Compare-filter combinations in compare mode and argument validation.
452 : : */
453 : 2 : static Return test0028_6(void)
454 : : {
455 : 2 : INITTEST;
456 : :
457 : 2 : SLOWTEST;
458 : :
459 : : struct compare_filter_case {
460 : : const char *arguments;
461 : : int expected_return_code;
462 : : const char *stdout_pattern_file;
463 : : const char *stderr_pattern_file;
464 : : };
465 : :
466 : 2 : const struct compare_filter_case equal_cases[] = {
467 : : // Valid combinations with --compare for equal databases
468 : : {"--compare database1.db database2.db",COMPLETED,"templates/0028_005.txt",NULL},
469 : : {"--compare --compare-filter=checksum-mismatch database1.db database2.db",COMPLETED,"templates/0028_006_1.txt",NULL},
470 : : {"--compare database1.db database2.db --compare-filter=checksum-mismatch",COMPLETED,"templates/0028_006_1.txt",NULL},
471 : : {"--compare --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_006_2.txt",NULL},
472 : : {"--compare --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_3.txt",NULL},
473 : : {"--compare --compare-filter=first-source --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_4.txt",NULL},
474 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_006_5.txt",NULL},
475 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_6.txt",NULL},
476 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=first-source --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_19.txt",NULL}
477 : : };
478 : :
479 : 2 : const struct compare_filter_case one_sided_cases[] = {
480 : : // Regression: one-sided filter must not claim full identity if opposite side has differences
481 : : {"--compare --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_006_7.txt",NULL},
482 : : {"--compare --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_8.txt",NULL},
483 : : {"--compare database2.db database1.db --compare-filter=first-source",COMPLETED,"templates/0028_006_17.txt",NULL},
484 : : {"--compare database2.db database1.db --compare-filter=second-source",COMPLETED,"templates/0028_006_18.txt",NULL}
485 : : };
486 : :
487 : 2 : const struct compare_filter_case differences_cases[] = {
488 : : // Valid combinations with --compare for databases with all difference categories
489 : : {"--compare database1.db database2.db",COMPLETED,"templates/0028_001.txt",NULL},
490 : : {"--compare --compare-filter=checksum-mismatch database1.db database2.db",COMPLETED,"templates/0028_006_21.txt",NULL},
491 : : {"--compare --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_006_9.txt",NULL},
492 : : {"--compare --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_10.txt",NULL},
493 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_006_11.txt",NULL},
494 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_12.txt",NULL},
495 : : {"--compare --compare-filter=first-source --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_13.txt",NULL},
496 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=first-source --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_20.txt",NULL}
497 : : };
498 : :
499 : 2 : const struct compare_filter_case invalid_cases[] = {
500 : : // Invalid combinations: --compare-filter=value without --compare
501 : : {"--compare-filter=checksum-mismatch database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
502 : : {"--compare-filter=first-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
503 : : {"--compare-filter=second-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
504 : : {"--compare-filter=checksum-mismatch --compare-filter=first-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
505 : : {"--compare-filter=checksum-mismatch --compare-filter=second-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
506 : : {"--compare-filter=first-source --compare-filter=second-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
507 : : {"--compare-filter=checksum-mismatch --compare-filter=first-source --compare-filter=second-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
508 : :
509 : : // Invalid combinations: --compare-filter without argument
510 : : {"--compare database1.db database2.db --compare-filter",FAILURE,NULL,"templates/0028_006_16.txt"},
511 : : {"--compare-filter",FAILURE,NULL,"templates/0028_006_16.txt"}
512 : : };
513 : :
514 : 2 : ASSERT(SUCCESS & prepare_compare_filter_equal_fixture());
515 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
516 : :
517 [ + + + - ]: 20 : for(size_t i = 0; (i < sizeof(equal_cases) / sizeof(equal_cases[0])) && (SUCCESS == status); i++)
518 : : {
519 : 18 : ASSERT(SUCCESS & assert_compare_output(
520 : : equal_cases[i].arguments,
521 : : equal_cases[i].expected_return_code,
522 : : equal_cases[i].stdout_pattern_file,
523 : : equal_cases[i].stderr_pattern_file));
524 : : }
525 : :
526 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_equal_fixture());
527 : :
528 : 2 : ASSERT(SUCCESS & prepare_compare_filter_one_sided_fixture());
529 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
530 : :
531 [ + + + - ]: 10 : for(size_t i = 0; (i < sizeof(one_sided_cases) / sizeof(one_sided_cases[0])) && (SUCCESS == status); i++)
532 : : {
533 : 8 : ASSERT(SUCCESS & assert_compare_output(
534 : : one_sided_cases[i].arguments,
535 : : one_sided_cases[i].expected_return_code,
536 : : one_sided_cases[i].stdout_pattern_file,
537 : : one_sided_cases[i].stderr_pattern_file));
538 : : }
539 : :
540 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_differences_fixture());
541 : :
542 : 2 : ASSERT(SUCCESS & prepare_compare_filter_differences_fixture());
543 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
544 : :
545 [ + + + - ]: 18 : for(size_t i = 0; (i < sizeof(differences_cases) / sizeof(differences_cases[0])) && (SUCCESS == status); i++)
546 : : {
547 : 16 : ASSERT(SUCCESS & assert_compare_output(
548 : : differences_cases[i].arguments,
549 : : differences_cases[i].expected_return_code,
550 : : differences_cases[i].stdout_pattern_file,
551 : : differences_cases[i].stderr_pattern_file));
552 : : }
553 : :
554 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_differences_fixture());
555 : :
556 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
557 : :
558 [ + + + - ]: 20 : for(size_t i = 0; (i < sizeof(invalid_cases) / sizeof(invalid_cases[0])) && (SUCCESS == status); i++)
559 : : {
560 : 18 : ASSERT(SUCCESS & assert_compare_output(
561 : : invalid_cases[i].arguments,
562 : : invalid_cases[i].expected_return_code,
563 : : invalid_cases[i].stdout_pattern_file,
564 : : invalid_cases[i].stderr_pattern_file));
565 : : }
566 : :
567 : 2 : RETURN_STATUS;
568 : : }
569 : :
570 : : /**
571 : : * Invalid --compare-filter value should fail argument parsing
572 : : */
573 : 2 : static Return test0028_7(void)
574 : : {
575 : 2 : INITTEST;
576 : :
577 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
578 : :
579 : 2 : const char *arguments = "--compare --compare-filter=invalid-value database1.db database2.db";
580 : :
581 : 2 : ASSERT(SUCCESS & assert_compare_output(arguments,FAILURE,NULL,"templates/0028_007_1.txt"));
582 : :
583 : 2 : RETURN_STATUS;
584 : : }
585 : :
586 : : /**
587 : : * NULL vs non-NULL SHA512 rows must be reported as checksum mismatches
588 : : */
589 : 2 : static Return test0028_8(void)
590 : : {
591 : 2 : INITTEST;
592 : :
593 : 2 : ASSERT(SUCCESS & prepare_compare_filter_equal_fixture());
594 : 2 : ASSERT(SUCCESS == db_set_sha512_to_null("database2.db","1/AAA/ZAW/D/e/f/b_file.txt"));
595 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
596 : :
597 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare database1.db database2.db",COMPLETED,"templates/0028_000.txt",NULL));
598 : :
599 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_equal_fixture());
600 : :
601 : 2 : RETURN_STATUS;
602 : : }
603 : :
604 : : /**
605 : : * NULL SHA512 produced by fixture changes must be reported as a mismatch
606 : : */
607 : 2 : static Return test0028_9(void)
608 : : {
609 : 2 : INITTEST;
610 : :
611 : 2 : m_create(char,result,MEMORY_STRING);
612 : :
613 : 2 : ASSERT(SUCCESS == prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
614 : :
615 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
616 : :
617 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
618 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
619 : :
620 : 2 : ASSERT(result->length == 0);
621 : :
622 : 2 : ASSERT(SUCCESS == truncate_file_to_zero_size("tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt"));
623 : :
624 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
625 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
626 : :
627 : 2 : ASSERT(result->length == 0);
628 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
629 : :
630 : 2 : ASSERT(SUCCESS & assert_compare_output(
631 : : "--compare database1.db database2.db",
632 : : COMPLETED,
633 : : "templates/0028_000.txt",
634 : : NULL));
635 : :
636 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
637 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
638 : 2 : ASSERT(SUCCESS == restore_mutable_fixture("tests/fixtures/diffs/diff1"));
639 : :
640 : 2 : m_del(result);
641 : :
642 : 2 : RETURN_STATUS;
643 : : }
644 : :
645 : : /**
646 : : * Compare mode must support attached database paths containing apostrophes
647 : : */
648 : 2 : static Return test0028_10(void)
649 : : {
650 : 2 : INITTEST;
651 : :
652 : 2 : ASSERT(SUCCESS & prepare_compare_filter_equal_fixture());
653 : 2 : ASSERT(SUCCESS == move_path("database1.db","database'1.db"));
654 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
655 : :
656 : 2 : ASSERT(SUCCESS & assert_compare_output(
657 : : "--compare database\\'1.db database2.db",
658 : : COMPLETED,
659 : : "templates/0028_010_1.txt",
660 : : NULL));
661 : :
662 : 2 : ASSERT(SUCCESS == delete_path("database'1.db"));
663 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
664 : :
665 : 2 : RETURN_STATUS;
666 : : }
667 : :
668 : : /**
669 : : * Silent compare mode should print only compare results
670 : : */
671 : 2 : static Return test0028_11(void)
672 : : {
673 : : /* This function was reviewed line by line by a human and is not AI-generated
674 : : Any change to this function requires separate explicit approval */
675 : :
676 : 2 : INITTEST;
677 : :
678 : 2 : m_create(char,result,MEMORY_STRING);
679 : :
680 : 2 : ASSERT(SUCCESS & prepare_compare_filter_differences_fixture());
681 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
682 : :
683 : 2 : ASSERT(SUCCESS & assert_compare_output("--silent --compare database1.db database2.db",COMPLETED,"templates/0028_011_1.txt",NULL));
684 : 2 : ASSERT(SUCCESS & assert_compare_output("--silent --compare --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_011_2.txt",NULL));
685 : 2 : ASSERT(SUCCESS & assert_compare_output("--silent --compare --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_011_5.txt",NULL));
686 : 2 : ASSERT(SUCCESS & assert_compare_output("--silent --compare --compare-filter=checksum-mismatch database1.db database2.db",COMPLETED,"templates/0028_011_3.txt",NULL));
687 : 2 : ASSERT(SUCCESS & assert_compare_output("--silent --compare --compare-filter=first-source --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_011_4.txt",NULL));
688 : :
689 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_differences_fixture());
690 : :
691 : 2 : ASSERT(SUCCESS & prepare_compare_filter_equal_fixture());
692 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
693 : :
694 : 2 : ASSERT(SUCCESS == runit("--silent --compare database1.db database2.db",result,NULL,COMPLETED,ALLOW_BOTH));
695 : 2 : ASSERT(result->length == 0);
696 : :
697 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_equal_fixture());
698 : :
699 : 2 : m_del(result);
700 : :
701 : 2 : RETURN_STATUS;
702 : : }
703 : :
704 : : /**
705 : : * Compare mode must apply --ignore and --include to the reported compare scope
706 : : *
707 : : * Hidden paths are treated as out of scope for category listings, category
708 : : * summaries, and final equality messages. Paths restored with --include become
709 : : * visible again even when they also match an --ignore pattern
710 : : */
711 : 2 : static Return test0028_12(void)
712 : : {
713 : 2 : INITTEST;
714 : :
715 : 2 : ASSERT(SUCCESS & prepare_compare_filter_differences_fixture());
716 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
717 : :
718 : : // All three raw differences are filtered out, so the filtered compare scope is fully identical
719 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^1/AAA/ZAW/D/e/f/b_file\\.txt$\" --ignore=\"^2/AAA/BBB/CZC/.*$\" database1.db database2.db",COMPLETED,"templates/0028_012_1.txt",NULL));
720 : :
721 : : // Restore only the first-source path a.txt; the hidden checksum mismatch stays outside the reported scope
722 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^1/AAA/ZAW/D/e/f/b_file\\.txt$\" --ignore=\"^2/AAA/BBB/CZC/.*$\" --include=\"^2/AAA/BBB/CZC/a\\.txt$\" database1.db database2.db",COMPLETED,"templates/0028_012_2.txt",NULL));
723 : :
724 : : // Keep only the first-source path a.txt visible by filtering out the checksum mismatch and the opposite-side path
725 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^1/AAA/ZAW/D/e/f/b_file\\.txt$\" --ignore=\"^2/AAA/BBB/CZC/b\\.txt$\" database1.db database2.db",COMPLETED,"templates/0028_012_3.txt",NULL));
726 : :
727 : : // Hide only a.txt so the remaining reported scope still contains the opposite-side path and the checksum mismatch
728 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^2/AAA/BBB/CZC/a\\.txt$\" database1.db database2.db",COMPLETED,"templates/0028_012_4.txt",NULL));
729 : :
730 : : // Ignore everything, then restore only b.txt; the checksum mismatch remains intentionally out of scope
731 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^.*$\" --include=\"^2/AAA/BBB/CZC/b\\.txt$\" database1.db database2.db",COMPLETED,"templates/0028_012_5.txt",NULL));
732 : :
733 : : // Ignore the whole 2/ subtree, then restore both existence-side differences while the 1/ checksum mismatch remains visible
734 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^2/.*$\" --include=\"^2/AAA/BBB/CZC/a\\.txt$\" --include=\"^2/AAA/BBB/CZC/b\\.txt$\" database1.db database2.db",COMPLETED,"templates/0028_012_6.txt",NULL));
735 : :
736 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_differences_fixture());
737 : :
738 : 2 : RETURN_STATUS;
739 : : }
740 : :
741 : : /**
742 : : *
743 : : * Testing the --compare mode across different types of responses
744 : : *
745 : : */
746 : 2 : Return test0028(void)
747 : : {
748 : 2 : INITTEST;
749 : :
750 : 2 : TEST(test0028_1,"One file is removed, updated, and added at a time");
751 : 2 : TEST(test0028_2,"One file is removed. It should be reflected as a change in one of the databases");
752 : 2 : TEST(test0028_3,"One file is added. It should be reflected as a change in one of the databases");
753 : 2 : TEST(test0028_4,"One file is updated and its checksum should change");
754 : 2 : TEST(test0028_5,"Nothing changes. The databases should be equivalent");
755 : 2 : TEST(test0028_6,"All supported --compare-filter combinations should behave as expected");
756 : 2 : TEST(test0028_7,"Invalid --compare-filter value should fail with an argument parsing error");
757 : 2 : TEST(test0028_8,"NULL and non-NULL SHA512 values should be reported as mismatches");
758 : 2 : TEST(test0028_9,"NULL SHA512 created from fixture changes should be reported as a mismatch");
759 : 2 : TEST(test0028_10,"Compare mode should work with database names containing apostrophes");
760 : 2 : TEST(test0028_11,"Silent compare mode should print only compare results");
761 : 2 : TEST(test0028_12,"Compare mode should apply --ignore and --include to the reported comparison scope, including summaries and equality messages");
762 : :
763 : 2 : RETURN_STATUS;
764 : : }
|