1 #include "../test.h"
2 #include "../builders/build.h"
3 #include "../../src/alloc.h"
4 #include "../../src/bu.h"
5 #include "../../src/conf.h"
6 #include "../../src/conffile.h"
7 #include "../../src/cstat.h"
8 #include "../../src/fsops.h"
9 #include "../../src/lock.h"
10 #include "../../src/prepend.h"
11 #include "../../src/server/bu_get.h"
12 #include "../../src/server/protocol1/fdirs.h"
13 #include "../../src/server/sdirs.h"
14 #include "../../src/server/timestamp.h"
15 
16 #define BASE		"utest_bu_get"
17 
setup(void)18 static struct sdirs *setup(void)
19 {
20 	struct sdirs *sdirs;
21 	fail_unless(recursive_delete(BASE)==0);
22 	fail_unless((sdirs=sdirs_alloc())!=NULL);
23 	return sdirs;
24 }
25 
tear_down(struct sdirs ** sdirs)26 static void tear_down(struct sdirs **sdirs)
27 {
28 	sdirs_free(sdirs);
29 	fail_unless(recursive_delete(BASE)==0);
30 	alloc_check();
31 }
32 
do_sdirs_init(struct sdirs * sdirs,enum protocol protocol)33 static void do_sdirs_init(struct sdirs *sdirs, enum protocol protocol)
34 {
35 	fail_unless(!sdirs_init(sdirs, protocol,
36 		BASE, // directory
37 		"utestclient", // cname
38 		NULL, // client_lockdir
39 		"a_group", // dedup_group
40 		NULL // manual_delete
41 		));
42 }
43 
do_assert_bu_list(struct bu * bu_list,struct sd * s,unsigned int len)44 static void do_assert_bu_list(struct bu *bu_list,
45 	struct sd *s, unsigned int len)
46 {
47 	unsigned int count=0;
48 	struct bu *bu;
49 	struct bu *last;
50 
51 	bu=bu_list;
52 	last=NULL;
53 	for(count=0; count<len; count++)
54 	{
55 		fail_unless(bu!=NULL);
56 
57 		fail_unless(s[count].bno==bu->bno);
58 		fail_unless(s[count].index==bu->index);
59 		fail_unless(s[count].flags==bu->flags);
60 		ck_assert_str_eq(s[count].timestamp, bu->timestamp);
61 
62 		// Check reverse linkage.
63 		fail_unless(last==bu->prev);
64 
65 		last=bu;
66 		bu=bu->next;
67 	}
68 	fail_unless(len==count);
69 	fail_unless(bu==NULL);
70 }
71 
proto2_hack(struct sd * s,unsigned int len)72 static void proto2_hack(struct sd *s, unsigned int len)
73 {
74 	unsigned int count;
75 	for(count=0; count<len; count++)
76 	{
77 		// Protocol2 backups are never hardlinked, and are always
78 		// deletable.
79 		s[count].flags&=~BU_HARDLINKED;
80 		s[count].flags|=BU_DELETABLE;
81 	}
82 }
83 
assert_bu_list(struct sdirs * sdirs,struct sd * s,unsigned int len)84 void assert_bu_list(struct sdirs *sdirs, struct sd *s, unsigned int len)
85 {
86 	struct bu *bu_list=NULL;
87 	if(sdirs->protocol==PROTO_2)
88 		proto2_hack(s, len);
89 	fail_unless(!bu_get_list(sdirs, &bu_list));
90 	do_assert_bu_list(bu_list, s, len);
91 	bu_list_free(&bu_list);
92 }
93 
build_and_check(struct sd * s,int slen,struct sd * e,int elen,enum protocol protocol)94 static void build_and_check(struct sd *s, int slen,
95 	struct sd *e, int elen,
96 	enum protocol protocol)
97 {
98 	struct sdirs *sdirs=setup();
99 	do_sdirs_init(sdirs, protocol);
100 	build_storage_dirs(sdirs, s, slen);
101 	assert_bu_list(sdirs, e, elen);
102 	tear_down(&sdirs);
103 }
104 
105 static struct sd sd1[] = {
106 	{ "0000005 1970-01-05 00:00:00", 5, 1, BU_CURRENT|BU_DELETABLE }
107 };
108 
109 static struct sd sd2[] = {
110 	{ "0000001 1970-01-01 00:00:00", 1, 1, BU_DELETABLE },
111 	{ "0000005 1970-01-05 00:00:00", 5, 2, BU_CURRENT }
112 };
113 
114 static struct sd sd3[] = {
115 	{ "0000001 1970-01-01 00:00:00", 1, 1, BU_DELETABLE },
116 	{ "0000003 1970-01-03 00:00:00", 3, 2, 0 },
117 	{ "0000005 1970-01-05 00:00:00", 5, 3, BU_CURRENT }
118 };
119 
120 static struct sd sd4[] = {
121 	{ "0000001 1970-01-01 00:00:00", 1, 1, BU_DELETABLE },
122 	{ "0000002 1970-01-02 00:00:00", 2, 2, 0 },
123 	{ "0000003 1970-01-03 00:00:00", 3, 3, 0 },
124 	{ "0000004 1970-01-04 00:00:00", 4, 4, 0 },
125 	{ "0000005 1970-01-05 00:00:00", 5, 5, BU_CURRENT }
126 };
127 
128 static struct sd sd5[] = {
129 	{ "0000001 1970-01-01 00:00:00", 1, 1, BU_DELETABLE },
130 	{ "0000002 1970-01-02 00:00:00", 2, 2, 0 },
131 	{ "0000003 1970-01-03 00:00:00", 3, 3, BU_HARDLINKED },
132 	{ "0000004 1970-01-04 00:00:00", 4, 4, BU_DELETABLE },
133 	{ "0000005 1970-01-05 00:00:00", 5, 5, BU_CURRENT }
134 };
135 
136 static struct sd sd6[] = {
137 	{ "0000001 1970-01-01 00:00:00", 1, 1, BU_HARDLINKED|BU_DELETABLE },
138 	{ "0000002 1970-01-02 00:00:00", 2, 2, BU_HARDLINKED|BU_DELETABLE },
139 	{ "0000005 1970-01-05 00:00:00", 5, 3, BU_HARDLINKED|BU_DELETABLE|BU_CURRENT }
140 };
141 
142 static struct sd sd7[] = {
143 	{ "0000001 1970-01-01 00:00:00", 1,  1, BU_HARDLINKED|BU_DELETABLE },
144 	{ "0000005 1970-01-05 00:00:00", 5,  2, BU_HARDLINKED|BU_DELETABLE },
145 	{ "0000010 1970-01-10 00:00:00", 10, 3, BU_HARDLINKED|BU_DELETABLE },
146 	{ "0000020 1970-01-20 00:00:00", 20, 4, BU_DELETABLE },
147 	{ "0000021 1970-01-21 00:00:00", 21, 5, 0 },
148 	{ "0000022 1970-01-22 00:00:00", 22, 6, 0 },
149 	{ "0000023 1970-01-23 00:00:00", 23, 7, BU_CURRENT }
150 };
151 
152 static struct sd sd8[] = {
153 	{ "0000010 1970-01-01 00:00:00", 10, 1, BU_HARDLINKED|BU_DELETABLE },
154 	{ "0000015 1970-01-05 00:00:00", 15, 2, BU_HARDLINKED|BU_DELETABLE },
155 	{ "0000020 1970-01-10 00:00:00", 20, 3, BU_HARDLINKED|BU_DELETABLE },
156 	{ "0000030 1970-01-20 00:00:00", 30, 4, BU_DELETABLE },
157 	{ "0000031 1970-01-21 00:00:00", 31, 5, 0 },
158 	{ "0000032 1970-01-22 00:00:00", 32, 6, 0 },
159 	{ "0000033 1970-01-23 00:00:00", 33, 7, BU_CURRENT }
160 };
161 
162 static struct sd sd9[] = {
163 	{ "0000001 1970-01-01 00:00:00", 1, 1, BU_DELETABLE },
164 	{ "0000002 1970-01-02 00:00:00", 2, 2, 0 },
165 	{ "0000003 1970-01-03 00:00:00", 3, 3, 0 },
166 	{ "0000004 1970-01-04 00:00:00", 4, 4, 0 },
167 	{ "0000005 1970-01-05 00:00:00", 5, 5, BU_CURRENT },
168 	{ "0000006 1970-01-06 00:00:00", 6, 6, BU_WORKING }
169 };
170 
171 static struct sd sd10[] = {
172 	{ "0000001 1970-01-01 00:00:00", 1, 1, BU_DELETABLE },
173 	{ "0000002 1970-01-02 00:00:00", 2, 2, 0 },
174 	{ "0000003 1970-01-03 00:00:00", 3, 3, 0 },
175 	{ "0000004 1970-01-04 00:00:00", 4, 4, 0 },
176 	{ "0000005 1970-01-05 00:00:00", 5, 5, BU_CURRENT },
177 	{ "0000006 1970-01-06 00:00:00", 6, 6, BU_FINISHING }
178 };
179 
180 static struct sd sd11[] = {
181 	{ "0000005 1970-01-01 00:00:00", 5, 1, BU_DELETABLE|BU_MANIFEST },
182 	{ "0000006 1970-01-02 00:00:00", 6, 2, BU_MANIFEST },
183 	{ "0000007 1970-01-03 00:00:00", 7, 3, BU_MANIFEST },
184 	{ "0000008 1970-01-04 00:00:00", 8, 4, BU_MANIFEST },
185 	{ "0000009 1970-01-05 00:00:00", 9, 5, BU_MANIFEST|BU_CURRENT },
186 };
187 
188 static struct sd sd12[] = {
189 	{ "0000005 1970-01-01 00:00:00", 5, 1,
190 		BU_MANIFEST|BU_LOG_BACKUP|BU_DELETABLE },
191 	{ "0000006 1970-01-02 00:00:00", 6, 2,
192 		BU_MANIFEST|BU_LOG_BACKUP|BU_LOG_RESTORE },
193 	{ "0000007 1970-01-03 00:00:00", 7, 3,
194 		BU_MANIFEST|BU_LOG_BACKUP|BU_LOG_VERIFY|BU_LOG_RESTORE },
195 	{ "0000008 1970-01-04 00:00:00", 8, 4,
196 		BU_MANIFEST|BU_LOG_BACKUP },
197 	{ "0000009 1970-01-05 00:00:00", 9, 5,
198 		BU_MANIFEST|BU_LOG_BACKUP|BU_LOG_VERIFY|BU_CURRENT },
199 };
200 
build_and_check_same(struct sd * s,int len,enum protocol p)201 static void build_and_check_same(struct sd *s, int len, enum protocol p)
202 {
203 	build_and_check(s, len, s, len, p);
204 }
205 
do_tests(enum protocol p)206 static void do_tests(enum protocol p)
207 {
208 	build_and_check_same(sd1, ARR_LEN(sd1), p);
209 	build_and_check_same(sd2, ARR_LEN(sd2), p);
210 	build_and_check_same(sd3, ARR_LEN(sd3), p);
211 	build_and_check_same(sd4, ARR_LEN(sd4), p);
212 	build_and_check_same(sd5, ARR_LEN(sd5), p);
213 	build_and_check_same(sd6, ARR_LEN(sd6), p);
214 	build_and_check_same(sd7, ARR_LEN(sd7), p);
215 	build_and_check_same(sd8, ARR_LEN(sd8), p);
216 	// These two should not have working/finishing loaded.
217 	build_and_check(sd9, ARR_LEN(sd9), sd4, ARR_LEN(sd4), p);
218 	build_and_check(sd10, ARR_LEN(sd10), sd4, ARR_LEN(sd4), p);
219 	build_and_check_same(sd11, ARR_LEN(sd11), p);
220 	// This should not have the log stuff loaded.
221 	build_and_check(sd12, ARR_LEN(sd12), sd11, ARR_LEN(sd11), p);
222 }
223 
START_TEST(test_bu_get_proto_1)224 START_TEST(test_bu_get_proto_1)
225 {
226 	do_tests(PROTO_1);
227 }
228 END_TEST
229 
START_TEST(test_bu_get_proto_2)230 START_TEST(test_bu_get_proto_2)
231 {
232 	do_tests(PROTO_2);
233 }
234 END_TEST
235 
236 static enum run_status run_status=RUN_STATUS_IDLE;
237 static enum cntr_status cntr_status=CNTR_STATUS_UNSET;
238 
assert_bu_list_with_working(struct sdirs * sdirs,struct sd * s,unsigned int len)239 static void assert_bu_list_with_working(struct sdirs *sdirs,
240 	struct sd *s, unsigned int len)
241 {
242 	struct bu *bu_list=NULL;
243 	struct cntr cntr;
244 	if(sdirs->protocol==PROTO_2)
245 		proto2_hack(s, len);
246 	memset(&cntr, 0, sizeof(cntr));
247 	cntr.cntr_status=cntr_status;
248 	fail_unless(!bu_get_list_with_working(sdirs, &bu_list));
249 	do_assert_bu_list(bu_list, s, len);
250 	bu_list_free(&bu_list);
251 }
252 
253 static int compressed_logs=0;
254 
build_and_check_working(struct sd * s,int slen,struct sd * e,int elen,enum protocol protocol)255 static void build_and_check_working(struct sd *s, int slen,
256 	struct sd *e, int elen,
257 	enum protocol protocol)
258 {
259 	struct sdirs *sdirs=setup();
260 	do_sdirs_init(sdirs, protocol);
261 	if(compressed_logs)
262 		build_storage_dirs_compressed_logs(sdirs, s, slen);
263 	else
264 		build_storage_dirs(sdirs, s, slen);
265 	assert_bu_list_with_working(sdirs, e, elen);
266 	tear_down(&sdirs);
267 }
268 
build_and_check_working_same(struct sd * s,int len,enum protocol p)269 static void build_and_check_working_same(struct sd *s, int len, enum protocol p)
270 {
271 	build_and_check_working(s, len, s, len, p);
272 }
273 
do_tests_with_working(enum protocol p)274 static void do_tests_with_working(enum protocol p)
275 {
276 	build_and_check_working_same(sd1, ARR_LEN(sd1), p);
277 	build_and_check_working_same(sd2, ARR_LEN(sd2), p);
278 	build_and_check_working_same(sd3, ARR_LEN(sd3), p);
279 	build_and_check_working_same(sd4, ARR_LEN(sd4), p);
280 	build_and_check_working_same(sd5, ARR_LEN(sd5), p);
281 	build_and_check_working_same(sd6, ARR_LEN(sd6), p);
282 	build_and_check_working_same(sd7, ARR_LEN(sd7), p);
283 	build_and_check_working_same(sd8, ARR_LEN(sd8), p);
284 	build_and_check_working_same(sd9, ARR_LEN(sd9), p);
285 	build_and_check_working_same(sd10, ARR_LEN(sd10), p);
286 	build_and_check_working_same(sd11, ARR_LEN(sd11), p);
287 	build_and_check_working_same(sd12, ARR_LEN(sd12), p);
288 }
289 
START_TEST(test_bu_get_with_working_proto_1)290 START_TEST(test_bu_get_with_working_proto_1)
291 {
292 	run_status=RUN_STATUS_IDLE;
293 	cntr_status=CNTR_STATUS_UNSET;
294 	compressed_logs=0;
295 	do_tests_with_working(PROTO_1);
296 	compressed_logs=1;
297 	do_tests_with_working(PROTO_1);
298 }
299 END_TEST
300 
START_TEST(test_bu_get_with_working_proto_2)301 START_TEST(test_bu_get_with_working_proto_2)
302 {
303 	run_status=RUN_STATUS_IDLE;
304 	cntr_status=CNTR_STATUS_UNSET;
305 	compressed_logs=0;
306 	do_tests_with_working(PROTO_2);
307 	compressed_logs=1;
308 	do_tests_with_working(PROTO_2);
309 }
310 END_TEST
311 
312 static struct sd rn1[] = {
313 	{ "0000001 1970-01-01 00:00:00", 1, 1, BU_DELETABLE },
314 	{ "0000003 1970-01-03 00:00:00", 3, 2, },
315 	{ "0000005 1970-01-05 00:00:00", 5, 3, BU_CURRENT }
316 };
317 static struct sd rn2[] = {
318 	{ "0000001 1970-01-01 00:00:00", 1, 1, BU_DELETABLE },
319 	{ "0000003 1970-01-03 00:00:00", 3, 2, },
320 	{ "0000005 1970-01-05 00:00:00", 5, 3, BU_CURRENT }
321 };
322 static struct sd rn3[] = {
323 	{ "0000001 1970-01-01 00:00:00", 1, 1, BU_DELETABLE },
324 	{ "0000003 1970-01-03 00:00:00", 3, 2, },
325 	{ "0000005 1970-01-05 00:00:00", 5, 3, BU_CURRENT }
326 };
327 
do_tests_with_running(enum protocol p)328 static void do_tests_with_running(enum protocol p)
329 {
330 	run_status=RUN_STATUS_RUNNING;
331 	cntr_status=CNTR_STATUS_UNSET;
332 	build_and_check_working_same(sd3, ARR_LEN(sd3), p);
333 	cntr_status=CNTR_STATUS_SCANNING;
334 	build_and_check_working_same(rn1, ARR_LEN(rn1), p);
335 	cntr_status=CNTR_STATUS_RESTORING;
336 	build_and_check_working_same(rn2, ARR_LEN(rn2), p);
337 	cntr_status=CNTR_STATUS_VERIFYING;
338 	build_and_check_working_same(rn3, ARR_LEN(rn3), p);
339 }
340 
START_TEST(test_bu_get_with_running_proto_1)341 START_TEST(test_bu_get_with_running_proto_1)
342 {
343 	do_tests_with_running(PROTO_1);
344 }
345 END_TEST
346 
START_TEST(test_bu_get_with_running_proto_2)347 START_TEST(test_bu_get_with_running_proto_2)
348 {
349 	do_tests_with_running(PROTO_2);
350 }
351 END_TEST
352 
assert_bu_list_current(struct sdirs * sdirs,struct sd * s,unsigned int len)353 static void assert_bu_list_current(struct sdirs *sdirs,
354 	struct sd *s, unsigned int len)
355 {
356 	struct bu *bu_list=NULL;
357 	fail_unless(!bu_get_current(sdirs, &bu_list));
358 	do_assert_bu_list(bu_list, s, len);
359 	bu_list_free(&bu_list);
360 }
361 
build_and_check_current(struct sd * s,int slen,struct sd * e,int elen,enum protocol protocol)362 static void build_and_check_current(struct sd *s, int slen,
363 	struct sd *e, int elen,
364 	enum protocol protocol)
365 {
366 	struct sdirs *sdirs=setup();
367 	do_sdirs_init(sdirs, protocol);
368 	build_storage_dirs(sdirs, s, slen);
369 	assert_bu_list_current(sdirs, e, elen);
370 	tear_down(&sdirs);
371 }
372 
373 static struct sd c1[] = {
374 	{ "0000005 1970-01-05 00:00:00", 5, 0, BU_CURRENT }
375 };
376 
do_tests_current(enum protocol p)377 static void do_tests_current(enum protocol p)
378 {
379 	build_and_check_current(sd1, ARR_LEN(sd1), c1, ARR_LEN(c1), p);
380 	build_and_check_current(sd2, ARR_LEN(sd2), c1, ARR_LEN(c1), p);
381 	build_and_check_current(sd3, ARR_LEN(sd3), c1, ARR_LEN(c1), p);
382 	build_and_check_current(sd4, ARR_LEN(sd4), c1, ARR_LEN(c1), p);
383 }
384 
START_TEST(test_bu_get_current_proto_1)385 START_TEST(test_bu_get_current_proto_1)
386 {
387 	do_tests_current(PROTO_1);
388 }
389 END_TEST
390 
START_TEST(test_bu_get_current_proto_2)391 START_TEST(test_bu_get_current_proto_2)
392 {
393 	do_tests_current(PROTO_2);
394 }
395 END_TEST
396 
build_and_check_deleteme(struct sd * s,int slen,struct sd * e,int elen,enum protocol protocol)397 static void build_and_check_deleteme(struct sd *s, int slen,
398 	struct sd *e, int elen,
399 	enum protocol protocol)
400 {
401 	char backup[128]="";
402 	char renamed[128]="";
403 	struct sdirs *sdirs=setup();
404 	do_sdirs_init(sdirs, protocol);
405 	build_storage_dirs(sdirs, s, slen);
406 
407 	// Rename the first one.
408 	snprintf(backup, sizeof(backup),
409 		"%s/%s", sdirs->client, s[0].timestamp);
410 	fail_unless(!rename(backup, sdirs->deleteme));
411 	assert_bu_list(sdirs, e, elen);
412 
413 	// Do it again, renamed to something that looks like a timestamp.
414 	snprintf(renamed, sizeof(renamed), "%s/1010101 1970-01-05 00:00:00",
415 		sdirs->client);
416 	fail_unless(!rename(sdirs->deleteme, renamed));
417 	assert_bu_list(sdirs, e, elen);
418 
419 	tear_down(&sdirs);
420 }
421 
422 static struct sd dm1[] = {
423 	{ "0000003 1970-01-03 00:00:00", 3, 1, BU_DELETABLE },
424 	{ "0000005 1970-01-05 00:00:00", 5, 2, BU_CURRENT }
425 };
426 
do_tests_deleteme(enum protocol p)427 static void do_tests_deleteme(enum protocol p)
428 {
429 	build_and_check_deleteme(sd3, ARR_LEN(sd3), dm1, ARR_LEN(dm1), p);
430 }
431 
START_TEST(test_bu_get_deleteme_proto_1)432 START_TEST(test_bu_get_deleteme_proto_1)
433 {
434 	do_tests_deleteme(PROTO_1);
435 }
436 END_TEST
437 
START_TEST(test_bu_get_deleteme_proto_2)438 START_TEST(test_bu_get_deleteme_proto_2)
439 {
440 	do_tests_deleteme(PROTO_2);
441 }
442 END_TEST
443 
suite_server_bu_get(void)444 Suite *suite_server_bu_get(void)
445 {
446 	Suite *s;
447 	TCase *tc_core;
448 
449 	s=suite_create("server_bu_get");
450 
451 	tc_core=tcase_create("Core");
452 	tcase_set_timeout(tc_core, 60);
453 
454 	tcase_add_test(tc_core, test_bu_get_proto_1);
455 	tcase_add_test(tc_core, test_bu_get_proto_2);
456 	tcase_add_test(tc_core, test_bu_get_with_working_proto_1);
457 	tcase_add_test(tc_core, test_bu_get_with_working_proto_2);
458 	tcase_add_test(tc_core, test_bu_get_with_running_proto_1);
459 	tcase_add_test(tc_core, test_bu_get_with_running_proto_2);
460 	tcase_add_test(tc_core, test_bu_get_current_proto_1);
461 	tcase_add_test(tc_core, test_bu_get_current_proto_2);
462 	tcase_add_test(tc_core, test_bu_get_deleteme_proto_1);
463 	tcase_add_test(tc_core, test_bu_get_deleteme_proto_2);
464 	suite_add_tcase(s, tc_core);
465 
466 	return s;
467 }
468