HACK source4/torture/basic/delaywrite.c
[metze/samba/wip.git] / source4 / torture / basic / delaywrite.c
index 4f6d4fda0ca87a5de3d43a7e136d4dd74ad21ed5..dd261d86d09630200148b55b240cd8176c785ffa 100644 (file)
@@ -29,6 +29,8 @@
 #include "system/filesys.h"
 #include "libcli/libcli.h"
 #include "torture/util.h"
+#include "torture/basic/proto.h"
+#include "lib/util/time_basic.h"
 
 #define BASEDIR "\\delaywrite"
 
@@ -42,83 +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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update\n");
+
+       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_comment(tctx, "Failed to open %s\n", 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");
 
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-               return false;
-       }
-       
-       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_comment(tctx, "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 < (2 * 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_comment(tctx, "Server did not update write time (wrong!)\n");
-               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);
@@ -138,28 +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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update1\n");
+
+       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_comment(tctx, "Failed to open %s\n", 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;
@@ -170,129 +157,118 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
 
        status = smb_raw_fileinfo(cli->tree, tctx, &finfo1);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-               return false;
-       }
+       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_comment(tctx, "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) {
-                       DEBUG(0, ("file not truncated\n"));
-                       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_comment(tctx, "Server did not update write time (wrong!)\n");
-               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);
+       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_comment(tctx, "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, (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\n"));
-                       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_comment(tctx, "Server updated write time (wrong!)\n");
-               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);
        fnum1 = -1;
 
        status = smb_raw_pathinfo(cli->tree, tctx, &pinfo4);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("pathinfo failed: %s\n", nt_errstr(status)));
-               return false;
-       }
+       torture_assert_ntstatus_ok(tctx, status, "pathinfo failed");
 
-       if (finfo3.all_info.out.write_time == pinfo4.all_info.out.write_time) {
-               torture_comment(tctx, "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);
@@ -315,28 +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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update1a\n");
+
+       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_comment(tctx, "Failed to open %s\n", 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;
@@ -347,129 +323,113 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb
 
        status = smb_raw_fileinfo(cli->tree, tctx, &finfo1);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-               return false;
-       }
+       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_comment(tctx, "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);
+       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) {
-                       DEBUG(0, ("file not truncated\n"));
-                       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_comment(tctx, "Server did not update write time (wrong!)\n");
-               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);
+       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_comment(tctx, "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, (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 != 10240) {
-                       DEBUG(0, ("file not truncated\n"));
-                       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_comment(tctx, "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);
        fnum1 = -1;
 
        status = smb_raw_pathinfo(cli->tree, tctx, &pinfo4);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("pathinfo failed: %s\n", nt_errstr(status)));
-               return false;
-       }
+       torture_assert_ntstatus_ok(tctx, status, "pathinfo failed");
 
-       if (finfo3.all_info.out.write_time == pinfo4.all_info.out.write_time) {
-               torture_comment(tctx, "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);
@@ -492,28 +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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update1b\n");
+
+       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_comment(tctx, "Failed to open %s\n", 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;
@@ -524,129 +484,112 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
 
        status = smb_raw_fileinfo(cli->tree, tctx, &finfo1);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-               return false;
-       }
+       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);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               torture_comment(tctx, "SET_END_OF_FILE failed (%s)\n",
-                      nt_errstr(status));
-               return false;
-       }
+       torture_assert_ntstatus_ok(tctx, status, "SET_END_OF_FILE 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)) {
-                       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) {
-                       DEBUG(0, ("file not truncated\n"));
-                       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 SET_END_OF_FILE 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_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_comment(tctx, "Server did not update write time (wrong!)\n");
-               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);
+       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_comment(tctx, "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, (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 != 10240) {
-                       DEBUG(0, ("file not truncated\n"));
-                       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_comment(tctx, "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);
        fnum1 = -1;
 
        status = smb_raw_pathinfo(cli->tree, tctx, &pinfo4);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("pathinfo failed: %s\n", nt_errstr(status)));
-               return false;
-       }
+       torture_assert_ntstatus_ok(tctx, status, "pathinfo failed");
 
-       if (finfo3.all_info.out.write_time == pinfo4.all_info.out.write_time) {
-               torture_comment(tctx, "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);
@@ -669,28 +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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update1c\n");
+
+       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_comment(tctx, "Failed to open %s\n", 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;
@@ -701,133 +644,113 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
 
        status = smb_raw_fileinfo(cli->tree, tctx, &finfo1);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-               return false;
-       }
+       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;
        parms.allocation_info.in.file.fnum = fnum1;
        parms.allocation_info.in.alloc_size = 0;
 
-        status = smb_raw_setfileinfo(cli->tree, &parms);
+       status = smb_raw_setfileinfo(cli->tree, &parms);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               torture_comment(tctx, "RAW_SFILEINFO_ALLOCATION_INFO failed (%s)\n",
-                      nt_errstr(status));
-               return false;
-       }
+       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)) {
-                       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 != 0) {
-                       DEBUG(0, ("file not truncated\n"));
-                       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_comment(tctx, "Server did not update write time (wrong!)\n");
-               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);
+       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_comment(tctx, "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, (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 != 1) {
-                       DEBUG(0, ("file not expanded\n"));
-                       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_comment(tctx, "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);
        fnum1 = -1;
 
        status = smb_raw_pathinfo(cli->tree, tctx, &pinfo4);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("pathinfo failed: %s\n", nt_errstr(status)));
-               return false;
-       }
-
-       if (finfo3.all_info.out.write_time == pinfo4.all_info.out.write_time) {
-               torture_comment(tctx, "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_ntstatus_ok(tctx, status, "pathinfo failed");
+
+       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);
@@ -853,15 +776,15 @@ 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;
        union smb_flush flsh;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update2\n");
+
+       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) {
@@ -875,17 +798,14 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
 
        status = smb_raw_fileinfo(cli->tree, tctx, &finfo1);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-               return false;
-       }
+       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);
+       smb_msleep(3 * msec);
 
        {
                /* Try using setfileinfo instead of write to update write time. */
@@ -908,10 +828,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
 
                status = smb_raw_setfileinfo(cli->tree, &sfinfo);
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0, ("sfileinfo failed: %s\n", nt_errstr(status)));
-                       return false;
-               }
+               torture_assert_ntstatus_ok(tctx, status, "sfileinfo failed");
        }
 
        finfo2.basic_info.in.file.path = fname;
@@ -928,7 +845,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        if (finfo1.basic_info.out.write_time != finfo2.basic_info.out.write_time) {
                torture_comment(tctx, "Server updated write_time (correct)\n");
        } else {
-               torture_comment(tctx, "Server did not update write time (wrong!)\n");
+               torture_result(tctx, TORTURE_FAIL, "Server did not update write time (wrong!)\n");
                ret = false;
        }
 
@@ -954,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;
        }
@@ -988,23 +905,26 @@ 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) {
                torture_comment(tctx, "Server did not update write time (correct)\n");
        }
 
+       fflush(stdout);
+       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;
        }
        
@@ -1013,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;
        }
@@ -1027,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;
        }
 
@@ -1040,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;
        }
@@ -1057,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;
        }
 
@@ -1077,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) {
@@ -1116,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;
        }
@@ -1139,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;
        }
 
@@ -1158,25 +1078,25 @@ 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 < (2 * 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) {
-               torture_comment(tctx, "Server did not update write time (wrong!)\n");
+               torture_result(tctx, TORTURE_FAIL, "Server did not update write time (wrong!)\n");
                ret = false;
        }
 
@@ -1214,14 +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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_finfo_after_write\n");
+
+       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) {
@@ -1241,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);
 
@@ -1258,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"
@@ -1303,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;
 
@@ -1389,6 +1309,10 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
 } while (0)
 
 #define GET_INFO_FILE(finfo) do { \
+       struct timeval atv; \
+       struct timeval wtv; \
+       struct timeval_buf atvb; \
+       struct timeval_buf wtvb; \
        NTSTATUS _status; \
        _status = smb_raw_fileinfo(cli->tree, tctx, &finfo); \
        if (!NT_STATUS_IS_OK(_status)) { \
@@ -1397,6 +1321,21 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
                               nt_errstr(_status)); \
                goto done; \
        } \
+       nttime_to_timeval(&atv, finfo.basic_info.out.access_time); \
+       nttime_to_timeval(&wtv, finfo.basic_info.out.write_time); \
+       torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \
+                       timeval_str_buf(&atv, false, true, &atvb), \
+                       timeval_str_buf(&wtv, false, true, &wtvb)); \
+} while (0)
+#define GET_INFO_FILE2(finfo) do { \
+       NTSTATUS _status; \
+       _status = smb_raw_fileinfo(cli2->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)); \
@@ -1441,26 +1380,48 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
 #define SET_INFO_FILE(finfo, wrtime) \
        SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1)
 
+#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \
+       NTSTATUS _status; \
+       union smb_setfileinfo sfinfo; \
+       sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \
+       sfinfo.basic_info.in.file.fnum = tfnum; \
+       sfinfo.basic_info.in.create_time = 0; \
+       sfinfo.basic_info.in.access_time = 0; \
+       unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \
+       sfinfo.basic_info.in.write_time += (ns); \
+       sfinfo.basic_info.in.change_time = 0; \
+       sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \
+       _status = smb_raw_setfileinfo(tree, &sfinfo); \
+       if (!NT_STATUS_IS_OK(_status)) { \
+               torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \
+                              nt_errstr(_status)); \
+               ret = false; \
+               goto done; \
+       } \
+} while (0)
+
 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;
-       const char *fname = BASEDIR "\\torture_file.txt";
+       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);
+       //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000);
+       //int normal_delay = 1000000;
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       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");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -1475,14 +1436,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);
@@ -1508,20 +1467,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 < (2 * 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, "111Server 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);
@@ -1544,13 +1503,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(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -1560,7 +1519,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);
@@ -1589,27 +1548,32 @@ static bool test_delayed_write_update3(struct torture_context *tctx,
        return ret;
 }
 
+/*
+ * Show that a truncate write always updates the write time even
+ * if an initial write has already updated the write time.
+ */
+
 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;
-       const char *fname = BASEDIR "\\torture_file.txt";
+       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;
        ssize_t written;
        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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update3a\n");
+
+       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);
@@ -1624,14 +1588,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);
@@ -1640,7 +1602,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);
@@ -1667,8 +1629,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 < (2 * 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;
@@ -1676,22 +1638,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);
@@ -1706,6 +1670,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);
@@ -1723,13 +1689,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);
@@ -1739,7 +1705,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);
@@ -1750,7 +1716,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);
@@ -1766,7 +1732,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);
@@ -1794,26 +1760,31 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
        return ret;
 }
 
+/*
+ * Show a close after write updates the write timestamp to
+ * the close time, not the last write time.
+ */
+
 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;
-       const char *fname = BASEDIR "\\torture_file.txt";
+       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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update3b\n");
+
+       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);
@@ -1828,14 +1799,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);
@@ -1844,7 +1813,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);
@@ -1871,20 +1840,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 < (2 * 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);
@@ -1907,13 +1876,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);
@@ -1923,7 +1892,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);
@@ -1952,27 +1921,34 @@ static bool test_delayed_write_update3b(struct torture_context *tctx,
        return ret;
 }
 
+/*
+ * Check that a write after a truncate write doesn't update
+ * the timestamp, but a truncate write after a write does.
+ * Also prove that a close after a truncate write updates the
+ * timestamp to current, not the time of last write.
+ */
+
 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;
-       const char *fname = BASEDIR "\\torture_file.txt";
+       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;
        ssize_t written;
        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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update3c\n");
+
+       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);
@@ -1987,14 +1963,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);
@@ -2003,7 +1977,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);
@@ -2014,7 +1988,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);
@@ -2045,13 +2019,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);
@@ -2061,7 +2035,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);
@@ -2072,7 +2046,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);
@@ -2088,7 +2062,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);
@@ -2110,13 +2084,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);
@@ -2126,7 +2100,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);
@@ -2155,26 +2129,32 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
        return ret;
 }
 
+/*
+ * Show only the first write updates the timestamp, and a close
+ * after writes updates to current (I think this is the same
+ * as test 3b. JRA).
+ */
+
 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;
-       const char *fname = BASEDIR "\\torture_file.txt";
+       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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update4\n");
+
+       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);
@@ -2189,20 +2169,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");
@@ -2229,20 +2207,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 < (2 * 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);
@@ -2265,13 +2243,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);
@@ -2281,7 +2259,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);
@@ -2310,26 +2288,30 @@ static bool test_delayed_write_update4(struct torture_context *tctx,
        return ret;
 }
 
+/*
+ * Show writes and closes have no effect on updating times once a SETWRITETIME is done.
+ */
+
 static bool test_delayed_write_update5(struct torture_context *tctx,
                                       struct smbcli_state *cli,
                                       struct smbcli_state *cli2)
 {
        union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4, finfo5;
        union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5, pinfo6;
-       const char *fname = BASEDIR "\\torture_file.txt";
+       const char *fname = BASEDIR "\\torture_file5.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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update5\n");
+
+       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);
@@ -2390,13 +2372,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);
@@ -2422,13 +2404,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);
@@ -2438,7 +2420,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);
@@ -2466,26 +2448,30 @@ static bool test_delayed_write_update5(struct torture_context *tctx,
        return ret;
 }
 
+/*
+ * Show truncate writes and closes have no effect on updating times once a SETWRITETIME is done.
+ */
+
 static bool test_delayed_write_update5b(struct torture_context *tctx,
                                        struct smbcli_state *cli,
                                        struct smbcli_state *cli2)
 {
        union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4, finfo5;
        union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5, pinfo6;
-       const char *fname = BASEDIR "\\torture_file.txt";
+       const char *fname = BASEDIR "\\torture_fileb.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;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update5b\n");
+
+       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);
@@ -2546,13 +2532,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);
@@ -2561,13 +2547,13 @@ static bool test_delayed_write_update5b(struct torture_context *tctx,
                torture_comment(tctx, "Server did not update write_time (correct)\n");
        }
 
-       /* sure any further write (truncates) update the write time */
+       /* Do any further write (truncates) update the write time ? */
        start = timeval_current();
        end = timeval_add(&start, 15 * sec, 0);
        while (!timeval_expired(&end)) {
                /* do a write */
                torture_comment(tctx, "Do a truncate write on the file handle\n");
-               written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 0);
+               written = smbcli_smbwrite(cli->tree, fnum1, "x", 1024, 0);
                if (written != 0) {
                        torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written);
                        ret = false;
@@ -2578,13 +2564,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);
@@ -2594,7 +2580,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);
@@ -2622,28 +2608,36 @@ static bool test_delayed_write_update5b(struct torture_context *tctx,
        return ret;
 }
 
+/*
+ * Open 2 handles on a file. Write one one and then set the
+ * WRITE TIME explicitly on the other. Ensure the write time
+ * update is cancelled. Ensure the write time is updated to
+ * the close time when the non-explicit set handle is closed.
+ *
+ */
+
 static bool test_delayed_write_update6(struct torture_context *tctx,
                                       struct smbcli_state *cli,
                                       struct smbcli_state *cli2)
 {
        union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4, finfo5;
        union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5, pinfo6, pinfo7;
-       const char *fname = BASEDIR "\\torture_file.txt";
+       const char *fname = BASEDIR "\\torture_file6.txt";
        int fnum1 = -1;
        int fnum2 = -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;
        bool first = true;
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_comment(tctx, "\nRunning test_delayed_write_update6\n");
+
+       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);
@@ -2707,7 +2701,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 */
@@ -2715,13 +2709,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);
@@ -2732,7 +2726,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");
@@ -2747,13 +2741,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);
@@ -2763,7 +2757,7 @@ again:
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        GET_INFO_BOTH(finfo5,pinfo5);
        COMPARE_WRITE_TIME_EQUAL(finfo5, finfo4);
@@ -2783,6 +2777,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;
@@ -2815,17 +2873,217 @@ again:
        return ret;
 }
 
+static bool test_delayed_write_update7(struct torture_context *tctx, struct smbcli_state *cli)
+{
+       union smb_open open_parms;
+       union smb_fileinfo finfo1, finfo2, finfo3;
+       const char *fname = BASEDIR "\\torture_file7.txt";
+       NTSTATUS status;
+       int fnum1 = -1;
+       bool ret = true;
+       TALLOC_CTX *mem_ctx; 
 
-/* 
+       torture_comment(tctx, "\nRunning test_delayed_write_update7 (timestamp resolution test)\n");
+
+        mem_ctx = talloc_init("test_delayed_write_update7");
+        if (!mem_ctx) return false;
+
+       ZERO_STRUCT(finfo1);
+       ZERO_STRUCT(finfo2);
+       ZERO_STRUCT(finfo3);
+       ZERO_STRUCT(open_parms);
+
+       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);
+       if (fnum1 == -1) {
+               torture_result(tctx, TORTURE_FAIL, "Failed to open %s", fname);
+               return false;
+       }
+
+       finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
+       finfo1.basic_info.in.file.fnum = fnum1;
+       finfo2 = finfo1;
+       finfo3 = finfo1;
+
+       /* Get the initial timestamps. */
+       status = smb_raw_fileinfo(cli->tree, tctx, &finfo1);
+
+       torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
+       
+       /* Set the pending write time to a value with ns. */
+       SET_INFO_FILE_NS(finfo, time(NULL) + 86400, 103, cli->tree, fnum1);
+
+       /* Get the current pending write time by fnum. */
+       status = smb_raw_fileinfo(cli->tree, tctx, &finfo2);
+
+       torture_assert_ntstatus_ok(tctx, status, "fileinfo failed");
+
+       /* Ensure the time is actually different. */
+       if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) {
+               torture_result(tctx, TORTURE_FAIL,
+                       "setfileinfo time matches original fileinfo time");
+               ret = false;
+       }
+
+       /* Get the current pending write time by path. */
+       finfo3.basic_info.in.file.path = fname;
+       status = smb_raw_pathinfo(cli->tree, tctx, &finfo3);
+
+       if (finfo2.basic_info.out.write_time != finfo3.basic_info.out.write_time) {
+               torture_result(tctx, TORTURE_FAIL, 
+                       "qpathinfo time doesn't match fileinfo time");
+               ret = false;
+       }
+
+       /* Now close the file. Re-open and check that the write
+          time is identical to the one we wrote. */
+
+       smbcli_close(cli->tree, fnum1);
+
+       open_parms.ntcreatex.level = RAW_OPEN_NTCREATEX;
+       open_parms.ntcreatex.in.flags = 0;
+       open_parms.ntcreatex.in.access_mask = SEC_GENERIC_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 = 0;
+       open_parms.ntcreatex.in.fname = fname;
+
+       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,
+                       "setfileinfo time matches original fileinfo time");
+               ret = false;
+       }
+
+       fnum1 = open_parms.ntcreatex.out.file.fnum;
+
+       /* Check the returned time matches. */
+        if (open_parms.ntcreatex.out.write_time != finfo2.basic_info.out.write_time) {
+               torture_result(tctx, TORTURE_FAIL,
+                       "final open time does not match set time");
+               ret = false;
+       }
+
+ done:
+
+       smbcli_close(cli->tree, fnum1);
+
+       smbcli_unlink(cli->tree, fname);
+       smbcli_deltree(cli->tree, BASEDIR);
+       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;
+}
+
+/*
    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);
-       torture_suite_add_1smb_test(suite, "update of write time and SMBwrite truncate ", test_delayed_write_update1);
+       torture_suite_add_1smb_test(suite, "update of write time and SMBwrite truncate", test_delayed_write_update1);
        torture_suite_add_1smb_test(suite, "update of write time and SMBwrite truncate expand", test_delayed_write_update1a);
        torture_suite_add_1smb_test(suite, "update of write time using SET_END_OF_FILE", test_delayed_write_update1b);
        torture_suite_add_1smb_test(suite, "update of write time using SET_ALLOCATION_SIZE", test_delayed_write_update1c);
@@ -2838,6 +3096,8 @@ struct torture_suite *torture_delay_write(void)
        torture_suite_add_2smb_test(suite, "delayed update of write time 5", test_delayed_write_update5);
        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, "directory timestamp update test", test_directory_update8);
 
        return suite;
 }