[PATCH][autotest] UBUNTU SAUCE: ubuntu_performance_fio: add device and file system support

Colin King colin.king at canonical.com
Wed Apr 8 15:12:46 UTC 2020


From: Colin Ian King <colin.king at canonical.com>

Add support to specify target device and file system to allow finer
control for performance testing. This is backwardly compatible with
the previous mode of operation.

One can now specify the device with TEST_DRIVE_DEV and the file
system with TEST_FILESYSTEM variables.  File systems currently
supported are: xfs, jfs, btrfs, zfs and ext4.  One needs to run the
test using sudo -E to pass the settings through sudo to the autotest
environment, for example:

TEST_DRIVE_DEV=/dev/nvme0n1 TEST_FILESYSTEM=zfs sudo -E \
  autotest/client/autotest-local autotest/client/tests/ubuntu_performance_fio/control

If TEST_DRIVE_DEV and TEST_FILESYSTEM are not defined then the fio test will
run in the older legacy mode which is still required for some existing projects.

This test is specifically designed to be automatically run by jenkins, the
output is machine parsed and data scraped and populated into an influxdb
for trend plotting.  Hence the tagged names are rather long and unwieldy
as they contain test context.

Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 ubuntu_performance_fio/control                | 85 +++++++++++-------
 .../ubuntu_performance_fio.py                 | 90 ++++++++++++++++++-
 2 files changed, 140 insertions(+), 35 deletions(-)

diff --git a/ubuntu_performance_fio/control b/ubuntu_performance_fio/control
index 11fbda19..5c1205dc 100644
--- a/ubuntu_performance_fio/control
+++ b/ubuntu_performance_fio/control
@@ -13,47 +13,70 @@ DOC = ""
 name = 'ubuntu_performance_fio'
 
 tests = [
-	'rd-100,wr-0,rand,blk-8k,jobs-4,iodepth-32',
-	'rd-100,wr-0,rand,blk-8k,jobs-8,iodepth-32',
-	'rd-100,wr-0,rand,blk-8k,jobs-16,iodepth-32',
+    'rd-100,wr-0,rand,blk-8k,jobs-4,iodepth-32',
+    'rd-100,wr-0,rand,blk-8k,jobs-8,iodepth-32',
+    'rd-100,wr-0,rand,blk-8k,jobs-16,iodepth-32',
 
-	'rd-100,wr-0,rand,blk-128k,jobs-4,iodepth-8',
-	'rd-100,wr-0,rand,blk-128k,jobs-8,iodepth-8',
-	'rd-100,wr-0,rand,blk-128k,jobs-16,iodepth-8',
+    'rd-100,wr-0,rand,blk-128k,jobs-4,iodepth-8',
+    'rd-100,wr-0,rand,blk-128k,jobs-8,iodepth-8',
+    'rd-100,wr-0,rand,blk-128k,jobs-16,iodepth-8',
 
-	'rd-100,wr-0,seq,blk-128k,jobs-4,iodepth-8',
-	'rd-100,wr-0,seq,blk-128k,jobs-8,iodepth-8',
-	'rd-100,wr-0,seq,blk-128k,jobs-16,iodepth-8',
+    'rd-100,wr-0,seq,blk-128k,jobs-4,iodepth-8',
+    'rd-100,wr-0,seq,blk-128k,jobs-8,iodepth-8',
+    'rd-100,wr-0,seq,blk-128k,jobs-16,iodepth-8',
 
-	'rd-0,wr-100,rand,blk-8k,jobs-4,iodepth-32',
-	'rd-0,wr-100,rand,blk-8k,jobs-8,iodepth-32',
-	'rd-0,wr-100,rand,blk-8k,jobs-16,iodepth-32',
+    'rd-0,wr-100,rand,blk-8k,jobs-4,iodepth-32',
+    'rd-0,wr-100,rand,blk-8k,jobs-8,iodepth-32',
+    'rd-0,wr-100,rand,blk-8k,jobs-16,iodepth-32',
 
-	'rd-0,wr-100,seq,blk-128k,jobs-16,iodepth-8',
-	'rd-0,wr-100,seq,blk-128k,jobs-4,iodepth-8',
-	'rd-0,wr-100,seq,blk-128k,jobs-8,iodepth-8',
+    'rd-0,wr-100,seq,blk-128k,jobs-16,iodepth-8',
+    'rd-0,wr-100,seq,blk-128k,jobs-4,iodepth-8',
+    'rd-0,wr-100,seq,blk-128k,jobs-8,iodepth-8',
 
-	'rd-75,wr-25,rand,blk-8k,jobs-16,iodepth-32',
-	'rd-75,wr-25,rand,blk-8k,jobs-4,iodepth-32',
-	'rd-75,wr-25,rand,blk-8k,jobs-8,iodepth-32',
+    'rd-75,wr-25,rand,blk-8k,jobs-16,iodepth-32',
+    'rd-75,wr-25,rand,blk-8k,jobs-4,iodepth-32',
+    'rd-75,wr-25,rand,blk-8k,jobs-8,iodepth-32',
 ]
 
 results = job.run_test_detail('ubuntu_performance_fio', test_name='setup', tag='setup', media='')
 
-media_types = [ 'ramdisk', 'dataset' ]
-#
-# Spec states that config1 should not run ramdisk tests
-#
-if 'TEST_CONFIG' in os.environ:
-	if  os.environ['TEST_CONFIG'] == 'config1':
-		media_types = [ 'dataset' ]
-
-#
-#  Media is 'ramdisk' (/dev/shm) or 'dataset' (normally a raid device)
-#
-for media_type in media_types:
+if 'TEST_DRIVE_DEV' in os.environ and 'TEST_FILESYSTEM' in os.environ:
+    #
+    #  Normal ubuntu kernel team regression fio tests (for graphana profile data)
+    #
     for test in tests:
-	results += job.run_test_detail('ubuntu_performance_fio', test_name=test, tag='ubuntu-performance-fio-' + media_type + '-' + test, media=media_type, timeout=120*60)
+        device = os.environ['TEST_DRIVE_DEV']
+        devname = device.replace('/dev/', '')
+        devname = devname.replace('/', '-')
+        hostname = os.uname()[1]
+        model = utils.system_output('lsblk ' + device + ' -io MODEL -n').splitlines()
+        if len(model) > 0:
+            model = model[0].rstrip()
+        else:
+            model = 'unknown'
+        model = model.replace(' ', '').replace('-', '')
+        model = model.lower()
+        media = hostname + '-' + devname + '-' + model + '-' + os.environ['TEST_FILESYSTEM']
+        meida = media
+        tag = 'ubuntu-performance-fio-' + media + '-' + test.replace(',','-')
+        results += job.run_test_detail('ubuntu_performance_fio', test_name=test, tag=tag, media=media, timeout=120*60)
+else:
+    #
+    #  Legacy fio tests for large host testing
+    #
+    media_types = [ 'ramdisk', 'dataset' ]
+    #
+    # Spec states that config1 should not run ramdisk tests
+    #
+    if 'TEST_CONFIG' in os.environ:
+        if  os.environ['TEST_CONFIG'] == 'config1':
+            media_types = [ 'dataset' ]
+    #
+    #  Media is 'ramdisk' (/dev/shm) or 'dataset' (normally a raid device)
+    #
+    for media_type in media_types:
+        for test in tests:
+            results += job.run_test_detail('ubuntu_performance_fio', test_name=test, tag='ubuntu-performance-fio-' + media_type + '-' + test, media=media_type, timeout=120*60)
 
 print results
 
diff --git a/ubuntu_performance_fio/ubuntu_performance_fio.py b/ubuntu_performance_fio/ubuntu_performance_fio.py
index 31cc406b..8209e324 100644
--- a/ubuntu_performance_fio/ubuntu_performance_fio.py
+++ b/ubuntu_performance_fio/ubuntu_performance_fio.py
@@ -8,6 +8,11 @@ import subprocess
 import resource
 import shutil
 from autotest.client import test, utils
+from autotest.client.shared import error
+
+TEST_FILESYSTEM = os.getenv('TEST_FILESYSTEM')
+TEST_DRIVE_DEV  = os.getenv('TEST_DRIVE_DEV')
+TEST_MNT = '/mnt/autotest-fio'
 
 #
 #  Number of test iterations to get min/max/average stats
@@ -96,7 +101,11 @@ class ubuntu_performance_fio(test.test):
             'build-essential',
             'libaio-dev',
             'linux-tools-generic',
-            'linux-tools-' + release
+            'linux-tools-' + release,
+            'xfsprogs',
+            'btrfs-progs',
+            'jfsutils',
+            'zfsutils-linux'
         ]
         gcc = 'gcc' if arch in ['ppc64le', 'aarch64', 's390x'] else 'gcc-multilib'
         pkgs.append(gcc)
@@ -104,6 +113,72 @@ class ubuntu_performance_fio(test.test):
         cmd = 'apt-get install --yes --force-yes ' + ' '.join(pkgs)
         self.results = utils.system_output(cmd, retain_output=True)
 
+    def setup_drive(self):
+        if TEST_FILESYSTEM == None or TEST_DRIVE_DEV == None:
+            print("No test drive information provided, running on %s" % os.getcwd())
+            return True
+        for line in open('/proc/mounts').readlines():
+            words = line.split()
+            if len(words) > 2 and TEST_DRIVE_DEV in words[0]:
+                raise error.TestError("Device %s seems to be mounted on %s, aborting" % (TEST_DRIVE_DEV, words[1]))
+                return False
+
+        print("Testing on device %s with file system %s\n" % (TEST_DRIVE_DEV, TEST_FILESYSTEM))
+
+        if os.path.exists(TEST_MNT):
+            os.rmdir(TEST_MNT)
+
+        os.mkdir(TEST_MNT)
+        self.results = utils.system_output('dd if=/dev/zero of=%s bs=1M count=64' % TEST_DRIVE_DEV)
+        if TEST_FILESYSTEM == 'ext4':
+            cmd = 'mkfs.ext4 -F ' + TEST_DRIVE_DEV
+            self.results += utils.system_output(cmd)
+            self.results += utils.system_output('mount ' + TEST_DRIVE_DEV + ' ' + TEST_MNT)
+        elif TEST_FILESYSTEM == 'xfs':
+            cmd = 'mkfs.xfs -f ' + TEST_DRIVE_DEV
+            self.results += utils.system_output(cmd)
+            self.results += utils.system_output('mount ' + TEST_DRIVE_DEV + ' ' + TEST_MNT)
+        elif TEST_FILESYSTEM == 'btrfs':
+            cmd = 'mkfs.btrfs -f ' + TEST_DRIVE_DEV
+            self.results += utils.system_output(cmd)
+            self.results += utils.system_output('mount ' + TEST_DRIVE_DEV + ' ' + TEST_MNT)
+        elif TEST_FILESYSTEM == 'jfs':
+            cmd = 'mkfs.jfs ' + TEST_DRIVE_DEV
+            self.results += utils.system_output(cmd)
+            self.results += utils.system_output('mount ' + TEST_DRIVE_DEV + ' ' + TEST_MNT)
+        elif TEST_FILESYSTEM == 'zfs':
+            cmd = 'zpool create -f fiopool ' + TEST_DRIVE_DEV
+            self.results += utils.system_output(cmd)
+            cmd = 'zfs create fiopool/test'
+            self.results += utils.system_output(cmd)
+            cmd = 'zfs set mountpoint=' + TEST_MNT + ' fiopool/test'
+            self.results += utils.system_output(cmd)
+        else:
+            raise error.TestError("Unknown file system TEST_FILESYSTEM=%s, aborting" % TEST_FILESYSTEM)
+
+        return True
+
+    def cleanup_drive(self):
+        if TEST_FILESYSTEM == None or TEST_DRIVE_DEV == None:
+            return
+        self.results = utils.system_output('umount ' + TEST_MNT)
+        if os.path.exists(TEST_MNT):
+            os.rmdir(TEST_MNT)
+        if TEST_FILESYSTEM == 'zfs':
+            self.results += utils.system_output('zpool destroy fiopool')
+        for i in xrange(60):
+            mounted = False
+            for line in open('/proc/mounts').readlines():
+                words = line.split()
+                if len(words) > 2 and TEST_MNT in words[1]:
+                    mounted = True
+                    break
+            if not mounted:
+                return
+            time.sleep(1.0)
+
+        raise error.TestError("Failed to unmount %s filesystem from %s, aborting" % (TEST_FILESYSTEM, TEST_MNT))
+
     def initialize(self):
         pass
 
@@ -188,6 +263,8 @@ class ubuntu_performance_fio(test.test):
             "(sec)" : 1000000.0,
         }
 
+        self.setup_drive()
+
         #
         #  Edit various fio configs to use dynamic settings
         #  relevant to this test location and test size
@@ -205,13 +282,18 @@ class ubuntu_performance_fio(test.test):
         file_size = "%dM" % (file_size_mb)
 
         for line in fin:
-            line = line.replace("DIRECTORY", test_dir)
+            if TEST_FILESYSTEM == None or TEST_DRIVE_DEV == None:
+                line = line.replace("DIRECTORY", test_dir)
+            else:
+                line = line.replace("DIRECTORY", TEST_MNT)
             line = line.replace("SIZE", file_size)
             #
-            #  ramdisk can't do O_DIRECT, so skip this
+            #  zfs and ramdisk can't do O_DIRECT, so skip this
             #
             if media == 'ramdisk' and "direct=1" in line:
                 continue
+            if TEST_FILESYSTEM == 'zfs' and "direct=1" in line:
+                continue
             fout.write(line)
         fin.close()
         fout.close()
@@ -264,6 +346,7 @@ class ubuntu_performance_fio(test.test):
         values['latency_stddev'] = stdev
 
         self.fio_clean_files(testname)
+        self.cleanup_drive()
 
         return values
 
@@ -351,5 +434,4 @@ class ubuntu_performance_fio(test.test):
             print 'cannot execute "%s", required %dMB, only got %dMB on disc' % (test_name, file_size_mb, free_mb)
         print
 
-
 # vi:set ts=4 sw=4 expandtab syntax=python:
-- 
2.25.1




More information about the kernel-team mailing list