From 0bde1f7cb5e6d5db9b2e8afd66f49239a73e950b Mon Sep 17 00:00:00 2001 From: Giuseppe Di Natale Date: Thu, 6 Oct 2016 10:04:54 -0700 Subject: [PATCH 1/5] Correct style in arcstat and arc_summary Fix arcstat and arc_summary so they pass flake8 python code style checks. Signed-off-by: Giuseppe Di Natale --- cmd/arc_summary/arc_summary.py | 102 +++++++++++++++------------------ cmd/arcstat/arcstat.py | 7 ++- 2 files changed, 51 insertions(+), 58 deletions(-) diff --git a/cmd/arc_summary/arc_summary.py b/cmd/arc_summary/arc_summary.py index 9f6d8c1199..e7448fa5d8 100755 --- a/cmd/arc_summary/arc_summary.py +++ b/cmd/arc_summary/arc_summary.py @@ -66,32 +66,17 @@ def get_Kstat(): name, unused, value = kstat.split() Kstat[namespace + name] = D(value) - Kstats = [ - "hw.pagesize", - "hw.physmem", - "kern.maxusers", - "vm.kmem_map_free", - "vm.kmem_map_size", - "vm.kmem_size", - "vm.kmem_size_max", - "vm.kmem_size_min", - "vm.kmem_size_scale", - "vm.stats", - "vm.swap_total", - "vm.swap_reserved", - "kstat.zfs", - "vfs.zfs" - ] Kstat = {} load_proc_kstats('/proc/spl/kstat/zfs/arcstats', - 'kstat.zfs.misc.arcstats.') + 'kstat.zfs.misc.arcstats.') load_proc_kstats('/proc/spl/kstat/zfs/zfetchstats', - 'kstat.zfs.misc.zfetchstats.') + 'kstat.zfs.misc.zfetchstats.') load_proc_kstats('/proc/spl/kstat/zfs/vdev_cache_stats', - 'kstat.zfs.misc.vdev_cache_stats.') + 'kstat.zfs.misc.vdev_cache_stats.') return Kstat + def div1(): sys.stdout.write("\n") for i in range(18): @@ -188,17 +173,17 @@ def get_arc_summary(Kstat): output['memory_throttle_count'] = fHits(memory_throttle_count) - ### ARC Misc. ### + # ARC Misc. deleted = Kstat["kstat.zfs.misc.arcstats.deleted"] mutex_miss = Kstat["kstat.zfs.misc.arcstats.mutex_miss"] - ### ARC Misc. ### + # ARC Misc. output["arc_misc"] = {} output["arc_misc"]["deleted"] = fHits(deleted) output["arc_misc"]['mutex_miss'] = fHits(mutex_miss) output["arc_misc"]['evict_skips'] = fHits(mutex_miss) - ### ARC Sizing ### + # ARC Sizing arc_size = Kstat["kstat.zfs.misc.arcstats.size"] mru_size = Kstat["kstat.zfs.misc.arcstats.p"] target_max_size = Kstat["kstat.zfs.misc.arcstats.c_max"] @@ -207,7 +192,7 @@ def get_arc_summary(Kstat): target_size_ratio = (target_max_size / target_min_size) - ### ARC Sizing ### + # ARC Sizing output['arc_sizing'] = {} output['arc_sizing']['arc_size'] = { 'per': fPerc(arc_size, target_max_size), @@ -226,7 +211,7 @@ def get_arc_summary(Kstat): 'num': fBytes(target_size), } - ### ARC Hash Breakdown ### + # ARC Hash Breakdown output['arc_hash_break'] = {} output['arc_hash_break']['hash_chain_max'] = Kstat[ "kstat.zfs.misc.arcstats.hash_chain_max" @@ -267,7 +252,7 @@ def get_arc_summary(Kstat): 'num': fBytes(mfu_size), } - ### ARC Hash Breakdown ### + # ARC Hash Breakdown hash_chain_max = Kstat["kstat.zfs.misc.arcstats.hash_chain_max"] hash_chains = Kstat["kstat.zfs.misc.arcstats.hash_chains"] hash_collisions = Kstat["kstat.zfs.misc.arcstats.hash_collisions"] @@ -288,25 +273,25 @@ def get_arc_summary(Kstat): def _arc_summary(Kstat): - ### ARC Sizing ### + # ARC Sizing arc = get_arc_summary(Kstat) sys.stdout.write("ARC Summary: (%s)\n" % arc['health']) sys.stdout.write("\tMemory Throttle Count:\t\t\t%s\n" % - arc['memory_throttle_count']) + arc['memory_throttle_count']) sys.stdout.write("\n") - ### ARC Misc. ### + # ARC Misc. sys.stdout.write("ARC Misc:\n") sys.stdout.write("\tDeleted:\t\t\t\t%s\n" % arc['arc_misc']['deleted']) sys.stdout.write("\tMutex Misses:\t\t\t\t%s\n" % - arc['arc_misc']['mutex_miss']) + arc['arc_misc']['mutex_miss']) sys.stdout.write("\tEvict Skips:\t\t\t\t%s\n" % - arc['arc_misc']['mutex_miss']) + arc['arc_misc']['mutex_miss']) sys.stdout.write("\n") - ### ARC Sizing ### + # ARC Sizing sys.stdout.write("ARC Size:\t\t\t\t%s\t%s\n" % ( arc['arc_sizing']['arc_size']['per'], arc['arc_sizing']['arc_size']['num'] @@ -344,21 +329,21 @@ def _arc_summary(Kstat): sys.stdout.write("\n") - ### ARC Hash Breakdown ### + # ARC Hash Breakdown sys.stdout.write("ARC Hash Breakdown:\n") sys.stdout.write("\tElements Max:\t\t\t\t%s\n" % - arc['arc_hash_break']['elements_max']) + arc['arc_hash_break']['elements_max']) sys.stdout.write("\tElements Current:\t\t%s\t%s\n" % ( arc['arc_hash_break']['elements_current']['per'], arc['arc_hash_break']['elements_current']['num'], ) ) sys.stdout.write("\tCollisions:\t\t\t\t%s\n" % - arc['arc_hash_break']['collisions']) + arc['arc_hash_break']['collisions']) sys.stdout.write("\tChain Max:\t\t\t\t%s\n" % - arc['arc_hash_break']['chain_max']) + arc['arc_hash_break']['chain_max']) sys.stdout.write("\tChains:\t\t\t\t\t%s\n" % - arc['arc_hash_break']['chains']) + arc['arc_hash_break']['chains']) def get_arc_efficiency(Kstat): @@ -488,7 +473,7 @@ def _arc_efficiency(Kstat): arc = get_arc_efficiency(Kstat) sys.stdout.write("ARC Total accesses:\t\t\t\t\t%s\n" % - arc['total_accesses']) + arc['total_accesses']) sys.stdout.write("\tCache Hit Ratio:\t\t%s\t%s\n" % ( arc['cache_hit_ratio']['per'], arc['cache_hit_ratio']['num'], @@ -699,7 +684,7 @@ def _l2arc_summary(Kstat): else: sys.stdout.write("(HEALTHY)\n") sys.stdout.write("\tLow Memory Aborts:\t\t\t%s\n" % - arc['low_memory_aborts']) + arc['low_memory_aborts']) sys.stdout.write("\tFree on Write:\t\t\t\t%s\n" % arc['free_on_write']) sys.stdout.write("\tR/W Clashes:\t\t\t\t%s\n" % arc['rw_clashes']) sys.stdout.write("\tBad Checksums:\t\t\t\t%s\n" % arc['bad_checksums']) @@ -707,7 +692,7 @@ def _l2arc_summary(Kstat): sys.stdout.write("\n") sys.stdout.write("L2 ARC Size: (Adaptive)\t\t\t\t%s\n" % - arc["l2_arc_size"]["adative"]) + arc["l2_arc_size"]["adative"]) sys.stdout.write("\tCompressed:\t\t\t%s\t%s\n" % ( arc["l2_arc_size"]["actual"]["per"], arc["l2_arc_size"]["actual"]["num"], @@ -724,13 +709,13 @@ def _l2arc_summary(Kstat): arc["l2_arc_evicts"]["reading"] > 0: sys.stdout.write("L2 ARC Evicts:\n") sys.stdout.write("\tLock Retries:\t\t\t\t%s\n" % - arc["l2_arc_evicts"]['lock_retries']) + arc["l2_arc_evicts"]['lock_retries']) sys.stdout.write("\tUpon Reading:\t\t\t\t%s\n" % - arc["l2_arc_evicts"]["reading"]) + arc["l2_arc_evicts"]["reading"]) sys.stdout.write("\n") sys.stdout.write("L2 ARC Breakdown:\t\t\t\t%s\n" % - arc['l2_arc_breakdown']['value']) + arc['l2_arc_breakdown']['value']) sys.stdout.write("\tHit Ratio:\t\t\t%s\t%s\n" % ( arc['l2_arc_breakdown']['hit_ratio']['per'], arc['l2_arc_breakdown']['hit_ratio']['num'], @@ -744,7 +729,7 @@ def _l2arc_summary(Kstat): ) sys.stdout.write("\tFeeds:\t\t\t\t\t%s\n" % - arc['l2_arc_breakdown']['feeds']) + arc['l2_arc_breakdown']['feeds']) sys.stdout.write("\n") sys.stdout.write("L2 ARC Writes:\n") @@ -803,7 +788,7 @@ def _dmu_summary(Kstat): if arc['zfetch_access_total'] > 0: sys.stdout.write("DMU Prefetch Efficiency:\t\t\t\t\t%s\n" % - arc['dmu']['efficiency']['value']) + arc['dmu']['efficiency']['value']) sys.stdout.write("\tHit Ratio:\t\t\t%s\t%s\n" % ( arc['dmu']['efficiency']['hit_ratio']['per'], arc['dmu']['efficiency']['hit_ratio']['num'], @@ -822,11 +807,11 @@ def get_vdev_summary(Kstat): output = {} vdev_cache_delegations = \ - Kstat["kstat.zfs.misc.vdev_cache_stats.delegations"] + Kstat["kstat.zfs.misc.vdev_cache_stats.delegations"] vdev_cache_misses = Kstat["kstat.zfs.misc.vdev_cache_stats.misses"] vdev_cache_hits = Kstat["kstat.zfs.misc.vdev_cache_stats.hits"] vdev_cache_total = (vdev_cache_misses + vdev_cache_hits + - vdev_cache_delegations) + vdev_cache_delegations) output['vdev_cache_total'] = vdev_cache_total @@ -875,7 +860,8 @@ def _tunable_summary(Kstat): values = {} for name in names: - with open("/sys/module/zfs/parameters/" + name) as f: value = f.read() + with open("/sys/module/zfs/parameters/" + name) as f: + value = f.read() values[name] = value.strip() descriptions = {} @@ -884,7 +870,7 @@ def _tunable_summary(Kstat): try: command = ["/sbin/modinfo", "zfs", "-0"] p = Popen(command, stdin=PIPE, stdout=PIPE, - stderr=PIPE, shell=False, close_fds=True) + stderr=PIPE, shell=False, close_fds=True) p.wait() description_list = p.communicate()[0].strip().split('\0') @@ -899,11 +885,11 @@ def _tunable_summary(Kstat): descriptions[name] = description else: sys.stderr.write("%s: '%s' exited with code %i\n" % - (sys.argv[0], command[0], p.returncode)) + (sys.argv[0], command[0], p.returncode)) sys.stderr.write("Tunable descriptions will be disabled.\n") except OSError as e: sys.stderr.write("%s: Cannot run '%s': %s\n" % - (sys.argv[0], command[0], e.strerror)) + (sys.argv[0], command[0], e.strerror)) sys.stderr.write("Tunable descriptions will be disabled.\n") sys.stdout.write("ZFS Tunable:\n") @@ -942,21 +928,23 @@ def zfs_header(): def usage(): sys.stdout.write("Usage: arc_summary.py [-h] [-a] [-d] [-p PAGE]\n\n") sys.stdout.write("\t -h, --help : " - "Print this help message and exit\n") + "Print this help message and exit\n") sys.stdout.write("\t -a, --alternate : " - "Show an alternate sysctl layout\n") + "Show an alternate sysctl layout\n") sys.stdout.write("\t -d, --description : " - "Show the sysctl descriptions\n") + "Show the sysctl descriptions\n") sys.stdout.write("\t -p PAGE, --page=PAGE : " - "Select a single output page to display,\n") + "Select a single output page to display,\n") sys.stdout.write("\t " - "should be an integer between 1 and " + str(len(unSub)) + "\n\n") + "should be an integer between 1 and " + + str(len(unSub)) + "\n\n") sys.stdout.write("Examples:\n") sys.stdout.write("\tarc_summary.py -a\n") sys.stdout.write("\tarc_summary.py -p 4\n") sys.stdout.write("\tarc_summary.py -ad\n") sys.stdout.write("\tarc_summary.py --page=2\n") + def main(): global show_tunable_descriptions global alternate_tunable_layout @@ -987,9 +975,9 @@ def main(): if 'p' in args: try: pages.append(unSub[int(args['p']) - 1]) - except IndexError as e: + except IndexError: sys.stderr.write('the argument to -p must be between 1 and ' + - str(len(unSub)) + '\n') + str(len(unSub)) + '\n') sys.exit() else: pages = unSub diff --git a/cmd/arcstat/arcstat.py b/cmd/arcstat/arcstat.py index 8bd0d511dd..4161207950 100755 --- a/cmd/arcstat/arcstat.py +++ b/cmd/arcstat/arcstat.py @@ -229,15 +229,19 @@ def print_header(): sys.stdout.write("%*s%s" % (cols[col][0], col, sep)) sys.stdout.write("\n") + def get_terminal_lines(): try: - import fcntl, termios, struct + import fcntl + import termios + import struct data = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, '1234') sz = struct.unpack('hh', data) return sz[0] except: pass + def update_hdr_intr(): global hdr_intr @@ -245,6 +249,7 @@ def update_hdr_intr(): if lines and lines > 3: hdr_intr = lines - 3 + def resize_handler(signum, frame): update_hdr_intr() From 9285493adfab4c3f33ffbdb63f16c8c65bdeb8f1 Mon Sep 17 00:00:00 2001 From: Giuseppe Di Natale Date: Thu, 6 Oct 2016 10:11:06 -0700 Subject: [PATCH 2/5] Correct style in test-runner Correct test-runner.py so it passes flake8 python style checking. Signed-off-by: Giuseppe Di Natale --- tests/test-runner/cmd/test-runner.py | 43 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/tests/test-runner/cmd/test-runner.py b/tests/test-runner/cmd/test-runner.py index 4d31ddceb2..6872849078 100755 --- a/tests/test-runner/cmd/test-runner.py +++ b/tests/test-runner/cmd/test-runner.py @@ -127,12 +127,12 @@ class Cmd(object): self.killed = False self.result = Result() - if self.timeout == None: - self.timeout = 60 + if self.timeout is None: + self.timeout = 60 def __str__(self): return "Pathname: %s\nOutputdir: %s\nTimeout: %d\nUser: %s\n" % ( - self.pathname, self.outputdir, self.timeout, self.user) + self.pathname, self.outputdir, self.timeout, self.user) def kill_cmd(self, proc): """ @@ -309,9 +309,10 @@ class Test(Cmd): if len(self.post_user): post_user = ' (as %s)' % (self.post_user) return "Pathname: %s\nOutputdir: %s\nTimeout: %d\nPre: %s%s\nPost: " \ - "%s%s\nUser: %s\n" % (self.pathname, self.outputdir, - self.timeout, self.pre, pre_user, self.post, post_user, - self.user) + "%s%s\nUser: %s\n" % ( + self.pathname, self.outputdir, + self.timeout, self.pre, pre_user, self.post, post_user, + self.user) def verify(self, logger): """ @@ -384,9 +385,9 @@ class TestGroup(Test): if len(self.post_user): post_user = ' (as %s)' % (self.post_user) return "Pathname: %s\nOutputdir: %s\nTests: %s\nTimeout: %d\n" \ - "Pre: %s%s\nPost: %s%s\nUser: %s\n" % (self.pathname, - self.outputdir, self.tests, self.timeout, self.pre, pre_user, - self.post, post_user, self.user) + "Pre: %s%s\nPost: %s%s\nUser: %s\n" % ( + self.pathname, self.outputdir, self.tests, self.timeout, + self.pre, pre_user, self.post, post_user, self.user) def verify(self, logger): """ @@ -428,8 +429,8 @@ class TestGroup(Test): if not verify_file(os.path.join(self.pathname, test)): del self.tests[self.tests.index(test)] logger.info("Warning: Test '%s' removed from TestGroup '%s' " - "because it failed verification." % (test, - self.pathname)) + "because it failed verification." % + (test, self.pathname)) return len(self.tests) is not 0 @@ -634,7 +635,7 @@ class TestRun(object): components -= 1 for testfile in tmp_dict.keys(): uniq = '/'.join(testfile.split('/')[components:]).lstrip('/') - if not uniq in l: + if uniq not in l: l.append(uniq) tmp_dict[testfile].outputdir = os.path.join(base, uniq) else: @@ -705,8 +706,8 @@ class TestRun(object): m, s = divmod(time() - self.starttime, 60) h, m = divmod(m, 60) print '\nRunning Time:\t%02d:%02d:%02d' % (h, m, s) - print 'Percent passed:\t%.1f%%' % ((float(Result.runresults['PASS']) / - float(Result.total)) * 100) + print 'Percent passed:\t%.1f%%' % ( + (float(Result.runresults['PASS']) / float(Result.total)) * 100) print 'Log directory:\t%s' % self.outputdir @@ -717,10 +718,10 @@ def verify_file(pathname): if os.path.isdir(pathname) or os.path.islink(pathname): return False - if (os.path.isfile(pathname) and os.access(pathname, os.X_OK)) or \ - (os.path.isfile(pathname+'.ksh') and os.access(pathname+'.ksh', os.X_OK)) or \ - (os.path.isfile(pathname+'.sh') and os.access(pathname+'.sh', os.X_OK)): - return True + for ext in '', '.ksh', '.sh': + script_path = pathname + ext + if os.path.isfile(script_path) and os.access(script_path, os.X_OK): + return True return False @@ -731,15 +732,13 @@ def verify_user(user, logger): sudo without being prompted for a password. """ testcmd = [SUDO, '-n', '-u', user, TRUE] - can_sudo = exists = True if user in Cmd.verified_users: return True try: - _ = getpwnam(user) + getpwnam(user) except KeyError: - exists = False logger.info("Warning: user '%s' does not exist.", user) return False @@ -782,7 +781,7 @@ def options_cb(option, opt_str, value, parser): path_options = ['runfile', 'outputdir', 'template', 'testdir'] if option.dest is 'runfile' and '-w' in parser.rargs or \ - option.dest is 'template' and '-c' in parser.rargs: + option.dest is 'template' and '-c' in parser.rargs: fail('-c and -w are mutually exclusive.') if opt_str in parser.rargs: From e169749fc0b87904cb48e8cca0c87501eb46ebac Mon Sep 17 00:00:00 2001 From: Giuseppe Di Natale Date: Wed, 5 Oct 2016 08:41:26 -0700 Subject: [PATCH 3/5] Correct exit code for dbufstat -v and arcstat -v Both scripts were returning an error code of 1 when using the -v argument. -v should exit with an error code of 0. Signed-off-by: Giuseppe Di Natale --- cmd/arcstat/arcstat.py | 2 +- cmd/dbufstat/dbufstat.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/arcstat/arcstat.py b/cmd/arcstat/arcstat.py index 4161207950..b743fd8bc4 100755 --- a/cmd/arcstat/arcstat.py +++ b/cmd/arcstat/arcstat.py @@ -122,7 +122,7 @@ def detailed_usage(): sys.stderr.write("%11s : %s\n" % (key, cols[key][2])) sys.stderr.write("\n") - sys.exit(1) + sys.exit(0) def usage(): diff --git a/cmd/dbufstat/dbufstat.py b/cmd/dbufstat/dbufstat.py index 0bda1524e9..ceb0160cdc 100755 --- a/cmd/dbufstat/dbufstat.py +++ b/cmd/dbufstat/dbufstat.py @@ -143,7 +143,7 @@ def detailed_usage(): sys.stderr.write("%11s : %s\n" % (key, cols[key][2])) sys.stderr.write("\n") - sys.exit(1) + sys.exit(0) def usage(): From 46bb91e19307982c2dc829e0d88b012c5f571b8c Mon Sep 17 00:00:00 2001 From: Giuseppe Di Natale Date: Thu, 6 Oct 2016 10:50:15 -0700 Subject: [PATCH 4/5] Introduce a make recipe for flake8 Add a make recipe to enable developers to easily run flake8 if it is available. This will help enforce good python coding standards. Signed-off-by: Giuseppe Di Natale --- Makefile.am | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index abc98e4ed5..26f684d592 100644 --- a/Makefile.am +++ b/Makefile.am @@ -39,7 +39,7 @@ dist-hook: sed -i 's/Release:[[:print:]]*/Release: $(RELEASE)/' \ $(distdir)/META -checkstyle: cstyle shellcheck +checkstyle: cstyle shellcheck flake8 cstyle: @find ${top_srcdir} -name '*.[hc]' ! -name 'zfs_config.*' \ @@ -62,6 +62,11 @@ cppcheck: cppcheck --quiet --force --error-exitcode=2 ${top_srcdir}; \ fi +flake8: + @if type flake8 > /dev/null 2>&1; then \ + flake8 ${top_srcdir}; \ + fi + ctags: $(RM) tags find $(top_srcdir) -name .git -prune -o -name '*.[hc]' | xargs ctags From 70c7714dca90d01b83a29d15c67e65ff93d034d4 Mon Sep 17 00:00:00 2001 From: Giuseppe Di Natale Date: Tue, 4 Oct 2016 15:13:42 -0700 Subject: [PATCH 5/5] Introduce tests for python scripts Implement tests to ensure that python scripts that are distributed with ZFS continue to at minimum run without errors. This will help prevent accidental breaking of these scripts. Signed-off-by: Giuseppe Di Natale --- tests/runfiles/linux.run | 3 +- tests/zfs-tests/include/default.cfg.in | 3 ++ .../functional/cli_user/misc/Makefile.am | 5 ++- .../cli_user/misc/arc_summary_001_pos.ksh | 40 ++++++++++++++++++ .../cli_user/misc/arcstat_001_pos.ksh | 41 +++++++++++++++++++ .../cli_user/misc/dbufstat_001_pos.ksh | 40 ++++++++++++++++++ zfs-script-config.sh.in | 3 ++ 7 files changed, 133 insertions(+), 2 deletions(-) create mode 100755 tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_001_pos.ksh create mode 100755 tests/zfs-tests/tests/functional/cli_user/misc/arcstat_001_pos.ksh create mode 100755 tests/zfs-tests/tests/functional/cli_user/misc/dbufstat_001_pos.ksh diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run index 92f867ab96..7325228310 100644 --- a/tests/runfiles/linux.run +++ b/tests/runfiles/linux.run @@ -355,7 +355,8 @@ tests = ['zdb_001_neg', 'zfs_001_neg', 'zfs_allow_001_neg', 'zpool_history_001_neg', 'zpool_import_001_neg', 'zpool_import_002_neg', 'zpool_offline_001_neg', 'zpool_online_001_neg', 'zpool_remove_001_neg', 'zpool_replace_001_neg', 'zpool_scrub_001_neg', 'zpool_set_001_neg', - 'zpool_status_001_neg', 'zpool_upgrade_001_neg'] + 'zpool_status_001_neg', 'zpool_upgrade_001_neg', 'arcstat_001_pos', + 'arc_summary_001_pos', 'dbufstat_001_pos'] user = [tests/functional/cli_user/zfs_list] diff --git a/tests/zfs-tests/include/default.cfg.in b/tests/zfs-tests/include/default.cfg.in index a36ab3b1a4..f93bfa98c9 100644 --- a/tests/zfs-tests/include/default.cfg.in +++ b/tests/zfs-tests/include/default.cfg.in @@ -43,6 +43,9 @@ export ZPOOL=${ZPOOL:-${sbindir}/zpool} export ZTEST=${ZTEST:-${sbindir}/ztest} export ZPIOS=${ZPIOS:-${sbindir}/zpios} export RAIDZ_TEST=${RAIDZ_TEST:-${bindir}/raidz_test} +export ARC_SUMMARY=${ARC_SUMMARY:-${bindir}/arc_summary.py} +export ARCSTAT=${ARCSTAT:-${bindir}/arcstat.py} +export DBUFSTAT=${DBUFSTAT:-${bindir}/dbufstat.py} . $STF_SUITE/include/libtest.shlib diff --git a/tests/zfs-tests/tests/functional/cli_user/misc/Makefile.am b/tests/zfs-tests/tests/functional/cli_user/misc/Makefile.am index dad922c6dd..cf7502c27e 100644 --- a/tests/zfs-tests/tests/functional/cli_user/misc/Makefile.am +++ b/tests/zfs-tests/tests/functional/cli_user/misc/Makefile.am @@ -43,4 +43,7 @@ dist_pkgdata_SCRIPTS = \ zpool_scrub_001_neg.ksh \ zpool_set_001_neg.ksh \ zpool_status_001_neg.ksh \ - zpool_upgrade_001_neg.ksh + zpool_upgrade_001_neg.ksh \ + arcstat_001_pos.ksh \ + arc_summary_001_pos.ksh \ + dbufstat_001_pos.ksh diff --git a/tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_001_pos.ksh b/tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_001_pos.ksh new file mode 100755 index 0000000000..e65fbe6b40 --- /dev/null +++ b/tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_001_pos.ksh @@ -0,0 +1,40 @@ +#! /bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2015 by Lawrence Livermore National Security, LLC. +# All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +set -A args "" "-a" "-d" "-p 1" + +log_assert "arc_summary.py generates output and doesn't return an error code" + +typeset -i i=0 +while [[ $i -lt ${#args[*]} ]]; do + log_must eval "$ARC_SUMMARY ${args[i]} > /dev/null" + ((i = i + 1)) +done + +log_pass "arc_summary.py generates output and doesn't return an error code" diff --git a/tests/zfs-tests/tests/functional/cli_user/misc/arcstat_001_pos.ksh b/tests/zfs-tests/tests/functional/cli_user/misc/arcstat_001_pos.ksh new file mode 100755 index 0000000000..edf80b10ff --- /dev/null +++ b/tests/zfs-tests/tests/functional/cli_user/misc/arcstat_001_pos.ksh @@ -0,0 +1,41 @@ +#! /bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2015 by Lawrence Livermore National Security, LLC. +# All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +set -A args "" "-s \",\"" "-x" "-v" \ + "-f time,hit%,dh%,ph%,mh%" + +log_assert "arcstat.py generates output and doesn't return an error code" + +typeset -i i=0 +while [[ $i -lt ${#args[*]} ]]; do + log_must eval "$ARCSTAT ${args[i]} > /dev/null" + ((i = i + 1)) +done +log_pass "arcstat.py generates output and doesn't return an error code" + diff --git a/tests/zfs-tests/tests/functional/cli_user/misc/dbufstat_001_pos.ksh b/tests/zfs-tests/tests/functional/cli_user/misc/dbufstat_001_pos.ksh new file mode 100755 index 0000000000..229ba72cb0 --- /dev/null +++ b/tests/zfs-tests/tests/functional/cli_user/misc/dbufstat_001_pos.ksh @@ -0,0 +1,40 @@ +#! /bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2015 by Lawrence Livermore National Security, LLC. +# All rights reserved. +# + +. $STF_SUITE/include/libtest.shlib + +set -A args "" "-b" "-d" "-r" "-v" "-s \",\"" "-x" + +log_assert "dbufstat.py generates output and doesn't return an error code" + +typeset -i i=0 +while [[ $i -lt ${#args[*]} ]]; do + log_must eval "$DBUFSTAT ${args[i]} > /dev/null" + ((i = i + 1)) +done + +log_pass "dbufstat.py generates output and doesn't return an error code" diff --git a/zfs-script-config.sh.in b/zfs-script-config.sh.in index 594958fa03..d1ba71d764 100644 --- a/zfs-script-config.sh.in +++ b/zfs-script-config.sh.in @@ -29,6 +29,9 @@ export ZPOOL=${CMDDIR}/zpool/zpool export ZTEST=${CMDDIR}/ztest/ztest export ZPIOS=${CMDDIR}/zpios/zpios export RAIDZ_TEST=${CMDDIR}/raidz_test/raidz_test +export ARC_SUMMARY=${CMDDIR}/arc_summary/arc_summary.py +export ARCSTAT=${CMDDIR}/arcstat/arcstat.py +export DBUFSTAT=${CMDDIR}/dbufstat/dbufstat.py export COMMON_SH=${SCRIPTDIR}/common.sh export ZFS_SH=${SCRIPTDIR}/zfs.sh