Revert "test_delayed_write_update4 HACKS ..."
[metze/samba/wip.git] / source4 / torture / basic / delaywrite.c
index 71d8cc901fcca312a709227cec69015fd505006b..6f5bd2a8b6a9f2403bf788ae3cc731ae2c08a49e 100644 (file)
 #include "system/filesys.h"
 #include "libcli/libcli.h"
 #include "torture/util.h"
-
-#define W2K8R2_TIMEDELAY_SECS 1
-#define W2K3_TIMEDELAY_SECS 2
-#define TIMEDELAY_SECS W2K3_TIMEDELAY_SECS
+#include "torture/basic/proto.h"
+#include "lib/util/time_basic.h"
 
 #define BASEDIR "\\delaywrite"
 
@@ -46,84 +44,68 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
-       if (fnum1 == -1) {
-               torture_result(tctx, TORTURE_FAIL, "Failed to open %s", fname);
-               return false;
-       }
+       torture_assert_int_not_equal(tctx, fnum1, -1, talloc_asprintf(tctx,
+                                    "Failed to open %s", fname));
 
        finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
        finfo1.basic_info.in.file.fnum = fnum1;
        finfo2 = finfo1;
 
        status = smb_raw_fileinfo(cli->tree, tctx, &finfo1);
-
        torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
-       
-       torture_comment(tctx, "Initial write time %s\n", 
-              nt_time_string(tctx, finfo1.basic_info.out.write_time));
 
-       /* 3 second delay to ensure we get past any 2 second time
-          granularity (older systems may have that) */
-       msleep(3 * msec);
+       torture_comment(tctx, "Initial write time %s\n",
+                       nt_time_string(tctx, finfo1.basic_info.out.write_time));
 
        written =  smbcli_write(cli->tree, fnum1, 0, "x", 0, 1);
-
-       if (written != 1) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "write failed - wrote %d bytes (%s)\n", 
-                                          (int)written, __location__);
-               return false;
-       }
+       torture_assert_int_equal(tctx, written, 1,
+                                "unexpected number of bytes written");
 
        start = timeval_current();
-       end = timeval_add(&start, (120*sec), 0);
+       end = timeval_add(&start, (120 * sec), 0);
        while (!timeval_expired(&end)) {
                status = smb_raw_fileinfo(cli->tree, tctx, &finfo2);
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-                       ret = false;
-                       break;
-               }
-               torture_comment(tctx, "write time %s\n", 
-                      nt_time_string(tctx, finfo2.basic_info.out.write_time));
-               if (finfo1.basic_info.out.write_time != finfo2.basic_info.out.write_time) {
+               torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
+
+               torture_comment(tctx, "write time %s\n",
+                       nt_time_string(tctx, finfo2.basic_info.out.write_time));
+
+               if (finfo1.basic_info.out.write_time !=
+                   finfo2.basic_info.out.write_time)
+               {
                        double diff = timeval_elapsed(&start);
-                       if (diff < (TIMEDELAY_SECS * sec * 0.75)) { /* 0.75 to cope with vmware timing */
-                               torture_comment(tctx, "Server updated write_time after %.2f seconds"
-                                               "(1 sec == %.2f)(wrong!)\n",
-                                               diff, sec);
-                               ret = false;
-                               break;
-                       }
 
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(correct)\n",
-                                       diff, sec);
+                       torture_assert(tctx,
+                                      diff >= (used_delay / (double)1000000),
+                                      talloc_asprintf(tctx,
+                                       "Server updated write_time after %.2f "
+                                       "seconds (expected >= %.2f)\n",
+                                       diff, used_delay/(double)1000000));
+
+                       torture_comment(tctx, "Server updated write_time after %.2f seconds (correct)\n",
+                                       diff);
                        break;
                }
                fflush(stdout);
-               msleep(1 * msec);
-       }
-       
-       if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "Server did not update write time (wrong!)");
-               ret = false;
+               smb_msleep(1 * msec);
        }
 
+       torture_assert_u64_not_equal(tctx,
+                                    finfo2.basic_info.out.write_time,
+                                    finfo1.basic_info.out.write_time,
+                                    "Server did not update write time within "
+                                    "120 seconds");
 
        if (fnum1 != -1)
                smbcli_close(cli->tree, fnum1);
@@ -143,30 +125,28 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
        char buf[2048];
+       bool first;
+       bool updated;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update1\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
-       if (fnum1 == -1) {
-               torture_result(tctx, TORTURE_FAIL, "Failed to open %s", fname);
-               return false;
-       }
+       torture_assert_int_not_equal(tctx, fnum1, -1, talloc_asprintf(tctx,
+                                    "Failed to open %s", fname));
 
        memset(buf, 'x', 2048);
        written =  smbcli_write(cli->tree, fnum1, 0, buf, 0, 2048);
 
        /* 3 second delay to ensure we get past any 2 second time
           granularity (older systems may have that) */
-       msleep(3 * msec);
+       smb_msleep(3 * msec);
 
        finfo1.all_info.level = RAW_FILEINFO_ALL_INFO;
        finfo1.all_info.in.file.fnum = fnum1;
@@ -179,117 +159,97 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
 
        torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
-       torture_comment(tctx, "Initial write time %s\n", 
-              nt_time_string(tctx, finfo1.all_info.out.write_time));
+       torture_assert_u64_equal(tctx, finfo1.all_info.out.size, 2048,
+                                "file size not as expected after write(2048)");
+
+       torture_comment(tctx, "Initial write time %s\n",
+                       nt_time_string(tctx, finfo1.all_info.out.write_time));
+
+       /* 3 second delay to ensure we get past any 2 second time
+          granularity (older systems may have that) */
+       smb_msleep(3 * msec);
 
        /* Do a zero length SMBwrite call to truncate. */
        written = smbcli_smbwrite(cli->tree, fnum1, "x", 1024, 0);
-
-       if (written != 0) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "write failed - wrote %d bytes (%s)\n",
-                                          (int)written, __location__);
-               return false;
-       }
+       torture_assert_int_equal(tctx, written, 0,
+                                "unexpected number of bytes written");
 
        start = timeval_current();
-       end = timeval_add(&start, (120*sec), 0);
+       end = timeval_add(&start, (120 * sec), 0);
+       first = true;
+       updated = false;
        while (!timeval_expired(&end)) {
                status = smb_raw_fileinfo(cli->tree, tctx, &finfo2);
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-                       ret = false;
-                       break;
-               }
+               torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
-               if (finfo2.all_info.out.size != 1024) {
-                       torture_result(tctx, TORTURE_FAIL, 
-                                                  "file not truncated, size = %u (should be 1024)",
-                               (unsigned int)finfo2.all_info.out.size);
-                       ret = false;
-                       break;
-               }
+               torture_assert_u64_equal(tctx, finfo2.all_info.out.size, 1024,
+                                        "file not truncated to expected size "
+                                        "(1024)");
 
                torture_comment(tctx, "write time %s\n",
-                      nt_time_string(tctx, finfo2.all_info.out.write_time));
-               if (finfo1.all_info.out.write_time != finfo2.all_info.out.write_time) {
-                       double diff = timeval_elapsed(&start);
-                       if (diff > (0.25 * sec * 0.75)) { /* 0.75 to cope with vmware timing */
-                               torture_comment(tctx, "After SMBwrite truncate "
-                                       "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(wrong!)\n",
-                                       diff, sec);
-                               ret = false;
-                               break;
-                       }
+                       nt_time_string(tctx, finfo2.all_info.out.write_time));
 
-                       torture_comment(tctx, "After SMBwrite truncate "
-                                       "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(correct)\n",
-                                       diff, sec);
+               if (finfo1.all_info.out.write_time !=
+                   finfo2.all_info.out.write_time)
+               {
+                       updated = true;
                        break;
                }
+
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
+               first = false;
        }
 
-       if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "Server did not update write time (wrong!)");
-               ret = false;
-       }
+       torture_assert(tctx, updated,
+                      "Server did not update write time within 120 seconds");
+
+       torture_assert(tctx, first, talloc_asprintf(tctx,
+                      "Server did not update write time immediately but only "
+                      "after %.2f seconds!", timeval_elapsed(&start)));
+
+       torture_comment(tctx, "Server updated write time immediately. Good!\n");
 
        fflush(stdout);
-       msleep(2 * msec);
+       smb_msleep(2 * msec);
 
        /* Do a non-zero length SMBwrite and make sure it doesn't update the write time. */
        written = smbcli_smbwrite(cli->tree, fnum1, "x", 0, 1);
-
-       if (written != 1) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "write failed - wrote %d bytes (%s)",
-                                          (int)written, __location__);
-               return false;
-       }
+       torture_assert_int_equal(tctx, written, 1,
+                                "unexpected number of bytes written");
 
        start = timeval_current();
        end = timeval_add(&start, (10*sec), 0);
        while (!timeval_expired(&end)) {
                status = smb_raw_fileinfo(cli->tree, tctx, &finfo3);
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-                       ret = false;
-                       break;
-               }
+               torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
-               if (finfo3.all_info.out.size != 1024) {
-                       DEBUG(0, ("file not truncated, size = %u (should be 1024)\n",
-                               (unsigned int)finfo3.all_info.out.size));
-                       ret = false;
-                       break;
-               }
+               torture_assert_u64_equal(tctx, finfo3.all_info.out.size, 1024,
+                                        "file not truncated to expected size "
+                                        "(1024)");
 
                torture_comment(tctx, "write time %s\n",
-                      nt_time_string(tctx, finfo3.all_info.out.write_time));
-               if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
-                       double diff = timeval_elapsed(&start);
+                       nt_time_string(tctx, finfo3.all_info.out.write_time));
+
+               torture_assert_u64_equal(tctx,
+                                        finfo3.all_info.out.write_time,
+                                        finfo2.all_info.out.write_time,
+                                        talloc_asprintf(tctx,
+                                               "Server updated write time "
+                                               "after %.2f seconds (wrong!)",
+                                               timeval_elapsed(&start)));
 
-                       torture_comment(tctx, "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(correct)\n",
-                                       diff, sec);
-                       break;
-               }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
-       if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "Server updated write time (wrong!)");
-               ret = false;
-       }
+       torture_comment(tctx, "Server did not update write time within 10 "
+                       "seconds. Good!\n");
+
+       fflush(stdout);
+       smb_msleep(2 * msec);
 
        /* the close should trigger an write time update */
        smbcli_close(cli->tree, fnum1);
@@ -298,13 +258,17 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
        status = smb_raw_pathinfo(cli->tree, tctx, &pinfo4);
        torture_assert_ntstatus_ok(tctx, status, "pathinfo failed");
 
-       if (finfo3.all_info.out.write_time == pinfo4.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL,
-                                          "Server did not update write time on close (wrong!)");
-               ret = false;
-       } else if (finfo3.all_info.out.write_time < pinfo4.all_info.out.write_time) {
-               torture_comment(tctx, "Server updated write time on close (correct)\n");
-       }
+       torture_assert_u64_not_equal(tctx,
+                                    pinfo4.all_info.out.write_time,
+                                    finfo3.all_info.out.write_time,
+                                    "Server did not update write time on "
+                                    "close (wrong!)");
+       torture_assert(tctx,
+               pinfo4.all_info.out.write_time > finfo3.all_info.out.write_time,
+               "Server updated write time on close, but to an earlier point "
+               "in time");
+
+       torture_comment(tctx, "Server updated write time on close (correct)\n");
 
        if (fnum1 != -1)
                smbcli_close(cli->tree, fnum1);
@@ -327,30 +291,28 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
        char buf[2048];
+       bool first;
+       bool updated;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update1a\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
-       if (fnum1 == -1) {
-               torture_result(tctx, TORTURE_FAIL, "Failed to open %s", fname);
-               return false;
-       }
+       torture_assert_int_not_equal(tctx, fnum1, -1, talloc_asprintf(tctx,
+                                    "Failed to open %s", fname));
 
        memset(buf, 'x', 2048);
        written =  smbcli_write(cli->tree, fnum1, 0, buf, 0, 2048);
 
        /* 3 second delay to ensure we get past any 2 second time
           granularity (older systems may have that) */
-       msleep(3 * msec);
+       smb_msleep(3 * msec);
 
        finfo1.all_info.level = RAW_FILEINFO_ALL_INFO;
        finfo1.all_info.in.file.fnum = fnum1;
@@ -363,115 +325,92 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb
 
        torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
-       torture_comment(tctx, "Initial write time %s\n", 
-              nt_time_string(tctx, finfo1.all_info.out.write_time));
+       torture_assert_u64_equal(tctx, finfo1.all_info.out.size, 2048,
+                                "file size not as expected after write(2048)");
+
+       torture_comment(tctx, "Initial write time %s\n",
+                       nt_time_string(tctx, finfo1.all_info.out.write_time));
 
        /* Do a zero length SMBwrite call to truncate. */
        written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0);
 
-       if (written != 0) {
-               torture_result(tctx, TORTURE_FAIL, "write failed - wrote %d bytes (%s)",
-                      (int)written, __location__);
-               return false;
-       }
+       torture_assert_int_equal(tctx, written, 0,
+                                "unexpected number of bytes written");
 
        start = timeval_current();
        end = timeval_add(&start, (120*sec), 0);
+       first = true;
+       updated = false;
        while (!timeval_expired(&end)) {
                status = smb_raw_fileinfo(cli->tree, tctx, &finfo2);
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       torture_result(tctx, TORTURE_FAIL, "fileinfo failed: %s", 
-                                                  nt_errstr(status));
-                       ret = false;
-                       break;
-               }
+               torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
-               if (finfo2.all_info.out.size != 10240) {
-                       torture_result(tctx, TORTURE_FAIL, 
-                                                  "file not truncated, size = %u (should be 10240)",
-                               (unsigned int)finfo2.all_info.out.size);
-                       ret = false;
-                       break;
-               }
+               torture_assert_u64_equal(tctx, finfo2.all_info.out.size, 10240,
+                                        "file not truncated to expected size "
+                                        "(10240)");
 
                torture_comment(tctx, "write time %s\n",
-                      nt_time_string(tctx, finfo2.all_info.out.write_time));
-               if (finfo1.all_info.out.write_time != finfo2.all_info.out.write_time) {
-                       double diff = timeval_elapsed(&start);
-                       if (diff > (0.25 * sec * 0.75)) { /* 0.75 to cope with vmware timing */
-                               torture_comment(tctx, "After SMBwrite truncate "
-                                       "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(wrong!)\n",
-                                       diff, sec);
-                               ret = false;
-                               break;
-                       }
+                       nt_time_string(tctx, finfo2.all_info.out.write_time));
 
-                       torture_comment(tctx, "After SMBwrite truncate "
-                                       "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(correct)\n",
-                                       diff, sec);
+               if (finfo1.all_info.out.write_time !=
+                   finfo2.all_info.out.write_time)
+               {
+                       updated = true;
                        break;
                }
+
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
+               first = false;
        }
 
-       if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "Server did not update write time (wrong!)");
-               ret = false;
-       }
+       torture_assert(tctx, updated,
+                      "Server did not update write time within 120 seconds");
+
+       torture_assert(tctx, first, talloc_asprintf(tctx,
+                      "Server did not update write time immediately but only "
+                      "after %.2f seconds!", timeval_elapsed(&start)));
+
+       torture_comment(tctx, "Server updated write time immediately. Good!\n");
 
        fflush(stdout);
-       msleep(2 * msec);
+       smb_msleep(2 * msec);
 
        /* Do a non-zero length SMBwrite and make sure it doesn't update the write time. */
        written = smbcli_smbwrite(cli->tree, fnum1, "x", 0, 1);
 
-       torture_assert_int_equal(tctx, written, 1, 
-                                                        "unexpected number of bytes written");
+       torture_assert_int_equal(tctx, written, 1,
+                                "unexpected number of bytes written");
 
        start = timeval_current();
        end = timeval_add(&start, (10*sec), 0);
        while (!timeval_expired(&end)) {
                status = smb_raw_fileinfo(cli->tree, tctx, &finfo3);
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       torture_result(tctx, TORTURE_FAIL, "fileinfo failed: %s\n", 
-                                                  nt_errstr(status));
-                       ret = false;
-                       break;
-               }
+               torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
-               if (finfo3.all_info.out.size != 10240) {
-                       torture_result(tctx, TORTURE_FAIL, 
-                                                  "file not truncated, size = %u (should be 10240)",
-                                                  (unsigned int)finfo3.all_info.out.size);
-                       ret = false;
-                       break;
-               }
+               torture_assert_u64_equal(tctx, finfo3.all_info.out.size, 10240,
+                                        "file not truncated to expected size "
+                                        "(10240)");
 
                torture_comment(tctx, "write time %s\n",
-                      nt_time_string(tctx, finfo3.all_info.out.write_time));
-               if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
-                       double diff = timeval_elapsed(&start);
+                       nt_time_string(tctx, finfo3.all_info.out.write_time));
+
+               torture_assert_u64_equal(tctx,
+                                        finfo3.all_info.out.write_time,
+                                        finfo2.all_info.out.write_time,
+                                        talloc_asprintf(tctx,
+                                               "Server updated write time "
+                                               "after %.2f seconds (wrong!)",
+                                               timeval_elapsed(&start)));
 
-                       torture_comment(tctx, "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(correct)\n",
-                                       diff, sec);
-                       break;
-               }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
-       if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "Server updated write time (wrong!)");
-               ret = false;
-       }
+       torture_comment(tctx, "Server did not update write time within 10 "
+                       "seconds. Good!\n");
 
        /* the close should trigger an write time update */
        smbcli_close(cli->tree, fnum1);
@@ -480,13 +419,17 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb
        status = smb_raw_pathinfo(cli->tree, tctx, &pinfo4);
        torture_assert_ntstatus_ok(tctx, status, "pathinfo failed");
 
-       if (finfo3.all_info.out.write_time == pinfo4.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "Server did not update write time on close (wrong!)");
-               ret = false;
-       } else if (finfo3.all_info.out.write_time < pinfo4.all_info.out.write_time) {
-               torture_comment(tctx, "Server updated write time on close (correct)\n");
-       }
+       torture_assert_u64_not_equal(tctx,
+                                    pinfo4.all_info.out.write_time,
+                                    finfo3.all_info.out.write_time,
+                                    "Server did not update write time on "
+                                    "close (wrong!)");
+       torture_assert(tctx,
+               pinfo4.all_info.out.write_time > finfo3.all_info.out.write_time,
+               "Server updated write time on close, but to an earlier point "
+               "in time");
+
+       torture_comment(tctx, "Server updated write time on close (correct)\n");
 
        if (fnum1 != -1)
                smbcli_close(cli->tree, fnum1);
@@ -509,30 +452,28 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
        char buf[2048];
+       bool first;
+       bool updated;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update1b\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
-       if (fnum1 == -1) {
-               torture_result(tctx, TORTURE_FAIL, "Failed to open %s", fname);
-               return false;
-       }
+       torture_assert_int_not_equal(tctx, fnum1, -1, talloc_asprintf(tctx,
+                                    "Failed to open %s", fname));
 
        memset(buf, 'x', 2048);
        written =  smbcli_write(cli->tree, fnum1, 0, buf, 0, 2048);
 
        /* 3 second delay to ensure we get past any 2 second time
           granularity (older systems may have that) */
-       msleep(3 * msec);
+       smb_msleep(3 * msec);
 
        finfo1.all_info.level = RAW_FILEINFO_ALL_INFO;
        finfo1.all_info.in.file.fnum = fnum1;
@@ -545,8 +486,11 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
 
        torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
+       torture_assert_u64_equal(tctx, finfo1.all_info.out.size, 2048,
+                                "file size not as expected after write(2048)");
+
        torture_comment(tctx, "Initial write time %s\n",
-              nt_time_string(tctx, finfo1.all_info.out.write_time));
+               nt_time_string(tctx, finfo1.all_info.out.write_time));
 
        /* Do a SET_END_OF_FILE_INFO call to truncate. */
        status = smbcli_ftruncate(cli->tree, fnum1, (uint64_t)10240);
@@ -555,99 +499,78 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
 
        start = timeval_current();
        end = timeval_add(&start, (120*sec), 0);
+       first = true;
+       updated = false;
        while (!timeval_expired(&end)) {
                status = smb_raw_fileinfo(cli->tree, tctx, &finfo2);
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-                       ret = false;
-                       break;
-               }
+               torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
-               if (finfo2.all_info.out.size != 10240) {
-                       torture_result(tctx, TORTURE_FAIL,
-                                                  "file not truncated (size = %u, should be 10240)",
-                                                  (unsigned int)finfo2.all_info.out.size );
-                       ret = false;
-                       break;
-               }
+               torture_assert_u64_equal(tctx, finfo2.all_info.out.size, 10240,
+                                        "file not truncated to expected size "
+                                        "(10240)");
 
                torture_comment(tctx, "write time %s\n",
-                      nt_time_string(tctx, finfo2.all_info.out.write_time));
-               if (finfo1.all_info.out.write_time != finfo2.all_info.out.write_time) {
-                       double diff = timeval_elapsed(&start);
-                       if (diff > (0.25 * sec * 0.75)) { /* 0.75 to cope with vmware timing */
-                               torture_result(tctx, TORTURE_FAIL, 
-                                       "After SET_END_OF_FILE truncate "
-                                       "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(wrong!)",
-                                       diff, sec);
-                               ret = false;
-                               break;
-                       }
+                       nt_time_string(tctx, finfo2.all_info.out.write_time));
 
-                       torture_comment(tctx, "After SET_END_OF_FILE truncate "
-                                       "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(correct)\n",
-                                       diff, sec);
+               if (finfo1.all_info.out.write_time !=
+                   finfo2.all_info.out.write_time)
+               {
+                       updated = true;
                        break;
                }
+
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
+               first = false;
        }
 
-       if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL,
-                                          "Server did not update write time (wrong!)");
-               ret = false;
-       }
+       torture_assert(tctx, updated,
+                      "Server did not update write time within 120 seconds");
+
+       torture_assert(tctx, first, talloc_asprintf(tctx,
+                      "Server did not update write time immediately but only "
+                      "after %.2f seconds!", timeval_elapsed(&start)));
+
+       torture_comment(tctx, "Server updated write time immediately. Good!\n");
 
        fflush(stdout);
-       msleep(2 * msec);
+       smb_msleep(2 * msec);
 
        /* Do a non-zero length SMBwrite and make sure it doesn't update the write time. */
        written = smbcli_smbwrite(cli->tree, fnum1, "x", 0, 1);
 
-       torture_assert_int_equal(tctx, written, 1, 
-                                                        "unexpected number of bytes written");
+       torture_assert_int_equal(tctx, written, 1,
+                                "unexpected number of bytes written");
 
        start = timeval_current();
        end = timeval_add(&start, (10*sec), 0);
        while (!timeval_expired(&end)) {
                status = smb_raw_fileinfo(cli->tree, tctx, &finfo3);
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       torture_result(tctx, TORTURE_FAIL,
-                                                  "fileinfo failed: %s", nt_errstr(status));
-                       ret = false;
-                       break;
-               }
+               torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
-               if (finfo3.all_info.out.size != 10240) {
-                       DEBUG(0, ("file not truncated (size = %u, should be 10240)\n",
-                               (unsigned int)finfo3.all_info.out.size ));
-                       ret = false;
-                       break;
-               }
+               torture_assert_u64_equal(tctx, finfo3.all_info.out.size, 10240,
+                                        "file not truncated to expected size "
+                                        "(10240)");
 
                torture_comment(tctx, "write time %s\n",
-                      nt_time_string(tctx, finfo3.all_info.out.write_time));
-               if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
-                       double diff = timeval_elapsed(&start);
+                       nt_time_string(tctx, finfo3.all_info.out.write_time));
+
+               torture_assert_u64_equal(tctx,
+                                        finfo3.all_info.out.write_time,
+                                        finfo2.all_info.out.write_time,
+                                        talloc_asprintf(tctx,
+                                               "Server updated write time "
+                                               "after %.2f seconds (wrong!)",
+                                               timeval_elapsed(&start)));
 
-                       torture_comment(tctx, "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(correct)\n",
-                                       diff, sec);
-                       break;
-               }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
-       if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, "Server updated write time (wrong!)\n");
-               ret = false;
-       }
+       torture_comment(tctx, "Server did not update write time within 10 "
+                       "seconds. Good!\n");
 
        /* the close should trigger an write time update */
        smbcli_close(cli->tree, fnum1);
@@ -656,12 +579,17 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
        status = smb_raw_pathinfo(cli->tree, tctx, &pinfo4);
        torture_assert_ntstatus_ok(tctx, status, "pathinfo failed");
 
-       if (finfo3.all_info.out.write_time == pinfo4.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, "Server did not update write time on close (wrong!)\n");
-               ret = false;
-       } else if (finfo3.all_info.out.write_time < pinfo4.all_info.out.write_time) {
-               torture_comment(tctx, "Server updated write time on close (correct)\n");
-       }
+       torture_assert_u64_not_equal(tctx,
+                                    pinfo4.all_info.out.write_time,
+                                    finfo3.all_info.out.write_time,
+                                    "Server did not update write time on "
+                                    "close (wrong!)");
+       torture_assert(tctx,
+               pinfo4.all_info.out.write_time > finfo3.all_info.out.write_time,
+               "Server updated write time on close, but to an earlier point "
+               "in time");
+
+       torture_comment(tctx, "Server updated write time on close (correct)\n");
 
        if (fnum1 != -1)
                smbcli_close(cli->tree, fnum1);
@@ -684,30 +612,28 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
        char buf[2048];
+       bool first;
+       bool updated;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update1c\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
-       if (fnum1 == -1) {
-               torture_result(tctx, TORTURE_FAIL, "Failed to open %s", fname);
-               return false;
-       }
+       torture_assert_int_not_equal(tctx, fnum1, -1, talloc_asprintf(tctx,
+                                    "Failed to open %s", fname));
 
        memset(buf, 'x', 2048);
        written =  smbcli_write(cli->tree, fnum1, 0, buf, 0, 2048);
 
        /* 3 second delay to ensure we get past any 2 second time
           granularity (older systems may have that) */
-       msleep(3 * msec);
+       smb_msleep(3 * msec);
 
        finfo1.all_info.level = RAW_FILEINFO_ALL_INFO;
        finfo1.all_info.in.file.fnum = fnum1;
@@ -720,8 +646,11 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
 
        torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
+       torture_assert_u64_equal(tctx, finfo1.all_info.out.size, 2048,
+                                "file size not as expected after write(2048)");
+
        torture_comment(tctx, "Initial write time %s\n",
-              nt_time_string(tctx, finfo1.all_info.out.write_time));
+               nt_time_string(tctx, finfo1.all_info.out.write_time));
 
        /* Do a SET_ALLOCATION_SIZE call to truncate. */
        parms.allocation_info.level = RAW_SFILEINFO_ALLOCATION_INFO;
@@ -730,103 +659,81 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
 
        status = smb_raw_setfileinfo(cli->tree, &parms);
 
-       torture_assert_ntstatus_ok(tctx, status, 
-                                                          "RAW_SFILEINFO_ALLOCATION_INFO failed");
+       torture_assert_ntstatus_ok(tctx, status,
+                                  "RAW_SFILEINFO_ALLOCATION_INFO failed");
 
        start = timeval_current();
        end = timeval_add(&start, (120*sec), 0);
+       first = true;
+       updated = false;
        while (!timeval_expired(&end)) {
                status = smb_raw_fileinfo(cli->tree, tctx, &finfo2);
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       torture_result(tctx, TORTURE_FAIL, "fileinfo failed: %s", 
-                                                  nt_errstr(status));
-                       ret = false;
-                       break;
-               }
+               torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
-               if (finfo2.all_info.out.size != 0) {
-                       torture_result(tctx, TORTURE_FAIL, 
-                                                  "file not truncated (size = %u, should be 10240)",
-                               (unsigned int)finfo2.all_info.out.size);
-                       ret = false;
-                       break;
-               }
+               torture_assert_u64_equal(tctx, finfo2.all_info.out.size, 0,
+                                        "file not truncated to expected size "
+                                        "(0)");
 
                torture_comment(tctx, "write time %s\n",
-                      nt_time_string(tctx, finfo2.all_info.out.write_time));
-               if (finfo1.all_info.out.write_time != finfo2.all_info.out.write_time) {
-                       double diff = timeval_elapsed(&start);
-                       if (diff > (0.25 * sec * 0.75)) { /* 0.75 to cope with vmware timing */
-                               torture_comment(tctx, "After SET_ALLOCATION_INFO truncate "
-                                       "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(wrong!)\n",
-                                       diff, sec);
-                               ret = false;
-                               break;
-                       }
+                       nt_time_string(tctx, finfo2.all_info.out.write_time));
 
-                       torture_comment(tctx, "After SET_ALLOCATION_INFO truncate "
-                                       "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(correct)\n",
-                                       diff, sec);
+               if (finfo1.all_info.out.write_time !=
+                   finfo2.all_info.out.write_time)
+               {
+                       updated = true;
                        break;
                }
+
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
+               first = false;
        }
 
-       if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "Server did not update write time (wrong!)");
-               ret = false;
-       }
+       torture_assert(tctx, updated,
+                      "Server did not update write time within 120 seconds");
+
+       torture_assert(tctx, first, talloc_asprintf(tctx,
+                      "Server did not update write time immediately but only "
+                      "after %.2f seconds!", timeval_elapsed(&start)));
+
+       torture_comment(tctx, "Server updated write time immediately. Good!\n");
 
        fflush(stdout);
-       msleep(2 * msec);
+       smb_msleep(2 * msec);
 
        /* Do a non-zero length SMBwrite and make sure it doesn't update the write time. */
        written = smbcli_smbwrite(cli->tree, fnum1, "x", 0, 1);
-       torture_assert_int_equal(tctx, written, 1, 
-                                                        "Unexpected number of bytes written");
+       torture_assert_int_equal(tctx, written, 1,
+                                "Unexpected number of bytes written");
 
        start = timeval_current();
        end = timeval_add(&start, (10*sec), 0);
        while (!timeval_expired(&end)) {
                status = smb_raw_fileinfo(cli->tree, tctx, &finfo3);
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       torture_result(tctx, TORTURE_FAIL, "fileinfo failed: %s", 
-                                                  nt_errstr(status));
-                       ret = false;
-                       break;
-               }
+               torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
 
-               if (finfo3.all_info.out.size != 1) {
-                       torture_result(tctx, TORTURE_FAIL, "file not expanded");
-                       ret = false;
-                       break;
-               }
+               torture_assert_u64_equal(tctx, finfo3.all_info.out.size, 1,
+                                        "file not expaneded");
 
                torture_comment(tctx, "write time %s\n",
-                      nt_time_string(tctx, finfo3.all_info.out.write_time));
-               if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
-                       double diff = timeval_elapsed(&start);
+                       nt_time_string(tctx, finfo3.all_info.out.write_time));
+
+               torture_assert_u64_equal(tctx,
+                                        finfo3.all_info.out.write_time,
+                                        finfo2.all_info.out.write_time,
+                                        talloc_asprintf(tctx,
+                                               "Server updated write time "
+                                               "after %.2f seconds (wrong!)",
+                                               timeval_elapsed(&start)));
 
-                       torture_comment(tctx, "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(correct)\n",
-                                       diff, sec);
-                       break;
-               }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
-       if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, 
-                                          "Server updated write time (wrong!)");
-               ret = false;
-       }
+       torture_comment(tctx, "Server did not update write time within 10 "
+                       "seconds. Good!\n");
 
        /* the close should trigger an write time update */
        smbcli_close(cli->tree, fnum1);
@@ -835,12 +742,15 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
        status = smb_raw_pathinfo(cli->tree, tctx, &pinfo4);
        torture_assert_ntstatus_ok(tctx, status, "pathinfo failed");
 
-       if (finfo3.all_info.out.write_time == pinfo4.all_info.out.write_time) {
-               torture_result(tctx, TORTURE_FAIL, "Server did not update write time on close (wrong!)\n");
-               ret = false;
-       } else if (finfo3.all_info.out.write_time < pinfo4.all_info.out.write_time) {
-               torture_comment(tctx, "Server updated write time on close (correct)\n");
-       }
+       torture_assert_u64_not_equal(tctx,
+                                    pinfo4.all_info.out.write_time,
+                                    finfo3.all_info.out.write_time,
+                                    "Server did not update write time on "
+                                    "close (wrong!)");
+       torture_assert(tctx,
+               pinfo4.all_info.out.write_time > finfo3.all_info.out.write_time,
+               "Server updated write time on close, but to an earlier point "
+               "in time");
 
        if (fnum1 != -1)
                smbcli_close(cli->tree, fnum1);
@@ -866,7 +776,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
@@ -874,9 +784,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
 
        torture_comment(tctx, "\nRunning test_delayed_write_update2\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
@@ -897,7 +805,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
 
        /* 3 second delay to ensure we get past any 2 second time
           granularity (older systems may have that) */
-       msleep(3 * msec);
+       smb_msleep(3 * msec);
 
        {
                /* Try using setfileinfo instead of write to update write time. */
@@ -963,7 +871,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        written =  smbcli_write(cli->tree, fnum1, 0, "0123456789", 1, 10);
 
        if (written != 10) {
-               torture_comment(tctx, "write failed - wrote %d bytes (%s)\n", 
+               torture_result(tctx, TORTURE_FAIL, "write failed - wrote %d bytes (%s)\n",
                       (int)written, __location__);
                return false;
        }
@@ -997,14 +905,14 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
                       nt_time_string(tctx, finfo2.basic_info.out.write_time));
                if (finfo1.basic_info.out.write_time != finfo2.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds"
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds"
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
        
        if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) {
@@ -1012,11 +920,11 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        }
 
        fflush(stdout);
-       msleep(2 * msec);
+       smb_msleep(2 * msec);
 
        fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
        if (fnum2 == -1) {
-               torture_comment(tctx, "Failed to open %s\n", fname);
+               torture_result(tctx, TORTURE_FAIL, "Failed to open %s\n", fname);
                return false;
        }
        
@@ -1025,7 +933,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        written =  smbcli_write(cli->tree, fnum2, 0, "0123456789", 11, 10);
 
        if (written != 10) {
-               torture_comment(tctx, "write failed - wrote %d bytes (%s)\n", 
+               torture_result(tctx, TORTURE_FAIL, "write failed - wrote %d bytes (%s)\n",
                       (int)written, __location__);
                return false;
        }
@@ -1039,7 +947,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        torture_comment(tctx, "write time %s\n", 
               nt_time_string(tctx, finfo2.basic_info.out.write_time));
        if (finfo1.basic_info.out.write_time != finfo2.basic_info.out.write_time) {
-               torture_comment(tctx, "Server updated write_time (wrong!)\n");
+               torture_result(tctx, TORTURE_FAIL, "Server updated write_time (wrong!)\n");
                ret = false;
        }
 
@@ -1052,7 +960,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        written =  smbcli_write(cli->tree, fnum2, 0, "0123456789", 21, 10);
 
        if (written != 10) {
-               torture_comment(tctx, "write failed - wrote %d bytes (%s)\n", 
+               torture_result(tctx, TORTURE_FAIL, "write failed - wrote %d bytes (%s)\n",
                       (int)written, __location__);
                return false;
        }
@@ -1069,7 +977,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        torture_comment(tctx, "write time %s\n", 
               nt_time_string(tctx, finfo2.basic_info.out.write_time));
        if (finfo1.basic_info.out.write_time != finfo2.basic_info.out.write_time) {
-               torture_comment(tctx, "Server updated write_time (wrong!)\n");
+               torture_result(tctx, TORTURE_FAIL, "Server updated write_time (wrong!)\n");
                ret = false;
        }
 
@@ -1089,14 +997,14 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
                       nt_time_string(tctx, finfo2.basic_info.out.write_time));
                if (finfo1.basic_info.out.write_time != finfo2.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
        
        if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) {
@@ -1128,13 +1036,13 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        torture_comment(tctx, "Second open initial write time %s\n", 
               nt_time_string(tctx, finfo1.basic_info.out.write_time));
 
-       msleep(10 * msec);
+       smb_msleep(10 * msec);
        torture_comment(tctx, "Doing a 10 byte write to extend the file to see if this changes the last write time.\n");
 
        written =  smbcli_write(cli->tree, fnum1, 0, "0123456789", 31, 10);
 
        if (written != 10) {
-               torture_comment(tctx, "write failed - wrote %d bytes (%s)\n", 
+               torture_result(tctx, TORTURE_FAIL, "write failed - wrote %d bytes (%s)\n",
                       (int)written, __location__);
                return false;
        }
@@ -1151,7 +1059,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        torture_comment(tctx, "write time %s\n", 
               nt_time_string(tctx, finfo2.basic_info.out.write_time));
        if (finfo1.basic_info.out.write_time != finfo2.basic_info.out.write_time) {
-               torture_comment(tctx, "Server updated write_time (wrong!)\n");
+               torture_result(tctx, TORTURE_FAIL, "Server updated write_time (wrong!)\n");
                ret = false;
        }
 
@@ -1170,21 +1078,21 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
                       nt_time_string(tctx, finfo2.basic_info.out.write_time));
                if (finfo1.basic_info.out.write_time != finfo2.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       if (diff < (TIMEDELAY_SECS * sec * 0.75)) { /* 0.75 to cope with vmware timing */
-                               torture_comment(tctx, "Server updated write_time after %.2f seconds"
-                                               "(1sec == %.2f) (wrong!)\n",
-                                               diff, sec);
+                       if (diff < (used_delay / (double)1000000)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds"
+                                               "(expected > %.2f) (wrong!)\n",
+                                               diff, used_delay / (double)1000000);
                                ret = false;
                                break;
                        }
 
                        torture_comment(tctx, "Server updated write_time after %.2f seconds"
-                                       "(1sec == %.2f) (correct)\n",
-                                       diff, sec);
+                                       "(correct)\n",
+                                       diff);
                        break;
                }
                fflush(stdout);
-               msleep(1*msec);
+               smb_msleep(1*msec);
        }
        
        if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) {
@@ -1226,16 +1134,14 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
        int fnum2;
        bool ret = true;
        ssize_t written;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_finfo_after_write\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
@@ -1255,7 +1161,7 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
                goto done;
        }
 
-       msleep(1 * msec);
+       smb_msleep(1 * msec);
 
        written =  smbcli_write(cli->tree, fnum1, 0, "x", 0, 1);
 
@@ -1272,42 +1178,42 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
                ret = false;
                goto done;
        }
-       
+
        written =  smbcli_write(cli2->tree, fnum2, 0, "x", 0, 1);
-       
+
        if (written != 1) {
                torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", 
                       (int)written);
                ret = false;
                goto done;
        }
-       
+
        finfo2.basic_info.level = RAW_FILEINFO_BASIC_INFO;
        finfo2.basic_info.in.file.path = fname;
-       
+
        status = smb_raw_pathinfo(cli2->tree, tctx, &finfo2);
-       
+
        if (!NT_STATUS_IS_OK(status)) {
                torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", 
                          nt_errstr(status));
                ret = false;
                goto done;
        }
-       
+
        if (finfo1.basic_info.out.create_time !=
            finfo2.basic_info.out.create_time) {
                torture_result(tctx, TORTURE_FAIL, __location__": create_time changed");
                ret = false;
                goto done;
        }
-       
+
        if (finfo1.basic_info.out.access_time !=
            finfo2.basic_info.out.access_time) {
                torture_result(tctx, TORTURE_FAIL, __location__": access_time changed");
                ret = false;
                goto done;
        }
-       
+
        if (finfo1.basic_info.out.write_time !=
            finfo2.basic_info.out.write_time) {
                torture_result(tctx, TORTURE_FAIL, __location__": write_time changed:\n"
@@ -1317,19 +1223,19 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
                ret = false;
                goto done;
        }
-       
+
        if (finfo1.basic_info.out.change_time !=
            finfo2.basic_info.out.change_time) {
                torture_result(tctx, TORTURE_FAIL, __location__": change_time changed");
                ret = false;
                goto done;
        }
-       
+
        /* One of the two following calls updates the qpathinfo. */
-       
+
        /* If you had skipped the smbcli_write on fnum2, it would
         * *not* have updated the stat on disk */
-       
+
        smbcli_close(cli2->tree, fnum2);
        cli2 = NULL;
 
@@ -1402,31 +1308,48 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
        COMPARE_WRITE_TIME_EQUAL(given,correct); \
 } while (0)
 
-#define GET_INFO_FILE(finfo) do { \
+#define _DEBUG_BASIC_INFO(finfo, comment) do { \
+       struct timeval atv; \
+       struct timeval wtv; \
+       struct timeval_buf atvb; \
+       struct timeval_buf wtvb; \
+       nttime_to_timeval(&atv, finfo.basic_info.out.access_time); \
+       nttime_to_timeval(&wtv, finfo.basic_info.out.write_time); \
+       torture_comment(tctx, "%s: Access(%s) Write(%s)\n", \
+                       comment, \
+                       timeval_str_buf(&atv, false, true, &atvb), \
+                       timeval_str_buf(&wtv, false, true, &wtvb)); \
+} while (0)
+#define _GET_INFO_FILE(tree, finfo) do { \
        NTSTATUS _status; \
-       _status = smb_raw_fileinfo(cli->tree, tctx, &finfo); \
+       _status = smb_raw_fileinfo(tree, tctx, &finfo); \
        if (!NT_STATUS_IS_OK(_status)) { \
                ret = false; \
                torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \
                               nt_errstr(_status)); \
                goto done; \
        } \
-       torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \
-                       nt_time_string(tctx, finfo.basic_info.out.access_time), \
-                       nt_time_string(tctx, finfo.basic_info.out.write_time)); \
+       _DEBUG_BASIC_INFO(finfo, "fileinfo(" #tree ")"); \
 } while (0)
-#define GET_INFO_PATH(pinfo) do { \
+#define _GET_INFO_PATH(tree, pinfo) do { \
        NTSTATUS _status; \
-       _status = smb_raw_pathinfo(cli2->tree, tctx, &pinfo); \
+       _status = smb_raw_pathinfo(tree, tctx, &pinfo); \
        if (!NT_STATUS_IS_OK(_status)) { \
                torture_result(tctx, TORTURE_FAIL, __location__": pathinfo failed: %s", \
                               nt_errstr(_status)); \
                ret = false; \
                goto done; \
        } \
-       torture_comment(tctx, "pathinfo: Access(%s) Write(%s)\n", \
-                       nt_time_string(tctx, pinfo.basic_info.out.access_time), \
-                       nt_time_string(tctx, pinfo.basic_info.out.write_time)); \
+       _DEBUG_BASIC_INFO(pinfo, "pathinfo(" #tree ")"); \
+} while (0)
+#define GET_INFO_FILE(finfo) do { \
+       _GET_INFO_FILE(cli->tree, finfo); \
+} while (0)
+#define GET_INFO_FILE2(finfo) do { \
+       _GET_INFO_FILE(cli2->tree, finfo); \
+} while (0)
+#define GET_INFO_PATH(pinfo) do { \
+       _GET_INFO_PATH(cli2->tree, pinfo); \
 } while (0)
 #define GET_INFO_BOTH(finfo,pinfo) do { \
        GET_INFO_FILE(finfo); \
@@ -1479,24 +1402,22 @@ static bool test_delayed_write_update3(struct torture_context *tctx,
                                       struct smbcli_state *cli,
                                       struct smbcli_state *cli2)
 {
-       union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4;
-       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5;
+       union smb_fileinfo finfo0, finfo1, finfo2, finfo3;
+       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4;
        const char *fname = BASEDIR "\\torture_file3.txt";
        int fnum1 = -1;
        bool ret = true;
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update3\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -1511,14 +1432,12 @@ static bool test_delayed_write_update3(struct torture_context *tctx,
        finfo1 = finfo0;
        finfo2 = finfo0;
        finfo3 = finfo0;
-       finfo4 = finfo0;
        pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO;
        pinfo0.basic_info.in.file.path = fname;
        pinfo1 = pinfo0;
        pinfo2 = pinfo0;
        pinfo3 = pinfo0;
        pinfo4 = pinfo0;
-       pinfo5 = pinfo0;
 
        /* get the initial times */
        GET_INFO_BOTH(finfo0,pinfo0);
@@ -1544,20 +1463,20 @@ static bool test_delayed_write_update3(struct torture_context *tctx,
 
                if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       if (diff < (TIMEDELAY_SECS * sec * 0.75)) { /* 0.75 to cope with vmware timing */
-                               torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                               "(1sec == %.2f) (wrong!)\n",
-                                               diff, sec);
+                       if (diff < (used_delay / (double)1000000)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                               "(write time update delay == %.2f) (wrong!)\n",
+                                               diff, used_delay / (double)1000000);
                                ret = false;
                                break;
                        }
 
                        torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (correct)\n",
-                                       diff, sec);
+                                       "(correct)\n",
+                                       diff);
                        break;
                }
-               msleep(0.5 * msec);
+               smb_msleep(0.5 * msec);
        }
 
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -1580,13 +1499,13 @@ static bool test_delayed_write_update3(struct torture_context *tctx,
 
                if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -1596,7 +1515,7 @@ static bool test_delayed_write_update3(struct torture_context *tctx,
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        GET_INFO_BOTH(finfo3,pinfo3);
        COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2);
@@ -1634,8 +1553,8 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
                                        struct smbcli_state *cli,
                                        struct smbcli_state *cli2)
 {
-       union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4;
-       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5;
+       union smb_fileinfo finfo0, finfo1, finfo2, finfo3;
+       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4;
        const char *fname = BASEDIR "\\torture_file3a.txt";
        int fnum1 = -1;
        bool ret = true;
@@ -1643,16 +1562,14 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
        int i;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update3a\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -1667,14 +1584,12 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
        finfo1 = finfo0;
        finfo2 = finfo0;
        finfo3 = finfo0;
-       finfo4 = finfo0;
        pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO;
        pinfo0.basic_info.in.file.path = fname;
        pinfo1 = pinfo0;
        pinfo2 = pinfo0;
        pinfo3 = pinfo0;
        pinfo4 = pinfo0;
-       pinfo5 = pinfo0;
 
        /* get the initial times */
        GET_INFO_BOTH(finfo0,pinfo0);
@@ -1683,7 +1598,7 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
         * sleep some time, to demonstrate the handling of write times
         * doesn't depend on the time since the open
         */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        /* get the initial times */
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -1710,8 +1625,8 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
 
                if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       if (diff < (TIMEDELAY_SECS * sec * 0.75)) { /* 0.75 to cope with vmware timing */
-                               torture_comment(tctx, "Server updated write_time after %.2f seconds "
+                       if (diff < (used_delay / (double)1000000)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                                "(1sec == %.2f) (wrong!)\n",
                                                diff, sec);
                                ret = false;
@@ -1719,22 +1634,24 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
                        }
 
                        torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (correct)\n",
-                                       diff, sec);
+                                       "(correct)\n",
+                                       diff);
                        break;
                }
-               msleep(0.5 * msec);
+               smb_msleep(0.5 * msec);
        }
 
        GET_INFO_BOTH(finfo1,pinfo1);
        COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0);
 
+       smb_msleep(3 * msec);
+
        /*
         * demonstrate that a truncate write always
         * updates the write time immediately
         */
        for (i=0; i < 3; i++) {
-               msleep(1 * msec);
+               smb_msleep(2 * msec);
                /* do a write */
                torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i);
                written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0);
@@ -1749,6 +1666,8 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
                finfo1 = finfo2;
        }
 
+       smb_msleep(3 * msec);
+
        /* sure any further write doesn't update the write time */
        start = timeval_current();
        end = timeval_add(&start, 15 * sec, 0);
@@ -1766,13 +1685,13 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
 
                if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -1782,7 +1701,7 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(3 * msec);
 
        /* get the initial times */
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -1793,7 +1712,7 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
         * updates the write time immediately
         */
        for (i=0; i < 3; i++) {
-               msleep(1 * msec);
+               smb_msleep(2 * msec);
                /* do a write */
                torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i);
                written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0);
@@ -1809,7 +1728,7 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(3 * msec);
 
        GET_INFO_BOTH(finfo3,pinfo3);
        COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2);
@@ -1846,24 +1765,22 @@ static bool test_delayed_write_update3b(struct torture_context *tctx,
                                        struct smbcli_state *cli,
                                        struct smbcli_state *cli2)
 {
-       union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4;
-       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5;
+       union smb_fileinfo finfo0, finfo1, finfo2, finfo3;
+       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4;
        const char *fname = BASEDIR "\\torture_file3b.txt";
        int fnum1 = -1;
        bool ret = true;
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update3b\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -1878,14 +1795,12 @@ static bool test_delayed_write_update3b(struct torture_context *tctx,
        finfo1 = finfo0;
        finfo2 = finfo0;
        finfo3 = finfo0;
-       finfo4 = finfo0;
        pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO;
        pinfo0.basic_info.in.file.path = fname;
        pinfo1 = pinfo0;
        pinfo2 = pinfo0;
        pinfo3 = pinfo0;
        pinfo4 = pinfo0;
-       pinfo5 = pinfo0;
 
        /* get the initial times */
        GET_INFO_BOTH(finfo0,pinfo0);
@@ -1894,7 +1809,7 @@ static bool test_delayed_write_update3b(struct torture_context *tctx,
         * sleep some time, to demonstrate the handling of write times
         * doesn't depend on the time since the open
         */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        /* get the initial times */
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -1921,20 +1836,20 @@ static bool test_delayed_write_update3b(struct torture_context *tctx,
 
                if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       if (diff < (TIMEDELAY_SECS * sec * 0.75)) { /* 0.75 to cope with vmware timing */
-                               torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                               "(1sec == %.2f) (wrong!)\n",
-                                               diff, sec);
+                       if (diff < (used_delay / (double)1000000)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds"
+                                               "(expected > %.2f) (wrong!)\n",
+                                               diff, used_delay / (double)1000000);
                                ret = false;
                                break;
                        }
 
                        torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (correct)\n",
-                                       diff, sec);
+                                       "(write time update delay == %.2f) (correct)\n",
+                                       diff, used_delay / (double)1000000);
                        break;
                }
-               msleep(0.5 * msec);
+               smb_msleep(0.5 * msec);
        }
 
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -1957,13 +1872,13 @@ static bool test_delayed_write_update3b(struct torture_context *tctx,
 
                if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -1973,7 +1888,7 @@ static bool test_delayed_write_update3b(struct torture_context *tctx,
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        GET_INFO_BOTH(finfo3,pinfo3);
        COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2);
@@ -2013,8 +1928,8 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
                                        struct smbcli_state *cli,
                                        struct smbcli_state *cli2)
 {
-       union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4;
-       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5;
+       union smb_fileinfo finfo0, finfo1, finfo2, finfo3;
+       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4;
        const char *fname = BASEDIR "\\torture_file3c.txt";
        int fnum1 = -1;
        bool ret = true;
@@ -2022,16 +1937,14 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
        int i;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update3c\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2046,14 +1959,12 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
        finfo1 = finfo0;
        finfo2 = finfo0;
        finfo3 = finfo0;
-       finfo4 = finfo0;
        pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO;
        pinfo0.basic_info.in.file.path = fname;
        pinfo1 = pinfo0;
        pinfo2 = pinfo0;
        pinfo3 = pinfo0;
        pinfo4 = pinfo0;
-       pinfo5 = pinfo0;
 
        /* get the initial times */
        GET_INFO_BOTH(finfo0,pinfo0);
@@ -2062,7 +1973,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
         * sleep some time, to demonstrate the handling of write times
         * doesn't depend on the time since the open
         */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        /* get the initial times */
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -2073,7 +1984,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
         * updates the write time immediately
         */
        for (i=0; i < 3; i++) {
-               msleep(1 * msec);
+               smb_msleep(2 * msec);
                /* do a write */
                torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i);
                written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0);
@@ -2104,13 +2015,13 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
 
                if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -2120,7 +2031,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        /* get the initial times */
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -2131,7 +2042,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
         * updates the write time immediately
         */
        for (i=0; i < 3; i++) {
-               msleep(1 * msec);
+               smb_msleep(2 * msec);
                /* do a write */
                torture_comment(tctx, "Do a truncate write [%d] on the file handle\n", i);
                written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0);
@@ -2147,7 +2058,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        GET_INFO_BOTH(finfo2,pinfo2);
        COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1);
@@ -2169,13 +2080,13 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
 
                if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -2185,7 +2096,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        GET_INFO_BOTH(finfo3,pinfo3);
        COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2);
@@ -2224,24 +2135,22 @@ static bool test_delayed_write_update4(struct torture_context *tctx,
                                       struct smbcli_state *cli,
                                       struct smbcli_state *cli2)
 {
-       union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4;
-       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5;
+       union smb_fileinfo finfo0, finfo1, finfo2, finfo3;
+       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4;
        const char *fname = BASEDIR "\\torture_file4.txt";
        int fnum1 = -1;
        bool ret = true;
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update4\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2256,20 +2165,18 @@ static bool test_delayed_write_update4(struct torture_context *tctx,
        finfo1 = finfo0;
        finfo2 = finfo0;
        finfo3 = finfo0;
-       finfo4 = finfo0;
        pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO;
        pinfo0.basic_info.in.file.path = fname;
        pinfo1 = pinfo0;
        pinfo2 = pinfo0;
        pinfo3 = pinfo0;
        pinfo4 = pinfo0;
-       pinfo5 = pinfo0;
 
        /* get the initial times */
        GET_INFO_BOTH(finfo0,pinfo0);
 
        /* sleep a bit */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        /* do a write */
        torture_comment(tctx, "Do a write on the file handle\n");
@@ -2296,20 +2203,20 @@ static bool test_delayed_write_update4(struct torture_context *tctx,
 
                if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       if (diff < (TIMEDELAY_SECS * sec * 0.75)) { /* 0.75 to cope with vmware timing */
-                               torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                               "(1sec == %.2f) (wrong!)\n",
-                                               diff, sec);
+                       if (diff < (used_delay / (double)1000000)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds"
+                                               "(expected > %.2f) (wrong!)\n",
+                                               diff, used_delay / (double)1000000);
                                ret = false;
                                break;
                        }
 
                        torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (correct)\n",
-                                       diff, sec);
+                                       "(write time update delay == %.2f) (correct)\n",
+                                       diff, used_delay / (double)1000000);
                        break;
                }
-               msleep(0.5 * msec);
+               smb_msleep(0.5 * msec);
        }
 
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -2332,13 +2239,13 @@ static bool test_delayed_write_update4(struct torture_context *tctx,
 
                if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -2348,7 +2255,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx,
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        GET_INFO_BOTH(finfo3,pinfo3);
        COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2);
@@ -2393,16 +2300,14 @@ static bool test_delayed_write_update5(struct torture_context *tctx,
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update5\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2463,13 +2368,13 @@ static bool test_delayed_write_update5(struct torture_context *tctx,
 
                if (finfo3.basic_info.out.write_time > finfo2.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo3,pinfo3);
@@ -2495,13 +2400,13 @@ static bool test_delayed_write_update5(struct torture_context *tctx,
 
                if (finfo4.basic_info.out.write_time > finfo3.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo4,pinfo4);
@@ -2511,7 +2416,7 @@ static bool test_delayed_write_update5(struct torture_context *tctx,
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        GET_INFO_BOTH(finfo5,pinfo5);
        COMPARE_WRITE_TIME_EQUAL(finfo5, finfo4);
@@ -2555,16 +2460,14 @@ static bool test_delayed_write_update5b(struct torture_context *tctx,
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update5b\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2625,13 +2528,13 @@ static bool test_delayed_write_update5b(struct torture_context *tctx,
 
                if (finfo3.basic_info.out.write_time > finfo2.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo3,pinfo3);
@@ -2657,13 +2560,13 @@ static bool test_delayed_write_update5b(struct torture_context *tctx,
 
                if (finfo4.basic_info.out.write_time > finfo3.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo4,pinfo4);
@@ -2673,7 +2576,7 @@ static bool test_delayed_write_update5b(struct torture_context *tctx,
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        GET_INFO_BOTH(finfo5,pinfo5);
        COMPARE_WRITE_TIME_EQUAL(finfo5, finfo4);
@@ -2722,7 +2625,7 @@ static bool test_delayed_write_update6(struct torture_context *tctx,
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
@@ -2730,9 +2633,7 @@ static bool test_delayed_write_update6(struct torture_context *tctx,
 
        torture_comment(tctx, "\nRunning test_delayed_write_update6\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 again:
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2796,7 +2697,7 @@ again:
 
        /* make sure the 2 second delay from the first write are canceled */
        start = timeval_current();
-       end = timeval_add(&start, 15 * sec, 0);
+       end = timeval_add(&start, 10 * sec, 0);
        while (!timeval_expired(&end)) {
 
                /* get the times after the first write */
@@ -2804,13 +2705,13 @@ again:
 
                if (finfo3.basic_info.out.write_time > finfo2.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo3,pinfo3);
@@ -2821,7 +2722,7 @@ again:
 
        /* sure any further write doesn't update the write time */
        start = timeval_current();
-       end = timeval_add(&start, 15 * sec, 0);
+       end = timeval_add(&start, 10 * sec, 0);
        while (!timeval_expired(&end)) {
                /* do a write */
                torture_comment(tctx, "Do a write on the file handle\n");
@@ -2836,13 +2737,13 @@ again:
 
                if (finfo4.basic_info.out.write_time > finfo3.basic_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
-                       torture_comment(tctx, "Server updated write_time after %.2f seconds "
-                                       "(1sec == %.2f) (wrong!)\n",
-                                       diff, sec);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo4,pinfo4);
@@ -2852,7 +2753,7 @@ again:
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        GET_INFO_BOTH(finfo5,pinfo5);
        COMPARE_WRITE_TIME_EQUAL(finfo5, finfo4);
@@ -2872,6 +2773,70 @@ again:
                torture_comment(tctx, "Server updated the write_time on close (correct)\n");
        }
 
+       /* See what the second write handle thinks the time is ? */
+       finfo5.basic_info.in.file.fnum = fnum2;
+       GET_INFO_FILE2(finfo5);
+       COMPARE_WRITE_TIME_EQUAL(finfo5, pinfo6);
+
+       /* See if we have lost the sticky write time on handle2 */
+       smb_msleep(3 * msec);
+       torture_comment(tctx, "Have we lost the sticky write time ?\n");
+
+       /* Make sure any further normal write doesn't update the write time */
+       start = timeval_current();
+       end = timeval_add(&start, 10 * sec, 0);
+       while (!timeval_expired(&end)) {
+               /* do a write */
+               torture_comment(tctx, "Do a write on the second file handle\n");
+               written = smbcli_write(cli2->tree, fnum2, 0, "x", 0, 1);
+               if (written != 1) {
+                       torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written);
+                       ret = false;
+                       goto done;
+               }
+               /* get the times after the write */
+               GET_INFO_FILE2(finfo5);
+               GET_INFO_PATH(pinfo6);
+
+               if (finfo5.basic_info.out.write_time > pinfo6.basic_info.out.write_time) {
+                       double diff = timeval_elapsed(&start);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
+                       ret = false;
+                       break;
+               }
+               smb_msleep(1 * msec);
+       }
+
+       /* What about a truncate write ? */
+       start = timeval_current();
+       end = timeval_add(&start, 10 * sec, 0);
+       while (!timeval_expired(&end)) {
+               /* do a write */
+               torture_comment(tctx, "Do a truncate write on the second file handle\n");
+               written = smbcli_write(cli2->tree, fnum2, 0, "x", 0, 0);
+               if (written != 0) {
+                       torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written);
+                       ret = false;
+                       goto done;
+               }
+               /* get the times after the write */
+               GET_INFO_FILE2(finfo5);
+               GET_INFO_PATH(pinfo6);
+
+               if (finfo5.basic_info.out.write_time > pinfo6.basic_info.out.write_time) {
+                       double diff = timeval_elapsed(&start);
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
+                                       "(wrong!)\n",
+                                       diff);
+                       ret = false;
+                       break;
+               }
+               smb_msleep(1 * msec);
+       }
+
+
        /* keep the 2nd handle open and rerun tests */
        if (first) {
                first = false;
@@ -2924,9 +2889,7 @@ static bool test_delayed_write_update7(struct torture_context *tctx, struct smbc
        ZERO_STRUCT(finfo3);
        ZERO_STRUCT(open_parms);
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        /* Create the file. */
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2966,7 +2929,7 @@ static bool test_delayed_write_update7(struct torture_context *tctx, struct smbc
 
        if (finfo2.basic_info.out.write_time != finfo3.basic_info.out.write_time) {
                torture_result(tctx, TORTURE_FAIL, 
-                       "qpathinfo time doens't match fileinfo time");
+                       "qpathinfo time doesn't match fileinfo time");
                ret = false;
        }
 
@@ -3013,12 +2976,359 @@ static bool test_delayed_write_update7(struct torture_context *tctx, struct smbc
        return ret;
 }
 
+/*
+   Test if creating a file in a directory with an open handle updates the
+   write timestamp (it should).
+*/
+static bool test_directory_update8(struct torture_context *tctx, struct smbcli_state *cli)
+{
+       union smb_fileinfo dir_info1, dir_info2;
+       union smb_open open_parms;
+       const char *fname = BASEDIR "\\torture_file.txt";
+       NTSTATUS status;
+       int fnum1 = -1;
+       int fnum2 = -1;
+       bool ret = true;
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       int normal_delay = 2000000;
+       double sec = ((double)used_delay) / ((double)normal_delay);
+       int msec = 1000 * sec;
+       TALLOC_CTX *mem_ctx = talloc_init("test_delayed_write_update8");
+
+        if (!mem_ctx) return false;
+
+       torture_comment(tctx, "\nRunning test directory write update\n");
+
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
+
+       /* Open a handle on the directory - and leave it open. */
+       ZERO_STRUCT(open_parms);
+        open_parms.ntcreatex.level = RAW_OPEN_NTCREATEX;
+        open_parms.ntcreatex.in.flags = 0;
+        open_parms.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
+        open_parms.ntcreatex.in.file_attr = 0;
+        open_parms.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE|
+                                        NTCREATEX_SHARE_ACCESS_READ|
+                                        NTCREATEX_SHARE_ACCESS_WRITE;
+        open_parms.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+        open_parms.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+        open_parms.ntcreatex.in.fname = BASEDIR;
+
+        status = smb_raw_open(cli->tree, mem_ctx, &open_parms);
+        talloc_free(mem_ctx);
+
+        if (!NT_STATUS_IS_OK(status)) {
+                torture_result(tctx, TORTURE_FAIL,
+                        "failed to open directory handle");
+                ret = false;
+               goto done;
+        }
+
+        fnum1 = open_parms.ntcreatex.out.file.fnum;
+
+        /* Store the returned write time. */
+       ZERO_STRUCT(dir_info1);
+       dir_info1.basic_info.out.write_time = open_parms.ntcreatex.out.write_time;
+
+       torture_comment(tctx, "Initial write time %s\n",
+              nt_time_string(tctx, dir_info1.basic_info.out.write_time));
+
+       /* sleep */
+       smb_msleep(3 * msec);
+
+       /* Now create a file within the directory. */
+       fnum2 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
+       if (fnum2 == -1) {
+               torture_result(tctx, TORTURE_FAIL, "Failed to open %s", fname);
+                ret = false;
+               goto done;
+       }
+       smbcli_close(cli->tree, fnum2);
+
+       /* Read the directory write time again. */
+       ZERO_STRUCT(dir_info2);
+       dir_info2.basic_info.level = RAW_FILEINFO_BASIC_INFO;
+       dir_info2.basic_info.in.file.fnum = fnum1;
+
+       status = smb_raw_fileinfo(cli->tree, tctx, &dir_info2);
+
+       torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
+
+       /* Ensure it's been incremented. */
+       COMPARE_WRITE_TIME_GREATER(dir_info2, dir_info1);
+
+       torture_comment(tctx, "Updated write time %s\n",
+              nt_time_string(tctx, dir_info2.basic_info.out.write_time));
+
+ done:
+
+       if (fnum1 != -1)
+               smbcli_close(cli->tree, fnum1);
+       smbcli_unlink(cli->tree, fname);
+       smbcli_deltree(cli->tree, BASEDIR);
+
+       return ret;
+}
+
+#undef COMPARE_WRITE_TIME_CMP
+#undef COMPARE_ACCESS_TIME_CMP
+
+#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \
+       const uint64_t _r = 10*1000*1000; \
+       NTTIME _g = (given).basic_info.out.gelem; \
+       NTTIME _gr = (_g / _r) * _r; \
+       NTTIME _c = (correct).basic_info.out.celem; \
+       NTTIME _cr = (_c / _r) * _r; \
+       bool _strict = torture_setting_bool(tctx, "strict mode", false); \
+       const char *_err = NULL; \
+       if (_strict && (_g cmp _c)) { \
+               _err = "strict"; \
+       } else if ((_g cmp _c) && (_gr cmp _cr)) { \
+               /* handle filesystem without high resolution timestamps */ \
+               _err = "rounded"; \
+       } \
+       if (_err != NULL) { \
+               struct timeval _gtv; \
+               struct timeval _ctv; \
+               struct timeval_buf _gtvb; \
+               struct timeval_buf _ctvb; \
+               nttime_to_timeval(&_gtv, _g); \
+               nttime_to_timeval(&_ctv, _c); \
+               torture_result(tctx, TORTURE_FAIL, \
+                              __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \
+                              _err, \
+                              #given, #gelem, \
+                              timeval_str_buf(&_gtv, false, true, &_gtvb), \
+                              #cmp, \
+                              #correct, #celem, \
+                              timeval_str_buf(&_ctv, false, true, &_ctvb)); \
+               ret = false; \
+               goto done; \
+       } \
+} while (0)
+#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \
+       COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \
+} while (0)
+#define COMPARE_WRITE_TIME_EQUAL(given,correct) \
+       COMPARE_WRITE_TIME_CMP(given,correct,!=)
+#define COMPARE_WRITE_TIME_GREATER(given,correct) \
+       COMPARE_WRITE_TIME_CMP(given,correct,<=)
+
+#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \
+       COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \
+} while (0)
+#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \
+       COMPARE_ACCESS_TIME_CMP(given,correct,!=)
+#define COMPARE_ACCESS_TIME_GREATER(given,correct) \
+       COMPARE_ACCESS_TIME_CMP(given,correct,<=)
+
+#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \
+       COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \
+} while (0)
+#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \
+       COMPARE_CHANGE_TIME_CMP(given,correct,!=)
+#define COMPARE_CHANGE_TIME_GREATER(given,correct) \
+       COMPARE_CHANGE_TIME_CMP(given,correct,<=)
+
+#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \
+       COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \
+} while (0)
+#define COMPARE_CREATE_TIME_EQUAL(given,correct) \
+       COMPARE_CREATE_TIME_CMP(given,correct,!=)
+
+#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \
+       COMPARE_WRITE_TIME_EQUAL(given,correct); \
+       COMPARE_CHANGE_TIME_EQUAL(given,correct); \
+       COMPARE_ACCESS_TIME_EQUAL(given,correct); \
+       COMPARE_CREATE_TIME_EQUAL(given,correct); \
+} while (0)
+
+#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \
+       COMPARE_WRITE_TIME_GREATER(given,correct); \
+       COMPARE_CHANGE_TIME_GREATER(given,correct); \
+       COMPARE_ACCESS_TIME_EQUAL(given,correct); \
+       COMPARE_CREATE_TIME_EQUAL(given,correct); \
+       COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \
+} while (0)
+
+struct test_delaywrite_delaywrite1_state {
+       struct torture_context *tctx;
+       struct smbcli_state *cli1;
+       struct smbcli_state *cli2;
+       int fnum1;
+       int fnum2;
+       const char *fname;
+};
+
+static bool test_delaywrite_delaywrite1_get_info(void *private_data,
+                                                  union smb_fileinfo *finfo)
+{
+       struct test_delaywrite_delaywrite1_state *state =
+               (struct test_delaywrite_delaywrite1_state *)private_data;
+       struct torture_context *tctx = state->tctx;
+       struct smbcli_state *cli = state->cli1;
+       struct smbcli_state *cli2 = state->cli2;
+       union smb_fileinfo t1finfo;
+       union smb_fileinfo t2finfo;
+       bool ret = true;
+
+       ZERO_STRUCTP(finfo);
+
+       ZERO_STRUCT(t1finfo);
+       t1finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION;
+       t1finfo.basic_info.in.file.fnum = state->fnum1;
+
+       ZERO_STRUCT(t2finfo);
+       t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION;
+       t2finfo.basic_info.in.file.fnum = state->fnum2;
+
+       GET_INFO_FILE2(t2finfo);
+       GET_INFO_FILE(t1finfo);
+       if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) {
+               /*
+                * There was a race, get it again on handle 2,
+                * but then they have to match.
+                */
+               GET_INFO_FILE2(t2finfo);
+       }
+       COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo);
+
+       finfo->basic_info.out = t1finfo.basic_info.out;
+done:
+       return ret;
+}
+
+static bool test_delaywrite_delaywrite1_write_data(void *private_data)
+{
+       struct test_delaywrite_delaywrite1_state *state =
+               (struct test_delaywrite_delaywrite1_state *)private_data;
+       struct torture_context *tctx = state->tctx;
+       bool ret = true;
+       ssize_t nwritten;
+
+       nwritten = smbcli_write(state->cli1->tree, state->fnum1, 0, "x", 0, 1);
+       torture_assert_int_equal_goto(tctx, nwritten, 1,
+                                     ret, done, "smbcli_write");
+
+done:
+       return ret;
+}
+
+static bool test_delaywrite_delaywrite1_close(void *private_data,
+                                             union smb_fileinfo *finfo)
+{
+       struct test_delaywrite_delaywrite1_state *state =
+               (struct test_delaywrite_delaywrite1_state *)private_data;
+       struct torture_context *tctx = state->tctx;
+       struct smbcli_state *cli2 = state->cli2;
+       union smb_fileinfo t2finfo;
+       union smb_fileinfo t2pinfo;
+       bool ret = true;
+
+       ZERO_STRUCTP(finfo);
+
+       /*
+        * the close updates the write time to the time of the close
+        * and not to the time of the last write!
+        */
+       torture_comment(tctx, "Close the file handle\n");
+       smbcli_close(state->cli1->tree, state->fnum1);
+       state->fnum1 = -1;
+
+       ZERO_STRUCT(t2finfo);
+       t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFO;
+       t2finfo.basic_info.in.file.fnum = state->fnum2;
+       ZERO_STRUCT(t2pinfo);
+       t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFO;
+       t2pinfo.basic_info.in.file.path = state->fname;
+
+       GET_INFO_FILE2(t2finfo);
+
+       smbcli_close(state->cli2->tree, state->fnum2);
+       state->fnum2 = -1;
+
+       GET_INFO_PATH(t2pinfo);
+       COMPARE_ALL_TIMES_EQUAL(t2pinfo, t2finfo);
+
+       finfo->basic_info.out = t2pinfo.basic_info.out;
+
+done:
+       return ret;
+}
+
+static bool test_delaywrite_delaywrite1(struct torture_context *tctx,
+                                       struct smbcli_state *cli,
+                                       struct smbcli_state *cli2)
+{
+       struct test_delaywrite_delaywrite1_state state = {
+               .tctx = tctx,
+               .cli1 = cli,
+               .cli2 = cli2,
+               .fnum1 = -1,
+               .fnum2 = -1,
+       };
+       const char *fname = BASEDIR "\\torture_file3.txt";
+       bool ret = true;
+       double normal_delay = 1000000;
+       double used_delay;
+       bool ok;
+
+       used_delay = torture_setting_int(tctx, "writetimeupdatedelay",
+                                        normal_delay);
+
+       torture_comment(tctx, "\nRunning test_delayed_write_update3\n");
+
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR),
+                      "Failed to setup up test directory: " BASEDIR);
+
+       torture_comment(tctx, "Open the file handle\n");
+       state.fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
+       torture_assert_int_not_equal_goto(tctx, state.fnum1, -1,
+                                         ret, done,
+                                         "unable to open fnum1");
+       state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
+       torture_assert_int_not_equal_goto(tctx, state.fnum2, -1,
+                                         ret, done,
+                                         "unable to open fnum2");
+
+       state.fname = fname;
+
+       ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay,
+                       "run1",
+                       test_delaywrite_delaywrite1_get_info,
+                       test_delaywrite_delaywrite1_write_data,
+                       NULL, /* close_cb */
+                       &state);
+       torture_assert_goto(tctx, ok, ret, done,
+                            "test_smb_timestamp_writetime1(1)");
+       ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay,
+                       "run2",
+                       test_delaywrite_delaywrite1_get_info,
+                       test_delaywrite_delaywrite1_write_data,
+                       test_delaywrite_delaywrite1_close,
+                       &state);
+       torture_assert_goto(tctx, ok, ret, done,
+                           "test_smb_timestamp_writetime1(2)");
+
+ done:
+       if (state.fnum1 != -1) {
+               smbcli_close(cli->tree, state.fnum1);
+       }
+       if (state.fnum2 != -1) {
+               smbcli_close(cli2->tree, state.fnum2);
+       }
+       smbcli_unlink(cli->tree, fname);
+       smbcli_deltree(cli->tree, BASEDIR);
+
+       return ret;
+}
+
 /*
    testing of delayed update of write_time
 */
-struct torture_suite *torture_delay_write(void)
+struct torture_suite *torture_delay_write(TALLOC_CTX *ctx)
 {
-       struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "DELAYWRITE");
+       struct torture_suite *suite = torture_suite_create(ctx, "delaywrite");
 
        torture_suite_add_2smb_test(suite, "finfo update on close", test_finfo_after_write);
        torture_suite_add_1smb_test(suite, "delayed update of write time", test_delayed_write_update);
@@ -3036,7 +3346,8 @@ struct torture_suite *torture_delay_write(void)
        torture_suite_add_2smb_test(suite, "delayed update of write time 5b", test_delayed_write_update5b);
        torture_suite_add_2smb_test(suite, "delayed update of write time 6", test_delayed_write_update6);
        torture_suite_add_1smb_test(suite, "timestamp resolution test", test_delayed_write_update7);
-       torture_suite_add_1smb_test(suite, "timestamp resolution test", test_delayed_write_update7);
+       torture_suite_add_1smb_test(suite, "directory timestamp update test", test_directory_update8);
+       torture_suite_add_2smb_test(suite, "delaywrite1", test_delaywrite_delaywrite1);
 
        return suite;
 }