#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "testutils.h"
#include "../webdav/requestparser.h"
#include "../webdav/webdav.h"
#include "../webdav/multistatus.h"
#include "../webdav/operation.h"
#include "vfs.h"
#include "webdav.h"
static int webdav_is_initialized =
0;
static int backend2_init_called =
0;
static int backend2_propfind_do_count =
0;
static int backend2_propfind_finish_called =
0;
static int backend2_proppatch_commit =
0;
static int backend2_proppatch_do_count =
0;
static int backend2_proppatch_finish_count =
0;
static int backend2_propfind_init(
WebdavPropfindRequest *propfind,
const char *path,
const char *href,
WebdavPList **outPList)
{
backend2_init_called =
1;
return 0;
}
static int backend2_propfind_do(
WebdavPropfindRequest *propfind,
WebdavResponse *response,
VFS_DIR parent,
WebdavResource *resource,
struct stat *s)
{
backend2_propfind_do_count++;
return 0;
}
static int backend2_propfind_finish(WebdavPropfindRequest *propfind) {
backend2_propfind_finish_called =
1;
return 0;
}
static int backend2_proppatch_do(
WebdavProppatchRequest *request,
WebdavResource *response,
VFSFile *file,
WebdavPList **out_set,
WebdavPList **out_remove)
{
backend2_proppatch_do_count++;
if(*out_remove) {
return 1;
}
WebdavPListIterator i = webdav_plist_iterator(out_set);
WebdavPList *cur;
while(webdav_plist_iterator_next(&i, &cur)) {
if(!strcmp(cur->property->name,
"a")) {
return 1;
}
else if(!strcmp(cur->property->name,
"abort")) {
return 1;
}
response->addproperty(response, cur->property,
200);
webdav_plist_iterator_remove_current(&i);
}
return 0;
}
static int backend2_proppatch_finish(
WebdavProppatchRequest *request,
WebdavResource *response,
VFSFile *file,
WSBool commit)
{
backend2_proppatch_finish_count++;
backend2_proppatch_commit = commit;
return 0;
}
static WebdavBackend backend2 = {
backend2_propfind_init,
backend2_propfind_do,
backend2_propfind_finish,
backend2_proppatch_do,
backend2_proppatch_finish,
NULL,
NULL,
NULL,
NULL,
0,
NULL,
NULL
};
static int backend1_init_called =
0;
static int backend1_propfind_do_count =
0;
static int backend1_propfind_finish_called =
0;
static int backend1_proppatch_commit =
0;
static int backend1_proppatch_do_count =
0;
static int backend1_proppatch_finish_count =
0;
static int backend1_propfind_init(
WebdavPropfindRequest *propfind,
const char *path,
const char *href,
WebdavPList **outPList)
{
backend1_init_called =
1;
WebdavPList *plist = *outPList;
WebdavProperty *p = plist->property;
if(!strcmp(p->name,
"displayname")) {
plist->next->prev =
NULL;
*outPList = plist->next;
}
else {
return 1;
}
return 0;
}
static int backend1_propfind_do(
WebdavPropfindRequest *propfind,
WebdavResponse *response,
VFS_DIR parent,
WebdavResource *resource,
struct stat *s)
{
backend1_propfind_do_count++;
return 0;
}
static int backend1_propfind_finish(WebdavPropfindRequest *propfind) {
backend1_propfind_finish_called =
1;
return 0;
}
static int backend1_proppatch_do(
WebdavProppatchRequest *request,
WebdavResource *response,
VFSFile *file,
WebdavPList **out_set,
WebdavPList **out_remove)
{
backend1_proppatch_do_count++;
WebdavPListIterator i = webdav_plist_iterator(out_remove);
WebdavPList *cur;
while(webdav_plist_iterator_next(&i, &cur)) {
response->addproperty(response, cur->property,
200);
webdav_plist_iterator_remove_current(&i);
}
i = webdav_plist_iterator(out_set);
while(webdav_plist_iterator_next(&i, &cur)) {
if(!strcmp(cur->property->name,
"fail")) {
response->addproperty(response, cur->property,
403);
webdav_plist_iterator_remove_current(&i);
}
else if(!strcmp(cur->property->name,
"a")) {
response->addproperty(response, cur->property,
200);
webdav_plist_iterator_remove_current(&i);
}
}
return 0;
}
static int backend1_proppatch_finish(
WebdavProppatchRequest *request,
WebdavResource *response,
VFSFile *file,
WSBool commit)
{
backend1_proppatch_finish_count++;
backend1_proppatch_commit = commit;
return 0;
}
WebdavBackend backend1 = {
backend1_propfind_init,
backend1_propfind_do,
backend1_propfind_finish,
backend1_proppatch_do,
backend1_proppatch_finish,
NULL,
NULL,
NULL,
NULL,
0,
NULL,
&backend2
};
static void reset_backends(
void) {
backend1_init_called =
0;
backend1_propfind_do_count =
0;
backend1_propfind_finish_called =
0;
backend1_proppatch_commit =
0;
backend1_proppatch_do_count =
0;
backend1_proppatch_finish_count =
0;
backend2_init_called =
0;
backend2_propfind_do_count =
0;
backend2_propfind_finish_called =
0;
backend2_proppatch_commit =
0;
backend2_proppatch_do_count =
0;
backend2_proppatch_finish_count =
0;
}
static int test_init(
Session **out_sn,
Request **out_rq,
WebdavPropfindRequest **out_propfind,
const char *xml)
{
if(!webdav_is_initialized) {
if(webdav_init(
NULL,
NULL,
NULL) !=
REQ_PROCEED) {
return 1;
}
webdav_is_initialized =
1;
}
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PROPFIND",
"/");
int error =
0;
WebdavPropfindRequest *propfind = propfind_parse(
sn,
rq,
xml,
strlen(xml),
&error);
if(error) {
return 1;
}
if(!propfind || !propfind->properties) {
return 1;
}
*out_sn = sn;
*out_rq = rq;
*out_propfind = propfind;
return 0;
}
static WebdavOperation* test_propfind_op(
Session **out_sn,
Request **out_rq,
const char *xml)
{
WebdavPropfindRequest *propfind;
if(test_init(out_sn, out_rq, &propfind, xml)) {
return NULL;
}
Multistatus *ms = multistatus_response(*out_sn, *out_rq);
if(!ms) {
return NULL;
}
WebdavResponse *response = (WebdavResponse*)ms;
WebdavPropfindRequestList *requests =
NULL;
if(webdav_propfind_init(&backend1, propfind,
"/",
"/", &requests)) {
return NULL;
}
return webdav_create_propfind_operation(
(*out_sn),
(*out_rq),
&backend1,
propfind->properties,
requests,
response);
}
UCX_TEST(test_webdav_plist_add) {
Session *sn = testutil_session();
UCX_TEST_BEGIN;
WebdavPList *begin =
NULL;
WebdavPList *end =
NULL;
WebdavProperty p1, p2, p3;
ZERO(&p1,
sizeof(WebdavProperty));
ZERO(&p2,
sizeof(WebdavProperty));
ZERO(&p3,
sizeof(WebdavProperty));
int r;
r = webdav_plist_add(sn->pool, &begin, &end, &p1);
UCX_TEST_ASSERT(r ==
0,
"add 1 failed");
UCX_TEST_ASSERT(begin && end,
"ptrs are NULL");
UCX_TEST_ASSERT(begin == end,
"begin != end");
UCX_TEST_ASSERT(begin->prev ==
NULL,
"begin->prev not NULL");
UCX_TEST_ASSERT(begin->next ==
NULL,
"begin->next not NULL");
r = webdav_plist_add(sn->pool, &begin, &end, &p2);
UCX_TEST_ASSERT(r ==
0,
"add 2 failed");
UCX_TEST_ASSERT(begin && end,
"add2: ptrs are NULL");
UCX_TEST_ASSERT(begin->next,
"begin->next is NULL");
UCX_TEST_ASSERT(begin->next == end,
"begin->next != end");
UCX_TEST_ASSERT(end->prev = begin,
"end->prev != begin");
UCX_TEST_ASSERT(begin->prev ==
NULL,
"add2: begin->prev not NULL");
UCX_TEST_ASSERT(end->next ==
NULL,
"add2: end->next not NULL");
r = webdav_plist_add(sn->pool, &begin, &end, &p3);
UCX_TEST_ASSERT(r ==
0,
"add 3 failed");
UCX_TEST_ASSERT(begin && end,
"add3: ptrs are NULL");
UCX_TEST_ASSERT(begin->next == end->prev,
"begin->next != end->prev");
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_webdav_plist_size) {
Session *sn = testutil_session();
UCX_TEST_BEGIN;
WebdavPList *begin =
NULL;
WebdavPList *end =
NULL;
WebdavProperty p1, p2, p3;
ZERO(&p1,
sizeof(WebdavProperty));
ZERO(&p2,
sizeof(WebdavProperty));
ZERO(&p3,
sizeof(WebdavProperty));
int r;
UCX_TEST_ASSERT(webdav_plist_size(begin) ==
0,
"size != 0");
r = webdav_plist_add(sn->pool, &begin, &end, &p1);
UCX_TEST_ASSERT(webdav_plist_size(begin) ==
1,
"size != 1");
r = webdav_plist_add(sn->pool, &begin, &end, &p2);
UCX_TEST_ASSERT(webdav_plist_size(begin) ==
2,
"size != 2");
r = webdav_plist_add(sn->pool, &begin, &end, &p3);
UCX_TEST_ASSERT(webdav_plist_size(begin) ==
3,
"size != 3");
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_propfind_parse) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PROPFIND",
"/");
UCX_TEST_BEGIN
int error =
0;
WebdavPropfindRequest *p1 = propfind_parse(
sn,
rq,
TEST_PROPFIND1,
strlen(
TEST_PROPFIND1),
&error);
UCX_TEST_ASSERT(p1,
"p1 is NULL");
UCX_TEST_ASSERT(p1->properties,
"p1: no props");
UCX_TEST_ASSERT(!p1->allprop,
"p1: allprop is TRUE");
UCX_TEST_ASSERT(!p1->propname,
"p1: propname is TRUE");
UCX_TEST_ASSERT(p1->propcount ==
6,
"p1: wrong propcount");
WebdavPList *elm = p1->properties;
UCX_TEST_ASSERT(
!strcmp(elm->property->name,
"displayname"),
"p1: property 1 has wrong name");
UCX_TEST_ASSERT(
!strcmp((
char*)elm->property->namespace->href,
"DAV:"),
"p1: property 1 has wrong namespace");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p1: property 2 missing");
UCX_TEST_ASSERT(
!strcmp(elm->property->name,
"getcontentlength"),
"p1: property 2 has wrong name");
UCX_TEST_ASSERT(
!strcmp((
char*)elm->property->namespace->href,
"DAV:"),
"p1: property 2 has wrong namespace");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p1: property 3 missing");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p1: property 4 missing");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p1: property 5 missing");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p1: property 6 missing");
UCX_TEST_ASSERT(
!strcmp(elm->property->name,
"getetag"),
"p1: property 6 has wrong name");
UCX_TEST_ASSERT(
!strcmp((
char*)elm->property->namespace->href,
"DAV:"),
"p1: property 6 has wrong namespace");
UCX_TEST_ASSERT(!elm->next,
"p1: should not have property 7");
WebdavPropfindRequest *p2 = propfind_parse(
sn,
rq,
TEST_PROPFIND2,
strlen(
TEST_PROPFIND2),
&error);
UCX_TEST_ASSERT(p2,
"p2 is NULL");
UCX_TEST_ASSERT(p2->properties,
"p2: no props");
UCX_TEST_ASSERT(!p2->allprop,
"p2: allprop is TRUE");
UCX_TEST_ASSERT(!p2->propname,
"p2: propname is TRUE");
elm = p2->properties;
UCX_TEST_ASSERT(
!strcmp(elm->property->name,
"resourcetype"),
"p2: property 1 has wrong name");
UCX_TEST_ASSERT(
!strcmp((
char*)elm->property->namespace->href,
"DAV:"),
"p2: property 1 has wrong namespace");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p2: property 2 missing");
UCX_TEST_ASSERT(
!strcmp(elm->property->name,
"testprop"),
"p2: property 2 has wrong name");
UCX_TEST_ASSERT(
!strcmp((
char*)elm->property->namespace->href,
"http://example.com/"),
"p2: property 2 has wrong namespace");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p2: property 3 missing");
UCX_TEST_ASSERT(
!strcmp(elm->property->name,
"name"),
"p2: property 3 has wrong name");
UCX_TEST_ASSERT(
!strcmp((
char*)elm->property->namespace->href,
"http://example.com/"),
"p2: property 3 has wrong namespace");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p2: property 4 missing");
UCX_TEST_ASSERT(
!strcmp(elm->property->name,
"testprop"),
"p2: property 4 has wrong name");
UCX_TEST_ASSERT(
!strcmp((
char*)elm->property->namespace->href,
"testns"),
"p2: property 4 has wrong namespace");
WebdavPropfindRequest *p3 = propfind_parse(sn, rq,
TEST_PROPFIND3, strlen(
TEST_PROPFIND3), &error);
UCX_TEST_ASSERT(p3,
"p3 is NULL");
UCX_TEST_ASSERT(!p3->properties,
"p2: has props");
UCX_TEST_ASSERT(p3->allprop,
"p2: allprop is FALSE");
UCX_TEST_ASSERT(!p3->propname,
"p2: propname is TRUE");
UCX_TEST_ASSERT(p3->propcount ==
0,
"p2: wrong propcount");
WebdavPropfindRequest *p4 = propfind_parse(sn, rq,
TEST_PROPFIND4, strlen(
TEST_PROPFIND4), &error);
UCX_TEST_ASSERT(p4,
"p4 is NULL");
UCX_TEST_ASSERT(!p4->properties,
"p2: has props");
UCX_TEST_ASSERT(!p4->allprop,
"p2: allprop is TRUE");
UCX_TEST_ASSERT(p4->propname,
"p2: propname is FALSE");
WebdavPropfindRequest *p5 = propfind_parse(sn, rq,
TEST_PROPFIND5, strlen(
TEST_PROPFIND5), &error);
UCX_TEST_ASSERT(p5,
"p5 is NULL");
UCX_TEST_ASSERT(p5->properties,
"p5: no props");
UCX_TEST_ASSERT(!p5->allprop,
"p5: allprop is TRUE");
UCX_TEST_ASSERT(!p5->propname,
"p5: propname is TRUE");
UCX_TEST_ASSERT(p5->propcount ==
4,
"p5: wrong propcount");
elm = p5->properties;
UCX_TEST_ASSERT(elm,
"p5: property 1 missing");
UCX_TEST_ASSERT(
!strcmp(elm->property->name,
"displayname"),
"p5: property 1 has wrong name");
UCX_TEST_ASSERT(
!strcmp((
char*)elm->property->namespace->href,
"DAV:"),
"p5: property 1 has wrong namespace");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p5: property 2 missing");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p5: property 3 missing");
elm = elm->next;
UCX_TEST_ASSERT(elm,
"p5: property 4 missing");
UCX_TEST_ASSERT(
!strcmp(elm->property->name,
"resourcetype"),
"p5: property 4 has wrong name");
UCX_TEST_ASSERT(
!strcmp((
char*)elm->property->namespace->href,
"DAV:"),
"p5: property 4 has wrong namespace");
WebdavPropfindRequest *p6 = propfind_parse(sn, rq,
TEST_PROPFIND6, strlen(
TEST_PROPFIND6), &error);
UCX_TEST_ASSERT(p6,
"p5 is NULL");
UCX_TEST_ASSERT(!p6->properties,
"p5: has props");
UCX_TEST_ASSERT(p6->allprop,
"p5: allprop is FALSE");
UCX_TEST_ASSERT(!p6->propname,
"p5: propname is TRUE");
UCX_TEST_ASSERT(p6->propcount ==
0,
"p5: wrong propcount");
UCX_TEST_END
pool_destroy(sn->pool);
}
UCX_TEST(test_proppatch_parse) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PROPPATCH",
"/");
UCX_TEST_BEGIN
int error =
0;
WebdavProppatchRequest *p1 = proppatch_parse(sn, rq,
TEST_PROPPATCH1, strlen(
TEST_PROPPATCH1), &error);
UCX_TEST_ASSERT(p1->set,
"p1: missing set props");
UCX_TEST_ASSERT(!p1->remove,
"p1: has remove props");
UCX_TEST_ASSERT(p1->setcount ==
2,
"p1: wrong setcount");
UCX_TEST_ASSERT(p1->set->next,
"p1: set plist broken");
UCX_TEST_ASSERT(!p1->set->next->next,
"p1: set plist has no end");
UCX_TEST_ASSERT(p1->set->property,
"p1: missing property ptr in plist");
UCX_TEST_ASSERT(
!strcmp(p1->set->property->name,
"test"),
"p1: wrong property 1 name");
WebdavProppatchRequest *p2 = proppatch_parse(sn, rq,
TEST_PROPPATCH2, strlen(
TEST_PROPPATCH2), &error);
UCX_TEST_ASSERT(p2->set,
"p2: missing set props");
UCX_TEST_ASSERT(p2->remove,
"p2: missing remove props");
UCX_TEST_ASSERT(p2->setcount ==
4,
"p2: wrong setcount");
UCX_TEST_ASSERT(p2->removecount ==
1,
"p2: wrong removecount");
UCX_TEST_ASSERT(
!strcmp((
char*)p2->set->property->namespace->href,
"http://example.com/"),
"p2: set property 1: wrong namespace");
UCX_TEST_ASSERT(
!strcmp(p2->set->property->name,
"a"),
"p2: set property 1: wrong name");
WSXmlNode *p2set1 = p2->set->property->value.node;
UCX_TEST_ASSERT(
p2set1->type ==
WS_NODE_TEXT,
"p2: set property 1: wrong type");
UCX_TEST_ASSERT(
p2set1->content,
"p2: set property 1: no text");
UCX_TEST_ASSERT(
!strcmp((
char*)p2set1->content,
"test"),
"p2: set property 1: wrong value");
WSXmlNode *p2set3 = p2->set->next->next->property->value.node;
UCX_TEST_ASSERT(p2set3,
"p2: set property 3 missing");
UCX_TEST_ASSERT(
p2set3->type ==
WS_NODE_TEXT,
"p2: set property 3: wrong type");
UCX_TEST_ASSERT(
p2set3->next,
"p2: set property 3: missing element X:name");
UCX_TEST_ASSERT(
xmlHasProp(p2set3->next,
"test"BAD_CAST),
"p2: set property 3: missing attribute ''test''");
UCX_TEST_ASSERT(
xmlHasProp(p2set3->next,
"abc"BAD_CAST),
"p2: set property 3: missing attribute ''abc");
xmlChar *value1 = xmlGetProp(p2set3->next,
"test"BAD_CAST);
UCX_TEST_ASSERT(
!strcmp((
char*) value1,
"test1"),
"p2: set property 3: wrong attribute value 1");
xmlFree(value1);
xmlChar *value2 = xmlGetProp(p2set3->next,
"abc"BAD_CAST);
UCX_TEST_ASSERT(
!strcmp((
char*) value2,
"def"),
"p2: set property 3: wrong attribute value 2");
xmlFree(value2);
UCX_TEST_ASSERT(
!strcmp(p2->remove->property->name,
"e"),
"p2: wrong remove property");
UCX_TEST_END
pool_destroy(sn->pool);
}
UCX_TEST(test_lock_parse) {
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"LOCK",
"/");
UCX_TEST_BEGIN
int error =
0;
WebdavLockRequest *l1 = lock_parse(sn, rq,
TEST_LOCK1, strlen(
TEST_LOCK1), &error);
UCX_TEST_ASSERT(l1,
"l1 is NULL");
UCX_TEST_ASSERT(l1->type ==
WEBDAV_LOCK_WRITE,
"l1: wrong type");
UCX_TEST_ASSERT(l1->scope ==
WEBDAV_LOCK_SHARED,
"l1: wrong scope");
UCX_TEST_ASSERT(l1->owner,
"l1: owner is NULL");
UCX_TEST_ASSERT(!strcmp((
char*)l1->owner->content,
"User"),
"l1: wrong owner");
UCX_TEST_END
pool_destroy(sn->pool);
}
UCX_TEST(test_rqbody2buffer) {
Session *sn;
Request *rq;
UCX_TEST_BEGIN;
sn = testutil_session();
rq = testutil_request(sn->pool,
"PUT",
"/");
testutil_request_body(sn, rq,
"Hello World!",
12);
CxBuffer b1;
rqbody2buffer(sn, rq, &b1);
UCX_TEST_ASSERT(b1.size ==
12,
"b1: wrong size");
UCX_TEST_ASSERT(!memcmp(b1.space,
"Hello World!",
12),
"b1: wrong content");
cxBufferDestroy(&b1);
testutil_destroy_session(sn);
size_t len1 =
25000;
unsigned char *body1 = malloc(len1);
for(
int i=
0;i<len1;i++) {
body1[i] = i;
}
sn = testutil_session();
rq = testutil_request(sn->pool,
"PUT",
"/");
testutil_request_body(sn, rq, (
char*)body1, len1);
CxBuffer b2;
rqbody2buffer(sn, rq, &b2);
UCX_TEST_ASSERT(b2.size == len1,
"b2: wrong size");
UCX_TEST_ASSERT(!memcmp(b2.space, body1, len1),
"b2: wrong content");
cxBufferDestroy(&b2);
testutil_destroy_session(sn);
UCX_TEST_END;
}
UCX_TEST(test_webdav_plist_iterator) {
Session *sn;
Request *rq;
WebdavPropfindRequest *propfind;
UCX_TEST_BEGIN;
UCX_TEST_ASSERT(!test_init(&sn, &rq, &propfind,
TEST_PROPFIND1),
"init failed");
WebdavPList *properties = propfind->properties;
size_t count =
0;
WebdavPListIterator i = webdav_plist_iterator(&properties);
WebdavPList *cur;
while(webdav_plist_iterator_next(&i, &cur)) {
switch(i.index) {
case 0: {
UCX_TEST_ASSERT(!strcmp(cur->property->name,
"displayname"),
"wrong property 1");
break;
}
case 1: {
UCX_TEST_ASSERT(!strcmp(cur->property->name,
"getcontentlength"),
"wrong property 2");
break;
}
case 2: {
UCX_TEST_ASSERT(!strcmp(cur->property->name,
"getcontenttype"),
"wrong property 3");
break;
}
case 3: {
UCX_TEST_ASSERT(!strcmp(cur->property->name,
"getlastmodified"),
"wrong property 4");
break;
}
case 4: {
UCX_TEST_ASSERT(!strcmp(cur->property->name,
"resourcetype"),
"wrong property 5");
break;
}
case 5: {
UCX_TEST_ASSERT(!strcmp(cur->property->name,
"getetag"),
"wrong property 6");
break;
}
}
count++;
}
UCX_TEST_ASSERT(count == propfind->propcount,
"wrong count");
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_webdav_plist_iterator_remove_current) {
Session *sn;
Request *rq;
WebdavPropfindRequest *propfind;
UCX_TEST_BEGIN;
UCX_TEST_ASSERT(!test_init(&sn, &rq, &propfind,
TEST_PROPFIND1),
"init failed");
WebdavPList *properties1 = webdav_plist_clone(sn->pool, propfind->properties);
WebdavPList *properties2 = webdav_plist_clone(sn->pool, propfind->properties);
WebdavPList *properties3 = webdav_plist_clone(sn->pool, propfind->properties);
WebdavPList *properties4 = webdav_plist_clone(sn->pool, propfind->properties);
WebdavPListIterator i;
WebdavPList *cur;
i = webdav_plist_iterator(&properties1);
while(webdav_plist_iterator_next(&i, &cur)) {
if(i.index ==
0) {
webdav_plist_iterator_remove_current(&i);
}
}
UCX_TEST_ASSERT(!properties1->prev,
"test1: prev not cleared");
UCX_TEST_ASSERT(!strcmp(properties1->property->name,
"getcontentlength"),
"test1: wrong property");
UCX_TEST_ASSERT(!strcmp(properties1->next->property->name,
"getcontenttype"),
"test1: wrong property 2");
UCX_TEST_ASSERT(properties1->next->prev == properties1,
"test1: wrong link");
i = webdav_plist_iterator(&properties2);
while(webdav_plist_iterator_next(&i, &cur)) {
if(i.index ==
1) {
webdav_plist_iterator_remove_current(&i);
}
}
UCX_TEST_ASSERT(!strcmp(properties2->next->property->name,
"getcontenttype"),
"test2: wrong property");
UCX_TEST_ASSERT(properties2->next->prev == properties2,
"test2: wrong link");
UCX_TEST_ASSERT(webdav_plist_size(properties2) ==
5,
"test2: wrong size");
i = webdav_plist_iterator(&properties3);
while(webdav_plist_iterator_next(&i, &cur)) {
if(i.index ==
5) {
webdav_plist_iterator_remove_current(&i);
}
}
UCX_TEST_ASSERT(webdav_plist_size(properties3) ==
5,
"test3: wrong size");
UCX_TEST_ASSERT(!strcmp(properties3->next->next->next->next->property->name,
"resourcetype"),
"test2: wrong property");
i = webdav_plist_iterator(&properties4);
while(webdav_plist_iterator_next(&i, &cur)) {
webdav_plist_iterator_remove_current(&i);
switch(i.index) {
case 0: {
UCX_TEST_ASSERT(!strcmp(properties4->property->name,
"getcontentlength"),
"test4: wrong property 2");
UCX_TEST_ASSERT(properties4->prev ==
NULL,
"test4: prev not NULL (0)");
break;
}
case 1: {
UCX_TEST_ASSERT(!strcmp(properties4->property->name,
"getcontenttype"),
"test4: wrong property 3");
UCX_TEST_ASSERT(properties4->prev ==
NULL,
"test4: prev not NULL (1)");
break;
}
case 2: {
UCX_TEST_ASSERT(!strcmp(properties4->property->name,
"getlastmodified"),
"test4: wrong property 4");
UCX_TEST_ASSERT(properties4->prev ==
NULL,
"test4: prev not NULL (2)");
break;
}
case 3: {
UCX_TEST_ASSERT(!strcmp(properties4->property->name,
"resourcetype"),
"test4: wrong property 5");
UCX_TEST_ASSERT(properties4->prev ==
NULL,
"test4: prev not NULL (3)");
break;
}
case 4: {
UCX_TEST_ASSERT(!strcmp(properties4->property->name,
"getetag"),
"test4: wrong property 6");
UCX_TEST_ASSERT(properties4->prev ==
NULL,
"test4: prev not NULL (4)");
break;
}
default: {
UCX_TEST_ASSERT(i.index <=
5,
"fail");
}
}
}
UCX_TEST_ASSERT(properties4 ==
NULL,
"test4: list not NULL");
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_msresponse_addproperty) {
Session *sn;
Request *rq;
UCX_TEST_BEGIN;
WebdavOperation *op = test_propfind_op(&sn, &rq,
TEST_PROPFIND1);
UCX_TEST_ASSERT(op,
"init failed");
UCX_TEST_ASSERT(op->response,
"no response");
Multistatus *ms = (Multistatus*)op->response;
MSResponse *r = (MSResponse*)ms->response.addresource((WebdavResponse*)ms,
"/");
WebdavProperty p1;
WebdavProperty p[
16];
const char *names[] = {
"a1",
"a2",
"a3",
"a4",
"a5",
"a6",
"a7",
"a8",
"a9"};
WSNamespace ns1;
ZERO(&ns1,
sizeof(WSNamespace));
WSNamespace ns2;
ZERO(&ns2,
sizeof(WSNamespace));
ns1.prefix = (xmlChar*)
"x1";
ns1.href = (xmlChar*)
"http://example.com/test/";
ns2.prefix = (xmlChar*)
"x2";
ns2.href = (xmlChar*)
"http://example.com/test/";
WebdavProperty dp1;
ZERO(&dp1,
sizeof(WebdavProperty));
dp1.name =
"dup";
dp1.namespace = &ns1;
dp1.value.text.str =
"Hello";
dp1.value.text.length =
5;
dp1.vtype =
WS_VALUE_TEXT;
WebdavProperty dp2;
ZERO(&dp2,
sizeof(WebdavProperty));
dp2.name =
"dup";
dp2.namespace = &ns1;
dp2.value.text.str =
"Hello";
dp2.value.text.length =
5;
dp2.vtype =
WS_VALUE_TEXT;
WebdavProperty dp3;
ZERO(&dp3,
sizeof(WebdavProperty));
dp3.name =
"dup";
dp3.namespace = &ns2;
dp3.value.text.str =
"Hello";
dp3.value.text.length =
5;
dp3.vtype =
WS_VALUE_TEXT;
p1.namespace = webdav_dav_namespace();
p1.lang =
NULL;
p1.name =
"test1";
p1.value.data = (WSXmlData){
NULL,
NULL,
0};
p1.vtype =
0;
for(
int i=
0;i<
8;i++) {
p[i].namespace = webdav_dav_namespace();
p[i].name = names[i];
p[i].lang =
NULL;
p[i].value.node =
NULL;
p[
1].vtype =
0;
}
UCX_TEST_ASSERT(!r->plist_begin && !r->plist_end,
"plist not empty");
r->resource.addproperty((WebdavResource*)r, &p1,
200);
UCX_TEST_ASSERT(r->plist_begin,
"!plist_begin");
UCX_TEST_ASSERT(r->plist_begin == r->plist_end,
"plist begin != end");
r->resource.addproperty((WebdavResource*)r, &p[
0],
404);
r->resource.addproperty((WebdavResource*)r, &p[
1],
404);
r->resource.addproperty((WebdavResource*)r, &p[
2],
403);
r->resource.addproperty((WebdavResource*)r, &p[
3],
403);
r->resource.addproperty((WebdavResource*)r, &p[
4],
403);
r->resource.addproperty((WebdavResource*)r, &p[
5],
403);
r->resource.addproperty((WebdavResource*)r, &p[
6],
500);
UCX_TEST_ASSERT(r->plist_begin == r->plist_end,
"plist begin != end");
UCX_TEST_ASSERT(r->errors,
"no prop errors");
UCX_TEST_ASSERT(r->errors->next,
"no second error code");
UCX_TEST_ASSERT(r->errors->next->next,
"no third error code");
UCX_TEST_ASSERT(!r->errors->next->next->next,
"too many error codes");
UCX_TEST_ASSERT(webdav_plist_size(r->errors->begin) ==
2,
"404 list size != 2");
UCX_TEST_ASSERT(webdav_plist_size(r->errors->next->begin) ==
4,
"403 list size != 4");
UCX_TEST_ASSERT(webdav_plist_size(r->errors->next->next->begin) ==
1,
"500 list size != 1");
r = (MSResponse*)ms->response.addresource((WebdavResponse*)ms,
"/test");
UCX_TEST_ASSERT(r,
"cannot create second response");
r->resource.addproperty((WebdavResource*)r, &dp1,
200);
UCX_TEST_ASSERT(r->plist_begin,
"adding dp1 failed");
UCX_TEST_ASSERT(!r->plist_begin->next,
"dp1: list size not 1");
r->resource.addproperty((WebdavResource*)r, &dp2,
200);
UCX_TEST_ASSERT(!r->plist_begin->next,
"dp1: adding dp2 should not work");
r->resource.addproperty((WebdavResource*)r, &dp2,
404);
UCX_TEST_ASSERT(!r->plist_begin->next,
"dp1: adding dp2 with different status should not work (1)");
if(r->errors) {
UCX_TEST_ASSERT(webdav_plist_size(r->errors->begin) ==
0,
"dp1: error list not empty");
}
r->resource.addproperty((WebdavResource*)r, &dp3,
200);
UCX_TEST_ASSERT(!r->plist_begin->next,
"dp1: adding dp3 should not work");
UCX_TEST_END;
}
UCX_TEST(test_webdav_propfind_init) {
reset_backends();
Session *sn;
Request *rq;
WebdavPropfindRequest *propfind;
UCX_TEST_BEGIN;
UCX_TEST_ASSERT(!test_init(&sn, &rq, &propfind,
TEST_PROPFIND1),
"init failed");
WebdavPropfindRequestList *requests =
NULL;
int err = webdav_propfind_init(&backend1, propfind,
"/",
"/", &requests);
UCX_TEST_ASSERT(!err,
"webdav_propfind_init failed");
UCX_TEST_ASSERT(requests,
"request list is empty");
UCX_TEST_ASSERT(cx_linked_list_size(requests, offsetof(WebdavPropfindRequestList, next)),
"request list has wrong size");
WebdavPropfindRequest *p1 = requests->propfind;
WebdavPropfindRequest *p2 = requests->next->propfind;
UCX_TEST_ASSERT(p1 && p2,
"missing requests objects");
UCX_TEST_ASSERT(p1 != p2,
"request objects equal");
UCX_TEST_ASSERT(p1->properties != p2->properties,
"plists equal");
UCX_TEST_ASSERT(p1->propcount == p2->propcount +
1,
"first property not removed");
UCX_TEST_ASSERT(backend1_init_called ==
1,
"backend1 init not called");
UCX_TEST_ASSERT(backend2_init_called ==
1,
"backend2 init not called");
UCX_TEST_END;
pool_destroy(sn->pool);
}
UCX_TEST(test_webdav_op_propfind_begin) {
reset_backends();
Session *sn;
Request *rq;
UCX_TEST_BEGIN;
WebdavOperation *op = test_propfind_op(&sn, &rq,
TEST_PROPFIND1);
UCX_TEST_ASSERT(op,
"WebdavOperation not created");
int err = webdav_op_propfind_begin(op,
"/",
NULL,
NULL);
UCX_TEST_ASSERT(err ==
0,
"err not 0");
UCX_TEST_ASSERT(backend1_propfind_do_count ==
1,
"backend1 propfind_do not called");
UCX_TEST_ASSERT(backend2_propfind_do_count ==
1,
"backend2 propfind_do not called");
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_webdav_op_propfind_children) {
reset_backends();
Session *sn;
Request *rq;
UCX_TEST_BEGIN;
WebdavOperation *op = test_propfind_op(&sn, &rq,
TEST_PROPFIND1);
UCX_TEST_ASSERT(op,
"WebdavOperation not created");
int err = webdav_op_propfind_begin(op,
"/",
NULL,
NULL);
UCX_TEST_ASSERT(err ==
0,
"propfind_begin error");
rq->vfs = testvfs_create(sn);
VFSContext *vfs = vfs_request_context(sn, rq);
UCX_TEST_ASSERT(vfs,
"no vfs");
err = vfs_mkdir(vfs,
"/dir");
UCX_TEST_ASSERT(err ==
0,
"error not 0");
UCX_TEST_ASSERT(vfs_open(vfs,
"/dir/file1",
O_CREAT),
"creation of file1 failed");
UCX_TEST_ASSERT(vfs_open(vfs,
"/dir/file2",
O_CREAT),
"creation of file2 failed");
UCX_TEST_ASSERT(vfs_open(vfs,
"/dir/file3",
O_CREAT),
"creation of file3 failed");
UCX_TEST_ASSERT(vfs_open(vfs,
"/dir/file4",
O_CREAT),
"creation of file4 failed");
VFSDir *dir = vfs_opendir(vfs,
"/dir");
UCX_TEST_ASSERT(dir,
"dir not opened");
UCX_TEST_ASSERT(backend1_propfind_do_count ==
1,
"backend1 propfind_do not called");
UCX_TEST_ASSERT(backend2_propfind_do_count ==
1,
"backend1 propfind_do not called")
err = webdav_op_propfind_children(op, vfs,
"/",
"/dir");
UCX_TEST_ASSERT(err ==
0,
"webdav_op_propfind_children failed");
UCX_TEST_ASSERT(backend1_propfind_do_count ==
5,
"backend1 propfind_do wrong count");
UCX_TEST_ASSERT(backend2_propfind_do_count ==
5,
"backend2 propfind_do wrong count");
UCX_TEST_END;
testutil_destroy_session(sn);
}
void init_test_webdav_method(
Session **out_sn,
Request **out_rq,
TestIOStream **out_st,
pblock **out_pb,
const char *method,
const char *path,
const char *request_body)
{
Session *sn;
Request *rq;
TestIOStream *st;
pblock *pb;
sn = testutil_session();
rq = testutil_request(sn->pool, method,
"/");
pblock_nvinsert(
"path", path, rq->vars);
pblock_nvinsert(
"uri", path, rq->reqpb);
st = testutil_iostream(
2048,
TRUE);
sn->csd = (IOStream*)st;
if(request_body) {
testutil_request_body(sn, rq, request_body, strlen(request_body));
}
pb = pblock_create_pool(sn->pool,
4);
*out_sn = sn;
*out_rq = rq;
*out_st = st;
*out_pb = pb;
}
UCX_TEST(test_webdav_propfind) {
Session *sn;
Request *rq;
TestIOStream *st;
pblock *pb;
UCX_TEST_BEGIN;
int ret;
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/",
TEST_PROPFIND1);
ret = webdav_propfind(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (1) failed");
xmlDoc *doc = xmlReadMemory(
st->buf->space, st->buf->size,
NULL,
NULL,
0);
UCX_TEST_ASSERT(doc,
"propfind1: response is not valid xml");
testutil_destroy_session(sn);
xmlFreeDoc(doc);
testutil_iostream_destroy(st);
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPFIND",
"/",
TEST_PROPFIND2);
ret = webdav_propfind(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_propfind (2) failed");
xmlDoc *doc2 = xmlReadMemory(
st->buf->space, st->buf->size,
NULL,
NULL,
0);
UCX_TEST_ASSERT(doc,
"propfind2: response is not valid xml");
testutil_destroy_session(sn);
xmlFreeDoc(doc2);
testutil_iostream_destroy(st);
UCX_TEST_END;
}
static int test_proppatch_init(
Session **out_sn,
Request **out_rq,
WebdavProppatchRequest **out_proppatch,
const char *xml)
{
if(!webdav_is_initialized) {
if(webdav_init(
NULL,
NULL,
NULL) !=
REQ_PROCEED) {
return 1;
}
webdav_is_initialized =
1;
}
Session *sn = testutil_session();
Request *rq = testutil_request(sn->pool,
"PROPPATCH",
"/");
int error =
0;
WebdavProppatchRequest *proppatch = proppatch_parse(
sn,
rq,
xml,
strlen(xml),
&error);
if(error) {
return 1;
}
if(!proppatch || !(proppatch->set || proppatch->remove)) {
return 1;
}
*out_sn = sn;
*out_rq = rq;
*out_proppatch = proppatch;
return 0;
}
static WebdavOperation* test_proppatch_op1(
Session **out_sn,
Request **out_rq,
const char *xml)
{
WebdavProppatchRequest *proppatch;
if(test_proppatch_init(out_sn, out_rq, &proppatch, xml)) {
return NULL;
}
Multistatus *ms = multistatus_response(*out_sn, *out_rq);
if(!ms) {
return NULL;
}
WebdavResponse *response = (WebdavResponse*)ms;
return webdav_create_proppatch_operation(
(*out_sn),
(*out_rq),
&backend1,
proppatch,
response);
}
UCX_TEST(test_proppatch_msresponse) {
Session *sn;
Request *rq;
WebdavOperation *op;
Multistatus *ms;
WebdavResource *res;
WebdavProperty p[
16];
const char *names[] = {
"a1",
"a2",
"a3",
"a4",
"a5",
"a6",
"a7",
"a8",
"a9"};
for(
int i=
0;i<
8;i++) {
p[i].namespace = webdav_dav_namespace();
p[i].name = names[i];
p[i].lang =
NULL;
p[i].value.node =
NULL;
p[i].vtype =
0;
}
UCX_TEST_BEGIN;
op = test_proppatch_op1(&sn, &rq,
TEST_PROPPATCH2);
UCX_TEST_ASSERT(op,
"failed to create proppatch operation");
ms = (Multistatus*)op->response;
ms->proppatch =
TRUE;
res = ms->response.addresource(&ms->response,
"/");
UCX_TEST_ASSERT(res,
"cannot create resource 1");
UCX_TEST_ASSERT(!res->addproperty(res, &p[
0],
200),
"addproperty 1 failed");
UCX_TEST_ASSERT(!res->addproperty(res, &p[
1],
200),
"addproperty 2 failed");
UCX_TEST_ASSERT(!res->addproperty(res, &p[
2],
200),
"addproperty 3 failed");
UCX_TEST_ASSERT(!res->addproperty(res, &p[
3],
200),
"addproperty 4 failed");
UCX_TEST_ASSERT(!res->close(res),
"close failed");
MSResponse *msres = (MSResponse*)res;
UCX_TEST_ASSERT(!msres->errors,
"error list not NULL");
UCX_TEST_ASSERT(msres->plist_begin,
"elm1 missing");
UCX_TEST_ASSERT(msres->plist_begin->next,
"elm2 missing");
UCX_TEST_ASSERT(msres->plist_begin->next->next,
"elm3 missing");
UCX_TEST_ASSERT(msres->plist_begin->next->next->next,
"elm4 missing");
UCX_TEST_ASSERT(!msres->plist_begin->next->next->next->next,
"count != 4");
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_msresponse_addproperty_with_errors) {
Session *sn;
Request *rq;
WebdavOperation *op;
Multistatus *ms;
WebdavResource *res;
WebdavProperty p[
16];
const char *names[] = {
"a1",
"a2",
"a3",
"a4",
"a5",
"a6",
"a7",
"a8",
"a9"};
for(
int i=
0;i<
8;i++) {
p[i].namespace = webdav_dav_namespace();
p[i].name = names[i];
p[i].lang =
NULL;
p[i].value.node =
NULL;
p[i].vtype =
0;
}
UCX_TEST_BEGIN;
op = test_proppatch_op1(&sn, &rq,
TEST_PROPPATCH2);
UCX_TEST_ASSERT(op,
"failed to create proppatch operation");
ms = (Multistatus*)op->response;
ms->proppatch =
TRUE;
res = ms->response.addresource(&ms->response,
"/");
UCX_TEST_ASSERT(res,
"cannot create resource 1");
UCX_TEST_ASSERT(!res->addproperty(res, &p[
0],
200),
"addproperty 1 failed");
UCX_TEST_ASSERT(!res->addproperty(res, &p[
1],
200),
"addproperty 2 failed");
UCX_TEST_ASSERT(!res->addproperty(res, &p[
2],
409),
"addproperty 3 failed");
UCX_TEST_ASSERT(!res->addproperty(res, &p[
3],
200),
"addproperty 4 failed");
UCX_TEST_ASSERT(!res->close(res),
"close failed");
MSResponse *msres = (MSResponse*)res;
UCX_TEST_ASSERT(!msres->plist_begin,
"plist not NULL");
UCX_TEST_ASSERT(msres->errors,
"error list is NULL");
UCX_TEST_ASSERT(msres->errors->next,
"second error list is missing");
UCX_TEST_ASSERT(!msres->errors->next->next,
"wrong error list size");
if(msres->errors->status ==
409) {
UCX_TEST_ASSERT(msres->errors->next->status ==
424,
"wrong status code in second err elm");
UCX_TEST_ASSERT(msres->errors->begin,
"missing 409 property");
UCX_TEST_ASSERT(msres->errors->next->begin,
"missing 424 properties");
}
else {
UCX_TEST_ASSERT(msres->errors->next->status ==
409,
"wrong status code in second err elm");
UCX_TEST_ASSERT(msres->errors->begin,
"missing 424 properties");
UCX_TEST_ASSERT(msres->errors->next->begin,
"missing 409 property");
}
UCX_TEST_END;
testutil_destroy_session(sn);
}
UCX_TEST(test_webdav_op_proppatch) {
Session *sn;
Request *rq;
WebdavOperation *op;
Multistatus *ms;
WebdavResource *res;
WebdavProperty p[
16];
const char *names[] = {
"a1",
"a2",
"a3",
"a4",
"a5",
"a6",
"a7",
"a8",
"a9"};
for(
int i=
0;i<
8;i++) {
p[i].namespace = webdav_dav_namespace();
p[i].name = names[i];
p[i].lang =
NULL;
p[i].value.node =
NULL;
p[
1].vtype =
0;
}
UCX_TEST_BEGIN;
reset_backends();
op = test_proppatch_op1(&sn, &rq,
TEST_PROPPATCH2);
UCX_TEST_ASSERT(op,
"failed to create proppatch operation");
int ret = webdav_op_proppatch(op,
"/",
"/");
UCX_TEST_ASSERT(ret ==
0,
"webdav_op_proppatch failed");
UCX_TEST_ASSERT(backend1_proppatch_commit,
"backend1 no commit");
UCX_TEST_ASSERT(backend2_proppatch_commit,
"backend2 no commit");
UCX_TEST_ASSERT(backend1_proppatch_do_count ==
1,
"backend1 wrong count (1)");
UCX_TEST_ASSERT(backend2_proppatch_do_count ==
1,
"backend1 wrong count (1)");
UCX_TEST_ASSERT(backend1_proppatch_finish_count ==
1,
"backend1 wrong finish count (1)");
UCX_TEST_ASSERT(backend2_proppatch_finish_count ==
1,
"backend1 wrong finish count (1)");
reset_backends();
op = test_proppatch_op1(&sn, &rq,
TEST_PROPPATCH3);
UCX_TEST_ASSERT(op,
"failed to create proppatch operation 2");
ret = webdav_op_proppatch(op,
"/",
"/");
UCX_TEST_ASSERT(ret ==
0,
"webdav_op_proppatch failed (2)");
UCX_TEST_ASSERT(!backend1_proppatch_commit,
"backend1 commit");
UCX_TEST_ASSERT(!backend2_proppatch_commit,
"backend2 commit");
reset_backends();
op = test_proppatch_op1(&sn, &rq,
TEST_PROPPATCH4);
UCX_TEST_ASSERT(op,
"failed to create proppatch operation 3");
ret = webdav_op_proppatch(op,
"/",
"/");
UCX_TEST_ASSERT(ret !=
0,
"webdav_op_proppatch should fail");
UCX_TEST_ASSERT(backend1_proppatch_do_count ==
1,
"backend1 wrong count (2)");
UCX_TEST_ASSERT(backend2_proppatch_do_count ==
1,
"backend1 wrong count (2)");
UCX_TEST_ASSERT(backend1_proppatch_finish_count ==
1,
"backend1 wrong finish count (2)");
UCX_TEST_ASSERT(backend2_proppatch_finish_count ==
0,
"backend1 wrong finish count (2)");
UCX_TEST_END;
testutil_destroy_session(sn);
}
#define xstreq(a, b) (!strcmp((
const char*)a, (
const char*)b))
UCX_TEST(test_webdav_proppatch) {
Session *sn;
Request *rq;
TestIOStream *st;
pblock *pb;
UCX_TEST_BEGIN;
int ret;
init_test_webdav_method(&sn, &rq, &st, &pb,
"PROPPATCH",
"/",
TEST_PROPPATCH2);
rq->davCollection = &backend1;
ret = webdav_proppatch(pb, sn, rq);
UCX_TEST_ASSERT(ret ==
REQ_PROCEED,
"webdav_proppatch (1) failed");
xmlDoc *doc = xmlReadMemory(
st->buf->space, st->buf->size,
NULL,
NULL,
0);
UCX_TEST_ASSERT(doc,
"proppatch1: response is not valid xml");
xmlNode *root = xmlDocGetRootElement(doc);
UCX_TEST_ASSERT(root,
"proppatch1: no root");
xmlNode *nodeC =
NULL;
xmlNode *node = root->children;
int depth =
1;
while(node) {
const xmlChar *name = node->name;
int nextNode =
1;
if(node->type !=
XML_ELEMENT_NODE) {
}
else if(depth ==
1) {
if(xstreq(name,
"response")) {
nextNode =
0;
}
}
else if(depth ==
2) {
if(xstreq(name,
"propstat")) {
nextNode =
0;
}
}
else if(depth ==
3) {
if(xstreq(name,
"prop")) {
nextNode =
0;
}
}
else if(depth ==
4) {
if(xstreq(name,
"c")) {
nodeC = node;
break;
}
}
if(nextNode) {
node = node->next;
}
else {
node = node->children;
depth++;
}
}
UCX_TEST_ASSERT(nodeC,
"prop c not in response");
UCX_TEST_ASSERT(!nodeC->children,
"properties must not have a value");
testutil_destroy_session(sn);
xmlFreeDoc(doc);
testutil_iostream_destroy(st);
UCX_TEST_END;
}
static int mkcol_data1 =
10;
static int mkcol_data2 =
20;
static int mkcol_data3 =
30;
static int mkcol_data4 =
40;
static int mkcol_count =
0;
static int mkcol_finish_count =
0;
static int mkcol_err =
0;
static int set_created =
0;
static int test_webdav_mkcol(WebdavVFSRequest *req, WSBool *created) {
mkcol_count++;
switch(mkcol_count) {
case 1: {
req->userdata = &mkcol_data1;
break;
}
case 2: {
req->userdata = &mkcol_data2;
break;
}
case 3: {
req->userdata = &mkcol_data3;
break;
}
case 4: {
req->userdata = &mkcol_data4;
break;
}
default:
break;
}
if(set_created) {
*created =
TRUE;
set_created =
0;
}
return 0;
}
static int test_webdav_mkcol_finish(WebdavVFSRequest *req, WSBool success) {
mkcol_finish_count++;
if(mkcol_finish_count ==
1) {
int *data = req->userdata;
if(data != &mkcol_data1) {
mkcol_err =
1;
}
}
else if(mkcol_finish_count ==
3) {
int *data = req->userdata;
if(data != &mkcol_data3) {
mkcol_err =
1;
}
}
else {
int *data = req->userdata;
if(data == &mkcol_data4) {
mkcol_err =
1;
}
}
return 0;
}
static int test_webdav_mkcol_fail(WebdavVFSRequest *req, WSBool *created) {
mkcol_count++;
return 1;
}
static int delete_count =
0;
static int delete_finish_count =
0;
static int test_backend_webdav_delete(WebdavVFSRequest *req, WSBool *created) {
delete_count++;
return 0;
}
static int test_backend_webdav_delete_finish(WebdavVFSRequest *req, WSBool success) {
delete_finish_count++;
return 0;
}
UCX_TEST(test_webdav_vfs_op_do) {
Session *sn;
Request *rq;
TestIOStream *st;
pblock *pb;
init_test_webdav_method(&sn, &rq, &st, &pb,
"MKCOL",
"/",
NULL);
VFS *testvfs = testvfs_create(sn);
rq->vfs = testvfs;
WebdavBackend dav1;
ZERO(&dav1,
sizeof(WebdavBackend));
dav1.opt_mkcol = test_webdav_mkcol;
dav1.opt_mkcol_finish = test_webdav_mkcol_finish;
dav1.opt_delete = test_backend_webdav_delete;
dav1.opt_delete_finish = test_backend_webdav_delete_finish;
WebdavBackend dav2;
ZERO(&dav2,
sizeof(WebdavBackend));
dav2.opt_mkcol_finish = test_webdav_mkcol_finish;
WebdavBackend dav3;
ZERO(&dav3,
sizeof(WebdavBackend));
dav3.opt_mkcol = test_webdav_mkcol;
WebdavBackend dav4;
ZERO(&dav4,
sizeof(WebdavBackend));
dav4.opt_mkcol = test_webdav_mkcol;
dav4.opt_mkcol_finish = test_webdav_mkcol_finish;
dav1.next = &dav2;
dav2.next = &dav3;
dav3.next = &dav4;
rq->davCollection = &dav1;
UCX_TEST_BEGIN;
WebdavVFSOperation *op1 = webdav_vfs_op(sn, rq, &dav1,
FALSE);
int ret = webdav_vfs_op_do(op1,
WEBDAV_VFS_MKDIR);
UCX_TEST_ASSERT(!ret,
"webdav_vfs_op_do failed");
UCX_TEST_ASSERT(mkcol_count ==
3,
"wrong mkcol_count");
UCX_TEST_ASSERT(mkcol_finish_count ==
3,
"wrong mkcol_finish_count");
UCX_TEST_ASSERT(mkcol_err ==
0,
"mkcol_err");
rq->vfs =
NULL;
set_created =
1;
WebdavVFSOperation *op2 = webdav_vfs_op(sn, rq, &dav1,
FALSE);
ret = webdav_vfs_op_do(op2,
WEBDAV_VFS_MKDIR);
UCX_TEST_ASSERT(!ret,
"op2 failed");
mkcol_count =
0;
mkcol_finish_count =
0;
dav1.opt_mkcol = test_webdav_mkcol_fail;
WebdavVFSOperation *op3 = webdav_vfs_op(sn, rq, &dav1,
FALSE);
ret = webdav_vfs_op_do(op3,
WEBDAV_VFS_MKDIR);
UCX_TEST_ASSERT(ret,
"op3 should fail");
UCX_TEST_ASSERT(mkcol_count ==
1,
"op3: wrong mkcol_count");
UCX_TEST_ASSERT(mkcol_finish_count ==
1,
"op3: wrong mkcol_finish_count");
pblock_replace(
"path",
"/deltest", rq->vars);
rq->vfs = testvfs;
WebdavVFSOperation *op_del = webdav_vfs_op(sn, rq, &dav1,
FALSE);
vfs_open(op_del->vfs,
"/deltest",
O_CREAT);
ret = webdav_vfs_op_do(op_del,
WEBDAV_VFS_DELETE);
UCX_TEST_ASSERT(!ret,
"op_del failed");
UCX_TEST_ASSERT(delete_count ==
1,
"op_del: wrong delete_count");
UCX_TEST_ASSERT(delete_finish_count ==
1,
"op_del: wrong delete_finish_count");
UCX_TEST_END;
}
UCX_TEST(test_webdav_delete){
Session *sn;
Request *rq;
TestIOStream *st;
pblock *pb;
init_test_webdav_method(&sn, &rq, &st, &pb,
"DELETE",
"/",
NULL);
rq->vfs = testvfs_create(sn);
WebdavBackend dav1;
ZERO(&dav1,
sizeof(WebdavBackend));
dav1.opt_delete = test_backend_webdav_delete;
dav1.opt_delete_finish = test_backend_webdav_delete_finish;
delete_count =
0;
delete_finish_count =
0;
rq->davCollection = &dav1;
UCX_TEST_BEGIN;
VFSContext *vfs = vfs_request_context(sn, rq);
int err;
err = vfs_mkdir(vfs,
"/dir1");
UCX_TEST_ASSERT(err ==
0,
"mkdir dir1 failed");
err = vfs_mkdir(vfs,
"/dir2");
UCX_TEST_ASSERT(err ==
0,
"mkdir dir2 failed");
err = vfs_mkdir(vfs,
"/dir2/dir3");
UCX_TEST_ASSERT(err ==
0,
"mkdir dir3 failed");
err = vfs_mkdir(vfs,
"/dir2/dir4");
UCX_TEST_ASSERT(err ==
0,
"mkdir dir4 failed");
err = vfs_mkdir(vfs,
"/dir2/dir4/dir5");
UCX_TEST_ASSERT(err ==
0,
"mkdir dir5 failed");
SYS_FILE f0 = vfs_open(vfs,
"/file0",
O_CREAT);
UCX_TEST_ASSERT(f0,
"f0 create failed");
SYS_FILE f2 = vfs_open(vfs,
"/dir2/file2",
O_CREAT);
UCX_TEST_ASSERT(f2,
"f2 create failed");
SYS_FILE f3 = vfs_open(vfs,
"/dir2/dir3/file3",
O_CREAT);
UCX_TEST_ASSERT(f3,
"f3 create failed");
SYS_FILE f4 = vfs_open(vfs,
"/dir2/dir4/file4",
O_CREAT);
UCX_TEST_ASSERT(f4,
"f4 create failed");
SYS_FILE f5 = vfs_open(vfs,
"/dir2/dir4/dir5/file5",
O_CREAT);
UCX_TEST_ASSERT(f5,
"f5 create failed");
pblock_replace(
"path",
"/file0", rq->vars);
err = webdav_delete(
NULL, sn, rq);
UCX_TEST_ASSERT(err ==
0,
"DELETE /file0 failed");
UCX_TEST_ASSERT(delete_count ==
1,
"del1: wrong delete count");
delete_count =
0;
pblock_replace(
"path",
"/dir1", rq->vars);
err = webdav_delete(
NULL, sn, rq);
UCX_TEST_ASSERT(err ==
0,
"DELETE /dir1 failed");
UCX_TEST_ASSERT(delete_count ==
1,
"del1: wrong delete count");
delete_count =
0;
pblock_replace(
"path",
"/dir2", rq->vars);
err = webdav_delete(
NULL, sn, rq);
UCX_TEST_ASSERT(err ==
0,
"DELETE /dir2 failed");
UCX_TEST_ASSERT(delete_count ==
8,
"del2: wrong delete count");
UCX_TEST_END;
}
UCX_TEST(test_webdav_put) {
Session *sn;
Request *rq;
TestIOStream *st;
pblock *pb;
const char *content_const =
"Hello World";
init_test_webdav_method(&sn, &rq, &st, &pb,
"PUT",
"/", content_const);
rq->vfs = testvfs_create(sn);
UCX_TEST_BEGIN;
int err;
pblock_replace(
"path",
"/file0", rq->vars);
err = webdav_put(
NULL, sn, rq);
UCX_TEST_ASSERT(err ==
REQ_PROCEED,
"put failed");
VFSContext *vfs = vfs_request_context(sn, rq);
SYS_FILE f0 = vfs_open(vfs,
"/file0",
0);
UCX_TEST_ASSERT(f0,
"cannot open file0");
char buf[
1024];
int r = system_fread(f0, buf,
1024);
UCX_TEST_ASSERT(r == strlen(content_const),
"wrong file size");
UCX_TEST_ASSERT(!memcmp(content_const, buf, r),
"wrong file content");
testutil_destroy_session(sn);
testutil_iostream_destroy(st);
UCX_TEST_END;
}