#include <stdio.h>
#include <inttypes.h>
#include "../../util/util.h"
#include "../../test/testutils.h"
#include "../../test/webdav.h"
#include "../../public/nsapi.h"
#include "../../public/webdav.h"
#include "../../webdav/webdav.h"
#include <cx/string.h>
#include <cx/utils.h>
#include <cx/buffer.h>
#include "pgtest.h"
#include "vfs.h"
#include "webdav.h"
#include <libpq-fe.h>
#define xstreq(a,b) xmlStrEqual(
BAD_CAST a,
BAD_CAST b)
#define MAP_GET(map, key) cxMapGet(map, cx_hash_key_str(key))
#define MAP_PUT(map, key, value) cxMapPut(map, cx_hash_key_str(key), value)
static char *pg_connstr =
"postgresql://localhost/test1";
static int abort_pg_tests =
0;
static PGconn *test_connection;
static ResourceData resdata;
static PgRepository test_repo;
void debug_print_resources(
void) {
PGresult *result = PQexec(test_connection,
"select * from Resource;");
int n = PQntuples(result);
printf(
"\nntuples: %d\n-----------------------------------------------\n", n);
printf(
"%10s %10s %s\n",
"resource_id",
"parent_id",
"nodename");
for(
int i=
0;i<n;i++) {
char *res_id = PQgetvalue(result, i,
0);
char *parent_id = PQgetvalue(result, i,
1);
char *nodename = PQgetvalue(result, i,
2);
printf(
"%10s %10s %s\n", res_id, parent_id, nodename);
}
printf(
"\n");
}
static void test_root_lookup(
void) {
memset(&test_repo,
0,
sizeof(PgRepository));
int64_t root_id = -
1;
int err = pg_lookup_root(&resdata,
"root", &root_id);
test_repo.root_resource_id = root_id;
if(err || root_id <
0) {
abort_pg_tests =
1;
}
}
void register_pg_tests(
int argc,
char **argv, UcxTestSuite *suite) {
test_connection = PQconnectdb(pg_connstr);
if(!test_connection) {
abort_pg_tests =
1;
}
if(PQstatus(test_connection) !=
CONNECTION_OK) {
abort_pg_tests =
1;
}
resdata.data = test_connection;
test_root_lookup();
ucx_test_register(suite, test_pg_conn);
if(!abort_pg_tests) {
ucx_test_register(suite, test_pg_lookup_root);
ucx_test_register(suite, test_pg_vfs_open);
ucx_test_register(suite, test_pg_vfs_io);
ucx_test_register(suite, test_pg_vfs_stat);
ucx_test_register(suite, test_pg_vfs_mkdir);
ucx_test_register(suite, test_pg_vfs_unlink);
ucx_test_register(suite, test_pg_vfs_rmdir);
ucx_test_register(suite, test_pg_webdav_create_from_resdata);
ucx_test_register(suite, test_pg_prepare_tests);
ucx_test_register(suite, test_pg_webdav_propfind);
ucx_test_register(suite, test_pg_webdav_propfind_allprop);
ucx_test_register(suite, test_pg_webdav_proppatch_set);
PGresult *result = PQexec(test_connection,
"BEGIN");
PQclear(result);
}
}
static void parse_response_tag(TestMultistatus *ms, xmlNode *node) {
CxAllocator *a = (CxAllocator*)ms->mp->allocator;
node = node->children;
cxmutstr href = {
NULL,
0};
CxMap *properties = cxHashMapCreate(a,
CX_STORE_POINTERS,
16);
while(node) {
if(node->type ==
XML_ELEMENT_NODE) {
if(xstreq(node->name,
"href")) {
xmlNode *href_node = node->children;
if(href_node->type !=
XML_TEXT_NODE) {
return;
}
href = cx_strdup_a(a, cx_str((
const char*)href_node->content));
}
else if(xstreq(node->name,
"propstat")) {
xmlNode *n = node->children;
xmlNode *prop_node =
NULL;
int status_code =
0;
while(n) {
if(n->type ==
XML_ELEMENT_NODE) {
if(xstreq(n->name,
"prop")) {
prop_node = n;
}
else if(xstreq(n->name,
"status")) {
xmlNode *status_node = n->children;
if(status_node->type !=
XML_TEXT_NODE) {
return;
}
cxmutstr status_str = cx_mutstr((
char*)status_node->content);
if(status_str.length <
13) {
return;
}
status_str = cx_strsubsl_m(status_str,
9,
3);
cxmutstr status_s = cx_strdup(cx_strcast(status_str));
status_code = atoi(status_s.ptr);
free(status_s.ptr);
}
}
n = n->next;
}
n = prop_node->children;
while(n) {
if(n->type ==
XML_ELEMENT_NODE) {
TestProperty *property = cxCalloc(ms->mp->allocator,
1,
sizeof(TestProperty));
if(n->ns) {
property->prefix = n->ns->prefix ? cx_strdup_a(a, cx_str((
const char*)n->ns->prefix)).ptr :
NULL;
property->namespace = n->ns->href ? cx_strdup_a(a, cx_str((
const char*)n->ns->href)).ptr :
NULL;
}
property->name = cx_strdup_a(a, cx_str((
const char*)n->name)).ptr;
property->node = n;
property->status = status_code;
xmlNode *value = n->children;
if(value && value->type ==
XML_TEXT_NODE) {
property->value = cx_strdup_a(a, cx_str((
const char*)value->content)).ptr;
}
if(property->namespace && property->name) {
cxmutstr pname = cx_strcat(
2, cx_str(property->namespace), cx_str(property->name));
cxMapPut(properties, cx_hash_key(pname.ptr, pname.length), property);
free(pname.ptr);
}
}
n = n->next;
}
}
}
node = node->next;
}
TestResponse *resp = cxMalloc(a,
sizeof(TestResponse));
resp->href = href.ptr;
resp->properties = properties;
cxMapPut(ms->responses, cx_hash_key(href.ptr, href.length), resp);
}
TestMultistatus* test_parse_multistatus(
const char *space,
size_t size) {
xmlDoc *doc = xmlReadMemory(space, size,
NULL,
NULL,
0);
if(!doc) {
return NULL;
}
CxMempool *mp = cxBasicMempoolCreate(
64);
TestMultistatus *ms = cxMalloc(mp->allocator,
sizeof(TestMultistatus));
ms->doc = doc;
ms->mp = mp;
ms->responses = cxHashMapCreate((CxAllocator*)mp->allocator,
CX_STORE_POINTERS,
8);
xmlNode *xml_root = xmlDocGetRootElement(doc);
xmlNode *node = xml_root->children;
while(node) {
if(node->type ==
XML_ELEMENT_NODE) {
if(xstreq(node->name,
"response")) {
parse_response_tag(ms, node);
}
}
node = node->next;
}
return ms;
}
void test_multistatus_destroy(TestMultistatus *ms) {
if(!ms)
return;
xmlFreeDoc(ms->doc);
cxMempoolDestroy(ms->mp);
}
UCX_TEST(test_pg_conn) {
char *msg = test_connection ? PQerrorMessage(test_connection) :
"no connection";
UCX_TEST_BEGIN;
if(abort_pg_tests) {
int msglen = strlen(msg);
if(msglen >
0 && msg[msglen-
1] ==
'\n') {
msglen--;
}
fprintf(stdout,
"%.*s: ", msglen, msg);
UCX_TEST_ASSERT(
1 ==
0,
"skip pg tests");
}
else {
UCX_TEST_ASSERT(
1 ==
1,
"ok");
}
UCX_TEST_END;
}
UCX_TEST(test_pg_lookup_root) {
UCX_TEST_BEGIN;
UCX_TEST_ASSERT(!abort_pg_tests,
"Lookup failed");
UCX_TEST_END;
}
static VFS* create_test_pgvfs(Session *sn, Request *rq) {
return pg_vfs_create_from_resourcedata(sn, rq, &test_repo, &resdata);
}
UCX_TEST(test_pg_vfs_open) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PUT",
"/");
rq->vfs = create_test_pgvfs(sn, rq);
VFSContext *vfs = vfs_request_context(sn, rq);
SYS_FILE file;
UCX_TEST_BEGIN;
file = vfs_open(vfs,
"/test_notfound1",
O_RDONLY);
UCX_TEST_ASSERT(!file,
"/test_notfound should not exist");
file = vfs_open(vfs,
"/test_file1",
O_RDWR |
O_CREAT);
UCX_TEST_ASSERT(file,
"cannot create file 1");
vfs_close(file);
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_pg_vfs_io) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PUT",
"/");
rq->vfs = create_test_pgvfs(sn, rq);
VFSContext *vfs = vfs_request_context(sn, rq);
SYS_FILE file;
SYS_FILE file2;
UCX_TEST_BEGIN;
file = vfs_open(vfs,
"/test_f1",
O_WRONLY |
O_CREAT);
UCX_TEST_ASSERT(file,
"cannot open file1");
int w = system_fwrite(file,
"test1\n",
6);
UCX_TEST_ASSERT(w ==
6,
"fwrite ret (1)");
w = system_fwrite(file,
"2",
1);
UCX_TEST_ASSERT(w ==
1,
"fwrite ret (2)");
vfs_close(file);
file = vfs_open(vfs,
"/test_f1",
O_RDONLY);
file2 = vfs_open(vfs,
"/test_f2",
O_WRONLY |
O_CREAT);
UCX_TEST_ASSERT(file,
"cannot open file1");
UCX_TEST_ASSERT(file2,
"cannot open file2");
char buf[
128];
int r = system_fread(file, buf,
128);
UCX_TEST_ASSERT(r ==
7,
"cannot read from file1");
w = system_fwrite(file2, buf, r);
UCX_TEST_ASSERT(w ==
7,
"cannot write to file2");
vfs_close(file);
vfs_close(file2);
file2 = vfs_open(vfs,
"/test_f2",
O_RDONLY);
r = system_fread(file, buf,
128);
UCX_TEST_ASSERT(r ==
7,
"fread ret");
UCX_TEST_ASSERT(!memcmp(buf,
"test1\n2",
7),
"wrong buffer content after read");
vfs_close(file2);
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_pg_vfs_stat) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PUT",
"/");
rq->vfs = create_test_pgvfs(sn, rq);
VFSContext *vfs = vfs_request_context(sn, rq);
UCX_TEST_BEGIN;
char test1[
512];
memset(test1,
'x',
512);
const int test_len1 =
200;
const int test_len2 =
432;
SYS_FILE f1 = vfs_open(vfs,
"/test_s1",
O_WRONLY|
O_CREAT);
UCX_TEST_ASSERT(f1,
"cannot open test_s1");
system_fwrite(f1, test1, test_len1);
vfs_close(f1);
SYS_FILE f2 = vfs_open(vfs,
"/test_s2",
O_RDWR|
O_CREAT);
UCX_TEST_ASSERT(f2,
"cannot open test_s2");
system_fwrite(f2, test1, test_len2);
vfs_close(f2);
struct stat st1, st2;
int r1 = vfs_stat(vfs,
"/test_s1", &st1);
int r2 = vfs_stat(vfs,
"/test_s2", &st2);
UCX_TEST_ASSERT(r1 ==
0,
"stat1 failed");
UCX_TEST_ASSERT(r2 ==
0,
"stat2 failed");
UCX_TEST_ASSERT(st1.st_size == test_len1,
"s1 wrong length");
UCX_TEST_ASSERT(st2.st_size == test_len2,
"s2 wrong length");
int testfail = vfs_stat(vfs,
"/test_stat_fail", &st1);
UCX_TEST_ASSERT(testfail !=
0,
"stat 3 should fail");
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_pg_vfs_mkdir) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PUT",
"/");
rq->vfs = create_test_pgvfs(sn, rq);
VFSContext *vfs = vfs_request_context(sn, rq);
UCX_TEST_BEGIN;
struct stat s;
SYS_FILE f1 = vfs_open(vfs,
"/test_mkdir/file",
O_WRONLY|
O_CREAT);
UCX_TEST_ASSERT(f1 ==
NULL,
"open should fail");
int r = vfs_mkdir(vfs,
"/test_mkdir");
UCX_TEST_ASSERT(r ==
0,
"mkdir failed");
r = vfs_stat(vfs,
"/test_mkdir", &s);
UCX_TEST_ASSERT(r ==
0,
"stat (1) failed");
UCX_TEST_ASSERT(
S_ISDIR(s.st_mode),
"/test_mkdir is not a directory");
f1 = vfs_open(vfs,
"/test_mkdir/file",
O_WRONLY|
O_CREAT);
vfs_close(f1);
UCX_TEST_ASSERT(f1,
"open failed");
r = vfs_stat(vfs,
"/test_mkdir/file", &s);
UCX_TEST_ASSERT(r ==
0,
"stat (2) failed");
r = vfs_mkdir(vfs,
"/test_mkdir/test_sub");
UCX_TEST_ASSERT(r ==
0,
"mkdir failed (2)");
r = vfs_stat(vfs,
"/test_mkdir/test_sub", &s);
UCX_TEST_ASSERT(r ==
0,
"stat (3) failed");
UCX_TEST_ASSERT(
S_ISDIR(s.st_mode),
"/test_mkdir/test_sub is not a directory");
r = vfs_mkdir(vfs,
"/test_mkdir/test_sub/test_sub2/");
UCX_TEST_ASSERT(r ==
0,
"mkdir failed (4)");
r = vfs_stat(vfs,
"/test_mkdir/test_sub/test_sub2/", &s);
UCX_TEST_ASSERT(r ==
0,
"stat (4) failed");
UCX_TEST_ASSERT(
S_ISDIR(s.st_mode),
"/test_mkdir/test_sub/test_sub2/ is not a directory");
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_pg_vfs_unlink) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PUT",
"/");
rq->vfs = create_test_pgvfs(sn, rq);
VFSContext *vfs = vfs_request_context(sn, rq);
UCX_TEST_BEGIN;
SYS_FILE f1 = vfs_open(vfs,
"/test_unlink1",
O_WRONLY|
O_CREAT);
UCX_TEST_ASSERT(f1,
"cannot create test file");
system_fwrite(f1,
"test",
4);
PgFile *pgfile = f1->data;
Oid oid = pgfile->oid;
vfs_close(f1);
int r = vfs_unlink(vfs,
"/test_unlink1");
UCX_TEST_ASSERT(r ==
0,
"unlink failed");
f1 = vfs_open(vfs,
"/test_unlink1",
O_RDONLY);
UCX_TEST_ASSERT(f1 ==
NULL,
"test file not deleted");
PGresult *result = PQexec(test_connection,
"savepoint sp;");
PQclear(result);
int pgfd = lo_open(test_connection, oid,
INV_READ);
UCX_TEST_ASSERT(pgfd <
0,
"large object not deleted");
result = PQexec(test_connection,
"rollback to savepoint sp;");
PQclear(result);
r = vfs_unlink(vfs,
"/test_unlink1");
UCX_TEST_ASSERT(r,
"unlink should fail");
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_pg_vfs_rmdir) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PUT",
"/");
rq->vfs = create_test_pgvfs(sn, rq);
VFSContext *vfs = vfs_request_context(sn, rq);
PQexec(test_connection,
"delete from Resource where parent_id is not null;");
UCX_TEST_BEGIN;
int r;
SYS_FILE f1;
r = vfs_mkdir(vfs,
"/rmdir_test");
UCX_TEST_ASSERT(r ==
0,
"mkdir failed (1)");
r = vfs_mkdir(vfs,
"/rmdir_test/subdir1");
UCX_TEST_ASSERT(r ==
0,
"mkdir failed (2)");
r = vfs_mkdir(vfs,
"/rmdir_test/subdir2");
UCX_TEST_ASSERT(r ==
0,
"mkdir failed (3)");
f1 = vfs_open(vfs,
"/rmdir_test/subdir2/file",
O_CREAT|
O_WRONLY);
UCX_TEST_ASSERT(f1,
"open failed");
vfs_close(f1);
r = vfs_rmdir(vfs,
"/rmdir_test/subdir1");
UCX_TEST_ASSERT(r ==
0,
"rmdir failed");;
r = vfs_rmdir(vfs,
"/rmdir_test/subdir2");
UCX_TEST_ASSERT(r !=
0,
"rmdir should fail if the dir is not empty");
r = vfs_unlink(vfs,
"/rmdir_test/subdir2/file");
UCX_TEST_ASSERT(r ==
0,
"unlink failed");
r = vfs_rmdir(vfs,
"/rmdir_test/subdir2");
UCX_TEST_ASSERT(r ==
0,
"rmdir failed 2");
UCX_TEST_END;
testutil_destroy_session(sn);
}
static WebdavBackend* create_test_pgdav(Session *sn, Request *rq) {
return pg_webdav_create_from_resdata(sn, rq, &test_repo, &resdata);
}
UCX_TEST(test_pg_webdav_create_from_resdata) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PROPFIND",
"/");
UCX_TEST_BEGIN;
WebdavBackend *dav = create_test_pgdav(sn, rq);
UCX_TEST_ASSERT(dav,
"cannot create pg dav backend");
UCX_TEST_END;
}
UCX_TEST(test_pg_prepare_tests) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PUT",
"/");
rq->vfs = create_test_pgvfs(sn, rq);
VFSContext *vfs = vfs_request_context(sn, rq);
UCX_TEST_BEGIN;
vfs_mkdir(vfs,
"/propfind");
vfs_mkdir(vfs,
"/proppatch");
SYS_FILE f1;
int64_t res1_id, res2_id;
f1 = vfs_open(vfs,
"/propfind/res1",
O_WRONLY|
O_CREAT);
UCX_TEST_ASSERT(f1,
"res1 create failed");
res1_id = ((PgFile*)f1->data)->resource_id;
vfs_close(f1);
f1 = vfs_open(vfs,
"/propfind/res2",
O_WRONLY|
O_CREAT);
UCX_TEST_ASSERT(f1,
"res2 create failed");
res2_id = ((PgFile*)f1->data)->resource_id;
vfs_close(f1);
f1 = vfs_open(vfs,
"/propfind/res3",
O_WRONLY|
O_CREAT);
UCX_TEST_ASSERT(f1,
"res3 create failed");
vfs_close(f1);
int r = vfs_mkdir(vfs,
"/propfind/sub");
UCX_TEST_ASSERT(r ==
0,
"sub create failed");
f1 = vfs_open(vfs,
"/propfind/sub/res4",
O_WRONLY|
O_CREAT);
UCX_TEST_ASSERT(f1,
"res4 create failed");
vfs_close(f1);
f1 = vfs_open(vfs,
"/proppatch/pp1",
O_WRONLY|
O_CREAT);
UCX_TEST_ASSERT(f1,
"pp1 create failed");
vfs_close(f1);
char idstr[
32];
snprintf(idstr,
32,
"%" PRId64, res1_id);
const char* params[
1] = { idstr };
PGresult *result = PQexecParams(
test_connection,
"insert into Property(resource_id, prefix, xmlns, pname, pvalue) values ($1, ''x'', ''http://example.com/'', ''test'', ''testvalue'');",
1,
NULL,
params,
NULL,
NULL,
0);
UCX_TEST_ASSERT(PQresultStatus(result) ==
PGRES_COMMAND_OK,
"cannot create property 1");
PQclear(result);
result = PQexecParams(
test_connection,
"insert into Property(resource_id, prefix, xmlns, pname, pvalue) values ($1, ''x'', ''http://example.com/'', ''prop2'', ''value2'');",
1,
NULL,
params,
NULL,
NULL,
0);
UCX_TEST_ASSERT(PQresultStatus(result) ==
PGRES_COMMAND_OK,
"cannot create property 1");
PQclear(result);
snprintf(idstr,
32,
"%" PRId64, res2_id);
result = PQexecParams(
test_connection,
"insert into Property(resource_id, prefix, xmlns, pname, pvalue) values ($1, ''x'', ''http://example.com/'', ''test'', ''res2test'');",
1,
NULL,
params,
NULL,
NULL,
0);
UCX_TEST_ASSERT(PQresultStatus(result) ==
PGRES_COMMAND_OK,
"cannot create property 1");
PQclear(result);
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_pg_webdav_propfind) {
Session *sn;
Request *rq;
TestIOStream *st;
pblock *pb;
UCX_TEST_BEGIN;
int ret;
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_PROPFIND1);
rq->davCollection = create_test_pgdav(sn, rq);
pblock_nvinsert(
"depth",
"0", rq->headers);
ret = webdav_propfind(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (1) failed");
TestMultistatus *ms = test_parse_multistatus(st->buf->space, st->buf->size);
UCX_TEST_ASSERT(ms,
"propfind1: response is not valid xml");
TestResponse *r1 =
MAP_GET(ms->responses,
"/propfind/");
UCX_TEST_ASSERT(r1,
"propfind1: missing /propfind/ response");
UCX_TEST_ASSERT(ms->responses->size ==
1,
"propfind1: wrong response count");
TestProperty *p =
MAP_GET(r1->properties,
"DAV:resourcetype");
UCX_TEST_ASSERT(p,
"propfind1: missing property ''resourcetype''");
UCX_TEST_ASSERT(p->status ==
200,
"propfind1: wrong status code for property ''resourcetype''");
p =
MAP_GET(r1->properties,
"DAV:getlastmodified");
UCX_TEST_ASSERT(p,
"propfind1: missing property ''getlastmodified''");
UCX_TEST_ASSERT(p->status ==
200,
"propfind1: wrong status code for property ''getlastmodified''");
testutil_destroy_session(sn);
test_multistatus_destroy(ms);
testutil_iostream_destroy(st);
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_PROPFIND2);
rq->davCollection = create_test_pgdav(sn, rq);
pblock_nvinsert(
"depth",
"1", rq->headers);
ret = webdav_propfind(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (2) failed");
ms = test_parse_multistatus(st->buf->space, st->buf->size);
UCX_TEST_ASSERT(ms,
"propfind2: response is not valid xml");
r1 =
MAP_GET(ms->responses,
"/propfind/");
UCX_TEST_ASSERT(r1,
"propfind2: missing /propfind/ response");
UCX_TEST_ASSERT(ms->responses->size ==
5,
"propfind2: wrong response count");
r1 =
MAP_GET(ms->responses,
"/propfind/res2");
UCX_TEST_ASSERT(r1,
"propfind2: missing /propfind/res2 response");
p =
MAP_GET(r1->properties,
"http://example.com/test");
UCX_TEST_ASSERT(p,
"propfind2: missing property ''test''");
UCX_TEST_ASSERT(p->status ==
200,
"propfind2: wrong status code for property ''test''");
UCX_TEST_ASSERT(!strcmp(p->value,
"res2test"),
"propfind2: wrong property value");
testutil_destroy_session(sn);
test_multistatus_destroy(ms);
testutil_iostream_destroy(st);
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_PROPFIND2);
rq->davCollection = create_test_pgdav(sn, rq);
pblock_nvinsert(
"depth",
"infinity", rq->headers);
ret = webdav_propfind(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (3) failed");
ms = test_parse_multistatus(st->buf->space, st->buf->size);
UCX_TEST_ASSERT(ms,
"propfind3: response is not valid xml");
r1 =
MAP_GET(ms->responses,
"/propfind/");
UCX_TEST_ASSERT(r1,
"propfind3: missing /propfind/ response");
UCX_TEST_ASSERT(ms->responses->size ==
6,
"propfind3: wrong response count");
r1 =
MAP_GET(ms->responses,
"/propfind/res1");
UCX_TEST_ASSERT(r1,
"propfind3: missing /propfind/sub/res1 response");
p =
MAP_GET(r1->properties,
"http://example.com/test");
UCX_TEST_ASSERT(p,
"propfind3: missing property ''test''");
UCX_TEST_ASSERT(p->status ==
200,
"propfind3: wrong status code for property ''test''");
UCX_TEST_ASSERT(!strcmp(p->value,
"testvalue"),
"propfind3: wrong property value");
p =
MAP_GET(r1->properties,
"http://example.com/prop2");
UCX_TEST_ASSERT(p,
"propfind3: missing property ''prop2''");
UCX_TEST_ASSERT(p->status ==
200,
"propfind3: wrong status code for property ''prop2''");
UCX_TEST_ASSERT(!strcmp(p->value,
"value2"),
"propfind3: wrong property value");
r1 =
MAP_GET(ms->responses,
"/propfind/sub/res4");
UCX_TEST_ASSERT(r1,
"propfind3: missing /propfind/sub/res4 response");
testutil_destroy_session(sn);
test_multistatus_destroy(ms);
testutil_iostream_destroy(st);
UCX_TEST_END;
}
UCX_TEST(test_pg_webdav_propfind_allprop) {
Session *sn;
Request *rq;
TestIOStream *st;
pblock *pb;
UCX_TEST_BEGIN;
int ret;
TestResponse *r1;
TestProperty *p;
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_ALLPROP);
rq->davCollection = create_test_pgdav(sn, rq);
pblock_nvinsert(
"depth",
"0", rq->headers);
ret = webdav_propfind(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (1) failed");
TestMultistatus *ms = test_parse_multistatus(st->buf->space, st->buf->size);
UCX_TEST_ASSERT(ms,
"propfind1: response is not valid xml");
r1 =
MAP_GET(ms->responses,
"/propfind/");
UCX_TEST_ASSERT(r1,
"propfind1: missing /propfind/ response");
UCX_TEST_ASSERT(ms->responses->size ==
1,
"propfind1: wrong response count");
p =
MAP_GET(r1->properties,
"DAV:resourcetype");
UCX_TEST_ASSERT(r1,
"propfind1: missing resourcetype property");
testutil_destroy_session(sn);
test_multistatus_destroy(ms);
testutil_iostream_destroy(st);
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_ALLPROP);
rq->davCollection = create_test_pgdav(sn, rq);
pblock_nvinsert(
"depth",
"1", rq->headers);
ret = webdav_propfind(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (2) failed");
ms = test_parse_multistatus(st->buf->space, st->buf->size);
UCX_TEST_ASSERT(ms,
"propfind2: response is not valid xml");
r1 =
MAP_GET(ms->responses,
"/propfind/");
UCX_TEST_ASSERT(r1,
"propfind2: missing /propfind/ response");
UCX_TEST_ASSERT(ms->responses->size ==
5,
"propfind2: wrong response count");
r1 =
MAP_GET(ms->responses,
"/propfind/res1");
UCX_TEST_ASSERT(r1,
"propfind2: missing /propfind/res1 response");
p =
MAP_GET(r1->properties,
"DAV:resourcetype");
UCX_TEST_ASSERT(r1,
"propfind2: missing resourcetype property");
p =
MAP_GET(r1->properties,
"http://example.com/test");
UCX_TEST_ASSERT(r1,
"propfind2: missing test property");
p =
MAP_GET(r1->properties,
"http://example.com/prop2");
UCX_TEST_ASSERT(r1,
"propfind2: missing prop2 property");
UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/res2"),
"propfind2: missing /propfind/res2 response");
UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/res3"),
"propfind2: missing /propfind/res3 response");
UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/sub/"),
"propfind2: missing /propfind/sub response");
testutil_destroy_session(sn);
test_multistatus_destroy(ms);
testutil_iostream_destroy(st);
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/propfind/",
PG_TEST_ALLPROP);
rq->davCollection = create_test_pgdav(sn, rq);
pblock_nvinsert(
"depth",
"infinity", rq->headers);
ret = webdav_propfind(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (2) failed");
ms = test_parse_multistatus(st->buf->space, st->buf->size);
UCX_TEST_ASSERT(ms,
"propfind3: response is not valid xml");
r1 =
MAP_GET(ms->responses,
"/propfind/");
UCX_TEST_ASSERT(r1,
"propfind3: missing /propfind/ response");
UCX_TEST_ASSERT(ms->responses->size ==
6,
"propfind3: wrong response count");
r1 =
MAP_GET(ms->responses,
"/propfind/res1");
UCX_TEST_ASSERT(r1,
"propfind3: missing /propfind/res1 response");
p =
MAP_GET(r1->properties,
"DAV:resourcetype");
UCX_TEST_ASSERT(r1,
"propfind3: missing resourcetype property");
p =
MAP_GET(r1->properties,
"http://example.com/test");
UCX_TEST_ASSERT(r1,
"propfind3: missing test property");
p =
MAP_GET(r1->properties,
"http://example.com/prop2");
UCX_TEST_ASSERT(r1,
"propfind3: missing prop2 property");
UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/res2"),
"propfind3: missing /propfind/res2 response");
UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/res3"),
"propfind3: missing /propfind/res3 response");
UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/sub/"),
"propfind3: missing /propfind/sub response");
UCX_TEST_ASSERT(
MAP_GET(ms->responses,
"/propfind/sub/res4"),
"propfind3: missing /propfind/sub/res4 response");
testutil_destroy_session(sn);
test_multistatus_destroy(ms);
testutil_iostream_destroy(st);
UCX_TEST_END;
}
UCX_TEST(test_pg_webdav_proppatch_set) {
Session *sn;
Request *rq;
TestIOStream *st;
pblock *pb;
UCX_TEST_BEGIN;
int ret;
TestResponse *r1;
TestProperty *p;
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPPATCH",
"/proppatch/pp1",
PG_TEST_PROPPATCH1);
rq->davCollection = create_test_pgdav(sn, rq);
ret = webdav_proppatch(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"proppatch1 failed");
TestMultistatus *ms = test_parse_multistatus(st->buf->space, st->buf->size);
UCX_TEST_ASSERT(ms,
"proppatch1 response is not valid xml");
testutil_destroy_session(sn);
test_multistatus_destroy(ms);
testutil_iostream_destroy(st);
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPPATCH",
"/proppatch/pp1",
PG_TEST_PROPPATCH2);
rq->davCollection = create_test_pgdav(sn, rq);
ret = webdav_proppatch(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"proppatch2 failed");
ms = test_parse_multistatus(st->buf->space, st->buf->size);
UCX_TEST_ASSERT(ms,
"proppatch2 response is not valid xml");
testutil_destroy_session(sn);
test_multistatus_destroy(ms);
testutil_iostream_destroy(st);
UCX_TEST_END;
}