torture: Store writetimeupdatedelay in a double to allow easier comparison
[obnox/samba/samba-obnox.git] / source4 / torture / basic / delaywrite.c
index 61678f4e529579a7bd2fb2418fe430854d59e58a..23130e1f47fc05ee7ebc4385713851babf97bd8f 100644 (file)
 #include "system/filesys.h"
 #include "libcli/libcli.h"
 #include "torture/util.h"
+#include "torture/basic/proto.h"
+
+#define W2K8R2_TIMEDELAY_SECS 1
+#define W2K3_TIMEDELAY_SECS 2
+#define TIMEDELAY_SECS W2K3_TIMEDELAY_SECS
 
 #define BASEDIR "\\delaywrite"
 
@@ -42,16 +47,14 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
@@ -70,10 +73,6 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl
        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);
-
        written =  smbcli_write(cli->tree, fnum1, 0, "x", 0, 1);
 
        if (written != 1) {
@@ -97,8 +96,8 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl
                       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"
+                       if (diff < (TIMEDELAY_SECS * sec)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds"
                                                "(1 sec == %.2f)(wrong!)\n",
                                                diff, sec);
                                ret = false;
@@ -111,7 +110,7 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl
                        break;
                }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
        
        if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) {
@@ -139,7 +138,7 @@ 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;
@@ -147,9 +146,7 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
 
        torture_comment(tctx, "\nRunning test_delayed_write_update1\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
@@ -162,7 +159,7 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
 
        /* 3 second delay to ensure we get past any 2 second time
           granularity (older systems may have that) */
-       msleep(3 * msec);
+       smb_msleep(3 * msec);
 
        finfo1.all_info.level = RAW_FILEINFO_ALL_INFO;
        finfo1.all_info.in.file.fnum = fnum1;
@@ -178,6 +175,10 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
        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);
 
@@ -211,8 +212,8 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
                       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 "
+                       if (diff > (0.25 * sec)) {
+                               torture_result(tctx, TORTURE_FAIL, "After SMBwrite truncate "
                                        "server updated write_time after %.2f seconds"
                                        "(1 sec == %.2f)(wrong!)\n",
                                        diff, sec);
@@ -227,7 +228,7 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
                        break;
                }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
        if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) {
@@ -236,6 +237,9 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
                ret = false;
        }
 
+       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);
 
@@ -270,12 +274,12 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
                        double diff = timeval_elapsed(&start);
 
                        torture_comment(tctx, "server updated write_time after %.2f seconds"
-                                       "(1 sec == %.2f)(correct)\n",
+                                       "(1 sec == %.2f)(wrong)\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) {
@@ -284,6 +288,9 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc
                ret = false;
        }
 
+       fflush(stdout);
+       smb_msleep(2 * msec);
+
        /* the close should trigger an write time update */
        smbcli_close(cli->tree, fnum1);
        fnum1 = -1;
@@ -320,7 +327,7 @@ 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;
@@ -328,9 +335,7 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb
 
        torture_comment(tctx, "\nRunning test_delayed_write_update1a\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
@@ -343,7 +348,7 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb
 
        /* 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;
@@ -392,8 +397,8 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb
                       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 "
+                       if (diff > (0.25 * sec)) {
+                               torture_result(tctx, TORTURE_FAIL, "After SMBwrite truncate "
                                        "server updated write_time after %.2f seconds"
                                        "(1 sec == %.2f)(wrong!)\n",
                                        diff, sec);
@@ -408,7 +413,7 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb
                        break;
                }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
        if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) {
@@ -417,6 +422,9 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb
                ret = false;
        }
 
+       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);
 
@@ -448,13 +456,13 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb
                if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
                        double diff = timeval_elapsed(&start);
 
-                       torture_comment(tctx, "server updated write_time after %.2f seconds"
+                       torture_result(tctx, TORTURE_FAIL, "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) {
@@ -499,7 +507,7 @@ 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;
@@ -507,9 +515,7 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
 
        torture_comment(tctx, "\nRunning test_delayed_write_update1b\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
@@ -522,7 +528,7 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
 
        /* 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;
@@ -566,7 +572,7 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
                       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 */
+                       if (diff > (0.25 * sec)) {
                                torture_result(tctx, TORTURE_FAIL, 
                                        "After SET_END_OF_FILE truncate "
                                        "server updated write_time after %.2f seconds"
@@ -583,7 +589,7 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
                        break;
                }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
        if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) {
@@ -592,6 +598,9 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
                ret = false;
        }
 
+       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);
 
@@ -628,7 +637,7 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb
                        break;
                }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
        if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
@@ -671,7 +680,7 @@ 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;
@@ -679,9 +688,7 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
 
        torture_comment(tctx, "\nRunning test_delayed_write_update1c\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
@@ -694,7 +701,7 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
 
        /* 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;
@@ -744,8 +751,8 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
                       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 "
+                       if (diff > (0.25 * sec)) {
+                               torture_result(tctx, TORTURE_FAIL, "After SET_ALLOCATION_INFO truncate "
                                        "server updated write_time after %.2f seconds"
                                        "(1 sec == %.2f)(wrong!)\n",
                                        diff, sec);
@@ -760,7 +767,7 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
                        break;
                }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
        if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) {
@@ -769,6 +776,9 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
                ret = false;
        }
 
+       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);
        torture_assert_int_equal(tctx, written, 1, 
@@ -803,7 +813,7 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb
                        break;
                }
                fflush(stdout);
-               msleep(1 * msec);
+               smb_msleep(1 * msec);
        }
 
        if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) {
@@ -850,7 +860,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
@@ -858,9 +868,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
 
        torture_comment(tctx, "\nRunning test_delayed_write_update2\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
@@ -881,7 +889,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
 
        /* 3 second delay to ensure we get past any 2 second time
           granularity (older systems may have that) */
-       msleep(3 * msec);
+       smb_msleep(3 * msec);
 
        {
                /* Try using setfileinfo instead of write to update write time. */
@@ -947,7 +955,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;
        }
@@ -981,23 +989,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"
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds"
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        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;
        }
        
@@ -1006,7 +1017,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;
        }
@@ -1020,7 +1031,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;
        }
 
@@ -1033,7 +1044,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;
        }
@@ -1050,7 +1061,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;
        }
 
@@ -1070,14 +1081,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        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) {
@@ -1109,13 +1120,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;
        }
@@ -1132,7 +1143,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;
        }
 
@@ -1151,8 +1162,8 @@ 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"
+                       if (diff < (TIMEDELAY_SECS * sec)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds"
                                                "(1sec == %.2f) (wrong!)\n",
                                                diff, sec);
                                ret = false;
@@ -1165,7 +1176,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc
                        break;
                }
                fflush(stdout);
-               msleep(1*msec);
+               smb_msleep(1*msec);
        }
        
        if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) {
@@ -1207,16 +1218,14 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
        int fnum2;
        bool ret = true;
        ssize_t written;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_finfo_after_write\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
@@ -1236,7 +1245,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);
 
@@ -1253,42 +1262,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"
@@ -1298,19 +1307,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;
 
@@ -1396,6 +1405,19 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
                        nt_time_string(tctx, finfo.basic_info.out.access_time), \
                        nt_time_string(tctx, finfo.basic_info.out.write_time)); \
 } 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)); \
+} while (0)
 #define GET_INFO_PATH(pinfo) do { \
        NTSTATUS _status; \
        _status = smb_raw_pathinfo(cli2->tree, tctx, &pinfo); \
@@ -1436,28 +1458,46 @@ 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;
+       union smb_fileinfo finfo0, finfo1, finfo2, finfo3;
+       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4;
        const char *fname = BASEDIR "\\torture_file3.txt";
        int fnum1 = -1;
        bool ret = true;
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update3\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -1472,14 +1512,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);
@@ -1505,8 +1543,8 @@ 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 "
+                       if (diff < (TIMEDELAY_SECS * sec)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                                "(1sec == %.2f) (wrong!)\n",
                                                diff, sec);
                                ret = false;
@@ -1518,7 +1556,7 @@ static bool test_delayed_write_update3(struct torture_context *tctx,
                                        diff, sec);
                        break;
                }
-               msleep(0.5 * msec);
+               smb_msleep(0.5 * msec);
        }
 
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -1541,13 +1579,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -1557,7 +1595,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);
@@ -1595,8 +1633,8 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
                                        struct smbcli_state *cli,
                                        struct smbcli_state *cli2)
 {
-       union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4;
-       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5;
+       union smb_fileinfo finfo0, finfo1, finfo2, finfo3;
+       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4;
        const char *fname = BASEDIR "\\torture_file3a.txt";
        int fnum1 = -1;
        bool ret = true;
@@ -1604,16 +1642,14 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
        int i;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update3a\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -1628,14 +1664,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);
@@ -1644,7 +1678,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);
@@ -1671,8 +1705,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 < (TIMEDELAY_SECS * sec)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                                "(1sec == %.2f) (wrong!)\n",
                                                diff, sec);
                                ret = false;
@@ -1684,18 +1718,20 @@ static bool test_delayed_write_update3a(struct torture_context *tctx,
                                        diff, sec);
                        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);
@@ -1710,6 +1746,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);
@@ -1727,13 +1765,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -1743,7 +1781,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);
@@ -1754,7 +1792,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);
@@ -1770,7 +1808,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);
@@ -1807,24 +1845,22 @@ static bool test_delayed_write_update3b(struct torture_context *tctx,
                                        struct smbcli_state *cli,
                                        struct smbcli_state *cli2)
 {
-       union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4;
-       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5;
+       union smb_fileinfo finfo0, finfo1, finfo2, finfo3;
+       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4;
        const char *fname = BASEDIR "\\torture_file3b.txt";
        int fnum1 = -1;
        bool ret = true;
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update3b\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -1839,14 +1875,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);
@@ -1855,7 +1889,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);
@@ -1882,8 +1916,8 @@ 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 "
+                       if (diff < (TIMEDELAY_SECS * sec)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                                "(1sec == %.2f) (wrong!)\n",
                                                diff, sec);
                                ret = false;
@@ -1895,7 +1929,7 @@ static bool test_delayed_write_update3b(struct torture_context *tctx,
                                        diff, sec);
                        break;
                }
-               msleep(0.5 * msec);
+               smb_msleep(0.5 * msec);
        }
 
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -1918,13 +1952,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -1934,7 +1968,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);
@@ -1983,16 +2017,14 @@ static bool test_delayed_write_update3c(struct torture_context *tctx,
        int i;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update3c\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2023,7 +2055,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);
@@ -2034,7 +2066,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);
@@ -2065,13 +2097,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -2081,7 +2113,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);
@@ -2092,7 +2124,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);
@@ -2108,7 +2140,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);
@@ -2130,13 +2162,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -2146,7 +2178,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);
@@ -2185,24 +2217,22 @@ static bool test_delayed_write_update4(struct torture_context *tctx,
                                       struct smbcli_state *cli,
                                       struct smbcli_state *cli2)
 {
-       union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfo4;
-       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4, pinfo5;
+       union smb_fileinfo finfo0, finfo1, finfo2, finfo3;
+       union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4;
        const char *fname = BASEDIR "\\torture_file4.txt";
        int fnum1 = -1;
        bool ret = true;
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update4\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2217,20 +2247,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");
@@ -2257,8 +2285,8 @@ 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 "
+                       if (diff < (TIMEDELAY_SECS * sec)) {
+                               torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                                "(1sec == %.2f) (wrong!)\n",
                                                diff, sec);
                                ret = false;
@@ -2270,7 +2298,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx,
                                        diff, sec);
                        break;
                }
-               msleep(0.5 * msec);
+               smb_msleep(0.5 * msec);
        }
 
        GET_INFO_BOTH(finfo1,pinfo1);
@@ -2293,13 +2321,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo2,pinfo2);
@@ -2309,7 +2337,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);
@@ -2354,16 +2382,14 @@ static bool test_delayed_write_update5(struct torture_context *tctx,
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update5\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2424,13 +2450,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo3,pinfo3);
@@ -2456,13 +2482,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo4,pinfo4);
@@ -2472,7 +2498,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);
@@ -2516,16 +2542,14 @@ static bool test_delayed_write_update5b(struct torture_context *tctx,
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
 
        torture_comment(tctx, "\nRunning test_delayed_write_update5b\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2586,13 +2610,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo3,pinfo3);
@@ -2618,13 +2642,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo4,pinfo4);
@@ -2634,7 +2658,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);
@@ -2683,7 +2707,7 @@ static bool test_delayed_write_update6(struct torture_context *tctx,
        ssize_t written;
        struct timeval start;
        struct timeval end;
-       int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
+       double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000);
        int normal_delay = 2000000;
        double sec = ((double)used_delay) / ((double)normal_delay);
        int msec = 1000 * sec;
@@ -2691,9 +2715,7 @@ static bool test_delayed_write_update6(struct torture_context *tctx,
 
        torture_comment(tctx, "\nRunning test_delayed_write_update6\n");
 
-       if (!torture_setup_dir(cli, BASEDIR)) {
-               return false;
-       }
+       torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
 again:
        torture_comment(tctx, "Open the file handle\n");
        fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
@@ -2757,7 +2779,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 */
@@ -2765,13 +2787,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo3,pinfo3);
@@ -2782,7 +2804,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");
@@ -2797,13 +2819,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 "
+                       torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds "
                                        "(1sec == %.2f) (wrong!)\n",
                                        diff, sec);
                        ret = false;
                        break;
                }
-               msleep(2 * msec);
+               smb_msleep(1 * msec);
        }
 
        GET_INFO_BOTH(finfo4,pinfo4);
@@ -2813,7 +2835,7 @@ again:
        }
 
        /* sleep */
-       msleep(5 * msec);
+       smb_msleep(5 * msec);
 
        GET_INFO_BOTH(finfo5,pinfo5);
        COMPARE_WRITE_TIME_EQUAL(finfo5, finfo4);
@@ -2833,6 +2855,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 "
+                                       "(1sec == %.2f) (wrong!)\n",
+                                       diff, sec);
+                       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 "
+                                       "(1sec == %.2f) (wrong!)\n",
+                                       diff, sec);
+                       ret = false;
+                       break;
+               }
+               smb_msleep(1 * msec);
+       }
+
+
        /* keep the 2nd handle open and rerun tests */
        if (first) {
                first = false;
@@ -2865,12 +2951,213 @@ 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 doens'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 *suite = torture_suite_create(talloc_autofree_context(), "DELAYWRITE");
+       struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "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);
@@ -2887,6 +3174,9 @@ 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, "timestamp resolution test", test_delayed_write_update7);
+       torture_suite_add_1smb_test(suite, "directory timestamp update test", test_directory_update8);
 
        return suite;
 }