From patchwork Sat Sep 5 01:32:09 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 7126961 Return-Path: X-Original-To: patchwork-linux-nvdimm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 674859F32B for ; Sat, 5 Sep 2015 01:37:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D044D208AE for ; Sat, 5 Sep 2015 01:37:54 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 23FB4208A2 for ; Sat, 5 Sep 2015 01:37:53 +0000 (UTC) Received: from ml01.vlan14.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 14151182E35; Fri, 4 Sep 2015 18:37:53 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by ml01.01.org (Postfix) with ESMTP id 0FB26182E32 for ; Fri, 4 Sep 2015 18:37:52 -0700 (PDT) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP; 04 Sep 2015 18:37:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,471,1437462000"; d="scan'208";a="555637027" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.137]) by FMSMGA003.fm.intel.com with ESMTP; 04 Sep 2015 18:37:51 -0700 Subject: [PATCH 10/11] ndctl: gate tests by kernel version and report "skip" count From: Dan Williams To: linux-nvdimm@lists.01.org Date: Fri, 04 Sep 2015 21:32:09 -0400 Message-ID: <20150905013209.28464.121.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <20150905012538.28464.18136.stgit@dwillia2-desk3.amr.corp.intel.com> References: <20150905012538.28464.18136.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.17.1-8-g92dd MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, UNPARSEABLE_RELAY, URIBL_BLACK autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Attempts to run the unit tests on kernels that do not have the unit test modules available, or do not support a given test should be skipped. by default. The baseline assumption is a minimal kernel version of 4.2. Signed-off-by: Dan Williams --- Makefile.am | 11 +++++-- builtin-test.c | 40 ++++++++++++++++++++------ configure.ac | 2 + lib/blk_namespaces.c | 2 + lib/pmem_namespaces.c | 2 + lib/test-core.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/test-core.h | 8 +++++ lib/test-dpa-alloc.c | 28 +++++++++++++++--- lib/test-libndctl.c | 47 +++++++++++++++++++++++-------- lib/test-parent-uuid.c | 25 ++++++++++++++-- test-dpa-alloc.h | 3 +- test-libndctl.h | 3 +- test-parent-uuid.h | 3 +- 13 files changed, 207 insertions(+), 40 deletions(-) create mode 100644 lib/test-core.c create mode 100644 lib/test-core.h diff --git a/Makefile.am b/Makefile.am index 99ddfaff8ed9..d3b0c5274d94 100644 --- a/Makefile.am +++ b/Makefile.am @@ -63,7 +63,10 @@ ndctl_SOURCES = ndctl.c \ util/wrapper.c if ENABLE_TEST -ndctl_SOURCES += lib/test-libndctl.c lib/test-dpa-alloc.c lib/test-parent-uuid.c +ndctl_SOURCES += lib/test-libndctl.c \ + lib/test-dpa-alloc.c \ + lib/test-parent-uuid.c \ + lib/test-core.c endif if ENABLE_DESTRUCTIVE @@ -110,7 +113,7 @@ TESTS += lib/test-blk-ns lib/test-pmem-ns check_PROGRAMS += lib/test-blk-ns lib/test-pmem-ns endif -lib_test_libndctl_SOURCES = lib/test-libndctl.c +lib_test_libndctl_SOURCES = lib/test-libndctl.c lib/test-core.c lib_test_libndctl_LDADD = lib/libndctl.la $(UUID_LIBS) $(KMOD_LIBS) lib_test_blk_ns_SOURCES = lib/blk_namespaces.c @@ -119,8 +122,8 @@ lib_test_blk_ns_LDADD = lib/libndctl.la $(KMOD_LIBS) lib_test_pmem_ns_SOURCES = lib/pmem_namespaces.c lib_test_pmem_ns_LDADD = lib/libndctl.la $(KMOD_LIBS) -lib_test_dpa_alloc_SOURCES = lib/test-dpa-alloc.c +lib_test_dpa_alloc_SOURCES = lib/test-dpa-alloc.c lib/test-core.c lib_test_dpa_alloc_LDADD = lib/libndctl.la $(UUID_LIBS) $(KMOD_LIBS) -lib_test_parent_uuid_SOURCES = lib/test-parent-uuid.c +lib_test_parent_uuid_SOURCES = lib/test-parent-uuid.c lib/test-core.c lib_test_parent_uuid_LDADD = lib/libndctl.la $(UUID_LIBS) $(KMOD_LIBS) diff --git a/builtin-test.c b/builtin-test.c index 73a24e0b3c75..edb6e072174e 100644 --- a/builtin-test.c +++ b/builtin-test.c @@ -1,20 +1,36 @@ #include +#include #include +#include #include #include #include #include +static char *result(int rc) +{ + if (rc == 77) + return "SKIP"; + else if (rc) + return "FAIL"; + else + return "PASS"; +} + int cmd_test(int argc, const char **argv) { + struct ndctl_test *test; int loglevel = LOG_DEBUG, i, rc; const char * const u[] = { "ndctl test []", NULL }; + bool force = false; const struct option options[] = { OPT_INTEGER('l', "loglevel", &loglevel, "set the log level (default LOG_DEBUG)"), + OPT_BOOLEAN('f', "force", &force, + "force run all tests regardless of required kernel"), OPT_END(), }; @@ -26,17 +42,23 @@ int cmd_test(int argc, const char **argv) if (argc) usage_with_options(u, options); - rc = test_libndctl(loglevel); - fprintf(stderr, "test-libndctl: %s\n", rc ? "FAIL" : "PASS"); - if (rc) + if (force) + test = ndctl_test_new(UINT_MAX); + else + test = ndctl_test_new(0); + + rc = test_libndctl(loglevel, test); + fprintf(stderr, "test-libndctl: %s\n", result(rc)); + if (rc && rc != 77) return rc; - rc = test_dpa_alloc(loglevel); - fprintf(stderr, "test-dpa-alloc: %s\n", rc ? "FAIL" : "PASS"); - if (rc) + rc = test_dpa_alloc(loglevel, test); + fprintf(stderr, "test-dpa-alloc: %s\n", result(rc)); + if (rc && rc != 77) return rc; - rc = test_parent_uuid(loglevel); - fprintf(stderr, "test-parent-uuid: %s\n", rc ? "FAIL" : "PASS"); - return rc; + rc = test_parent_uuid(loglevel, test); + fprintf(stderr, "test-parent-uuid: %s\n", result(rc)); + + return ndctl_test_result(test, rc); } diff --git a/configure.ac b/configure.ac index 8162b723ecab..4b83e7444770 100644 --- a/configure.ac +++ b/configure.ac @@ -76,7 +76,7 @@ AC_CHECK_HEADER([linux/ndctl.h], [AC_DEFINE([HAVE_NDCTL_H], [1], [Define to 1 if you have .])], []) - +AC_CHECK_HEADERS_ONCE([linux/version.h]) AC_CHECK_FUNCS([ \ __secure_getenv \ diff --git a/lib/blk_namespaces.c b/lib/blk_namespaces.c index 40928579573f..040da41a64e3 100644 --- a/lib/blk_namespaces.c +++ b/lib/blk_namespaces.c @@ -228,7 +228,7 @@ int test_blk_namespaces(int log_level) bus = ndctl_bus_get_by_provider(ctx, provider); if (!bus) { fprintf(stderr, "%s: failed to find NFIT-provider\n", comm); - rc = ENODEV; + rc = 77; goto err_nobus; } else fprintf(stderr, "%s: found provider: %s\n", comm, diff --git a/lib/pmem_namespaces.c b/lib/pmem_namespaces.c index 38d0a00ca537..124900269a8b 100644 --- a/lib/pmem_namespaces.c +++ b/lib/pmem_namespaces.c @@ -188,7 +188,7 @@ int test_pmem_namespaces(int log_level) bus = ndctl_bus_get_by_provider(ctx, provider); if (!bus) { fprintf(stderr, "%s: failed to find NFIT-provider\n", comm); - rc = ENODEV; + rc = 77; goto err; } else fprintf(stderr, "%s: found provider: %s\n", comm, diff --git a/lib/test-core.c b/lib/test-core.c new file mode 100644 index 000000000000..932c2dd246f5 --- /dev/null +++ b/lib/test-core.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include + +#define KVER_STRLEN 20 + +struct ndctl_test { + unsigned int kver; + int attempt; + int skip; +}; + +struct ndctl_test *ndctl_test_new(unsigned int kver) +{ + struct ndctl_test *test = calloc(1, sizeof(*test)); + + if (!test) + return NULL; + + if (!kver) + test->kver = LINUX_VERSION_CODE; + else + test->kver = kver; + + return test; +} + +int ndctl_test_result(struct ndctl_test *test, int rc) +{ + if (ndctl_test_get_skipped(test)) + fprintf(stderr, "attempted: %d skipped: %d\n", + ndctl_test_get_attempted(test), + ndctl_test_get_skipped(test)); + if (rc && rc != 77) + return rc; + if (ndctl_test_get_skipped(test) >= ndctl_test_get_attempted(test)) + return 77; + /* return success if no failures and at least one test not skipped */ + return 0; +} + +static char *kver_str(char *buf, unsigned int kver) +{ + snprintf(buf, KVER_STRLEN, "%d.%d.%d", (kver >> 16) & 0xffff, + (kver >> 8) & 0xff, kver & 0xff); + return buf; +} + +int __ndctl_test_attempt(struct ndctl_test *test, unsigned int kver, + const char *caller, int line) +{ + char requires[KVER_STRLEN], current[KVER_STRLEN]; + + test->attempt++; + if (kver <= test->kver) + return 1; + fprintf(stderr, "%s: skip %s:%d requires: %s current: %s\n", + __func__, caller, line, kver_str(requires, kver), + kver_str(current, test->kver)); + test->skip++; + return 0; +} + +int ndctl_test_get_attempted(struct ndctl_test *test) +{ + return test->attempt; +} + +int ndctl_test_get_skipped(struct ndctl_test *test) +{ + return test->skip; +} diff --git a/lib/test-core.h b/lib/test-core.h new file mode 100644 index 000000000000..7f13bc28441b --- /dev/null +++ b/lib/test-core.h @@ -0,0 +1,8 @@ +struct ndctl_test; +struct ndctl_test *ndctl_test_new(unsigned int kver); +int ndctl_test_result(struct ndctl_test *test, int rc); +int ndctl_test_get_skipped(struct ndctl_test *test); +int ndctl_test_get_attempted(struct ndctl_test *test); +int __ndctl_test_attempt(struct ndctl_test *test, unsigned int kver, + const char *caller, int line); +#define ndctl_test_attempt(t, v) __ndctl_test_attempt(t, v, __func__, __LINE__) diff --git a/lib/test-dpa-alloc.c b/lib/test-dpa-alloc.c index 9a881f301c7f..c5d536df3881 100644 --- a/lib/test-dpa-alloc.c +++ b/lib/test-dpa-alloc.c @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include #include @@ -49,7 +51,7 @@ struct test_dpa_namespace { uuid_t uuid; } namespaces[NUM_NAMESPACES]; -static int do_test(struct ndctl_ctx *ctx) +static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test) { struct ndctl_region *region, *blk_region = NULL; unsigned int available_slots, i; @@ -292,13 +294,16 @@ static int do_test(struct ndctl_ctx *ctx) return 0; } -int test_dpa_alloc(int loglevel) +int test_dpa_alloc(int loglevel, struct ndctl_test *test) { struct ndctl_ctx *ctx; struct kmod_module *mod; struct kmod_ctx *kmod_ctx; int err, result = EXIT_FAILURE; + if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 2, 0))) + return 77; + err = ndctl_new(&ctx); if (err < 0) exit(EXIT_FAILURE); @@ -315,10 +320,14 @@ int test_dpa_alloc(int loglevel) err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); - if (err < 0) + if (err < 0) { + result = 77; + fprintf(stderr, "%s unavailable skipping tests\n", + NFIT_TEST_MODULE); goto err_module; + } - err = do_test(ctx); + err = do_test(ctx, test); if (err == 0) result = EXIT_SUCCESS; kmod_module_remove_module(mod, 0); @@ -332,5 +341,14 @@ int test_dpa_alloc(int loglevel) int __attribute__((weak)) main(int argc, char *argv[]) { - return test_dpa_alloc(LOG_DEBUG); + struct ndctl_test *test = ndctl_test_new(0); + int rc; + + if (!test) { + fprintf(stderr, "failed to initialize test\n"); + return EXIT_FAILURE; + } + + rc = test_dpa_alloc(LOG_DEBUG, test); + return ndctl_test_result(test, rc); } diff --git a/lib/test-libndctl.c b/lib/test-libndctl.c index ec03ad439d55..274c0096ec40 100644 --- a/lib/test-libndctl.c +++ b/lib/test-libndctl.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,7 @@ #include #endif #include +#include #define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */ #define BLKROSET _IO(0x12,93) /* set device read-only (0 = read-write) */ @@ -1362,7 +1364,8 @@ static int check_ars_status(struct ndctl_bus *bus, struct ndctl_dimm *dimm, #define BITS_PER_LONG 32 static int check_commands(struct ndctl_bus *bus, struct ndctl_dimm *dimm, - unsigned long bus_commands, unsigned long dimm_commands) + unsigned long bus_commands, unsigned long dimm_commands, + struct ndctl_test *test) { /* * For now, by coincidence, these are indexed in test execution @@ -1416,6 +1419,9 @@ static int check_commands(struct ndctl_bus *bus, struct ndctl_dimm *dimm, if (rc) goto out; + if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 3, 0))) + goto out; + /* Check Bus commands */ check_cmds = __check_bus_cmds; for (i = 1; i < BITS_PER_LONG; i++) { @@ -1449,7 +1455,8 @@ static int check_commands(struct ndctl_bus *bus, struct ndctl_dimm *dimm, } static int check_dimms(struct ndctl_bus *bus, struct dimm *dimms, int n, - unsigned long bus_commands, unsigned long dimm_commands) + unsigned long bus_commands, unsigned long dimm_commands, + struct ndctl_test *test) { int i, rc; @@ -1495,7 +1502,7 @@ static int check_dimms(struct ndctl_bus *bus, struct dimm *dimms, int n, return -ENXIO; } - rc = check_commands(bus, dimm, bus_commands, dimm_commands); + rc = check_commands(bus, dimm, bus_commands, dimm_commands, test); if (rc) return rc; } @@ -1503,7 +1510,7 @@ static int check_dimms(struct ndctl_bus *bus, struct dimm *dimms, int n, return 0; } -static int do_test0(struct ndctl_ctx *ctx) +static int do_test0(struct ndctl_ctx *ctx, struct ndctl_test *test) { struct ndctl_bus *bus = ndctl_bus_get_by_provider(ctx, NFIT_PROVIDER0); struct ndctl_region *region; @@ -1517,7 +1524,7 @@ static int do_test0(struct ndctl_ctx *ctx) ndctl_region_disable_invalidate(region); rc = check_dimms(bus, dimms0, ARRAY_SIZE(dimms0), bus_commands0, - dimm_commands0); + dimm_commands0, test); if (rc) return rc; @@ -1528,7 +1535,7 @@ static int do_test0(struct ndctl_ctx *ctx) return check_regions(bus, regions0, ARRAY_SIZE(regions0)); } -static int do_test1(struct ndctl_ctx *ctx) +static int do_test1(struct ndctl_ctx *ctx, struct ndctl_test *test) { struct ndctl_bus *bus = ndctl_bus_get_by_provider(ctx, NFIT_PROVIDER1); int rc; @@ -1536,20 +1543,20 @@ static int do_test1(struct ndctl_ctx *ctx) if (!bus) return -ENXIO; - rc = check_dimms(bus, dimms1, ARRAY_SIZE(dimms1), 0, 0); + rc = check_dimms(bus, dimms1, ARRAY_SIZE(dimms1), 0, 0, test); if (rc) return rc; return check_regions(bus, regions1, ARRAY_SIZE(regions1)); } -typedef int (*do_test_fn)(struct ndctl_ctx *ctx); +typedef int (*do_test_fn)(struct ndctl_ctx *ctx, struct ndctl_test *test); static do_test_fn do_test[] = { do_test0, do_test1, }; -int test_libndctl(int loglevel) +int test_libndctl(int loglevel, struct ndctl_test *test) { unsigned int i; struct ndctl_ctx *ctx; @@ -1557,6 +1564,9 @@ int test_libndctl(int loglevel) struct kmod_ctx *kmod_ctx; int err, result = EXIT_FAILURE; + if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 2, 0))) + return 77; + err = ndctl_new(&ctx); if (err < 0) exit(EXIT_FAILURE); @@ -1574,11 +1584,15 @@ int test_libndctl(int loglevel) err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); - if (err < 0) + if (err < 0) { + result = 77; + fprintf(stderr, "%s unavailable skipping tests\n", + NFIT_TEST_MODULE); goto err_module; + } for (i = 0; i < ARRAY_SIZE(do_test); i++) { - err = do_test[i](ctx); + err = do_test[i](ctx, test); if (err < 0) { fprintf(stderr, "ndctl-test%d failed: %d\n", i, err); break; @@ -1598,5 +1612,14 @@ int test_libndctl(int loglevel) int __attribute__((weak)) main(int argc, char *argv[]) { - return test_libndctl(LOG_DEBUG); + struct ndctl_test *test = ndctl_test_new(0); + int rc; + + if (!test) { + fprintf(stderr, "failed to initialize test\n"); + return EXIT_FAILURE; + } + + rc = test_libndctl(LOG_DEBUG, test); + return ndctl_test_result(test, rc); } diff --git a/lib/test-parent-uuid.c b/lib/test-parent-uuid.c index 9681a99364b8..cf48a8c4a58b 100644 --- a/lib/test-parent-uuid.c +++ b/lib/test-parent-uuid.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -129,7 +131,6 @@ static struct ndctl_btt *check_valid_btt(struct ndctl_region *region, return NULL; } - static int do_test(struct ndctl_ctx *ctx) { int rc; @@ -230,13 +231,16 @@ static int do_test(struct ndctl_ctx *ctx) return 0; } -int test_parent_uuid(int loglevel) +int test_parent_uuid(int loglevel, struct ndctl_test *test) { struct ndctl_ctx *ctx; struct kmod_module *mod; struct kmod_ctx *kmod_ctx; int err, result = EXIT_FAILURE; + if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 3, 0))) + return 77; + err = ndctl_new(&ctx); if (err < 0) exit(EXIT_FAILURE); @@ -253,8 +257,12 @@ int test_parent_uuid(int loglevel) err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); - if (err < 0) + if (err < 0) { + result = 77; + fprintf(stderr, "%s unavailable skipping tests\n", + NFIT_TEST_MODULE); goto err_module; + } err = do_test(ctx); if (err == 0) @@ -270,5 +278,14 @@ int test_parent_uuid(int loglevel) int __attribute__((weak)) main(int argc, char *argv[]) { - return test_parent_uuid(LOG_DEBUG); + struct ndctl_test *test = ndctl_test_new(0); + int rc; + + if (!test) { + fprintf(stderr, "failed to initialize test\n"); + return EXIT_FAILURE; + } + + rc = test_parent_uuid(LOG_DEBUG, test); + return ndctl_test_result(test, rc); } diff --git a/test-dpa-alloc.h b/test-dpa-alloc.h index 966db9108e95..f1145f4d278d 100644 --- a/test-dpa-alloc.h +++ b/test-dpa-alloc.h @@ -1,4 +1,5 @@ #ifndef __TEST_DPA_ALLOC__ #define __TEST_DPA_ALLOC__ -int test_dpa_alloc(int loglevel); +struct ndctl_test; +int test_dpa_alloc(int loglevel, struct ndctl_test *test); #endif diff --git a/test-libndctl.h b/test-libndctl.h index 53c3272a4068..20c5db816a29 100644 --- a/test-libndctl.h +++ b/test-libndctl.h @@ -1,4 +1,5 @@ #ifndef __TEST_LIBNDCTL__ #define __TEST_LIBNDCTL__ -int test_libndctl(int loglevel); +struct ndctl_test; +int test_libndctl(int loglevel, struct ndctl_test *test); #endif diff --git a/test-parent-uuid.h b/test-parent-uuid.h index 57a5ff75071b..585f1825ee27 100644 --- a/test-parent-uuid.h +++ b/test-parent-uuid.h @@ -1,4 +1,5 @@ #ifndef __TEST_PARENT_UUID__ #define __TEST_PARENT_UUID__ -int test_parent_uuid(int loglevel); +struct ndctl_test; +int test_parent_uuid(int loglevel, struct ndctl_test *test); #endif