1 #include "../test.h"
2 #include "../../src/alloc.h"
3 #include "../../src/asfd.h"
4 #include "../../src/async.h"
5 #include "../../src/conf.h"
6 #include "../../src/fsops.h"
7 #include "../../src/iobuf.h"
8 #include "../../src/sbuf.h"
9 #include "../../src/server/extra_comms.h"
10 #include "../../src/strlist.h"
11 #include "../builders/build.h"
12 #include "../builders/build_file.h"
13 #include "../builders/build_asfd_mock.h"
14
15 #define BASE "utest_server_extra_comms"
16 #define TESTCLIENT "testclient"
17 #define SPOOL BASE "/spool"
18 #define SRESTORE_FILE SPOOL "/testclient/restore"
19 #define SRESTORE_FILE_CLI2 SPOOL "/cli2/restore"
20
21 static struct ioevent_list reads;
22 static struct ioevent_list writes;
23
setup_conf(void)24 static struct conf **setup_conf(void)
25 {
26 struct conf **confs=NULL;
27 fail_unless((confs=confs_alloc())!=NULL);
28 fail_unless(!confs_init(confs));
29 return confs;
30 }
31
setup_async(void)32 static struct async *setup_async(void)
33 {
34 struct async *as;
35 fail_unless((as=async_alloc())!=NULL);
36 as->init(as, 0 /* estimate */);
37 return as;
38 }
39
clean(void)40 static void clean(void)
41 {
42 fail_unless(!recursive_delete(BASE));
43 fail_unless(!recursive_delete(CLIENTCONFDIR));
44 }
45
setup(struct async ** as,struct conf *** confs,struct conf *** cconfs)46 static void setup(struct async **as,
47 struct conf ***confs, struct conf ***cconfs)
48 {
49 clean();
50 if(as) *as=setup_async();
51 if(confs) *confs=setup_conf();
52 if(cconfs) *cconfs=setup_conf();
53 }
54
tear_down(struct async ** as,struct asfd ** asfd,struct conf *** confs,struct conf *** cconfs)55 static void tear_down(struct async **as, struct asfd **asfd,
56 struct conf ***confs, struct conf ***cconfs)
57 {
58 async_free(as);
59 asfd_free(asfd);
60 asfd_mock_teardown(&reads, &writes);
61 confs_free(confs);
62 confs_free(cconfs);
63 clean();
64 alloc_check();
65 }
66
async_rw_simple(struct async * as)67 static int async_rw_simple(struct async *as)
68 {
69 return as->asfd->read(as->asfd);
70 }
71
run_test(int expected_ret,void setup_callback (struct asfd * asfd,struct conf ** confs,struct conf ** cconfs),void checks_callback (struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore))72 static void run_test(int expected_ret,
73 void setup_callback(struct asfd *asfd,
74 struct conf **confs, struct conf **cconfs),
75 void checks_callback(struct conf **confs, struct conf **cconfs,
76 const char *incexc, int srestore))
77 {
78 struct async *as;
79 struct asfd *asfd;
80 struct conf **confs;
81 struct conf **cconfs;
82 char *incexc=NULL;
83 int srestore=0;
84
85 setup(&as, &confs, &cconfs);
86 asfd=asfd_mock_setup(&reads, &writes);
87 as->asfd_add(as, asfd);
88 as->read_write=async_rw_simple;
89 asfd->as=as;
90
91 setup_callback(asfd, confs, cconfs);
92
93 fail_unless(extra_comms(
94 as,
95 &incexc,
96 &srestore,
97 confs,
98 cconfs
99 )==expected_ret);
100
101 if(checks_callback)
102 checks_callback(confs, cconfs, incexc, srestore);
103
104 free_w(&incexc);
105 tear_down(&as, &asfd, &confs, &cconfs);
106 }
107
setup_no_version(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)108 static void setup_no_version(struct asfd *asfd,
109 struct conf **confs, struct conf **cconfs)
110 {
111 }
112
setup_old_version(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)113 static void setup_old_version(struct asfd *asfd,
114 struct conf **confs, struct conf **cconfs)
115 {
116 set_string(cconfs[OPT_PEER_VERSION], "1.2.0");
117 }
118
setup_unexpected_first_string(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)119 static void setup_unexpected_first_string(struct asfd *asfd,
120 struct conf **confs, struct conf **cconfs)
121 {
122 int r=0;
123 set_string(cconfs[OPT_PEER_VERSION], "1.4.40");
124 asfd_mock_read(asfd, &r, 0, CMD_GEN, "blah");
125 }
126
setup_1_3_0_write_problem(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)127 static void setup_1_3_0_write_problem(struct asfd *asfd,
128 struct conf **confs, struct conf **cconfs)
129 {
130 int r=0; int w=0;
131 set_string(cconfs[OPT_PEER_VERSION], "1.3.0");
132 asfd_mock_read(asfd, &r, 0, CMD_GEN, "extra_comms_begin");
133 asfd_assert_write(asfd, &w, -1, CMD_GEN, "extra_comms_begin ok");
134 }
135
common_confs(struct conf ** cconfs,const char * version,enum protocol protocol)136 static void common_confs(struct conf **cconfs, const char *version,
137 enum protocol protocol)
138 {
139 set_string(cconfs[OPT_PEER_VERSION], version);
140 set_string(cconfs[OPT_DIRECTORY], BASE "/spool");
141 set_string(cconfs[OPT_CNAME], TESTCLIENT);
142 set_string(cconfs[OPT_DEDUP_GROUP], "global");
143 set_protocol(cconfs, protocol);
144 }
145
get_features(enum protocol protocol,int srestore,const char * version)146 static const char *get_features(enum protocol protocol, int srestore,
147 const char *version)
148 {
149 char proto[32]="";
150 char rshash[32]="";
151 int old_version=0;
152 static char features[256]="";
153
154 #ifdef HAVE_BLAKE2
155 snprintf(rshash, sizeof(rshash), "rshash=blake2:");
156 #endif
157 if(protocol==PROTO_AUTO)
158 snprintf(proto, sizeof(proto), "csetproto:");
159 else
160 snprintf(proto, sizeof(proto), "forceproto=%d:",
161 (int)protocol);
162
163 if(version && !strcmp(version, "1.4.40"))
164 old_version=1;
165
166 snprintf(features, sizeof(features), "extra_comms_begin ok:autoupgrade:incexc:orig_client:uname:failover:vss_restore:regex_icase:%s%smsg:%s%sseed:", srestore?"srestore:":"", old_version?"":"counters_json:", proto, rshash);
167 return features;
168 }
169
setup_feature_write_problem(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)170 static void setup_feature_write_problem(struct asfd *asfd,
171 struct conf **confs, struct conf **cconfs)
172 {
173 int r=0; int w=0;
174 const char *features;
175 enum protocol protocol=PROTO_AUTO;
176 common_confs(cconfs, PACKAGE_VERSION, protocol);
177 asfd_mock_read(asfd, &r, 0, CMD_GEN, "extra_comms_begin");
178 features=get_features(protocol, /*srestore*/0, NULL/*version*/);
179 asfd_assert_write(asfd, &w, -1, CMD_GEN, features);
180 }
181
setup_send_features_proto_begin(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs,enum protocol protocol,int * r,int * w,const char * version,int srestore)182 static void setup_send_features_proto_begin(struct asfd *asfd,
183 struct conf **confs, struct conf **cconfs, enum protocol protocol,
184 int *r, int *w, const char *version, int srestore)
185 {
186 const char *features=NULL;
187 common_confs(cconfs, version, protocol);
188 asfd_mock_read(asfd, r, 0, CMD_GEN, "extra_comms_begin");
189 features=get_features(protocol, srestore, version);
190 asfd_assert_write(asfd, w, 0, CMD_GEN, features);
191 }
192
setup_send_features_proto_end(struct asfd * asfd,int * r,int * w)193 static void setup_send_features_proto_end(struct asfd *asfd, int *r, int *w)
194 {
195 asfd_mock_read(asfd, r, 0, CMD_GEN, "extra_comms_end");
196 asfd_assert_write(asfd, w, 0, CMD_GEN, "extra_comms_end ok");
197 }
198
setup_send_features_proto(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs,enum protocol protocol,const char * version)199 static void setup_send_features_proto(struct asfd *asfd,
200 struct conf **confs, struct conf **cconfs, enum protocol protocol,
201 const char *version)
202 {
203 int r=0; int w=0;
204 setup_send_features_proto_begin(asfd, confs, cconfs, protocol, &r, &w,
205 version, /*srestore*/0);
206 setup_send_features_proto_end(asfd, &r, &w);
207 }
208
setup_send_features_proto_auto(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)209 static void setup_send_features_proto_auto(struct asfd *asfd,
210 struct conf **confs, struct conf **cconfs)
211 {
212 setup_send_features_proto(asfd, confs, cconfs, PROTO_AUTO, PACKAGE_VERSION);
213 }
214
setup_send_features_proto_auto_old_client(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)215 static void setup_send_features_proto_auto_old_client(struct asfd *asfd,
216 struct conf **confs, struct conf **cconfs)
217 {
218 setup_send_features_proto(asfd, confs, cconfs, PROTO_AUTO, "1.4.40");
219 }
220
setup_send_features_proto1(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)221 static void setup_send_features_proto1(struct asfd *asfd,
222 struct conf **confs, struct conf **cconfs)
223 {
224 setup_send_features_proto(asfd, confs, cconfs, PROTO_1, PACKAGE_VERSION);
225 }
226
setup_send_features_proto1_old_client(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)227 static void setup_send_features_proto1_old_client(struct asfd *asfd,
228 struct conf **confs, struct conf **cconfs)
229 {
230 setup_send_features_proto(asfd, confs, cconfs, PROTO_1, "1.4.40");
231 }
232
setup_send_features_proto2(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)233 static void setup_send_features_proto2(struct asfd *asfd,
234 struct conf **confs, struct conf **cconfs)
235 {
236 setup_send_features_proto(asfd, confs, cconfs, PROTO_2, PACKAGE_VERSION);
237 }
238
setup_send_features_proto2_old_client(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)239 static void setup_send_features_proto2_old_client(struct asfd *asfd,
240 struct conf **confs, struct conf **cconfs)
241 {
242 setup_send_features_proto(asfd, confs, cconfs, PROTO_2, "1.4.40");
243 }
244
setup_send_features_proto_auto_auto(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)245 static void setup_send_features_proto_auto_auto(struct asfd *asfd,
246 struct conf **confs, struct conf **cconfs)
247 {
248 int r=0; int w=0;
249 setup_send_features_proto_begin(asfd, confs, cconfs,
250 PROTO_AUTO, &r, &w, PACKAGE_VERSION, /*srestore*/0);
251 asfd_mock_read(asfd, &r, 0, CMD_GEN, "protocol=0");
252 asfd_assert_write(asfd, &w, 0, CMD_ERROR,
253 "Client is trying to use protocol=0, which is unknown\n");
254 }
255
setup_send_features_proto_proto(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs,const char * version,enum protocol protocol_server,enum protocol protocol_client)256 static void setup_send_features_proto_proto(struct asfd *asfd,
257 struct conf **confs, struct conf **cconfs, const char *version,
258 enum protocol protocol_server, enum protocol protocol_client)
259 {
260 int r=0; int w=0;
261 char cprotocol[16]="";
262 snprintf(cprotocol, sizeof(cprotocol),
263 "protocol=%d", (int)protocol_client);
264 setup_send_features_proto_begin(asfd, confs, cconfs,
265 protocol_server, &r, &w, version, /*srestore*/0);
266 asfd_mock_read(asfd, &r, 0, CMD_GEN, cprotocol);
267 setup_send_features_proto_end(asfd, &r, &w);
268 }
269
setup_send_features_proto_auto_1(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)270 static void setup_send_features_proto_auto_1(struct asfd *asfd,
271 struct conf **confs, struct conf **cconfs)
272 {
273 setup_send_features_proto_proto(asfd, confs, cconfs, PACKAGE_VERSION,
274 PROTO_AUTO, PROTO_1);
275 }
276
setup_send_features_proto_auto_1_old_client(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)277 static void setup_send_features_proto_auto_1_old_client(struct asfd *asfd,
278 struct conf **confs, struct conf **cconfs)
279 {
280 setup_send_features_proto_proto(asfd, confs, cconfs, "1.4.40",
281 PROTO_AUTO, PROTO_1);
282 }
283
setup_send_features_proto_auto_2(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)284 static void setup_send_features_proto_auto_2(struct asfd *asfd,
285 struct conf **confs, struct conf **cconfs)
286 {
287 setup_send_features_proto_proto(asfd, confs, cconfs, PACKAGE_VERSION,
288 PROTO_AUTO, PROTO_2);
289 }
290
setup_send_features_proto_auto_2_old_client(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)291 static void setup_send_features_proto_auto_2_old_client(struct asfd *asfd,
292 struct conf **confs, struct conf **cconfs)
293 {
294 setup_send_features_proto_proto(asfd, confs, cconfs, "1.4.40",
295 PROTO_AUTO, PROTO_2);
296 }
297
setup_send_features_proto_x_y(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs,enum protocol s_protocol,enum protocol c_protocol)298 static void setup_send_features_proto_x_y(struct asfd *asfd,
299 struct conf **confs, struct conf **cconfs,
300 enum protocol s_protocol, enum protocol c_protocol)
301 {
302 int r=0; int w=0;
303 char msg[256]="";
304 char cliproto[16]="";
305 snprintf(cliproto, sizeof(cliproto), "protocol=%d", (int)c_protocol);
306 setup_send_features_proto_begin(asfd, confs, cconfs,
307 s_protocol, &r, &w, PACKAGE_VERSION, /*srestore*/0);
308 asfd_mock_read(asfd, &r, 0, CMD_GEN, cliproto);
309 snprintf(msg, sizeof(msg), "Client is trying to use protocol=%d but server is set to protocol=%d\n", (int)c_protocol, (int)s_protocol);
310 asfd_assert_write(asfd, &w, 0, CMD_ERROR, msg);
311 }
312
setup_send_features_proto_1_auto(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)313 static void setup_send_features_proto_1_auto(struct asfd *asfd,
314 struct conf **confs, struct conf **cconfs)
315 {
316 setup_send_features_proto_x_y(asfd, confs, cconfs,
317 PROTO_1, PROTO_AUTO);
318 }
319
setup_send_features_proto_2_auto(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)320 static void setup_send_features_proto_2_auto(struct asfd *asfd,
321 struct conf **confs, struct conf **cconfs)
322 {
323 setup_send_features_proto_x_y(asfd, confs, cconfs,
324 PROTO_2, PROTO_AUTO);
325 }
326
setup_send_features_proto_1_2(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)327 static void setup_send_features_proto_1_2(struct asfd *asfd,
328 struct conf **confs, struct conf **cconfs)
329 {
330 setup_send_features_proto_x_y(asfd, confs, cconfs,
331 PROTO_1, PROTO_2);
332 }
333
setup_send_features_proto_2_1(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)334 static void setup_send_features_proto_2_1(struct asfd *asfd,
335 struct conf **confs, struct conf **cconfs)
336 {
337 setup_send_features_proto_x_y(asfd, confs, cconfs,
338 PROTO_2, PROTO_1);
339 }
340
setup_send_features_proto_1_1(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)341 static void setup_send_features_proto_1_1(struct asfd *asfd,
342 struct conf **confs, struct conf **cconfs)
343 {
344 setup_send_features_proto_proto(asfd, confs, cconfs, PACKAGE_VERSION,
345 PROTO_1, PROTO_1);
346 }
347
setup_send_features_proto_2_2(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)348 static void setup_send_features_proto_2_2(struct asfd *asfd,
349 struct conf **confs, struct conf **cconfs)
350 {
351 setup_send_features_proto_proto(asfd, confs, cconfs, PACKAGE_VERSION,
352 PROTO_2, PROTO_2);
353 }
354
checks_proto_auto_no_features_from_client(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)355 static void checks_proto_auto_no_features_from_client(
356 struct conf **confs, struct conf **cconfs, const char *incexc,
357 int srestore)
358 {
359 // Server is PROTO_AUTO, client said nothing.
360 fail_unless(get_protocol(confs)==PROTO_1);
361 }
362
checks_proto_auto_no_features_from_client_old_client(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)363 static void checks_proto_auto_no_features_from_client_old_client(
364 struct conf **confs, struct conf **cconfs, const char *incexc,
365 int srestore)
366 {
367 // Server is PROTO_AUTO, client said nothing. Client is old version,
368 // so should be forced to PROTO_1.
369 fail_unless(get_protocol(cconfs)==PROTO_1);
370 fail_unless(get_protocol(confs)==PROTO_1);
371 }
372
checks_proto1_no_features_from_client(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)373 static void checks_proto1_no_features_from_client(
374 struct conf **confs, struct conf **cconfs, const char *incexc,
375 int srestore)
376 {
377 // Server is PROTO_1, client said nothing.
378 fail_unless(get_protocol(confs)==PROTO_AUTO);
379 }
380
checks_proto1_no_features_from_client_old_client(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)381 static void checks_proto1_no_features_from_client_old_client(
382 struct conf **confs, struct conf **cconfs, const char *incexc,
383 int srestore)
384 {
385 // Server is PROTO_1, client said nothing. Client is old version.
386 fail_unless(get_protocol(confs)==PROTO_AUTO);
387 }
388
checks_proto2_no_features_from_client(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)389 static void checks_proto2_no_features_from_client(
390 struct conf **confs, struct conf **cconfs, const char *incexc,
391 int srestore)
392 {
393 // Server is PROTO_2, client said nothing.
394 fail_unless(get_protocol(confs)==PROTO_AUTO);
395 }
396
checks_proto_auto_1(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)397 static void checks_proto_auto_1(
398 struct conf **confs, struct conf **cconfs, const char *incexc,
399 int srestore)
400 {
401 // Server is PROTO_AUTO, client said PROTO_1
402 fail_unless(get_protocol(confs)==PROTO_1);
403 // We did not set OPT_RSHASH. It should be set to RSHASH_MD4 for us.
404 fail_unless(get_e_rshash(confs[OPT_RSHASH])==RSHASH_MD4);
405 fail_unless(get_e_rshash(cconfs[OPT_RSHASH])==RSHASH_MD4);
406 }
407
checks_proto_auto_2(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)408 static void checks_proto_auto_2(
409 struct conf **confs, struct conf **cconfs, const char *incexc,
410 int srestore)
411 {
412 // Server is PROTO_AUTO, client said PROTO_2
413 fail_unless(get_protocol(confs)==PROTO_2);
414 }
415
setup_unexpected_cmd_feature(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)416 static void setup_unexpected_cmd_feature(struct asfd *asfd,
417 struct conf **confs, struct conf **cconfs)
418 {
419 int r=0; int w=0;
420 setup_send_features_proto_begin(asfd, confs, cconfs,
421 PROTO_AUTO, &r, &w, PACKAGE_VERSION, /*srestore*/0);
422 asfd_mock_read(asfd, &r, 0, CMD_FILE, "blah");
423 }
424
setup_simple(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs,const char * feature,int srestore)425 static void setup_simple(struct asfd *asfd,
426 struct conf **confs, struct conf **cconfs, const char *feature,
427 int srestore)
428 {
429 int r=0; int w=0;
430 setup_send_features_proto_begin(asfd, confs, cconfs,
431 PROTO_AUTO, &r, &w, PACKAGE_VERSION, srestore);
432 asfd_mock_read(asfd, &r, 0, CMD_GEN, feature);
433 setup_send_features_proto_end(asfd, &r, &w);
434 }
435
setup_autoupgrade_no_os(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)436 static void setup_autoupgrade_no_os(struct asfd *asfd,
437 struct conf **confs, struct conf **cconfs)
438 {
439 setup_simple(asfd, confs, cconfs, "autoupgrade:", /*srestore*/0);
440 }
441
setup_autoupgrade(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)442 static void setup_autoupgrade(struct asfd *asfd,
443 struct conf **confs, struct conf **cconfs)
444 {
445 int r=0; int w=0;
446 setup_send_features_proto_begin(asfd, confs, cconfs,
447 PROTO_AUTO, &r, &w, PACKAGE_VERSION, /*srestore*/0);
448 asfd_mock_read(asfd, &r, 0, CMD_GEN, "autoupgrade:some_os");
449 // Server does not have an autoupgrade_dir set.
450 asfd_assert_write(asfd, &w, 0, CMD_GEN, "do not autoupgrade");
451 setup_send_features_proto_end(asfd, &r, &w);
452 }
453
setup_rshash_blake2(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)454 static void setup_rshash_blake2(struct asfd *asfd,
455 struct conf **confs, struct conf **cconfs)
456 {
457 #ifdef HAVE_BLAKE2
458 setup_simple(asfd, confs, cconfs, "rshash=blake2", /*srestore*/0);
459 #else
460 int r=0; int w=0;
461 setup_send_features_proto_begin(asfd, confs, cconfs,
462 PROTO_AUTO, &r, &w, PACKAGE_VERSION, /*srestore*/0);
463 asfd_mock_read(asfd, &r, 0, CMD_GEN, "rshash=blake2");
464 #endif
465 }
466
checks_rshash_blake2(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)467 static void checks_rshash_blake2(struct conf **confs, struct conf **cconfs,
468 const char *incexc, int srestore)
469 {
470 #ifdef HAVE_BLAKE2
471 fail_unless(get_e_rshash(confs[OPT_RSHASH])==RSHASH_BLAKE2);
472 fail_unless(get_e_rshash(cconfs[OPT_RSHASH])==RSHASH_BLAKE2);
473 #else
474 fail_unless(get_e_rshash(confs[OPT_RSHASH])==RSHASH_UNSET);
475 fail_unless(get_e_rshash(cconfs[OPT_RSHASH])==RSHASH_UNSET);
476 #endif
477 }
478
setup_msg(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)479 static void setup_msg(struct asfd *asfd,
480 struct conf **confs, struct conf **cconfs)
481 {
482 setup_simple(asfd, confs, cconfs, "msg", /*srestore*/0);
483 }
484
checks_msg(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)485 static void checks_msg(struct conf **confs, struct conf **cconfs,
486 const char *incexc, int srestore)
487 {
488 fail_unless(get_int(confs[OPT_MESSAGE])==1);
489 fail_unless(get_int(cconfs[OPT_MESSAGE])==1);
490 }
491
setup_counters_ok(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)492 static void setup_counters_ok(struct asfd *asfd,
493 struct conf **confs, struct conf **cconfs)
494 {
495 setup_simple(asfd, confs, cconfs, "counters_json ok", /*srestore*/0);
496 }
497
checks_counters_ok(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)498 static void checks_counters_ok(struct conf **confs, struct conf **cconfs,
499 const char *incexc, int srestore)
500 {
501 fail_unless(get_int(cconfs[OPT_SEND_CLIENT_CNTR])==1);
502 }
503
setup_uname(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)504 static void setup_uname(struct asfd *asfd,
505 struct conf **confs, struct conf **cconfs)
506 {
507 setup_simple(asfd, confs, cconfs, "uname=some_os", /*srestore*/0);
508 }
509
checks_uname(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)510 static void checks_uname(struct conf **confs, struct conf **cconfs,
511 const char *incexc, int srestore)
512 {
513 fail_unless(get_int(cconfs[OPT_CLIENT_IS_WINDOWS])==0);
514 }
515
setup_uname_is_windows(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)516 static void setup_uname_is_windows(struct asfd *asfd,
517 struct conf **confs, struct conf **cconfs)
518 {
519 setup_simple(asfd, confs, cconfs, "uname=Windows", /*srestore*/0);
520 }
521
checks_uname_is_windows(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)522 static void checks_uname_is_windows(struct conf **confs, struct conf **cconfs,
523 const char *incexc, int srestore)
524 {
525 fail_unless(get_int(cconfs[OPT_CLIENT_IS_WINDOWS])==1);
526 }
527
setup_unexpected_feature(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)528 static void setup_unexpected_feature(struct asfd *asfd,
529 struct conf **confs, struct conf **cconfs)
530 {
531 int r=0; int w=0;
532 setup_send_features_proto_begin(asfd, confs, cconfs,
533 PROTO_AUTO, &r, &w, PACKAGE_VERSION, /*srestore*/0);
534 asfd_mock_read(asfd, &r, 0, CMD_GEN, "somenonsense");
535 }
536
setup_srestore_not_ok(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)537 static void setup_srestore_not_ok(struct asfd *asfd,
538 struct conf **confs, struct conf **cconfs)
539 {
540 build_file(SRESTORE_FILE, "");
541 setup_simple(asfd, confs, cconfs, "srestore not ok", /*srestore*/1);
542 }
543
checks_srestore_not_ok(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)544 static void checks_srestore_not_ok(struct conf **confs, struct conf **cconfs,
545 const char *incexc, int srestore)
546 {
547 struct stat statp;
548 // Should have deleted the restore file.
549 fail_unless(lstat(SRESTORE_FILE, &statp));
550 fail_unless(get_string(cconfs[OPT_RESTORE_PATH])==NULL);
551 }
552
setup_srestore(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs,int * r,int * w)553 static void setup_srestore(struct asfd *asfd,
554 struct conf **confs, struct conf **cconfs, int *r, int *w)
555 {
556 struct strlist *strlist=NULL;
557 build_file(SRESTORE_FILE, "");
558 setup_send_features_proto_begin(asfd, confs, cconfs, PROTO_AUTO,
559 r, w, PACKAGE_VERSION, /*srestore*/1);
560
561 strlist_add(&strlist, "/some/path", 1);
562 // This needs to get unset.
563 set_strlist(cconfs[OPT_INCEXCDIR], strlist);
564
565 asfd_mock_read(asfd, r, 0, CMD_GEN, "srestore ok");
566 asfd_assert_write(asfd, w, 0, CMD_GEN, "overwrite = 0");
567 asfd_assert_write(asfd, w, 0, CMD_GEN, "strip = 0");
568 asfd_assert_write(asfd, w, 0, CMD_GEN, "regex_case_insensitive = 0");
569 asfd_assert_write(asfd, w, 0, CMD_GEN, "srestore end");
570 }
571
setup_srestore_ok(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)572 static void setup_srestore_ok(struct asfd *asfd,
573 struct conf **confs, struct conf **cconfs)
574 {
575 int r=0; int w=0;
576 setup_srestore(asfd, confs, cconfs, &r, &w);
577 asfd_mock_read(asfd, &r, 0, CMD_GEN, "srestore end ok");
578 setup_send_features_proto_end(asfd, &r, &w);
579 }
580
checks_srestore_ok(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)581 static void checks_srestore_ok(struct conf **confs, struct conf **cconfs,
582 const char *incexc, int srestore)
583 {
584 struct stat statp;
585 // Should not have deleted the restore file.
586 fail_unless(!lstat(SRESTORE_FILE, &statp));
587 fail_unless(!strcmp(get_string(cconfs[OPT_RESTORE_PATH]),
588 SRESTORE_FILE));
589 fail_unless(srestore==1);
590 fail_unless(get_strlist(cconfs[OPT_INCEXCDIR])==NULL);
591 }
592
setup_srestore_ok_error(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)593 static void setup_srestore_ok_error(struct asfd *asfd,
594 struct conf **confs, struct conf **cconfs)
595 {
596 int r=0; int w=0;
597 setup_srestore(asfd, confs, cconfs, &r, &w);
598 asfd_mock_read(asfd, &r, -1, CMD_GEN, "srestore end ok");
599 }
600
setup_sincexc_ok(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)601 static void setup_sincexc_ok(struct asfd *asfd,
602 struct conf **confs, struct conf **cconfs)
603 {
604 int r=0; int w=0;
605 setup_send_features_proto_begin(asfd, confs, cconfs, PROTO_AUTO,
606 &r, &w, PACKAGE_VERSION, /*srestore*/0);
607 asfd_mock_read(asfd, &r, 0, CMD_GEN, "sincexc ok");
608 asfd_assert_write(asfd, &w, 0, CMD_GEN, "cross_all_filesystems = 0");
609 asfd_assert_write(asfd, &w, 0, CMD_GEN, "read_all_fifos = 0");
610 asfd_assert_write(asfd, &w, 0, CMD_GEN, "read_all_blockdevs = 0");
611 asfd_assert_write(asfd, &w, 0, CMD_GEN, "min_file_size = 0");
612 asfd_assert_write(asfd, &w, 0, CMD_GEN, "max_file_size = 0");
613 asfd_assert_write(asfd, &w, 0, CMD_GEN, "split_vss = 0");
614 asfd_assert_write(asfd, &w, 0, CMD_GEN, "strip_vss = 0");
615 asfd_assert_write(asfd, &w, 0, CMD_GEN, "acl = 1");
616 asfd_assert_write(asfd, &w, 0, CMD_GEN, "xattr = 1");
617 asfd_assert_write(asfd, &w, 0, CMD_GEN, "atime = 0");
618 asfd_assert_write(asfd, &w, 0,
619 CMD_GEN, "scan_problem_raises_error = 0");
620 asfd_assert_write(asfd, &w, 0, CMD_GEN, "overwrite = 0");
621 asfd_assert_write(asfd, &w, 0, CMD_GEN, "strip = 0");
622 asfd_assert_write(asfd, &w, 0, CMD_GEN, "regex_case_insensitive = 0");
623 asfd_assert_write(asfd, &w, 0, CMD_GEN, "sincexc end");
624 asfd_mock_read(asfd, &r, 0, CMD_GEN, "sincexc end ok");
625 setup_send_features_proto_end(asfd, &r, &w);
626 }
627
setup_incexc(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)628 static void setup_incexc(struct asfd *asfd,
629 struct conf **confs, struct conf **cconfs)
630 {
631 int r=0; int w=0;
632 setup_send_features_proto_begin(asfd, confs, cconfs, PROTO_AUTO,
633 &r, &w, PACKAGE_VERSION, /*srestore*/0);
634 asfd_mock_read(asfd, &r, 0, CMD_GEN, "incexc");
635 asfd_assert_write(asfd, &w, 0, CMD_GEN, "incexc ok");
636 asfd_mock_read(asfd, &r, 0, CMD_GEN, "include = /some/path");
637 asfd_mock_read(asfd, &r, 0, CMD_GEN, "incexc end");
638 asfd_assert_write(asfd, &w, 0, CMD_GEN, "incexc end ok");
639 setup_send_features_proto_end(asfd, &r, &w);
640 }
641
checks_incexc(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)642 static void checks_incexc(struct conf **confs, struct conf **cconfs,
643 const char *incexc, int srestore)
644 {
645 fail_unless(!strcmp(incexc,
646 "include = /some/path\n\ncompression = 9\n"));
647 }
648
setup_orig_client_not_existing(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)649 static void setup_orig_client_not_existing(struct asfd *asfd,
650 struct conf **confs, struct conf **cconfs)
651 {
652 int r=0; int w=0;
653
654 setup_send_features_proto_begin(asfd, confs, cconfs,
655 PROTO_AUTO, &r, &w, PACKAGE_VERSION, /*srestore*/0);
656 asfd_mock_read(asfd, &r, 0, CMD_GEN, "orig_client=cli2");
657 }
658
setup_orig_client(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)659 static void setup_orig_client(struct asfd *asfd,
660 struct conf **confs, struct conf **cconfs)
661 {
662 int r=0; int w=0;
663 enum protocol protocol=PROTO_AUTO;
664
665 common_confs(cconfs, PACKAGE_VERSION, protocol);
666 set_string(confs[OPT_CLIENTCONFDIR], CLIENTCONFDIR);
667 build_file(CLIENTCONFDIR "/cli2", "restore_client=" TESTCLIENT);
668 setup_send_features_proto_begin(asfd, confs, cconfs,
669 protocol, &r, &w, PACKAGE_VERSION, /*srestore*/0);
670 asfd_mock_read(asfd, &r, 0, CMD_GEN, "orig_client=cli2");
671 asfd_assert_write(asfd, &w, 0, CMD_GEN, "orig_client ok");
672 setup_send_features_proto_end(asfd, &r, &w);
673 }
674
checks_orig_client(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)675 static void checks_orig_client(struct conf **confs, struct conf **cconfs,
676 const char *incexc, int srestore)
677 {
678 const char *orig_client;
679 const char *restore_client;
680 fail_unless(!strcmp(get_string(cconfs[OPT_CNAME]), "cli2"));
681 restore_client=get_string(cconfs[OPT_SUPER_CLIENT]);
682 orig_client=get_string(cconfs[OPT_ORIG_CLIENT]);
683 fail_unless(!strcmp(orig_client, restore_client));
684 }
685
setup_orig_client_srestore(struct asfd * asfd,struct conf ** confs,struct conf ** cconfs)686 static void setup_orig_client_srestore(struct asfd *asfd,
687 struct conf **confs, struct conf **cconfs)
688 {
689 int r=0; int w=0;
690 enum protocol protocol=PROTO_AUTO;
691 build_file(SRESTORE_FILE, "overwrite=1");
692 build_file(SRESTORE_FILE_CLI2, "strip=1");
693
694 common_confs(cconfs, PACKAGE_VERSION, protocol);
695 set_string(confs[OPT_CLIENTCONFDIR], CLIENTCONFDIR);
696 build_file(CLIENTCONFDIR "/cli2", "restore_client=" TESTCLIENT);
697 setup_send_features_proto_begin(asfd, confs, cconfs,
698 protocol, &r, &w, PACKAGE_VERSION, /*srestore*/1);
699
700 asfd_mock_read(asfd, &r, 0, CMD_GEN, "srestore ok");
701 asfd_assert_write(asfd, &w, 0, CMD_GEN, "overwrite = 1");
702 asfd_assert_write(asfd, &w, 0, CMD_GEN, "strip = 0");
703 asfd_assert_write(asfd, &w, 0, CMD_GEN, "regex_case_insensitive = 0");
704 asfd_assert_write(asfd, &w, 0, CMD_GEN, "srestore end");
705 asfd_mock_read(asfd, &r, 0, CMD_GEN, "srestore end ok");
706
707 asfd_mock_read(asfd, &r, 0, CMD_GEN, "orig_client=cli2");
708 asfd_assert_write(asfd, &w, 0, CMD_GEN, "orig_client ok");
709
710 // Should get the same as before, with orig_client added.
711 // That is, it should not read from cli2's restore file.
712 asfd_mock_read(asfd, &r, 0, CMD_GEN, "srestore ok");
713 asfd_assert_write(asfd, &w, 0, CMD_GEN, "overwrite = 1");
714 asfd_assert_write(asfd, &w, 0, CMD_GEN, "strip = 0");
715 asfd_assert_write(asfd, &w, 0, CMD_GEN, "regex_case_insensitive = 0");
716 asfd_assert_write(asfd, &w, 0, CMD_GEN, "orig_client = cli2");
717 asfd_assert_write(asfd, &w, 0, CMD_GEN, "srestore end");
718 asfd_mock_read(asfd, &r, 0, CMD_GEN, "srestore end ok");
719
720 setup_send_features_proto_end(asfd, &r, &w);
721 }
722
checks_orig_client_srestore(struct conf ** confs,struct conf ** cconfs,const char * incexc,int srestore)723 static void checks_orig_client_srestore(struct conf **confs,
724 struct conf **cconfs, const char *incexc, int srestore)
725 {
726 struct stat statp;
727 fail_unless(srestore==1);
728 // Should not have deleted either restore file.
729 fail_unless(!lstat(SRESTORE_FILE, &statp));
730 fail_unless(!lstat(SRESTORE_FILE_CLI2, &statp));
731 }
732
START_TEST(test_server_extra_comms)733 START_TEST(test_server_extra_comms)
734 {
735 run_test(0, setup_no_version, NULL);
736 run_test(0, setup_old_version, NULL);
737
738 run_test(-1, setup_unexpected_first_string, NULL);
739 run_test(-1, setup_1_3_0_write_problem, NULL);
740 run_test(-1, setup_feature_write_problem, NULL);
741
742 run_test(0, setup_send_features_proto_auto,
743 checks_proto_auto_no_features_from_client);
744 run_test(0, setup_send_features_proto1,
745 checks_proto1_no_features_from_client);
746 run_test(0, setup_send_features_proto2,
747 checks_proto2_no_features_from_client);
748 run_test(0, setup_send_features_proto_auto_1,
749 checks_proto_auto_1);
750 run_test(0, setup_send_features_proto_auto_2,
751 checks_proto_auto_2);
752
753 run_test(0, setup_send_features_proto_auto_old_client,
754 checks_proto_auto_no_features_from_client_old_client);
755 run_test(0, setup_send_features_proto1_old_client,
756 checks_proto1_no_features_from_client_old_client);
757 run_test(-1, setup_send_features_proto2_old_client,
758 NULL);
759 run_test(0, setup_send_features_proto_auto_1_old_client,
760 checks_proto_auto_1);
761 run_test(-1, setup_send_features_proto_auto_2_old_client,
762 NULL);
763
764 run_test(-1, setup_send_features_proto_auto_auto,
765 NULL);
766 run_test(-1, setup_send_features_proto_1_auto,
767 NULL);
768 run_test(-1, setup_send_features_proto_2_auto,
769 NULL);
770 run_test(-1, setup_send_features_proto_1_2,
771 NULL);
772 run_test(-1, setup_send_features_proto_2_1,
773 NULL);
774
775 run_test(0, setup_send_features_proto_1_1,
776 NULL);
777 run_test(0, setup_send_features_proto_2_2,
778 NULL);
779
780 run_test(-1, setup_unexpected_cmd_feature,
781 NULL);
782
783 run_test(0, setup_autoupgrade_no_os,
784 NULL);
785 run_test(0, setup_autoupgrade,
786 NULL);
787
788 #ifdef HAVE_BLAKE2
789 run_test(0, setup_rshash_blake2, checks_rshash_blake2);
790 #else
791 run_test(-1, setup_rshash_blake2, checks_rshash_blake2);
792 #endif
793 run_test(0, setup_counters_ok, checks_counters_ok);
794 run_test(0, setup_msg, checks_msg);
795 run_test(0, setup_uname, checks_uname);
796 run_test(0, setup_uname_is_windows, checks_uname_is_windows);
797 run_test(-1, setup_unexpected_feature, NULL);
798 run_test(0, setup_srestore_not_ok, checks_srestore_not_ok);
799
800 run_test(0, setup_srestore_ok, checks_srestore_ok);
801 run_test(-1, setup_srestore_ok_error, NULL);
802 run_test(0, setup_sincexc_ok, NULL);
803 run_test(0, setup_incexc, checks_incexc);
804 run_test(-1, setup_orig_client_not_existing, NULL);
805 run_test(0, setup_orig_client, checks_orig_client);
806 run_test(0, setup_orig_client_srestore, checks_orig_client_srestore);
807 }
808 END_TEST
809
suite_server_extra_comms(void)810 Suite *suite_server_extra_comms(void)
811 {
812 Suite *s;
813 TCase *tc_core;
814
815 s=suite_create("server_extra_comms");
816
817 tc_core=tcase_create("Core");
818 tcase_set_timeout(tc_core, 60);
819
820 tcase_add_test(tc_core, test_server_extra_comms);
821
822 suite_add_tcase(s, tc_core);
823
824 return s;
825 }
826