test: test job for randtrimwrite
authorVincent Fu <vincent.fu@samsung.com>
Fri, 30 Sep 2022 19:48:56 +0000 (12:48 -0700)
committerVincent Fu <vincent.fu@samsung.com>
Mon, 3 Oct 2022 21:36:57 +0000 (17:36 -0400)
This test exposes a problem with randtrimwrite when norandommap is
enabled.

Currently we check to see if the last write and last trim ended at the
same position. If so, we decide that the next operation should be a
trim. This is ok in most cases but if norandommap is enabled, it could
happen by chance that we just finished a trim + write on an offset and
randomly chose that same offset again. This would fool fio into thinking
that it already finished a trim + write pair when it actually issued
only a trim operation.

Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
t/jobs/t0023.fio [new file with mode: 0644]
t/run-fio-tests.py

diff --git a/t/jobs/t0023.fio b/t/jobs/t0023.fio
new file mode 100644 (file)
index 0000000..0250ee1
--- /dev/null
@@ -0,0 +1,75 @@
+# randtrimwrite data direction tests
+[global]
+filesize=1M
+ioengine=null
+rw=randtrimwrite
+log_offset=1
+per_job_logs=0
+randrepeat=0
+stonewall
+
+# Expected result:     trim issued to random offset followed by write to same offset
+#                      all offsets touched
+#                      block sizes match
+# Buggy result:        something else
+[basic]
+write_bw_log
+
+# Expected result:     trim issued to random offset followed by write to same offset
+#                      all offsets trimmed
+#                      block sizes 8k for both write and trim
+# Buggy result:        something else
+[bs]
+write_bw_log
+bs=4k,4k,8k
+
+# Expected result:     trim issued to random offset followed by write to same offset
+#                      all offsets trimmed
+#                      block sizes match
+# Buggy result:        something else
+[bsrange]
+write_bw_log
+bsrange=512-4k
+
+# Expected result:     trim issued to random offset followed by write to same offset
+#                      all offsets trimmed
+#                      block sizes match
+# Buggy result:        something else
+[bssplit]
+write_bw_log
+bsrange=512/25:1k:25:2k:25:4k/25
+
+# Expected result:     trim issued to random offset followed by write to same offset
+#                      all offsets touched
+#                      block sizes match
+# Buggy result:        something else
+[basic_no_rm]
+write_bw_log
+norandommap=1
+
+# Expected result:     trim issued to random offset followed by write to same offset
+#                      all offsets trimmed
+#                      block sizes 8k for both write and trim
+# Buggy result:        something else
+[bs_no_rm]
+write_bw_log
+bs=4k,4k,8k
+norandommap=1
+
+# Expected result:     trim issued to random offset followed by write to same offset
+#                      all offsets trimmed
+#                      block sizes match
+# Buggy result:        something else
+[bsrange_no_rm]
+write_bw_log
+bsrange=512-4k
+norandommap=1
+
+# Expected result:     trim issued to random offset followed by write to same offset
+#                      all offsets trimmed
+#                      block sizes match
+# Buggy result:        something else
+[bssplit_no_rm]
+write_bw_log
+bsrange=512/25:1k:25:2k:25:4k/25
+norandommap=1
index e72fa2a01cb1e99e51ec9918b0560ec1a1ae1f1e..a2b036d9c8bcf1a6e370309c583d7a0293f67c56 100755 (executable)
@@ -649,6 +649,61 @@ class FioJobTest_t0022(FioJobTest):
             self.failure_reason += " no duplicate offsets found with norandommap=1".format(len(offsets))
 
 
+class FioJobTest_t0023(FioJobTest):
+    """Test consists of fio test job t0023"""
+
+    def check_seq(self, filename):
+        bw_log_filename = os.path.join(self.test_dir, filename)
+        file_data, success = self.get_file(bw_log_filename)
+        log_lines = file_data.split('\n')
+
+        prev_ddir = 1
+        for line in log_lines:
+            if len(line.strip()) == 0:
+                continue
+            vals = line.split(',')
+            ddir = int(vals[2])
+            bs = int(vals[3])
+            offset = int(vals[4])
+            if prev_ddir == 1:
+                if ddir != 2:
+                    self.passed = False
+                    self.failure_reason += " {0}: write not preceeded by trim: {1}".format(bw_log_filename, line)
+                    break
+            else:
+                if ddir != 1:
+                    self.passed = False
+                    self.failure_reason += " {0}: trim not preceeded by write: {1}".format(bw_log_filename, line)
+                    break
+                else:
+                    if prev_bs != bs:
+                        self.passed = False
+                        self.failure_reason += " {0}: block size does not match: {1}".format(bw_log_filename, line)
+                        break
+                    if prev_offset != offset:
+                        self.passed = False
+                        self.failure_reason += " {0}: offset does not match: {1}".format(bw_log_filename, line)
+                        break
+            prev_ddir = ddir
+            prev_bs = bs
+            prev_offset = offset
+
+
+    def check_result(self):
+        super(FioJobTest_t0023, self).check_result()
+
+        self.check_seq("basic_bw.log")
+        self.check_seq("bs_bw.log")
+        self.check_seq("bsrange_bw.log")
+        self.check_seq("bssplit_bw.log")
+        self.check_seq("basic_no_rm_bw.log")
+        self.check_seq("bs_no_rm_bw.log")
+        self.check_seq("bsrange_no_rm_bw.log")
+        self.check_seq("bssplit_no_rm_bw.log")
+
+        # TODO make sure all offsets were touched
+
+
 class FioJobTest_iops_rate(FioJobTest):
     """Test consists of fio test job t0009
     Confirm that job0 iops == 1000
@@ -1026,6 +1081,15 @@ TEST_LIST = [
         'pre_success':      None,
         'requirements':     [],
     },
+    {
+        'test_id':          23,
+        'test_class':       FioJobTest_t0023,
+        'job':              't0023.fio',
+        'success':          SUCCESS_DEFAULT,
+        'pre_job':          None,
+        'pre_success':      None,
+        'requirements':     [],
+    },
     {
         'test_id':          1000,
         'test_class':       FioExeTest,