1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <stdio.h>
30 #include <inttypes.h>
31
32 #include "../../util/util.h"
33 #include "../../test/testutils.h"
34 #include "../../test/webdav.h"
35 #include "../../public/nsapi.h"
36 #include "../../public/webdav.h"
37 #include "../../webdav/webdav.h"
38
39 #include <cx/string.h>
40 #include <cx/utils.h>
41 #include <cx/buffer.h>
42
43 #include "pgtest.h"
44 #include "vfs.h"
45 #include "webdav.h"
46
47 #include <libpq-fe.h>
48
49 #define xstreq(a,b) xmlStrEqual(
BAD_CAST a,
BAD_CAST b)
50
51 #define MAP_GET(map, key) cxMapGet(map, cx_hash_key_str(key))
52 #define MAP_PUT(map, key, value) cxMapPut(map, cx_hash_key_str(key), value)
53
54 static char *pg_connstr =
"postgresql://localhost/test1";
55 static int abort_pg_tests =
0;
56 static PGconn *test_connection;
57 static ResourceData resdata;
58 static PgRepository test_repo;
59
60 void debug_print_resources(
void) {
61 PGresult *result = PQexec(test_connection,
"select * from Resource;");
62 int n = PQntuples(result);
63 printf(
"\nntuples: %d\n-----------------------------------------------\n", n);
64 printf(
"%10s %10s %s\n",
"resource_id",
"parent_id",
"nodename");
65 for(
int i=
0;i<n;i++) {
66 char *res_id = PQgetvalue(result, i,
0);
67 char *parent_id = PQgetvalue(result, i,
1);
68 char *nodename = PQgetvalue(result, i,
2);
69 printf(
"%10s %10s %s\n", res_id, parent_id, nodename);
70 }
71 printf(
"\n");
72 }
73
74 static void test_root_lookup(
void) {
75 memset(&test_repo,
0,
sizeof(PgRepository));
76
77 int64_t root_id = -
1;
78 int err = pg_lookup_root(&resdata,
"root", &root_id);
79 test_repo.root_resource_id = root_id;
80
81 if(err || root_id <
0) {
82 abort_pg_tests =
1;
83 }
84 }
85
86 void register_pg_tests(
int argc,
char **argv, UcxTestSuite *suite) {
87
88 test_connection = PQconnectdb(pg_connstr);
89 if(!test_connection) {
90 abort_pg_tests =
1;
91 }
92
93 if(PQstatus(test_connection) !=
CONNECTION_OK) {
94 abort_pg_tests =
1;
95 }
96
97 resdata.data = test_connection;
98 test_root_lookup();
99
100 ucx_test_register(suite, test_pg_conn);
101 if(!abort_pg_tests) {
102 ucx_test_register(suite, test_pg_lookup_root);
103
104 ucx_test_register(suite, test_pg_vfs_open);
105 ucx_test_register(suite, test_pg_vfs_io);
106 ucx_test_register(suite, test_pg_vfs_stat);
107 ucx_test_register(suite, test_pg_vfs_mkdir);
108 ucx_test_register(suite, test_pg_vfs_unlink);
109 ucx_test_register(suite, test_pg_vfs_rmdir);
110
111 ucx_test_register(suite, test_pg_webdav_create_from_resdata);
112 ucx_test_register(suite, test_pg_prepare_tests);
113 ucx_test_register(suite, test_pg_webdav_propfind);
114 ucx_test_register(suite, test_pg_webdav_propfind_allprop);
115 ucx_test_register(suite, test_pg_webdav_proppatch_set);
116
117 PGresult *result = PQexec(test_connection,
"BEGIN");
118 PQclear(result);
119 }
120 }
121
122 static void parse_response_tag(TestMultistatus *ms, xmlNode *node) {
123
124 CxAllocator *a = (CxAllocator*)ms->mp->allocator;
125 node = node->children;
126
127 cxmutstr href = {
NULL,
0};
128 CxMap *properties = cxHashMapCreate(a,
CX_STORE_POINTERS,
16);
129
130 while(node) {
131 if(node->type ==
XML_ELEMENT_NODE) {
132 if(xstreq(node->name,
"href")) {
133 xmlNode *href_node = node->children;
134 if(href_node->type !=
XML_TEXT_NODE) {
135 return;
136 }
137 href = cx_strdup_a(a, cx_str((
const char*)href_node->content));
138 }
else if(xstreq(node->name,
"propstat")) {
139 xmlNode *n = node->children;
140 xmlNode *prop_node =
NULL;
141 int status_code =
0;
142 while(n) {
143 if(n->type ==
XML_ELEMENT_NODE) {
144 if(xstreq(n->name,
"prop")) {
145 prop_node = n;
146 }
else if(xstreq(n->name,
"status")) {
147 xmlNode *status_node = n->children;
148 if(status_node->type !=
XML_TEXT_NODE) {
149 return;
150 }
151 cxmutstr status_str = cx_mutstr((
char*)status_node->content);
152 if(status_str.length <
13) {
153 return;
154 }
155 status_str = cx_strsubsl_m(status_str,
9,
3);
156 cxmutstr status_s = cx_strdup(cx_strcast(status_str));
157 status_code = atoi(status_s.ptr);
158 free(status_s.ptr);
159 }
160 }
161 n = n->next;
162 }
163
164 n = prop_node->children;
165 while(n) {
166 if(n->type ==
XML_ELEMENT_NODE) {
167 TestProperty *property = cxCalloc(ms->mp->allocator,
1,
sizeof(TestProperty));
168 if(n->ns) {
169 property->prefix = n->ns->prefix ? cx_strdup_a(a, cx_str((
const char*)n->ns->prefix)).ptr :
NULL;
170 property->namespace = n->ns->href ? cx_strdup_a(a, cx_str((
const char*)n->ns->href)).ptr :
NULL;
171 }
172 property->name = cx_strdup_a(a, cx_str((
const char*)n->name)).ptr;
173 property->node = n;
174 property->status = status_code;
175 xmlNode *value = n->children;
176 if(value && value->type ==
XML_TEXT_NODE) {
177 property->value = cx_strdup_a(a, cx_str((
const char*)value->content)).ptr;
178 }
179 if(property->namespace && property->name) {
180 cxmutstr pname = cx_strcat(
2, cx_str(property->namespace), cx_str(property->name));
181 cxMapPut(properties, cx_hash_key(pname.ptr, pname.length), property);
182 free(pname.ptr);
183 }
184 }
185 n = n->next;
186 }
187 }
188 }
189 node = node->next;
190 }
191
192 TestResponse *resp = cxMalloc(a,
sizeof(TestResponse));
193 resp->href = href.ptr;
194 resp->properties = properties;
195
196 cxMapPut(ms->responses, cx_hash_key(href.ptr, href.length), resp);
197 }
198
199 TestMultistatus* test_parse_multistatus(
const char *space,
size_t size) {
200 xmlDoc *doc = xmlReadMemory(space, size,
NULL,
NULL,
0);
201 if(!doc) {
202 return NULL;
203 }
204
205 CxMempool *mp = cxBasicMempoolCreate(
64);
206 TestMultistatus *ms = cxMalloc(mp->allocator,
sizeof(TestMultistatus));
207 ms->doc = doc;
208 ms->mp = mp;
209 ms->responses = cxHashMapCreate((CxAllocator*)mp->allocator,
CX_STORE_POINTERS,
8);
210
211
212 xmlNode *xml_root = xmlDocGetRootElement(doc);
213 xmlNode *node = xml_root->children;
214 while(node) {
215 if(node->type ==
XML_ELEMENT_NODE) {
216 if(xstreq(node->name,
"response")) {
217 parse_response_tag(ms, node);
218 }
219 }
220 node = node->next;
221 }
222
223 return ms;
224 }
225
226
227 void test_multistatus_destroy(TestMultistatus *ms) {
228 if(!ms)
return;
229 xmlFreeDoc(ms->doc);
230 cxMempoolDestroy(ms->mp);
231 }
232
233
234 UCX_TEST(test_pg_conn) {
235 char *msg = test_connection ? PQerrorMessage(test_connection) :
"no connection";
236
237 UCX_TEST_BEGIN;
238
239 if(abort_pg_tests) {
240 int msglen = strlen(msg);
241 if(msglen >
0 && msg[msglen-
1] ==
'\n') {
242 msglen--;
243 }
244 fprintf(stdout,
"%.*s: ", msglen, msg);
245 UCX_TEST_ASSERT(
1 ==
0,
"skip pg tests");
246 }
else {
247 UCX_TEST_ASSERT(
1 ==
1,
"ok");
248 }
249
250 UCX_TEST_END;
251 }
252
253 UCX_TEST(test_pg_lookup_root) {
254 UCX_TEST_BEGIN;
255
256
257 UCX_TEST_ASSERT(!abort_pg_tests,
"Lookup failed");
258
259 UCX_TEST_END;
260 }
261
262
263 static VFS* create_test_pgvfs(Session *sn, Request *rq) {
264 return pg_vfs_create_from_resourcedata(sn, rq, &test_repo, &resdata);
265 }
266
267
268 UCX_TEST(test_pg_vfs_open) {
269 Session *sn = testutil_session();
270 Request *rq = testutil_request(sn->pool,
"PUT",
"/");
271 rq->vfs = create_test_pgvfs(sn, rq);
272 VFSContext *vfs = vfs_request_context(sn, rq);
273 SYS_FILE file;
274
275 UCX_TEST_BEGIN;
276
277 file = vfs_open(vfs,
"/test_notfound1",
O_RDONLY);
278 UCX_TEST_ASSERT(!file,
"/test_notfound should not exist");
279
280 file = vfs_open(vfs,
"/test_file1",
O_RDWR |
O_CREAT);
281 UCX_TEST_ASSERT(file,
"cannot create file 1");
282
283 vfs_close(file);
284
285 UCX_TEST_END;
286
287 testutil_destroy_session(sn);
288 }
289
290 UCX_TEST(test_pg_vfs_io) {
291 Session *sn = testutil_session();
292 Request *rq = testutil_request(sn->pool,
"PUT",
"/");
293 rq->vfs = create_test_pgvfs(sn, rq);
294 VFSContext *vfs = vfs_request_context(sn, rq);
295 SYS_FILE file;
296 SYS_FILE file2;
297
298 UCX_TEST_BEGIN;
299
300 file = vfs_open(vfs,
"/test_f1",
O_WRONLY |
O_CREAT);
301 UCX_TEST_ASSERT(file,
"cannot open file1");
302
303 int w = system_fwrite(file,
"test1\n",
6);
304 UCX_TEST_ASSERT(w ==
6,
"fwrite ret (1)");
305 w = system_fwrite(file,
"2",
1);
306 UCX_TEST_ASSERT(w ==
1,
"fwrite ret (2)");
307
308 vfs_close(file);
309
310 file = vfs_open(vfs,
"/test_f1",
O_RDONLY);
311 file2 = vfs_open(vfs,
"/test_f2",
O_WRONLY |
O_CREAT);
312 UCX_TEST_ASSERT(file,
"cannot open file1");
313 UCX_TEST_ASSERT(file2,
"cannot open file2");
314
315 char buf[
128];
316 int r = system_fread(file, buf,
128);
317 UCX_TEST_ASSERT(r ==
7,
"cannot read from file1");
318
319 w = system_fwrite(file2, buf, r);
320 UCX_TEST_ASSERT(w ==
7,
"cannot write to file2");
321
322 vfs_close(file);
323 vfs_close(file2);
324
325 file2 = vfs_open(vfs,
"/test_f2",
O_RDONLY);
326
327 r = system_fread(file, buf,
128);
328 UCX_TEST_ASSERT(r ==
7,
"fread ret");
329 UCX_TEST_ASSERT(!memcmp(buf,
"test1\n2",
7),
"wrong buffer content after read");
330
331 vfs_close(file2);
332
333
334 UCX_TEST_END;
335
336 testutil_destroy_session(sn);
337 }
338
339 UCX_TEST(test_pg_vfs_stat) {
340 Session *sn = testutil_session();
341 Request *rq = testutil_request(sn->pool,
"PUT",
"/");
342 rq->vfs = create_test_pgvfs(sn, rq);
343 VFSContext *vfs = vfs_request_context(sn, rq);
344
345 UCX_TEST_BEGIN;
346
347
348 char test1[
512];
349 memset(test1,
'x',
512);
350 const int test_len1 =
200;
351 const int test_len2 =
432;
352
353 SYS_FILE f1 = vfs_open(vfs,
"/test_s1",
O_WRONLY|
O_CREAT);
354 UCX_TEST_ASSERT(f1,
"cannot open test_s1");
355 system_fwrite(f1, test1, test_len1);
356 vfs_close(f1);
357
358 SYS_FILE f2 = vfs_open(vfs,
"/test_s2",
O_RDWR|
O_CREAT);
359 UCX_TEST_ASSERT(f2,
"cannot open test_s2");
360 system_fwrite(f2, test1, test_len2);
361 vfs_close(f2);
362
363 struct stat st1, st2;
364 int r1 = vfs_stat(vfs,
"/test_s1", &st1);
365 int r2 = vfs_stat(vfs,
"/test_s2", &st2);
366
367 UCX_TEST_ASSERT(r1 ==
0,
"stat1 failed");
368 UCX_TEST_ASSERT(r2 ==
0,
"stat2 failed");
369
370 UCX_TEST_ASSERT(st1.st_size == test_len1,
"s1 wrong length");
371 UCX_TEST_ASSERT(st2.st_size == test_len2,
"s2 wrong length");
372
373 int testfail = vfs_stat(vfs,
"/test_stat_fail", &st1);
374 UCX_TEST_ASSERT(testfail !=
0,
"stat 3 should fail");
375
376 UCX_TEST_END;
377
378 testutil_destroy_session(sn);
379 }
380
381 UCX_TEST(test_pg_vfs_mkdir) {
382 Session *sn = testutil_session();
383 Request *rq = testutil_request(sn->pool,
"PUT",
"/");
384 rq->vfs = create_test_pgvfs(sn, rq);
385 VFSContext *vfs = vfs_request_context(sn, rq);
386
387 UCX_TEST_BEGIN;
388
389 struct stat s;
390
391 SYS_FILE f1 = vfs_open(vfs,
"/test_mkdir/file",
O_WRONLY|
O_CREAT);
392 UCX_TEST_ASSERT(f1 ==
NULL,
"open should fail");
393
394 int r = vfs_mkdir(vfs,
"/test_mkdir");
395 UCX_TEST_ASSERT(r ==
0,
"mkdir failed");
396
397 r = vfs_stat(vfs,
"/test_mkdir", &s);
398 UCX_TEST_ASSERT(r ==
0,
"stat (1) failed");
399
400 UCX_TEST_ASSERT(
S_ISDIR(s.st_mode),
"/test_mkdir is not a directory");
401
402 f1 = vfs_open(vfs,
"/test_mkdir/file",
O_WRONLY|
O_CREAT);
403 vfs_close(f1);
404 UCX_TEST_ASSERT(f1,
"open failed");
405
406 r = vfs_stat(vfs,
"/test_mkdir/file", &s);
407 UCX_TEST_ASSERT(r ==
0,
"stat (2) failed");
408
409 r = vfs_mkdir(vfs,
"/test_mkdir/test_sub");
410 UCX_TEST_ASSERT(r ==
0,
"mkdir failed (2)");
411
412 r = vfs_stat(vfs,
"/test_mkdir/test_sub", &s);
413 UCX_TEST_ASSERT(r ==
0,
"stat (3) failed");
414 UCX_TEST_ASSERT(
S_ISDIR(s.st_mode),
"/test_mkdir/test_sub is not a directory");
415
416 r = vfs_mkdir(vfs,
"/test_mkdir/test_sub/test_sub2/");
417 UCX_TEST_ASSERT(r ==
0,
"mkdir failed (4)");
418
419 r = vfs_stat(vfs,
"/test_mkdir/test_sub/test_sub2/", &s);
420 UCX_TEST_ASSERT(r ==
0,
"stat (4) failed");
421 UCX_TEST_ASSERT(
S_ISDIR(s.st_mode),
"/test_mkdir/test_sub/test_sub2/ is not a directory");
422
423 UCX_TEST_END;
424
425 testutil_destroy_session(sn);
426 }
427
428 UCX_TEST(test_pg_vfs_unlink) {
429 Session *sn = testutil_session();
430 Request *rq = testutil_request(sn->pool,
"PUT",
"/");
431 rq->vfs = create_test_pgvfs(sn, rq);
432 VFSContext *vfs = vfs_request_context(sn, rq);
433
434 UCX_TEST_BEGIN;
435
436 SYS_FILE f1 = vfs_open(vfs,
"/test_unlink1",
O_WRONLY|
O_CREAT);
437 UCX_TEST_ASSERT(f1,
"cannot create test file");
438 system_fwrite(f1,
"test",
4);
439
440 PgFile *pgfile = f1->data;
441 Oid oid = pgfile->oid;
442
443 vfs_close(f1);
444
445 int r = vfs_unlink(vfs,
"/test_unlink1");
446 UCX_TEST_ASSERT(r ==
0,
"unlink failed");
447
448 f1 = vfs_open(vfs,
"/test_unlink1",
O_RDONLY);
449 UCX_TEST_ASSERT(f1 ==
NULL,
"test file not deleted");
450
451 PGresult *result = PQexec(test_connection,
"savepoint sp;");
452 PQclear(result);
453 int pgfd = lo_open(test_connection, oid,
INV_READ);
454 UCX_TEST_ASSERT(pgfd <
0,
"large object not deleted");
455 result = PQexec(test_connection,
"rollback to savepoint sp;");
456 PQclear(result);
457
458 r = vfs_unlink(vfs,
"/test_unlink1");
459 UCX_TEST_ASSERT(r,
"unlink should fail");
460
461 UCX_TEST_END;
462
463 testutil_destroy_session(sn);
464 }
465
466 UCX_TEST(test_pg_vfs_rmdir) {
467 Session *sn = testutil_session();
468 Request *rq = testutil_request(sn->pool,
"PUT",
"/");
469 rq->vfs = create_test_pgvfs(sn, rq);
470 VFSContext *vfs = vfs_request_context(sn, rq);
471
472 PQexec(test_connection,
"delete from Resource where parent_id is not null;");
473
474 UCX_TEST_BEGIN;
475
476 int r;
477 SYS_FILE f1;
478
479
480 r = vfs_mkdir(vfs,
"/rmdir_test");
481 UCX_TEST_ASSERT(r ==
0,
"mkdir failed (1)");
482 r = vfs_mkdir(vfs,
"/rmdir_test/subdir1");
483 UCX_TEST_ASSERT(r ==
0,
"mkdir failed (2)");
484 r = vfs_mkdir(vfs,
"/rmdir_test/subdir2");
485 UCX_TEST_ASSERT(r ==
0,
"mkdir failed (3)");
486
487 f1 = vfs_open(vfs,
"/rmdir_test/subdir2/file",
O_CREAT|
O_WRONLY);
488 UCX_TEST_ASSERT(f1,
"open failed");
489 vfs_close(f1);
490
491
492 r = vfs_rmdir(vfs,
"/rmdir_test/subdir1");
493 UCX_TEST_ASSERT(r ==
0,
"rmdir failed");;
494
495 r = vfs_rmdir(vfs,
"/rmdir_test/subdir2");
496 UCX_TEST_ASSERT(r !=
0,
"rmdir should fail if the dir is not empty");
497
498 r = vfs_unlink(vfs,
"/rmdir_test/subdir2/file");
499 UCX_TEST_ASSERT(r ==
0,
"unlink failed");
500
501 r = vfs_rmdir(vfs,
"/rmdir_test/subdir2");
502 UCX_TEST_ASSERT(r ==
0,
"rmdir failed 2");
503
504 UCX_TEST_END;
505
506 testutil_destroy_session(sn);
507 }
508
509
510
511
512 static WebdavBackend* create_test_pgdav(Session *sn, Request *rq) {
513 return pg_webdav_create_from_resdata(sn, rq, &test_repo, &resdata);
514 }
515
516 UCX_TEST(test_pg_webdav_create_from_resdata) {
517 Session *sn = testutil_session();
518 Request *rq = testutil_request(sn->pool,
"PROPFIND",
"/");
519
520 UCX_TEST_BEGIN;
521
522 WebdavBackend *dav = create_test_pgdav(sn, rq);
523 UCX_TEST_ASSERT(dav,
"cannot create pg dav backend");
524
525 UCX_TEST_END;
526 }
527
528 UCX_TEST(test_pg_prepare_tests) {
529 Session *sn = testutil_session();
530 Request *rq = testutil_request(sn->pool,
"PUT",
"/");
531 rq->vfs = create_test_pgvfs(sn, rq);
532 VFSContext *vfs = vfs_request_context(sn, rq);
533
534 UCX_TEST_BEGIN;
535
536 vfs_mkdir(vfs,
"/propfind");
537 vfs_mkdir(vfs,
"/proppatch");
538 SYS_FILE f1;
539
540 int64_t res1_id, res2_id;
541
542 f1 = vfs_open(vfs,
"/propfind/res1",
O_WRONLY|
O_CREAT);
543 UCX_TEST_ASSERT(f1,
"res1 create failed");
544 res1_id = ((PgFile*)f1->data)->resource_id;
545 vfs_close(f1);
546
547 f1 = vfs_open(vfs,
"/propfind/res2",
O_WRONLY|
O_CREAT);
548 UCX_TEST_ASSERT(f1,
"res2 create failed");
549 res2_id = ((PgFile*)f1->data)->resource_id;
550 vfs_close(f1);
551
552 f1 = vfs_open(vfs,
"/propfind/res3",
O_WRONLY|
O_CREAT);
553 UCX_TEST_ASSERT(f1,
"res3 create failed");
554 vfs_close(f1);
555
556 int r = vfs_mkdir(vfs,
"/propfind/sub");
557 UCX_TEST_ASSERT(r ==
0,
"sub create failed");
558
559 f1 = vfs_open(vfs,
"/propfind/sub/res4",
O_WRONLY|
O_CREAT);
560 UCX_TEST_ASSERT(f1,
"res4 create failed");
561 vfs_close(f1);
562
563 f1 = vfs_open(vfs,
"/proppatch/pp1",
O_WRONLY|
O_CREAT);
564 UCX_TEST_ASSERT(f1,
"pp1 create failed");
565 vfs_close(f1);
566
567
568 char idstr[
32];
569 snprintf(idstr,
32,
"%" PRId64, res1_id);
570 const char* params[
1] = { idstr };
571 PGresult *result = PQexecParams(
572 test_connection,
573 "insert into Property(resource_id, prefix, xmlns, pname, pvalue) values ($1, ''x'', ''http://example.com/'', ''test'', ''testvalue'');",
574 1,
575 NULL,
576 params,
577 NULL,
578 NULL,
579 0);
580
581 UCX_TEST_ASSERT(PQresultStatus(result) ==
PGRES_COMMAND_OK,
"cannot create property 1");
582 PQclear(result);
583
584 result = PQexecParams(
585 test_connection,
586 "insert into Property(resource_id, prefix, xmlns, pname, pvalue) values ($1, ''x'', ''http://example.com/'', ''prop2'', ''value2'');",
587 1,
588 NULL,
589 params,
590 NULL,
591 NULL,
592 0);
593
594 UCX_TEST_ASSERT(PQresultStatus(result) ==
PGRES_COMMAND_OK,
"cannot create property 1");
595 PQclear(result);
596
597
598 snprintf(idstr,
32,
"%" PRId64, res2_id);
599 result = PQexecParams(
600 test_connection,
601 "insert into Property(resource_id, prefix, xmlns, pname, pvalue) values ($1, ''x'', ''http://example.com/'', ''test'', ''res2test'');",
602 1,
603 NULL,
604 params,
605 NULL,
606 NULL,
607 0);
608
609 UCX_TEST_ASSERT(PQresultStatus(result) ==
PGRES_COMMAND_OK,
"cannot create property 1");
610 PQclear(result);
611
612 UCX_TEST_END;
613
614 testutil_destroy_session(sn);
615 }
616
617 UCX_TEST(test_pg_webdav_propfind) {
618 Session *sn;
619 Request *rq;
620 TestIOStream *st;
621 pblock *pb;
622
623 UCX_TEST_BEGIN;
624
625
626
627
628
629
630
631
632
633
634 int ret;
635
636 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_PROPFIND1);
637 rq->davCollection = create_test_pgdav(sn, rq);
638 pblock_nvinsert(
"depth",
"0", rq->headers);
639
640 ret = webdav_propfind(pb, sn, rq);
641
642 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (1) failed");
643
644 TestMultistatus *ms = test_parse_multistatus(st->buf->space, st->buf->size);
645 UCX_TEST_ASSERT(ms,
"propfind1: response is not valid xml");
646
647 TestResponse *r1 =
MAP_GET(ms->responses,
"/propfind/");
648 UCX_TEST_ASSERT(r1,
"propfind1: missing /propfind/ response");
649
650 UCX_TEST_ASSERT(ms->responses->size ==
1,
"propfind1: wrong response count");
651
652 TestProperty *p =
MAP_GET(r1->properties,
"DAV:resourcetype");
653 UCX_TEST_ASSERT(p,
"propfind1: missing property ''resourcetype''");
654 UCX_TEST_ASSERT(p->status ==
200,
"propfind1: wrong status code for property ''resourcetype''");
655
656 p =
MAP_GET(r1->properties,
"DAV:getlastmodified");
657 UCX_TEST_ASSERT(p,
"propfind1: missing property ''getlastmodified''");
658 UCX_TEST_ASSERT(p->status ==
200,
"propfind1: wrong status code for property ''getlastmodified''");
659
660 testutil_destroy_session(sn);
661 test_multistatus_destroy(ms);
662 testutil_iostream_destroy(st);
663
664
665
666 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_PROPFIND2);
667 rq->davCollection = create_test_pgdav(sn, rq);
668 pblock_nvinsert(
"depth",
"1", rq->headers);
669
670 ret = webdav_propfind(pb, sn, rq);
671
672
673
674 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (2) failed");
675
676 ms = test_parse_multistatus(st->buf->space, st->buf->size);
677 UCX_TEST_ASSERT(ms,
"propfind2: response is not valid xml");
678
679 r1 =
MAP_GET(ms->responses,
"/propfind/");
680 UCX_TEST_ASSERT(r1,
"propfind2: missing /propfind/ response");
681
682 UCX_TEST_ASSERT(ms->responses->size ==
5,
"propfind2: wrong response count");
683
684 r1 =
MAP_GET(ms->responses,
"/propfind/res2");
685 UCX_TEST_ASSERT(r1,
"propfind2: missing /propfind/res2 response");
686
687 p =
MAP_GET(r1->properties,
"http://example.com/test");
688 UCX_TEST_ASSERT(p,
"propfind2: missing property ''test''");
689 UCX_TEST_ASSERT(p->status ==
200,
"propfind2: wrong status code for property ''test''");
690 UCX_TEST_ASSERT(!strcmp(p->value,
"res2test"),
"propfind2: wrong property value");
691
692
693 testutil_destroy_session(sn);
694 test_multistatus_destroy(ms);
695 testutil_iostream_destroy(st);
696
697
698
699
700 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_PROPFIND2);
701 rq->davCollection = create_test_pgdav(sn, rq);
702 pblock_nvinsert(
"depth",
"infinity", rq->headers);
703
704 ret = webdav_propfind(pb, sn, rq);
705
706
707
708 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (3) failed");
709
710 ms = test_parse_multistatus(st->buf->space, st->buf->size);
711 UCX_TEST_ASSERT(ms,
"propfind3: response is not valid xml");
712
713 r1 =
MAP_GET(ms->responses,
"/propfind/");
714 UCX_TEST_ASSERT(r1,
"propfind3: missing /propfind/ response");
715
716 UCX_TEST_ASSERT(ms->responses->size ==
6,
"propfind3: wrong response count");
717
718
719 r1 =
MAP_GET(ms->responses,
"/propfind/res1");
720 UCX_TEST_ASSERT(r1,
"propfind3: missing /propfind/sub/res1 response");
721
722 p =
MAP_GET(r1->properties,
"http://example.com/test");
723 UCX_TEST_ASSERT(p,
"propfind3: missing property ''test''");
724 UCX_TEST_ASSERT(p->status ==
200,
"propfind3: wrong status code for property ''test''");
725 UCX_TEST_ASSERT(!strcmp(p->value,
"testvalue"),
"propfind3: wrong property value");
726
727 p =
MAP_GET(r1->properties,
"http://example.com/prop2");
728 UCX_TEST_ASSERT(p,
"propfind3: missing property ''prop2''");
729 UCX_TEST_ASSERT(p->status ==
200,
"propfind3: wrong status code for property ''prop2''");
730 UCX_TEST_ASSERT(!strcmp(p->value,
"value2"),
"propfind3: wrong property value");
731
732
733 r1 =
MAP_GET(ms->responses,
"/propfind/sub/res4");
734 UCX_TEST_ASSERT(r1,
"propfind3: missing /propfind/sub/res4 response");
735
736 testutil_destroy_session(sn);
737 test_multistatus_destroy(ms);
738 testutil_iostream_destroy(st);
739
740 UCX_TEST_END;
741 }
742
743
744 UCX_TEST(test_pg_webdav_propfind_allprop) {
745 Session *sn;
746 Request *rq;
747 TestIOStream *st;
748 pblock *pb;
749
750 UCX_TEST_BEGIN;
751
752
753
754
755
756
757
758
759
760
761 int ret;
762 TestResponse *r1;
763 TestProperty *p;
764
765 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_ALLPROP);
766 rq->davCollection = create_test_pgdav(sn, rq);
767 pblock_nvinsert(
"depth",
"0", rq->headers);
768
769 ret = webdav_propfind(pb, sn, rq);
770
771 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (1) failed");
772
773 TestMultistatus *ms = test_parse_multistatus(st->buf->space, st->buf->size);
774 UCX_TEST_ASSERT(ms,
"propfind1: response is not valid xml");
775
776 r1 =
MAP_GET(ms->responses,
"/propfind/");
777 UCX_TEST_ASSERT(r1,
"propfind1: missing /propfind/ response");
778 UCX_TEST_ASSERT(ms->responses->size ==
1,
"propfind1: wrong response count");
779
780 p =
MAP_GET(r1->properties,
"DAV:resourcetype");
781 UCX_TEST_ASSERT(r1,
"propfind1: missing resourcetype property");
782
783 testutil_destroy_session(sn);
784 test_multistatus_destroy(ms);
785 testutil_iostream_destroy(st);
786
787
788 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_ALLPROP);
789 rq->davCollection = create_test_pgdav(sn, rq);
790 pblock_nvinsert(
"depth",
"1", rq->headers);
791
792 ret = webdav_propfind(pb, sn, rq);
793
794
795
796 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (2) failed");
797
798 ms = test_parse_multistatus(st->buf->space, st->buf->size);
799 UCX_TEST_ASSERT(ms,
"propfind2: response is not valid xml");
800
801 r1 =
MAP_GET(ms->responses,
"/propfind/");
802 UCX_TEST_ASSERT(r1,
"propfind2: missing /propfind/ response");
803 UCX_TEST_ASSERT(ms->responses->size ==
5,
"propfind2: wrong response count");
804
805 r1 =
MAP_GET(ms->responses,
"/propfind/res1");
806 UCX_TEST_ASSERT(r1,
"propfind2: missing /propfind/res1 response");
807
808 p =
MAP_GET(r1->properties,
"DAV:resourcetype");
809 UCX_TEST_ASSERT(r1,
"propfind2: missing resourcetype property");
810 p =
MAP_GET(r1->properties,
"http://example.com/test");
811 UCX_TEST_ASSERT(r1,
"propfind2: missing test property");
812 p =
MAP_GET(r1->properties,
"http://example.com/prop2");
813 UCX_TEST_ASSERT(r1,
"propfind2: missing prop2 property");
814
815 UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/res2"),
"propfind2: missing /propfind/res2 response");
816 UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/res3"),
"propfind2: missing /propfind/res3 response");
817 UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/sub/"),
"propfind2: missing /propfind/sub response");
818
819 testutil_destroy_session(sn);
820 test_multistatus_destroy(ms);
821 testutil_iostream_destroy(st);
822
823
824 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_ALLPROP);
825 rq->davCollection = create_test_pgdav(sn, rq);
826 pblock_nvinsert(
"depth",
"infinity", rq->headers);
827
828 ret = webdav_propfind(pb, sn, rq);
829
830 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (2) failed");
831
832 ms = test_parse_multistatus(st->buf->space, st->buf->size);
833 UCX_TEST_ASSERT(ms,
"propfind3: response is not valid xml");
834
835 r1 =
MAP_GET(ms->responses,
"/propfind/");
836 UCX_TEST_ASSERT(r1,
"propfind3: missing /propfind/ response");
837 UCX_TEST_ASSERT(ms->responses->size ==
6,
"propfind3: wrong response count");
838
839 r1 =
MAP_GET(ms->responses,
"/propfind/res1");
840 UCX_TEST_ASSERT(r1,
"propfind3: missing /propfind/res1 response");
841
842 p =
MAP_GET(r1->properties,
"DAV:resourcetype");
843 UCX_TEST_ASSERT(r1,
"propfind3: missing resourcetype property");
844 p =
MAP_GET(r1->properties,
"http://example.com/test");
845 UCX_TEST_ASSERT(r1,
"propfind3: missing test property");
846 p =
MAP_GET(r1->properties,
"http://example.com/prop2");
847 UCX_TEST_ASSERT(r1,
"propfind3: missing prop2 property");
848
849 UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/res2"),
"propfind3: missing /propfind/res2 response");
850 UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/res3"),
"propfind3: missing /propfind/res3 response");
851 UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/sub/"),
"propfind3: missing /propfind/sub response");
852 UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/sub/res4"),
"propfind3: missing /propfind/sub/res4 response");
853
854 testutil_destroy_session(sn);
855 test_multistatus_destroy(ms);
856 testutil_iostream_destroy(st);
857
858
859 UCX_TEST_END;
860 }
861
862 UCX_TEST(test_pg_webdav_proppatch_set) {
863 Session *sn;
864 Request *rq;
865 TestIOStream *st;
866 pblock *pb;
867
868 UCX_TEST_BEGIN;
869
870
871
872
873
874
875
876
877
878
879 int ret;
880 TestResponse *r1;
881 TestProperty *p;
882
883 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPPATCH",
"/proppatch/pp1",
PG_TEST_PROPPATCH1);
884 rq->davCollection = create_test_pgdav(sn, rq);
885
886 ret = webdav_proppatch(pb, sn, rq);
887 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"proppatch1 failed");
888
889
890
891 TestMultistatus *ms = test_parse_multistatus(st->buf->space, st->buf->size);
892 UCX_TEST_ASSERT(ms,
"proppatch1 response is not valid xml");
893
894 testutil_destroy_session(sn);
895 test_multistatus_destroy(ms);
896 testutil_iostream_destroy(st);
897
898
899 init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPPATCH",
"/proppatch/pp1",
PG_TEST_PROPPATCH2);
900 rq->davCollection = create_test_pgdav(sn, rq);
901
902 ret = webdav_proppatch(pb, sn, rq);
903 UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"proppatch2 failed");
904
905
906
907 ms = test_parse_multistatus(st->buf->space, st->buf->size);
908 UCX_TEST_ASSERT(ms,
"proppatch2 response is not valid xml");
909
910 testutil_destroy_session(sn);
911 test_multistatus_destroy(ms);
912 testutil_iostream_destroy(st);
913
914
915 UCX_TEST_END;
916 }
917