Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2017, Citrix Systems, Inc.
3 : : *
4 : : * All rights reserved.
5 : : *
6 : : * Redistribution and use in source and binary forms, with or without
7 : : * modification, are permitted provided that the following conditions are met:
8 : : *
9 : : * 1. Redistributions of source code must retain the above copyright
10 : : * notice, this list of conditions and the following disclaimer.
11 : : * 2. Redistributions in binary form must reproduce the above copyright
12 : : * notice, this list of conditions and the following disclaimer in the
13 : : * documentation and/or other materials provided with the distribution.
14 : : * 3. Neither the name of the copyright holder nor the names of its
15 : : * contributors may be used to endorse or promote products derived from
16 : : * this software without specific prior written permission.
17 : : *
18 : : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 : : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 : : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 : : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22 : : * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 : : * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 : : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 : : * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 : : * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 : : * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 : : * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 : : */
30 : :
31 : : #include <stdlib.h>
32 : : #include <string.h>
33 : : #include <stddef.h>
34 : : #include <stdarg.h>
35 : : #include <setjmp.h>
36 : : #include <cmocka.h>
37 : : #include <errno.h>
38 : :
39 : : #include <cbt-util-priv.h>
40 : : #include <wrappers.h>
41 : : #include "test-suites.h"
42 : :
43 : : /*
44 : : * Test failure when no parent parameter provided
45 : : */
46 : 1 : void test_cbt_util_coalesce_no_parent_failure(void **state)
47 : : {
48 : : int result;
49 : 1 : char* args[] = { "cbt-util", "coalesce", "-c", "test_child.log" };
50 : : struct printf_data *output;
51 : :
52 : 1 : output = setup_vprintf_mock(1024);
53 : :
54 : 1 : result = cbt_util_coalesce(4, args);
55 : 1 : assert_int_equal(result, -EINVAL);
56 : 1 : free_printf_data(output);
57 : 1 : }
58 : :
59 : : /*
60 : : * Test failure when no child parameter provided
61 : : */
62 : 1 : void test_cbt_util_coalesce_no_child_failure(void **state)
63 : : {
64 : : int result;
65 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log" };
66 : : struct printf_data *output;
67 : :
68 : 1 : output = setup_vprintf_mock(1024);
69 : :
70 : 1 : result = cbt_util_coalesce(4, args);
71 : 1 : assert_int_equal(result, -EINVAL);
72 : 1 : free_printf_data(output);
73 : 1 : }
74 : :
75 : : /*
76 : : * Test failure when parent log file doesn't exist
77 : : */
78 : 1 : void test_cbt_util_coalesce_no_parent_file_failure(void **state)
79 : : {
80 : : int result;
81 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
82 : :
83 : 1 : will_return(__wrap_fopen, NULL);
84 : :
85 : 1 : result = cbt_util_coalesce(6, args);
86 : :
87 : 1 : assert_int_equal(result, -ENOENT);
88 : 1 : }
89 : :
90 : : /*
91 : : * Test failure when child log file doesn't exist
92 : : */
93 : 1 : void test_cbt_util_coalesce_no_child_file_failure(void **state)
94 : : {
95 : : int result;
96 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
97 : :
98 : : void *log_meta;
99 : :
100 : 1 : log_meta = malloc(sizeof(struct cbt_log_metadata));
101 : 1 : FILE *parent_log = fmemopen((void*)log_meta,
102 : : sizeof(struct cbt_log_metadata), "r");
103 : :
104 : 1 : will_return(__wrap_fopen, parent_log);
105 : 1 : expect_value(__wrap_fclose, fp, parent_log);
106 : :
107 : 1 : will_return(__wrap_fopen, NULL);
108 : :
109 : 1 : result = cbt_util_coalesce(6, args);
110 : :
111 : 1 : assert_int_equal(result, -ENOENT);
112 : 1 : free(log_meta);
113 : 1 : }
114 : :
115 : : /*
116 : : * Test failure to malloc cbt_log_metadata structure for parent
117 : : */
118 : 1 : void test_cbt_util_coalesce_parent_log_malloc_failure(void **state)
119 : : {
120 : : int result;
121 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
122 : : void *log_meta[1];
123 : 1 : FILE *test_log = fmemopen((void*)log_meta, 1, "r");
124 : :
125 : 1 : will_return(__wrap_fopen, test_log);
126 : 1 : expect_value(__wrap_fclose, fp, test_log);
127 : :
128 : 1 : malloc_succeeds(false);
129 : :
130 : 1 : result = cbt_util_coalesce(6, args);
131 : 1 : assert_int_equal(result, -ENOMEM);
132 : :
133 : 1 : disable_malloc_mock();
134 : 1 : }
135 : :
136 : : /*
137 : : * Test failure to malloc cbt_log_metadata structure for child
138 : : */
139 : 1 : void test_cbt_util_coalesce_child_log_malloc_failure(void **state)
140 : : {
141 : : int result;
142 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
143 : :
144 : : void *log_meta;
145 : :
146 : 1 : log_meta = malloc(sizeof(struct cbt_log_metadata));
147 : 1 : FILE *parent_log = fmemopen((void*)log_meta,
148 : : sizeof(struct cbt_log_metadata), "r");
149 : 1 : FILE *child_log = fmemopen((void*)log_meta,
150 : : sizeof(struct cbt_log_metadata), "r");
151 : :
152 : 1 : will_return(__wrap_fopen, parent_log);
153 : 1 : expect_value(__wrap_fclose, fp, parent_log);
154 : :
155 : 1 : will_return(__wrap_fopen, child_log);
156 : 1 : expect_value(__wrap_fclose, fp, child_log);
157 : :
158 : 1 : malloc_succeeds(true);
159 : 1 : malloc_succeeds(false);
160 : :
161 : 1 : result = cbt_util_coalesce(6, args);
162 : :
163 : 1 : assert_int_equal(result, -ENOMEM);
164 : :
165 : 1 : disable_malloc_mock();
166 : 1 : free(log_meta);
167 : 1 : }
168 : :
169 : : /*
170 : : * Test failure to read log metadata for parent
171 : : */
172 : 1 : void test_cbt_util_coalesce_no_parent_meta_failure(void **state)
173 : : {
174 : : int result;
175 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
176 : : void *log_meta[1];
177 : :
178 : 1 : FILE *test_log = fmemopen((void*)log_meta, 1, "r");
179 : :
180 : 1 : will_return(__wrap_fopen, test_log);
181 : 1 : expect_value(__wrap_fclose, fp, test_log);
182 : :
183 : 1 : result = cbt_util_coalesce(6, args);
184 : 1 : assert_int_equal(result, -EIO);
185 : 1 : }
186 : :
187 : : /*
188 : : * Test failure to read log metadata for child
189 : : */
190 : 1 : void test_cbt_util_coalesce_no_child_meta_failure(void **state)
191 : : {
192 : : int result;
193 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
194 : : void *parent_meta;
195 : : void *child_meta[1];
196 : :
197 : 1 : parent_meta = malloc(sizeof(struct cbt_log_metadata));
198 : 1 : FILE *parent_log = fmemopen((void*)parent_meta,
199 : : sizeof(struct cbt_log_metadata), "r");
200 : 1 : FILE *child_log = fmemopen((void*)child_meta, 1, "r");
201 : :
202 : 1 : will_return(__wrap_fopen, parent_log);
203 : 1 : expect_value(__wrap_fclose, fp, parent_log);
204 : 1 : will_return(__wrap_fopen, child_log);
205 : 1 : expect_value(__wrap_fclose, fp, child_log);
206 : :
207 : 1 : result = cbt_util_coalesce(6, args);
208 : 1 : assert_int_equal(result, -EIO);
209 : :
210 : 1 : free(parent_meta);
211 : 1 : }
212 : :
213 : : /*
214 : : * Test failure when parent bitmap is larger than child bitmap
215 : : */
216 : 1 : void test_cbt_util_coalesce_larger_parent_bitmap_failure(void **state)
217 : : {
218 : : int result;
219 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
220 : : void *parent_meta;
221 : : void *child_meta;
222 : :
223 : 1 : parent_meta = malloc(sizeof(struct cbt_log_metadata));
224 : 1 : child_meta = malloc(sizeof(struct cbt_log_metadata));
225 : :
226 : 1 : ((struct cbt_log_metadata *)parent_meta)->size = 1310720;
227 : 1 : ((struct cbt_log_metadata *)child_meta)->size = 655360;
228 : :
229 : 1 : FILE *parent_log = fmemopen((void*)parent_meta,
230 : : sizeof(struct cbt_log_metadata), "r");
231 : 1 : FILE *child_log = fmemopen((void*)child_meta,
232 : : sizeof(struct cbt_log_metadata), "r");
233 : :
234 : 1 : will_return(__wrap_fopen, parent_log);
235 : 1 : expect_value(__wrap_fclose, fp, parent_log);
236 : 1 : will_return(__wrap_fopen, child_log);
237 : 1 : expect_value(__wrap_fclose, fp, child_log);
238 : :
239 : 1 : result = cbt_util_coalesce(6, args);
240 : 1 : assert_int_equal(result, -EINVAL);
241 : :
242 : 1 : free(parent_meta);
243 : 1 : free(child_meta);
244 : 1 : }
245 : :
246 : : /*
247 : : * Test failure to allocate bitmap buffer for parent
248 : : */
249 : 1 : void test_cbt_util_coalesce_parent_bitmap_malloc_failure(void **state)
250 : : {
251 : : int result;
252 : : int file_size;
253 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
254 : : void *log_meta;
255 : :
256 : 1 : file_size = 4194304 + sizeof(struct cbt_log_metadata);
257 : 1 : log_meta = malloc(file_size);
258 : 1 : FILE *parent_log = fmemopen((void*)log_meta, file_size, "r");
259 : 1 : FILE *child_log = fmemopen((void*)log_meta, file_size, "r+");
260 : :
261 : 1 : will_return(__wrap_fopen, parent_log);
262 : 1 : expect_value(__wrap_fclose, fp, parent_log);
263 : 1 : will_return(__wrap_fopen, child_log);
264 : 1 : expect_value(__wrap_fclose, fp, child_log);
265 : :
266 : 1 : malloc_succeeds(true);
267 : 1 : malloc_succeeds(true);
268 : 1 : malloc_succeeds(false);
269 : :
270 : 1 : result = cbt_util_coalesce(6, args);
271 : 1 : assert_int_equal(result, -ENOMEM);
272 : :
273 : 1 : disable_malloc_mock();
274 : 1 : free(log_meta);
275 : 1 : }
276 : :
277 : : /*
278 : : * Test failure to allocate bitmap buffer for child
279 : : */
280 : 1 : void test_cbt_util_coalesce_child_bitmap_malloc_failure(void **state)
281 : : {
282 : : int result;
283 : : uint64_t disk_size, file_size;
284 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
285 : : void *log_meta;
286 : :
287 : 1 : disk_size = 2199023255552; //2TB
288 : 1 : file_size = bitmap_size(disk_size) + sizeof(struct cbt_log_metadata);
289 : 1 : log_meta = malloc(file_size);
290 : 1 : ((struct cbt_log_metadata*)log_meta)->size = disk_size;
291 : 1 : FILE *parent_log = fmemopen((void*)log_meta, file_size, "r");
292 : 1 : FILE *child_log = fmemopen((void*)log_meta, file_size, "r+");
293 : :
294 : 1 : will_return(__wrap_fopen, parent_log);
295 : 1 : expect_value(__wrap_fclose, fp, parent_log);
296 : 1 : will_return(__wrap_fopen, child_log);
297 : 1 : expect_value(__wrap_fclose, fp, child_log);
298 : :
299 : 1 : malloc_succeeds(true);
300 : 1 : malloc_succeeds(true);
301 : 1 : malloc_succeeds(true);
302 : 1 : malloc_succeeds(false);
303 : :
304 : 1 : result = cbt_util_coalesce(6, args);
305 : 1 : assert_int_equal(result, -ENOMEM);
306 : :
307 : 1 : disable_malloc_mock();
308 : 1 : free(log_meta);
309 : 1 : }
310 : :
311 : : /*
312 : : * Test failure to read bitmap from parent log file
313 : : */
314 : 1 : void test_cbt_util_coalesce_parent_no_bitmap_data_failure(void **state)
315 : : {
316 : : int result;
317 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
318 : : void *log_meta;
319 : :
320 : 1 : log_meta = malloc(sizeof(struct cbt_log_metadata));
321 : : //Intialise size in metadata file
322 : 1 : ((struct cbt_log_metadata*)log_meta)->size = 2199023255552; //2TB
323 : 1 : FILE *parent_log = fmemopen((void*)log_meta,
324 : : sizeof(struct cbt_log_metadata), "r");
325 : 1 : FILE *child_log = fmemopen((void*)log_meta,
326 : : sizeof(struct cbt_log_metadata), "r+");
327 : :
328 : 1 : will_return(__wrap_fopen, parent_log);
329 : 1 : expect_value(__wrap_fclose, fp, parent_log);
330 : 1 : will_return(__wrap_fopen, child_log);
331 : 1 : expect_value(__wrap_fclose, fp, child_log);
332 : :
333 : 1 : result = cbt_util_coalesce(6, args);
334 : 1 : assert_int_equal(result, -EIO);
335 : :
336 : 1 : free(log_meta);
337 : 1 : }
338 : :
339 : : /*
340 : : * Test failure to read bitmap from child log file
341 : : */
342 : 1 : void test_cbt_util_coalesce_child_no_bitmap_data_failure(void **state)
343 : : {
344 : : int result;
345 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
346 : : void *parent_meta;
347 : : void *child_meta;
348 : : uint64_t disk_size, file_size;
349 : :
350 : 1 : disk_size = 2199023255552; //2TB
351 : 1 : file_size = bitmap_size(disk_size) + sizeof(struct cbt_log_metadata);
352 : :
353 : 1 : parent_meta = malloc(file_size);
354 : 1 : child_meta = malloc(sizeof(struct cbt_log_metadata));
355 : : //Intialise size in metadata file
356 : 1 : ((struct cbt_log_metadata*)parent_meta)->size = disk_size;
357 : 1 : ((struct cbt_log_metadata*)child_meta)->size = disk_size;
358 : 1 : FILE *parent_log = fmemopen((void*)parent_meta, file_size, "r");
359 : 1 : FILE *child_log = fmemopen((void*)child_meta,
360 : : sizeof(struct cbt_log_metadata), "r+");
361 : :
362 : 1 : will_return(__wrap_fopen, parent_log);
363 : 1 : expect_value(__wrap_fclose, fp, parent_log);
364 : 1 : will_return(__wrap_fopen, child_log);
365 : 1 : expect_value(__wrap_fclose, fp, child_log);
366 : :
367 : 1 : result = cbt_util_coalesce(6, args);
368 : 1 : assert_int_equal(result, -EIO);
369 : :
370 : 1 : free(parent_meta);
371 : 1 : free(child_meta);
372 : 1 : }
373 : :
374 : : /*
375 : : * Test successful coalesce
376 : : */
377 : 1 : void test_cbt_util_coalesce_success(void **state)
378 : : {
379 : : int result;
380 : : int file_size;
381 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
382 : : void *parent_data;
383 : : void *child_data;
384 : : struct fwrite_data *output;
385 : 1 : uint64_t size = 4194304;
386 : :
387 : 1 : uint64_t bmsize = bitmap_size(size);
388 : 1 : file_size = sizeof(struct cbt_log_metadata) + bmsize;
389 : 1 : parent_data = malloc(file_size);
390 : 1 : child_data = malloc(file_size);
391 : :
392 : : //Intialise size in metadata file
393 : 1 : ((struct cbt_log_metadata*)parent_data)->size = size;
394 : : //Fill bitmap with random bytes
395 : 1 : memcpy(parent_data + sizeof(struct cbt_log_metadata), (void*)memcpy, bmsize );
396 : 1 : FILE *parent_log = fmemopen((void*)parent_data, file_size, "r");
397 : :
398 : : //Intialise size in metadata file
399 : 1 : ((struct cbt_log_metadata*)child_data)->size = size;
400 : : //Fill bitmap with random bytes
401 : 1 : memcpy(child_data + sizeof(struct cbt_log_metadata), (void*)memcpy, bmsize );
402 : 1 : FILE *child_log = fmemopen((void*)child_data, file_size, "r");
403 : :
404 : 1 : will_return(__wrap_fopen, parent_log);
405 : 1 : expect_value(__wrap_fclose, fp, parent_log);
406 : 1 : will_return(__wrap_fopen, child_log);
407 : 1 : expect_value(__wrap_fclose, fp, child_log);
408 : 1 : enable_mock_fwrite();
409 : 1 : output = setup_fwrite_mock(bmsize);
410 : :
411 : 1 : result = cbt_util_coalesce(6, args);
412 : : // OR the contents of bitmap of both files
413 : : *((char *)child_data + sizeof(struct cbt_log_metadata))
414 : 1 : |= *((char *)parent_data + sizeof(struct cbt_log_metadata));
415 : 1 : assert_int_equal(result, 0);
416 : 1 : assert_memory_equal(output->buf,
417 : : child_data + sizeof(struct cbt_log_metadata), bmsize);
418 : :
419 : 1 : free_fwrite_data(output);
420 : 1 : free(parent_data);
421 : 1 : free(child_data);
422 : 1 : }
423 : :
424 : : /*
425 : : * Test failure to set file pointer to start of bitmap area
426 : : */
427 : 1 : void test_cbt_util_coalesce_set_file_pointer_failure(void **state)
428 : : {
429 : : int result;
430 : : int file_size;
431 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
432 : : void *parent_data;
433 : : void *child_data;
434 : 1 : uint64_t size = 4194304;
435 : :
436 : 1 : uint64_t bmsize = bitmap_size(size);
437 : 1 : file_size = sizeof(struct cbt_log_metadata) + bmsize;
438 : 1 : parent_data = malloc(file_size);
439 : 1 : child_data = malloc(file_size);
440 : :
441 : : //Intialise size in metadata file
442 : 1 : ((struct cbt_log_metadata*)parent_data)->size = size;
443 : : //Fill bitmap with random bytes
444 : 1 : memcpy(parent_data + sizeof(struct cbt_log_metadata), (void*)memcpy, bmsize );
445 : 1 : FILE *parent_log = fmemopen((void*)parent_data, file_size, "w+");
446 : :
447 : : //Intialise size in metadata file
448 : 1 : ((struct cbt_log_metadata*)child_data)->size = size;
449 : : //Fill bitmap with random bytes
450 : 1 : memcpy(child_data + sizeof(struct cbt_log_metadata), (void*)memcpy, bmsize );
451 : 1 : FILE *child_log = fmemopen((void*)child_data, file_size, "w+");
452 : :
453 : 1 : will_return(__wrap_fopen, parent_log);
454 : 1 : expect_value(__wrap_fclose, fp, parent_log);
455 : 1 : will_return(__wrap_fopen, child_log);
456 : 1 : expect_value(__wrap_fclose, fp, child_log);
457 : :
458 : 1 : fail_fseek(EIO);
459 : :
460 : 1 : result = cbt_util_coalesce(6, args);
461 : 1 : assert_int_equal(result, -EIO);
462 : :
463 : 1 : free(parent_data);
464 : 1 : free(child_data);
465 : 1 : }
466 : :
467 : : /*
468 : : * Test failure to write bitmap to log file
469 : : */
470 : 1 : void test_cbt_util_coalesce_write_bitmap_failure(void **state)
471 : : {
472 : : int result;
473 : : int file_size;
474 : 1 : char* args[] = { "cbt-util", "coalesce", "-p", "test_parent.log", "-c" , "test_child.log"};
475 : : void *parent_data;
476 : : void *child_data;
477 : 1 : uint64_t size = 4194304;
478 : :
479 : 1 : uint64_t bmsize = bitmap_size(size);
480 : 1 : file_size = sizeof(struct cbt_log_metadata) + bmsize;
481 : 1 : parent_data = malloc(file_size);
482 : 1 : child_data = malloc(file_size);
483 : :
484 : : //Intialise size in metadata file
485 : 1 : ((struct cbt_log_metadata*)parent_data)->size = size;
486 : : //Fill bitmap with random bytes
487 : 1 : memcpy(parent_data + sizeof(struct cbt_log_metadata), (void*)memcpy, bmsize );
488 : 1 : FILE *parent_log = fmemopen((void*)parent_data, file_size, "r");
489 : :
490 : : //Intialise size in metadata file
491 : 1 : ((struct cbt_log_metadata*)child_data)->size = size;
492 : : //Fill bitmap with random bytes
493 : 1 : memcpy(child_data + sizeof(struct cbt_log_metadata), (void*)memcpy, bmsize );
494 : 1 : FILE *child_log = fmemopen((void*)child_data, file_size, "r");
495 : :
496 : 1 : will_return(__wrap_fopen, parent_log);
497 : 1 : expect_value(__wrap_fclose, fp, parent_log);
498 : 1 : will_return(__wrap_fopen, child_log);
499 : 1 : expect_value(__wrap_fclose, fp, child_log);
500 : :
501 : 1 : result = cbt_util_coalesce(6, args);
502 : 1 : assert_int_equal(result, -EIO);
503 : :
504 : 1 : free(parent_data);
505 : 1 : free(child_data);
506 : 1 : }
|