/* Get a lock, store pointer in global 'getlock'. */ static int getlock(enum ne_lock_scope scope, int depth) { memset(&reslock, 0, sizeof(reslock)); ne_fill_server_uri(i_session, &reslock.uri); reslock.uri.path = res; reslock.depth = depth; reslock.scope = scope; reslock.type = ne_locktype_write; reslock.timeout = 3600; reslock.owner = ne_strdup("litmus test suite"); /* leave gotlock as NULL if the LOCK fails. */ gotlock = NULL; ONMREQ("LOCK", res, ne_lock(i_session, &reslock)); if (scope != reslock.scope) { t_context("requested lockscope not satisfied! got %s, wanted %s", scope == ne_lockscope_exclusive ? "exclusive" : "shared", reslock.scope == ne_lockscope_exclusive ? "exclusive" : "shared"); ne_unlock(i_session, &reslock); return FAIL; } /* Take a copy of the lock. */ gotlock = ne_lock_copy(&reslock); ne_lockstore_add(store, gotlock); return OK; }
static int init_largefile(void) { int n; #ifndef NE_LFS if (sizeof(off_t) == 4) { t_context("32-bit off_t and no LFS support detected " "=> cannot run tests!"); return SKIPREST; } #endif for (n = 0; n < BLOCKSIZE; n++) block[n] = n % 256; /* upload a random file to prep auth if necessary. */ CALL(upload_foo("random.txt")); path = ne_concat(i_path, "large.txt", NULL); /* don't log a message for each body block! */ ne_debug_init(ne_debug_stream, ne_debug_mask & ~(NE_DBG_HTTPBODY|NE_DBG_HTTP)); return OK; }
static int expect100(void) { ne_socket *sock = ne_sock_create(); char req[BUFSIZ], buf[BUFSIZ]; ne_status status = {0}; const ne_inet_addr *ia; int success = 0; if (strcmp(ne_get_scheme(i_session), "https") == 0) { t_context("skipping for SSL server"); return SKIP; } for (ia = ne_addr_first(i_address); ia && !success; ia = ne_addr_next(i_address)) success = ne_sock_connect(sock, ia, i_port) == 0; ONN("could not connect to server", !success); sprintf(req, "PUT %sexpect100 HTTP/1.1" EOL "Host: %s" EOL "Content-Length: 100" EOL "Expect: 100-continue" EOL EOL, i_path, ne_get_server_hostport(i_session)); NE_DEBUG(NE_DBG_SOCKET, "Request:\n%s", req); ONS("sending request", ne_sock_fullwrite(sock, req, strlen(req))); switch (ne_sock_block(sock, 30)) { case NE_SOCK_TIMEOUT: ONN("timeout waiting for interim response", FAIL); break; case 0: /* no error. */ break; default: ONN("error reading from socket", FAIL); break; } ONS("reading status line", ne_sock_readline(sock, buf, BUFSIZ)); NE_DEBUG(NE_DBG_HTTP, "[status] %s", buf); ONN("parse status line", ne_parse_statusline(buf, &status)); if (status.code == 100) { char rbuf[100] = {0}; ONN("write request body", ne_sock_fullwrite(sock, rbuf, 100)); } ne_sock_close(sock); return OK; }
static int open_foo(void) { char *foofn = ne_concat(htdocs_root, "/foo", NULL); i_foo_fd = open(foofn, O_RDONLY | O_BINARY); if (i_foo_fd < 0) { t_context("could not open %s: %s", foofn, strerror(errno)); return FAILHARD; } return OK; }
static int precond(void) { if (!i_class2) { t_context("locking tests skipped,\n" "server does not claim Class 2 compliance"); return SKIPREST; } return OK; }
int upload_foo(const char *path) { char *uri = ne_concat(i_path, path, NULL); int ret; /* i_foo_fd is rewound automagically by ne_request.c */ ret = ne_put(i_session, uri, i_foo_fd); free(uri); if (ret) t_context("PUT of `%s': %s", uri, ne_get_error(i_session)); return ret; }
static int test_resolve(const char *hostname, const char *name) { i_address = ne_addr_resolve(hostname, 0); if (ne_addr_result(i_address)) { char buf[256]; t_context("%s hostname `%s' lookup failed: %s", name, hostname, ne_addr_error(i_address, buf, sizeof buf)); return FAILHARD; } return OK; }
static int ssl_session_id(void) { ne_socket *sock; unsigned char buf[128]; size_t len1; CALL(begin(&sock, serve_close, NULL)); #ifdef SOCKET_SSL len1 = 0; ONN("retrieve session id length", ne_sock_sessid(sock, NULL, &len1)); if (len1 == 0) { /* recent versions of OpenSSL seem to do this, not sure * why or whether it's bad. */ finish(sock, 1); t_context("zero-length session ID, cannot test further"); return SKIP; } if (len1 < sizeof buf) { buf[len1] = 'Z'; } { size_t len2; len2 = sizeof buf; ONN("could not retrieve session id", ne_sock_sessid(sock, buf, &len2)); ONN("buffer size changed!?", len1 != len2); } ONN("buffer written past expected end", len1 < sizeof buf && buf[len1] != 'Z'); /* Attempt retrieval into too-short buffer: */ len1 = 0; ONN("success for buffer overflow case", ne_sock_sessid(sock, buf, &len1) == 0); #else len1 = sizeof buf; ONN("retrieved session id for non-SSL socket!?", ne_sock_sessid(sock, buf, &len1) == 0); #endif ne_sock_close(sock); return await_server(); }
/* Create and connect *sock to address addr on given port. */ static int do_connect(ne_socket **sock, ne_sock_addr *addr, unsigned int port) { const ne_inet_addr *ia; *sock = ne_sock_create(); ONN("could not create socket", *sock == NULL); for (ia = ne_addr_first(addr); ia; ia = ne_addr_next(addr)) { if (ne_sock_connect(*sock, ia, port) == 0) return OK; } t_context("could not connect to server: %s", ne_sock_error(*sock)); ne_sock_close(*sock); return FAIL; }
static int test_connect(void) { const ne_inet_addr *ia; ne_socket *sock = NULL; unsigned int port = proxy_hostname ? proxy_port : i_port; for (ia = ne_addr_first(i_address); ia && !sock; ia = ne_addr_next(i_address)) sock = ne_sock_connect(ia, port); if (sock == NULL) { t_context("connection refused by `%s' port %d", i_hostname, port); return FAILHARD; } ne_sock_close(sock); return OK; }
/* check that the lock returned has correct URI, token */ static void verify_discover(void *userdata, const struct ne_lock *lock, const char *uri, const ne_status *status) { int *ret = userdata; if (*ret == 1) { /* already failed. */ return; } if (lock) { *ret = compare_locks(gotlock, lock); } else { *ret = 1; t_context("failed: %d %s\n", status->code, status->reason_phrase); } }
int begin(void) { const char *scheme = use_secure?"https":"http"; char *space; static const char blanks[] = " "; static const char stars[] = "**********************************"; i_session = ne_session_create(scheme, i_hostname, i_port); CALL(init_session(i_session)); ne_hook_pre_send(i_session, i_pre_send, "X-Prestan"); space = ne_concat(i_path, "davtest/", NULL); ne_delete(i_session, space); if (ne_mkcol(i_session, space)) { t_context("Could not create new collection `%s' for tests: %s\n" "Server must allow `MKCOL %s' for tests to proceed", space, ne_get_error(i_session), space); return FAILHARD; } free(i_path); i_path = space; warmup(); printf("\nStart Testing %s:\n\n",pget_option.URL) ; printf("\n%s%s\n", blanks, stars); printf("\n%s* Number of Requests\t\t%d\n", blanks, pget_option.requests); printf("\n%s* Number of Dead Properties\t%d\n", blanks, pget_option.numprops); printf("\n%s* Depth of Collection\t\t%d\n", blanks, pget_option.depth); printf("\n%s* Width of Collection\t\t%d\n", blanks, pget_option.width); printf("\n%s* Type of Methods\t\t%s\n", blanks, pget_option.methods); printf("\n%s%s\n", blanks, stars); printf("\n\n"); return OK; }
static int init_session(ne_session *sess) { if (proxy_hostname) { ne_session_proxy(sess, proxy_hostname, proxy_port); } ne_set_useragent(i_session, "davtest/" PACKAGE_VERSION); if (i_username) { ne_set_server_auth(sess, auth, NULL); } if (use_secure) { if (!ne_supports_ssl()) { t_context("No SSL support, reconfigure using --with-ssl"); return FAILHARD; } else { ne_ssl_set_verify(sess, ignore_verify, NULL); } } return OK; }
int main(int argc, char *argv[]) { int n, fd, i; char *p; ne_test *testp; if ( read_options(argc, argv) == -1){ Usage(argv[0]); exit(-1); } if ( pget_option.outfile ){ if ((fd=open(pget_option.outfile, O_CREAT | O_TRUNC | O_RDWR, 0660)) < 0){ perror("open() :"); return -1; } close(STDOUT_FILENO); dup2(fd, STDOUT_FILENO); } test_argc = argc; test_argv = argv; if (tests[0].fn == NULL) { printf("-> no tests found in `%s'\n", test_suite); return -1; } if (ne_sock_init()) { COL("43;01"); printf("WARNING:"); NOCOL; printf(" Socket library initalization failed.\n"); } printf("\n"); printf("\n"); i = 0; p = Result_Header[i]; while ( p != NULL ){ printf("%s\n", p); i++; p = Result_Header[i]; } testp = &tests[0]; if ( !strcmp(pget_option.methods, "WebFolder") ) testp = &tests2[0]; for ( n=0; !aborted && testp[n].fn != NULL; n++) { int result; test_name = testp[n].name; have_context = 0; test_num = n; warned = 0; fflush(stdout); /* run the test. */ result = testp[n].fn(); if (testp[n].flags & T_EXPECT_FAIL) { if (result == OK) { t_context("test passed but expected failure"); result = FAIL; } else if (result == FAIL) result = OK; } /* align the result column if we've had warnings. */ if (warned) { printf(" %s ", dots); } } /* discount skipped tests */ if (skipped) { printf("-> %d %s.\n", skipped, skipped==1?"test was skipped":"tests were skipped"); n -= skipped; if (passes + fails != n) { printf("-> ARGH! Number of test results does not match " "number of tests.\n" "-> ARGH! Test Results are INRELIABLE.\n"); } } ne_sock_exit(); return fails; }
int init(void) { ne_uri u = {0}, proxy = {0}; int optc, n; char *proxy_url = NULL; char str[64], *src; int i; if ((times1=malloc(sizeof(float)*pget_option.requests)) == NULL){ perror("malloc(times1) :"); exit(-1); } if ((times2=malloc(sizeof(float)*pget_option.requests)) == NULL){ perror("malloc(times2) :"); exit(-1); } while ((optc = getopt_long(test_argc, test_argv, "d:hp", longopts, NULL)) != -1) { switch (optc) { case 'd': htdocs_root = optarg; break; case 'p': proxy_url = optarg; break; default: exit(1); } } n = test_argc - optind; if (n == 0 || n > 3 || n == 2) { exit(1); } if (htdocs_root == NULL) htdocs_root = "htdocs"; if (ne_uri_parse(test_argv[optind], &u)) { t_context("couldn't parse server URL `%s'", test_argv[optind]); return FAILHARD; } if (proxy_url) { if (ne_uri_parse(proxy_url, &proxy)) { t_context("couldn't parse proxy URL `%s'", proxy_url); return FAILHARD; } if (proxy.scheme && strcmp(proxy.scheme, "http") != 0) { t_context("cannot use scheme `%s' for proxy", proxy.scheme); return FAILHARD; } if (proxy.port > 0) { proxy_port = proxy.port; } else { proxy_port = 8080; } proxy_hostname = proxy.host; } if (u.scheme && strcmp(u.scheme, "https") == 0) use_secure = 1; i_hostname = u.host; if (u.port > 0) { i_port = u.port; } else { if (use_secure) { i_port = 443; } else { i_port = 80; } } if (ne_path_has_trailing_slash(u.path)) { i_path = u.path; } else { i_path = ne_concat(u.path, "/", NULL); } i_path = ne_path_escape(i_path); if (n > 2) { i_username = test_argv[optind+1]; i_password = test_argv[optind+2]; if (strlen(i_username) >= NE_ABUFSIZ) { t_context("username must be <%d chars", NE_ABUFSIZ); return FAILHARD; } if (strlen(i_password) >= NE_ABUFSIZ) { t_context("password must be <%d chars", NE_ABUFSIZ); return FAILHARD; } } if (proxy_hostname) CALL(test_resolve(proxy_hostname, "proxy server")); else CALL(test_resolve(i_hostname, "server")); CALL(open_foo()); CALL(test_connect()); printf("Done\n"); return OK; }
int main(int argc, char *argv[]) { int n; static const char dots[] = "......................"; /* get basename(argv[0]) */ test_suite = strrchr(argv[0], '/'); if (test_suite == NULL) { test_suite = argv[0]; } else { test_suite++; } #ifdef HAVE_SETLOCALE setlocale(LC_MESSAGES, ""); #endif ne_i18n_init(NULL); #if defined(HAVE_ISATTY) && defined(STDOUT_FILENO) if (isatty(STDOUT_FILENO)) { use_colour = 1; } #endif test_argc = argc; test_argv = argv; debug = fopen("debug.log", "a"); if (debug == NULL) { fprintf(stderr, "%s: Could not open debug.log: %s\n", test_suite, strerror(errno)); return -1; } child_debug = fopen("child.log", "a"); if (child_debug == NULL) { fprintf(stderr, "%s: Could not open child.log: %s\n", test_suite, strerror(errno)); fclose(debug); return -1; } if (tests[0].fn == NULL) { printf("-> no tests found in `%s'\n", test_suite); return -1; } /* install special SEGV handler. */ signal(SIGSEGV, parent_segv); signal(SIGABRT, parent_segv); /* test the "no-debugging" mode of ne_debug. */ ne_debug_init(NULL, 0); NE_DEBUG(TEST_DEBUG, "This message should go to /dev/null"); /* enable debugging for real. */ ne_debug_init(debug, TEST_DEBUG); NE_DEBUG(TEST_DEBUG | NE_DBG_FLUSH, "Version string: %s\n", ne_version_string()); /* another silly test. */ NE_DEBUG(0, "This message should also go to /dev/null"); if (ne_sock_init()) { COL("43;01"); printf("WARNING:"); NOCOL; printf(" Socket library initalization failed.\n"); } printf("-> running `%s':\n", test_suite); for (n = 0; !aborted && tests[n].fn != NULL; n++) { int result, is_xfail = 0; #ifdef NEON_MEMLEAK size_t allocated = ne_alloc_used; int is_xleaky = 0; #endif test_name = tests[n].name; printf("%2d. %s%.*s ", n, test_name, (int) (strlen(dots) - strlen(test_name)), dots); have_context = 0; test_num = n; warned = 0; fflush(stdout); NE_DEBUG(TEST_DEBUG, "******* Running test %d: %s ********\n", n, test_name); /* run the test. */ result = tests[n].fn(); #ifdef NEON_MEMLEAK /* issue warnings for memory leaks, if requested */ if ((tests[n].flags & T_CHECK_LEAKS) && result == OK && ne_alloc_used > allocated) { t_context("memory leak of %" NE_FMT_SIZE_T " bytes", ne_alloc_used - allocated); fprintf(debug, "Blocks leaked: "); ne_alloc_dump(debug); result = FAIL; } else if (tests[n].flags & T_EXPECT_LEAKS && result == OK && ne_alloc_used == allocated) { t_context("expected memory leak not detected"); result = FAIL; } else if (tests[n].flags & T_EXPECT_LEAKS && result == OK) { fprintf(debug, "Blocks leaked (expected): "); ne_alloc_dump(debug); is_xleaky = 1; } #endif if (tests[n].flags & T_EXPECT_FAIL) { if (result == OK) { t_context("test passed but expected failure"); result = FAIL; } else if (result == FAIL) { result = OK; is_xfail = 1; } } /* align the result column if we've had warnings. */ if (warned) { printf(" %s ", dots); } switch (result) { case OK: if (is_xfail) { COL("32;07"); printf("xfail"); } else { COL("32"); printf("pass"); } NOCOL; if (warned) { printf(" (with %d warning%s)", warned, (warned > 1)?"s":""); } #ifdef NEON_MEMLEAK if (is_xleaky) { printf(" (with expected leak, %" NE_FMT_SIZE_T " bytes)", ne_alloc_used - allocated); } #endif putchar('\n'); passes++; break; case FAILHARD: aborted = 1; /* fall-through */ case FAIL: COL("41;37;01"); printf("FAIL"); NOCOL; if (have_context) { printf(" (%s)", test_context); } putchar('\n'); fails++; break; case SKIPREST: aborted = 1; /* fall-through */ case SKIP: COL("44;37;01"); printf("SKIPPED"); NOCOL; if (have_context) { printf(" (%s)", test_context); } putchar('\n'); skipped++; break; default: COL("41;37;01"); printf("OOPS"); NOCOL; printf(" unexpected test result `%d'\n", result); break; } reap_server(); } /* discount skipped tests */ if (skipped) { printf("-> %d %s.\n", skipped, skipped==1?"test was skipped":"tests were skipped"); n -= skipped; if (passes + fails != n) { printf("-> ARGH! Number of test results does not match " "number of tests.\n" "-> ARGH! Test Results are INRELIABLE.\n"); } } /* print the summary. */ if (skipped && n == 0) { printf("<- all tests skipped for `%s'.\n", test_suite); } else { printf("<- summary for `%s': " "of %d tests run: %d passed, %d failed. %.1f%%\n", test_suite, n, passes, fails, 100*(float)passes/n); if (warnings) { printf("-> %d warning%s issued.\n", warnings, warnings==1?" was":"s were"); } } if (fclose(debug)) { fprintf(stderr, "Error closing debug.log: %s\n", strerror(errno)); fails = 1; } if (fclose(child_debug)) { fprintf(stderr, "Error closing child.log: %s\n", strerror(errno)); fails = 1; } ne_sock_exit(); return fails; }