Fix a debug msg typo
[ira/wip.git] / source3 / torture / torture.c
index 070474cf6fb645ac5dfd05e84b7899f5882f5fe3..1b9e394a681249c564b3ed175e0c6ebaeb74a577 100644 (file)
@@ -18,6 +18,7 @@
 */
 
 #include "includes.h"
+#include "wbc_async.h"
 
 extern char *optarg;
 extern int optind;
@@ -28,6 +29,7 @@ static const char *sockops="TCP_NODELAY";
 static int nprocs=1;
 static int port_to_use=0;
 int torture_numops=100;
+int torture_blocksize=1024*1024;
 static int procnum; /* records process count number when forking */
 static struct cli_state *current_cli;
 static fstring randomfname;
@@ -158,7 +160,7 @@ static struct cli_state *open_nbt_connection(void)
        make_nmb_name(&calling, myname, 0x0);
        make_nmb_name(&called , host, 0x20);
 
-        zero_addr(&ss);
+        zero_sockaddr(&ss);
 
        if (!(c = cli_initialise())) {
                printf("Failed initialize cli_struct to connect with %s\n", host);
@@ -294,15 +296,6 @@ static bool torture_open_connection_share(struct cli_state **c,
        return True;
 }
 
-void torture_open_connection_free_unclist(char **unc_list)
-{
-       if (unc_list!=NULL)
-       {
-               SAFE_FREE(unc_list[0]);
-               SAFE_FREE(unc_list);
-       }
-}
-
 bool torture_open_connection(struct cli_state **c, int conn_index)
 {
        char **unc_list = NULL;
@@ -311,7 +304,7 @@ bool torture_open_connection(struct cli_state **c, int conn_index)
 
        if (use_multishare_conn==True) {
                char *h, *s;
-               unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0);
+               unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
                if (!unc_list || num_unc_names <= 0) {
                        printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
                        exit(1);
@@ -321,14 +314,14 @@ bool torture_open_connection(struct cli_state **c, int conn_index)
                                      NULL, &h, &s)) {
                        printf("Failed to parse UNC name %s\n",
                               unc_list[conn_index % num_unc_names]);
-                       torture_open_connection_free_unclist(unc_list);
+                       TALLOC_FREE(unc_list);
                        exit(1);
                }
 
                result = torture_open_connection_share(c, h, s);
 
                /* h, s were copied earlier */
-               torture_open_connection_free_unclist(unc_list);
+               TALLOC_FREE(unc_list);
                return result;
        }
 
@@ -340,6 +333,7 @@ bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
        uint16 old_vuid = cli->vuid;
        fstring old_user_name;
        size_t passlen = strlen(password);
+       NTSTATUS status;
        bool ret;
 
        fstrcpy(old_user_name, cli->user_name);
@@ -350,7 +344,10 @@ bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
                                                workgroup));
        *new_vuid = cli->vuid;
        cli->vuid = old_vuid;
-       fstrcpy(cli->user_name, old_user_name);
+       status = cli_set_username(cli, old_user_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               return false;
+       }
        return ret;
 }
 
@@ -890,6 +887,7 @@ static bool run_netbench(int client)
        }
 
        while (fgets(line, sizeof(line)-1, f)) {
+               char *saveptr;
                line_count++;
 
                line[strlen(line)-1] = 0;
@@ -899,9 +897,9 @@ static bool run_netbench(int client)
                all_string_sub(line,"client1", cname, sizeof(line));
 
                /* parse the command parameters */
-               params[0] = strtok(line," ");
+               params[0] = strtok_r(line, " ", &saveptr);
                i = 0;
-               while (params[i]) params[++i] = strtok(NULL," ");
+               while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
 
                params[i] = "";
 
@@ -1108,6 +1106,7 @@ static bool run_tcon_test(int dummy)
        uint16 vuid1, vuid2;
        char buf[4];
        bool ret = True;
+       NTSTATUS status;
 
        memset(buf, '\0', sizeof(buf));
 
@@ -1134,10 +1133,11 @@ static bool run_tcon_test(int dummy)
                return False;
        }
 
-       if (!cli_send_tconX(cli, share, "?????",
-                           password, strlen(password)+1)) {
+       status = cli_tcon_andx(cli, share, "?????",
+                              password, strlen(password)+1);
+       if (!NT_STATUS_IS_OK(status)) {
                printf("%s refused 2nd tree connect (%s)\n", host,
-                          cli_errstr(cli));
+                      nt_errstr(status));
                cli_shutdown(cli);
                return False;
        }
@@ -1220,7 +1220,9 @@ static bool run_tcon2_test(int dummy)
 
        printf("starting tcon2 test\n");
 
-       asprintf(&service, "\\\\%s\\%s", host, share);
+       if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
+               return false;
+       }
 
        status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
 
@@ -1244,14 +1246,14 @@ static bool tcon_devtest(struct cli_state *cli,
                         const char *return_devtype,
                         NTSTATUS expected_error)
 {
-       bool status;
+       NTSTATUS status;
        bool ret;
 
-       status = cli_send_tconX(cli, myshare, devtype,
-                               password, strlen(password)+1);
+       status = cli_tcon_andx(cli, myshare, devtype,
+                              password, strlen(password)+1);
 
        if (NT_STATUS_IS_OK(expected_error)) {
-               if (status) {
+               if (NT_STATUS_IS_OK(status)) {
                        if (strcmp(cli->dev, return_devtype) == 0) {
                                ret = True;
                        } else { 
@@ -1269,7 +1271,7 @@ static bool tcon_devtest(struct cli_state *cli,
                }
                cli_tdis(cli);
        } else {
-               if (status) {
+               if (NT_STATUS_IS_OK(status)) {
                        printf("tconx to share %s with type %s "
                               "should have failed but succeeded\n",
                               myshare, devtype);
@@ -2162,7 +2164,7 @@ static bool run_fdsesstest(int dummy)
                return False;
 
        saved_cnum = cli->cnum;
-       if (!cli_send_tconX(cli, share, "?????", "", 1))
+       if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
                return False;
        new_cnum = cli->cnum;
        cli->cnum = saved_cnum;
@@ -2354,7 +2356,7 @@ static bool run_negprot_nowait(int dummy)
        }
 
        for (i=0;i<50000;i++) {
-               cli_negprot_send(cli);
+               cli_negprot_sendsync(cli);
        }
 
        if (!torture_close_connection(cli)) {
@@ -3684,7 +3686,8 @@ static bool run_rename(int dummy)
        }
 
        if (!cli_rename(cli1, fname, fname1)) {
-               printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have failed ! \n");
+               printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
+                       cli_errstr(cli1));
                correct = False;
        } else {
                printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
@@ -4151,6 +4154,119 @@ static bool run_opentest(int dummy)
        return correct;
 }
 
+/*
+  Test POSIX open /mkdir calls.
+ */
+static bool run_simple_posix_open_test(int dummy)
+{
+       static struct cli_state *cli1;
+       const char *fname = "\\posix:file";
+       const char *dname = "\\posix:dir";
+       uint16 major, minor;
+       uint32 caplow, caphigh;
+       int fnum1 = -1;
+       bool correct = false;
+
+       printf("Starting simple POSIX open test\n");
+
+       if (!torture_open_connection(&cli1, 0)) {
+               return false;
+       }
+
+       cli_sockopt(cli1, sockops);
+
+       if (!SERVER_HAS_UNIX_CIFS(cli1)) {
+               printf("Server doesn't support UNIX CIFS extensions.\n");
+               return false;
+       }
+
+       if (!cli_unix_extensions_version(cli1, &major,
+                       &minor, &caplow, &caphigh)) {
+               printf("Server didn't return UNIX CIFS extensions.\n");
+               return false;
+       }
+
+       if (!cli_set_unix_extensions_capabilities(cli1,
+                       major, minor, caplow, caphigh)) {
+               printf("Server doesn't support setting UNIX CIFS extensions.\n");
+               return false;
+        }
+
+       cli_setatr(cli1, fname, 0, 0);
+       cli_posix_unlink(cli1, fname);
+       cli_setatr(cli1, dname, 0, 0);
+       cli_posix_rmdir(cli1, dname);
+
+       /* Create a directory. */
+       if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
+               printf("Server doesn't support setting UNIX CIFS extensions.\n");
+               goto out;
+       }
+
+       fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600);
+       if (fnum1 == -1) {
+               printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
+               goto out;
+       }
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close failed (%s)\n", cli_errstr(cli1));
+               goto out;
+       }
+
+       /* Now open the file again for read only. */
+       fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
+       if (fnum1 == -1) {
+               printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
+               goto out;
+       }
+
+       /* Now unlink while open. */
+       if (!cli_posix_unlink(cli1, fname)) {
+               printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
+               goto out;
+       }
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close(2) failed (%s)\n", cli_errstr(cli1));
+               goto out;
+       }
+
+       /* Ensure the file has gone. */
+       fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
+       if (fnum1 != -1) {
+               printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
+               goto out;
+       }
+
+       if (!cli_posix_rmdir(cli1, dname)) {
+               printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
+               goto out;
+       }
+
+       printf("Simple POSIX open test passed\n");
+       correct = true;
+
+  out:
+
+       if (fnum1 != -1) {
+               cli_close(cli1, fnum1);
+               fnum1 = -1;
+       }
+
+       cli_setatr(cli1, fname, 0, 0);
+       cli_posix_unlink(cli1, fname);
+       cli_setatr(cli1, dname, 0, 0);
+       cli_posix_rmdir(cli1, dname);
+
+       if (!torture_close_connection(cli1)) {
+               correct = false;
+       }
+
+       return correct;
+}
+
+
 static uint32 open_attrs_table[] = {
                FILE_ATTRIBUTE_NORMAL,
                FILE_ATTRIBUTE_ARCHIVE,
@@ -4733,6 +4849,7 @@ static bool run_error_map_extract(int dummy) {
        
        static struct cli_state *c_dos;
        static struct cli_state *c_nt;
+       NTSTATUS status;
 
        uint32 error;
 
@@ -4751,8 +4868,11 @@ static bool run_error_map_extract(int dummy) {
 
        c_nt->use_spnego = False;
 
-       if (!cli_negprot(c_nt)) {
-               printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(c_nt));
+       status = cli_negprot(c_nt);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("%s rejected the NT-error negprot (%s)\n", host,
+                      nt_errstr(status));
                cli_shutdown(c_nt);
                return False;
        }
@@ -4772,8 +4892,10 @@ static bool run_error_map_extract(int dummy) {
        c_dos->use_spnego = False;
        c_dos->force_dos_errors = True;
 
-       if (!cli_negprot(c_dos)) {
-               printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(c_dos));
+       status = cli_negprot(c_dos);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("%s rejected the DOS-error negprot (%s)\n", host,
+                      nt_errstr(status));
                cli_shutdown(c_dos);
                return False;
        }
@@ -4839,17 +4961,21 @@ static bool run_error_map_extract(int dummy) {
 static bool run_sesssetup_bench(int dummy)
 {
        static struct cli_state *c;
+       const char *fname = "\\file.dat";
+       int fnum;
        NTSTATUS status;
        int i;
 
-       if (!(c = open_nbt_connection())) {
+       if (!torture_open_connection(&c, 0)) {
                return false;
        }
 
-       if (!cli_negprot(c)) {
-               printf("%s rejected the NT-error negprot (%s)\n", host,
-                      cli_errstr(c));
-               cli_shutdown(c);
+       fnum = cli_nt_create_full(
+               c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
+               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
+               FILE_DELETE_ON_CLOSE, 0);
+       if (fnum == -1) {
+               d_printf("open %s failed: %s\n", fname, cli_errstr(c));
                return false;
        }
 
@@ -4865,6 +4991,8 @@ static bool run_sesssetup_bench(int dummy)
                        return false;
                }
 
+               d_printf("\r%d   ", (int)c->vuid);
+
                if (!cli_ulogoff(c)) {
                        d_printf("(%s) cli_ulogoff failed: %s\n",
                                 __location__, cli_errstr(c));
@@ -4895,6 +5023,211 @@ static bool subst_test(const char *str, const char *user, const char *domain,
        return result;
 }
 
+static void chain1_open_completion(struct async_req *req)
+{
+       int fnum;
+       NTSTATUS status;
+
+       status = cli_open_recv(req, &fnum);
+       TALLOC_FREE(req);
+
+       d_printf("cli_open_recv returned %s: %d\n",
+                nt_errstr(status),
+                NT_STATUS_IS_OK(status) ? fnum : -1);
+}
+
+static void chain1_read_completion(struct async_req *req)
+{
+       NTSTATUS status;
+       ssize_t received;
+       uint8_t *rcvbuf;
+
+       status = cli_read_andx_recv(req, &received, &rcvbuf);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(req);
+               d_printf("cli_read_andx_recv returned %s\n",
+                        nt_errstr(status));
+               return;
+       }
+
+       d_printf("got %d bytes: %.*s\n", (int)received, (int)received,
+                (char *)rcvbuf);
+       TALLOC_FREE(req);
+}
+
+static void chain1_write_completion(struct async_req *req)
+{
+       NTSTATUS status;
+       size_t written;
+
+       status = cli_write_andx_recv(req, &written);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(req);
+               d_printf("cli_write_andx_recv returned %s\n",
+                        nt_errstr(status));
+               return;
+       }
+
+       d_printf("wrote %d bytes\n", (int)written);
+       TALLOC_FREE(req);
+}
+
+static void chain1_close_completion(struct async_req *req)
+{
+       NTSTATUS status;
+
+       status = cli_close_recv(req);
+       *((bool *)(req->async.priv)) = true;
+
+       TALLOC_FREE(req);
+
+       d_printf("cli_close returned %s\n", nt_errstr(status));
+}
+
+static bool run_chain1(int dummy)
+{
+       struct cli_state *cli1;
+       struct event_context *evt = event_context_init(NULL);
+       struct async_req *reqs[4];
+       bool done = false;
+       const char *text = "hallo";
+
+       printf("starting chain1 test\n");
+       if (!torture_open_connection(&cli1, 0)) {
+               return False;
+       }
+
+       cli_sockopt(cli1, sockops);
+
+       cli_chain_cork(cli1, evt, 0);
+       reqs[0] = cli_open_send(talloc_tos(), evt, cli1, "\\test",
+                               O_CREAT|O_RDWR, 0);
+       reqs[0]->async.fn = chain1_open_completion;
+       reqs[1] = cli_write_andx_send(talloc_tos(), evt, cli1, 0, 0,
+                                     (uint8_t *)text, 0, strlen(text));
+       reqs[1]->async.fn = chain1_write_completion;
+       reqs[2] = cli_read_andx_send(talloc_tos(), evt, cli1, 0, 1, 10);
+       reqs[2]->async.fn = chain1_read_completion;
+       reqs[3] = cli_close_send(talloc_tos(), evt, cli1, 0);
+       reqs[3]->async.fn = chain1_close_completion;
+       reqs[3]->async.priv = (void *)&done;
+       cli_chain_uncork(cli1);
+
+       while (!done) {
+               event_loop_once(evt);
+       }
+
+       torture_close_connection(cli1);
+       return True;
+}
+
+static size_t null_source(uint8_t *buf, size_t n, void *priv)
+{
+       size_t *to_pull = (size_t *)priv;
+       size_t thistime = *to_pull;
+
+       thistime = MIN(thistime, n);
+       if (thistime == 0) {
+               return 0;
+       }
+
+       memset(buf, 0, thistime);
+       *to_pull -= thistime;
+       return thistime;
+}
+
+static bool run_windows_write(int dummy)
+{
+       struct cli_state *cli1;
+       int fnum;
+       int i;
+       bool ret = false;
+       const char *fname = "\\writetest.txt";
+       double seconds;
+       double kbytes;
+
+       printf("starting windows_write test\n");
+       if (!torture_open_connection(&cli1, 0)) {
+               return False;
+       }
+
+       fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       if (fnum == -1) {
+               printf("open failed (%s)\n", cli_errstr(cli1));
+               return False;
+       }
+
+       cli_sockopt(cli1, sockops);
+
+       start_timer();
+
+       for (i=0; i<torture_numops; i++) {
+               char c = 0;
+               off_t start = i * torture_blocksize;
+               NTSTATUS status;
+               size_t to_pull = torture_blocksize - 1;
+
+               if (cli_write(cli1, fnum, 0, &c,
+                             start + torture_blocksize - 1, 1) != 1) {
+                       printf("cli_write failed: %s\n", cli_errstr(cli1));
+                       goto fail;
+               }
+
+               status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
+                                 null_source, &to_pull);
+               if (!NT_STATUS_IS_OK(status)) {
+                       printf("cli_push returned: %s\n", nt_errstr(status));
+                       goto fail;
+               }
+       }
+
+       seconds = end_timer();
+       kbytes = (double)torture_blocksize * torture_numops;
+       kbytes /= 1024;
+
+       printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
+              (double)seconds, (int)(kbytes/seconds));
+
+       ret = true;
+ fail:
+       cli_close(cli1, fnum);
+       cli_unlink(cli1, fname);
+       torture_close_connection(cli1);
+       return ret;
+}
+
+static bool run_cli_echo(int dummy)
+{
+       struct cli_state *cli;
+       struct event_context *ev = event_context_init(NULL);
+       struct async_req *req;
+       NTSTATUS status;
+
+       printf("starting cli_echo test\n");
+       if (!torture_open_connection(&cli, 0)) {
+               return false;
+       }
+       cli_sockopt(cli, sockops);
+
+       req = cli_echo_send(ev, ev, cli, 5, data_blob_const("hello", 5));
+       if (req == NULL) {
+               d_printf("cli_echo_send failed\n");
+               return false;
+       }
+
+       while (req->state < ASYNC_REQ_DONE) {
+               event_loop_once(ev);
+       }
+
+       status = cli_echo_recv(req);
+       d_printf("cli_echo returned %s\n", nt_errstr(status));
+
+       TALLOC_FREE(req);
+
+       torture_close_connection(cli);
+       return NT_STATUS_IS_OK(status);
+}
+
 static bool run_local_substitute(int dummy)
 {
        bool ok = true;
@@ -4962,7 +5295,7 @@ static bool run_local_gencache(int dummy)
                return False;
        }
 
-       blob = data_blob_string_const("bar");
+       blob = data_blob_string_const_null("bar");
        tm = time(NULL);
 
        if (!gencache_set_data_blob("foo", &blob, tm)) {
@@ -5069,8 +5402,13 @@ static bool run_local_rbtree(int dummy)
        for (i=0; i<1000; i++) {
                char *key, *value;
 
-               asprintf(&key, "key%ld", random());
-               asprintf(&value, "value%ld", random());
+               if (asprintf(&key, "key%ld", random()) == -1) {
+                       goto done;
+               }
+               if (asprintf(&value, "value%ld", random()) == -1) {
+                       SAFE_FREE(key);
+                       goto done;
+               }
 
                if (!rbt_testval(db, key, value)) {
                        SAFE_FREE(key);
@@ -5079,7 +5417,10 @@ static bool run_local_rbtree(int dummy)
                }
 
                SAFE_FREE(value);
-               asprintf(&value, "value%ld", random());
+               if (asprintf(&value, "value%ld", random()) == -1) {
+                       SAFE_FREE(key);
+                       goto done;
+               }
 
                if (!rbt_testval(db, key, value)) {
                        SAFE_FREE(key);
@@ -5187,6 +5528,11 @@ static bool run_local_memcache(int dummy)
        DATA_BLOB d1, d2, d3;
        DATA_BLOB v1, v2, v3;
 
+       TALLOC_CTX *mem_ctx;
+       char *str1, *str2;
+       size_t size1, size2;
+       bool ret = false;
+
        cache = memcache_init(NULL, 100);
 
        if (cache == NULL) {
@@ -5238,7 +5584,96 @@ static bool run_local_memcache(int dummy)
        }
 
        TALLOC_FREE(cache);
-       return true;
+
+       cache = memcache_init(NULL, 0);
+
+       mem_ctx = talloc_init("foo");
+
+       str1 = talloc_strdup(mem_ctx, "string1");
+       str2 = talloc_strdup(mem_ctx, "string2");
+
+       memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
+                           data_blob_string_const("torture"), &str1);
+       size1 = talloc_total_size(cache);
+
+       memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
+                           data_blob_string_const("torture"), &str2);
+       size2 = talloc_total_size(cache);
+
+       printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
+
+       if (size2 > size1) {
+               printf("memcache leaks memory!\n");
+               goto fail;
+       }
+
+       ret = true;
+ fail:
+       TALLOC_FREE(cache);
+       return ret;
+}
+
+static void wbclient_done(struct tevent_req *req)
+{
+       wbcErr wbc_err;
+       struct winbindd_response *wb_resp;
+       int *i = (int *)tevent_req_callback_data_void(req);
+
+       wbc_err = wb_trans_recv(req, req, &wb_resp);
+       TALLOC_FREE(req);
+       *i += 1;
+       d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
+}
+
+static bool run_local_wbclient(int dummy)
+{
+       struct event_context *ev;
+       struct wb_context **wb_ctx;
+       struct winbindd_request wb_req;
+       bool result = false;
+       int i, j;
+
+       BlockSignals(True, SIGPIPE);
+
+       ev = event_context_init(talloc_tos());
+       if (ev == NULL) {
+               goto fail;
+       }
+
+       wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
+       if (wb_ctx == NULL) {
+               goto fail;
+       }
+
+       ZERO_STRUCT(wb_req);
+       wb_req.cmd = WINBINDD_PING;
+
+       for (i=0; i<torture_numops; i++) {
+               wb_ctx[i] = wb_context_init(ev);
+               if (wb_ctx[i] == NULL) {
+                       goto fail;
+               }
+               for (j=0; j<5; j++) {
+                       struct tevent_req *req;
+                       req = wb_trans_send(ev, ev, wb_ctx[i],
+                                           (j % 2) == 0, &wb_req);
+                       if (req == NULL) {
+                               goto fail;
+                       }
+                       tevent_req_set_callback(req, wbclient_done, &i);
+               }
+       }
+
+       i = 0;
+
+       while (i < 5 * torture_numops) {
+               event_loop_once(ev);
+       }
+
+       result = true;
+ fail:
+       TALLOC_FREE(ev);
+       return result;
 }
 
 static double create_procs(bool (*fn)(int), bool *result)
@@ -5371,6 +5806,7 @@ static struct {
        {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
        {"RW3",  run_readwritelarge, 0},
        {"OPEN", run_opentest, 0},
+       {"POSIX", run_simple_posix_open_test, 0},
 #if 1
        {"OPENATTR", run_openattrtest, 0},
 #endif
@@ -5392,11 +5828,15 @@ static struct {
        {"FDSESS", run_fdsesstest, 0},
        { "EATEST", run_eatest, 0},
        { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
+       { "CHAIN1", run_chain1, 0},
+       { "WINDOWS-WRITE", run_windows_write, 0},
+       { "CLI_ECHO", run_cli_echo, 0},
        { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
        { "LOCAL-GENCACHE", run_local_gencache, 0},
        { "LOCAL-RBTREE", run_local_rbtree, 0},
        { "LOCAL-MEMCACHE", run_local_memcache, 0},
        { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
+       { "LOCAL-WBCLIENT", run_local_wbclient, 0},
        {NULL, NULL, 0}};
 
 
@@ -5501,6 +5941,7 @@ static void usage(void)
        int gotpass = 0;
        bool correct = True;
        TALLOC_CTX *frame = talloc_stackframe();
+       int seed = time(NULL);
 
        dbf = x_stdout;
 
@@ -5510,6 +5951,11 @@ static void usage(void)
 
        load_case_tables();
 
+       if (is_default_dyn_CONFIGFILE()) {
+               if(getenv("SMB_CONF_PATH")) {
+                       set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
+               }
+       }
        lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
        load_interfaces();
 
@@ -5546,17 +5992,15 @@ static void usage(void)
        argc--;
        argv++;
 
-       srandom(time(NULL));
-
        fstrcpy(workgroup, lp_workgroup());
 
-       while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:")) != EOF) {
+       while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
                switch (opt) {
                case 'p':
                        port_to_use = atoi(optarg);
                        break;
                case 's':
-                       srandom(atoi(optarg));
+                       seed = atoi(optarg);
                        break;
                case 'W':
                        fstrcpy(workgroup,optarg);
@@ -5613,12 +6057,19 @@ static void usage(void)
                        fstrcpy(multishare_conn_fname, optarg);
                        use_multishare_conn = True;
                        break;
+               case 'B':
+                       torture_blocksize = atoi(optarg);
+                       break;
                default:
                        printf("Unknown option %c (%d)\n", (char)opt, opt);
                        usage();
                }
        }
 
+       d_printf("using seed %d\n", seed);
+
+       srandom(seed);
+
        if(use_kerberos && !gotuser) gotpass = True;
 
        while (!gotpass) {