1 #include "../../test.h"
2 #include "../../builders/build.h"
3 #include "../../builders/build_file.h"
4 #include "../../../src/alloc.h"
5 #include "../../../src/asfd.h"
6 #include "../../../src/bu.h"
7 #include "../../../src/conf.h"
8 #include "../../../src/conffile.h"
9 #include "../../../src/cstat.h"
10 #include "../../../src/fsops.h"
11 #include "../../../src/fzp.h"
12 #include "../../../src/handy.h"
13 #include "../../../src/iobuf.h"
14 #include "../../../src/prepend.h"
15 #include "../../../src/server/monitor/cstat.h"
16 #include "../../../src/server/monitor/json_output.h"
17 #include "../../../src/server/sdirs.h"
18
19 #define BASE "utest_server_monitor_json_output"
20 #define SDIRS BASE "_sdirs"
21 #define EXPECTED TOP_SRCDIR "/utest/json_output"
22 #define CONF_BASE "utest_server_monitor_json_output_conf"
23 #define CONFFILE CONF_BASE "/burp.conf"
24
25 static struct fzp *output=NULL;
26
setup_tz(void)27 static char *setup_tz(void)
28 {
29 char *tz;
30 if((tz=getenv("TZ")))
31 fail_unless((tz=strdup_w(tz, __func__))!=NULL);
32 setenv("TZ", "UTC-10", 1);
33 return tz;
34 }
35
tear_down_tz(char ** tz)36 static void tear_down_tz(char **tz)
37 {
38 if(tz && *tz)
39 {
40 setenv("TZ", *tz, 1);
41 free_w(tz);
42 }
43 else
44 unsetenv("TZ");
45 }
46
tear_down(struct asfd ** asfd,char ** tz)47 static void tear_down(struct asfd **asfd, char **tz)
48 {
49 asfd_free(asfd);
50 fail_unless(!fzp_close(&output));
51 fail_unless(!recursive_delete(CLIENTCONFDIR));
52 tear_down_tz(tz);
53 alloc_check();
54 }
55
my_asfd_write(struct asfd * asfd,struct iobuf * wbuf)56 static int my_asfd_write(struct asfd *asfd, struct iobuf *wbuf)
57 {
58 fail_unless(fzp_write(output, wbuf->buf, wbuf->len)==wbuf->len);
59 return 0;
60 }
61
asfd_setup(const char * outputpath)62 static struct asfd *asfd_setup(const char *outputpath)
63 {
64 struct asfd *asfd;
65 fail_unless((asfd=asfd_alloc())!=NULL);
66 fail_unless((asfd->rbuf=iobuf_alloc())!=NULL);
67 asfd->write=my_asfd_write;
68 fail_unless(!build_path_w(outputpath));
69 fail_unless((output=fzp_open(outputpath, "wb"))!=NULL);
70 json_set_pretty_print(1);
71 return asfd;
72 }
73
START_TEST(test_json_send_warn)74 START_TEST(test_json_send_warn)
75 {
76 char *tz;
77 struct asfd *asfd;
78 tz=setup_tz();
79 asfd=asfd_setup(BASE "/warning");
80 fail_unless(!json_send_warn(asfd, "this is my warning"));
81 tear_down(&asfd, &tz);
82 }
83 END_TEST
84
START_TEST(test_json_send_empty)85 START_TEST(test_json_send_empty)
86 {
87 char *tz;
88 struct asfd *asfd;
89 tz=setup_tz();
90 asfd=asfd_setup(BASE "/empty");
91 fail_unless(!json_send(asfd, NULL, NULL, NULL, NULL, NULL, 0/*cache*/,
92 version_to_long(VERSION)));
93 tear_down(&asfd, &tz);
94 }
95 END_TEST
96
setup_conf(void)97 static struct conf **setup_conf(void)
98 {
99 struct conf **confs=NULL;
100 fail_unless((confs=confs_alloc())!=NULL);
101 fail_unless(!confs_init(confs));
102 return confs;
103 }
104
START_TEST(test_json_send_clients)105 START_TEST(test_json_send_clients)
106 {
107 char *tz;
108 struct asfd *asfd;
109 struct cstat *c=NULL;
110 struct cstat *clist=NULL;
111 struct conf **monitor_cconfs=NULL;
112 struct conf **globalcs=NULL;
113 struct conf **cconfs=NULL;
114 const char *cnames[] ={"cli1", "cli2", "cli3", NULL};
115
116 tz=setup_tz();
117 monitor_cconfs=setup_conf();
118 globalcs=setup_conf();
119 cconfs=setup_conf();
120
121 build_file(CONFFILE, MIN_SERVER_CONF);
122 fail_unless(!conf_load_global_only(CONFFILE, monitor_cconfs));
123 fail_unless(!conf_load_global_only(CONFFILE, globalcs));
124
125 fail_unless(recursive_delete(CLIENTCONFDIR)==0);
126 build_clientconfdir_files(cnames, "label=abc\nlabel=xyz\n");
127 fail_unless(!cstat_load_data_from_disk(&clist, monitor_cconfs,
128 globalcs, cconfs));
129 assert_cstat_list(clist, cnames);
130 for(c=clist; c; c=c->next)
131 c->permitted=1;
132 asfd=asfd_setup(BASE "/clients");
133 fail_unless(!json_send(asfd, clist, NULL, NULL, NULL, NULL, 0/*cache*/,
134 version_to_long(VERSION)));
135 for(c=clist; c; c=c->next)
136 sdirs_free((struct sdirs **)&c->sdirs);
137 cstat_list_free(&clist);
138 confs_free(&monitor_cconfs);
139 confs_free(&globalcs);
140 confs_free(&cconfs);
141 tear_down(&asfd, &tz);
142 }
143 END_TEST
144
145 static struct sd sd1[] = {
146 { "0000001 1971-01-01 10:00:00 +1000", 1, 1, BU_DELETABLE|BU_CURRENT },
147 };
148
setup_sdirs(enum protocol protocol,const char * cname)149 static struct sdirs *setup_sdirs(enum protocol protocol, const char *cname)
150 {
151 struct sdirs *sdirs;
152 fail_unless((sdirs=sdirs_alloc())!=NULL);
153 fail_unless(!sdirs_init(sdirs, protocol,
154 SDIRS, // directory
155 cname, // cname
156 NULL, // client_lockdir
157 "a_group", // dedup_group
158 NULL // manual_delete
159 ));
160 return sdirs;
161 }
162
cstat_list_free_sdirs(struct cstat * clist)163 static void cstat_list_free_sdirs(struct cstat *clist)
164 {
165 struct cstat *c;
166 for(c=clist; c; c=c->next)
167 sdirs_free((struct sdirs **)&c->sdirs);
168 }
169
do_test_json_send_clients_with_backup(const char * path,struct sd * sd,int s,const char * specific_client)170 static void do_test_json_send_clients_with_backup(const char *path,
171 struct sd *sd, int s, const char *specific_client)
172 {
173 char *tz;
174 struct asfd *asfd;
175 struct cstat *c=NULL;
176 struct cstat *clist=NULL;
177 const char *cnames[] ={"cli1", "cli2", "cli3", NULL};
178 tz=setup_tz();
179 fail_unless(recursive_delete(CLIENTCONFDIR)==0);
180 build_clientconfdir_files(cnames, NULL);
181 fail_unless(!cstat_get_client_names(&clist, CLIENTCONFDIR));
182 assert_cstat_list(clist, cnames);
183 for(c=clist; c; c=c->next)
184 {
185 c->permitted=1;
186 c->protocol=PROTO_1;
187 fail_unless((c->sdirs=setup_sdirs(c->protocol, c->name))!=NULL);
188 build_storage_dirs((struct sdirs *)c->sdirs, sd, s);
189 fail_unless(!cstat_set_backup_list(c));
190 fail_unless(c->bu!=NULL);
191
192 }
193 asfd=asfd_setup(path);
194
195 c=NULL;
196 if(specific_client)
197 fail_unless((c=cstat_get_by_name(clist, specific_client))!=NULL);
198
199 fail_unless(!json_send(asfd, clist, c, NULL, NULL, NULL, 0/*cache*/,
200 version_to_long(VERSION)));
201 cstat_list_free_sdirs(clist);
202 cstat_list_free(&clist);
203 fail_unless(!recursive_delete(SDIRS));
204 tear_down(&asfd, &tz);
205 }
206
START_TEST(test_json_send_clients_with_backup)207 START_TEST(test_json_send_clients_with_backup)
208 {
209 do_test_json_send_clients_with_backup(
210 BASE "/clients_with_backup",
211 sd1, ARR_LEN(sd1), NULL);
212 }
213 END_TEST
214
215 static struct sd sd12345[] = {
216 { "0000001 1971-01-01 10:00:00 +1000", 1, 1, BU_DELETABLE|BU_MANIFEST },
217 { "0000002 1971-01-02 10:00:00 +1000", 2, 2, 0 },
218 { "0000003 1971-01-03 10:00:00 +1000", 3, 3, BU_HARDLINKED },
219 { "0000004 1971-01-04 10:00:00 +1000", 4, 4, BU_DELETABLE },
220 { "0000005 1971-01-05 10:00:00 +1000", 5, 5, BU_CURRENT|BU_MANIFEST }
221 };
222
START_TEST(test_json_send_clients_with_backups)223 START_TEST(test_json_send_clients_with_backups)
224 {
225 do_test_json_send_clients_with_backup(
226 BASE "/clients_with_backups",
227 sd12345, ARR_LEN(sd12345), NULL);
228 }
229 END_TEST
230
231 static struct sd sd123w[] = {
232 { "0000001 1971-01-01 10:00:00 +1000", 1, 1, BU_DELETABLE|BU_MANIFEST },
233 { "0000002 1971-01-02 10:00:00 +1000", 2, 2, BU_CURRENT|BU_MANIFEST },
234 { "0000003 1971-01-03 10:00:00 +1000", 3, 3, BU_WORKING },
235 };
236
START_TEST(test_json_send_clients_with_backups_working)237 START_TEST(test_json_send_clients_with_backups_working)
238 {
239 do_test_json_send_clients_with_backup(
240 BASE "/clients_with_backups_working",
241 sd123w, ARR_LEN(sd123w), NULL);
242 }
243 END_TEST
244
245 static struct sd sd123f[] = {
246 { "0000001 1971-01-01 10:00:00 +1000", 1, 1, BU_DELETABLE|BU_MANIFEST },
247 { "0000002 1971-01-02 10:00:00 +1000", 2, 2, BU_CURRENT|BU_MANIFEST },
248 { "0000003 1971-01-03 10:00:00 +1000", 3, 3, BU_FINISHING },
249 };
250
START_TEST(test_json_send_clients_with_backups_finishing)251 START_TEST(test_json_send_clients_with_backups_finishing)
252 {
253 do_test_json_send_clients_with_backup(
254 BASE "/clients_with_backups_finishing",
255 sd123f, ARR_LEN(sd123f), NULL);
256 }
257 END_TEST
258
START_TEST(test_json_send_client_specific)259 START_TEST(test_json_send_client_specific)
260 {
261 do_test_json_send_clients_with_backup(
262 BASE "/client_specific",
263 sd12345, ARR_LEN(sd12345), "cli2");
264 }
265 END_TEST
266
do_assert_files_equal(const char * opath,const char * npath,int compressed)267 static void do_assert_files_equal(const char *opath, const char *npath,
268 int compressed)
269 {
270 fail_unless(files_equal(opath, npath, compressed)==1);
271 }
272
assert_files_equal(const char * opath,const char * npath)273 void assert_files_equal(const char *opath, const char *npath)
274 {
275 return do_assert_files_equal(opath, npath, 0/*compressed*/);
276 }
277
assert_files_compressed_equal(const char * opath,const char * npath)278 void assert_files_compressed_equal(const char *opath, const char *npath)
279 {
280 return do_assert_files_equal(opath, npath, 1/*compressed*/);
281 }
282
START_TEST(test_json_matching_output)283 START_TEST(test_json_matching_output)
284 {
285 int i=0;
286 int n=0;
287 struct dirent **dir=NULL;
288 fail_unless((n=scandir(BASE, &dir, filter_dot, NULL))>0);
289 for(i=0; i<n; i++)
290 {
291 char *bpath;
292 char *epath;
293 fail_unless(
294 (bpath=prepend_s(BASE, dir[i]->d_name))!=NULL);
295 fail_unless(
296 (epath=prepend_s(EXPECTED, dir[i]->d_name))!=NULL);
297
298 assert_files_equal(bpath, epath);
299
300 free_w(&bpath);
301 free_w(&epath);
302 }
303 for(i=0; i<n; i++) free(dir[i]);
304 free(dir);
305 dir=NULL;
306
307 // Check that all the files in the expected directory also exist
308 // in the directory that we generated.
309 fail_unless((n=scandir(EXPECTED, &dir, filter_dot, NULL))>0);
310 for(i=0; i<n; i++)
311 {
312 char *bpath;
313 struct stat statp;
314 fail_unless(
315 (bpath=prepend_s(BASE, dir[i]->d_name))!=NULL);
316 fail_unless(!lstat(bpath, &statp));
317 fail_unless(S_ISREG(statp.st_mode));
318 free_w(&bpath);
319 }
320 for(i=0; i<n; i++) free(dir[i]);
321 free(dir);
322 dir=NULL;
323 alloc_check();
324 }
325 END_TEST
326
START_TEST(cleanup)327 START_TEST(cleanup)
328 {
329 // Not a test. Just wanted to cleanup before and after this suite.
330 fail_unless(!recursive_delete(BASE));
331 fail_unless(!recursive_delete(SDIRS));
332 fail_unless(!recursive_delete(CONF_BASE));
333 }
334 END_TEST
335
suite_server_monitor_json_output(void)336 Suite *suite_server_monitor_json_output(void)
337 {
338 Suite *s;
339 TCase *tc_core;
340
341 s=suite_create("server_monitor_json_output");
342
343 tc_core=tcase_create("Core");
344 tcase_set_timeout(tc_core, 5);
345
346 tcase_add_test(tc_core, cleanup);
347 tcase_add_test(tc_core, test_json_send_warn);
348 tcase_add_test(tc_core, test_json_send_empty);
349 tcase_add_test(tc_core, test_json_send_clients);
350 tcase_add_test(tc_core, test_json_send_clients_with_backup);
351 tcase_add_test(tc_core, test_json_send_clients_with_backups);
352 tcase_add_test(tc_core, test_json_send_clients_with_backups_finishing);
353 tcase_add_test(tc_core, test_json_send_clients_with_backups_working);
354 tcase_add_test(tc_core, test_json_send_client_specific);
355 tcase_add_test(tc_core, test_json_matching_output);
356 tcase_add_test(tc_core, cleanup);
357
358 suite_add_tcase(s, tc_core);
359
360 return s;
361 }
362