From patchwork Wed Dec 19 00:02:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 10736653 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD78517E1 for ; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BA21C2B0FD for ; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AD3352B105; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3AC4D2B0FD for ; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727159AbeLSADJ (ORCPT ); Tue, 18 Dec 2018 19:03:09 -0500 Received: from mga01.intel.com ([192.55.52.88]:8278 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726818AbeLSADJ (ORCPT ); Tue, 18 Dec 2018 19:03:09 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Dec 2018 16:03:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,370,1539673200"; d="scan'208";a="284784589" Received: from ldmartin-desk.jf.intel.com ([10.7.200.65]) by orsmga005.jf.intel.com with ESMTP; 18 Dec 2018 16:03:05 -0800 From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Yauheni Kaliuta Subject: [PATCH 1/3] testsuite: split out function to compare outputs exactly Date: Tue, 18 Dec 2018 16:02:27 -0800 Message-Id: <20181219000229.10793-1-lucas.demarchi@intel.com> X-Mailer: git-send-email 2.20.0 MIME-Version: 1.0 Sender: owner-linux-modules@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Move functionality to compare the exact output to a separate function and allocate one buffer per output/match pair. This will allow us to extend this to allow other types of comparisons. --- testsuite/testsuite.c | 124 ++++++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index 8512b56..550c711 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -290,13 +290,64 @@ static int check_activity(int fd, bool activity, const char *path, return -1; } -static inline bool test_run_parent_check_outputs(const struct test *t, - int fdout, int fderr, int fdmonitor, pid_t child) +#define BUFSZ 4096 +struct buffer { + char buf[BUFSZ]; +}; + +/* read fd and fd_match, checking they match exactly */ +static bool cmpbuf_exact(const struct test *t, const char *prefix, + int fd, int fd_match, struct buffer *buf, + struct buffer *buf_match) +{ + int r, rmatch, done = 0; + + r = read(fd, buf, sizeof(buf->buf) - 1); + if (r <= 0) + /* try again later */ + return true; + + /* read as much data from fd_match as we read from fd */ + for (;;) { + rmatch = read(fd_match, buf_match->buf + done, r - done); + if (rmatch == 0) + break; + + if (rmatch < 0) { + if (errno == EINTR) + continue; + ERR("could not read match fd %d\n", fd_match); + return false; + } + + done += rmatch; + } + + buf->buf[r] = '\0'; + buf_match->buf[r] = '\0'; + + if (t->print_outputs) + printf("%s: %s\n", prefix, buf->buf); + + if (!streq(buf->buf, buf_match->buf)) { + ERR("Outputs do not match on %s:\n", prefix); + ERR("correct:\n%s\n", buf_match->buf); + ERR("wrong:\n%s\n", buf->buf); + return false; + } + + return true; +} + +static bool test_run_parent_check_outputs(const struct test *t, + int fdout, int fderr, int fdmonitor, + pid_t child) { struct epoll_event ep_outpipe, ep_errpipe, ep_monitor; int err, fd_ep, fd_matchout = -1, fd_matcherr = -1; bool fd_activityout = false, fd_activityerr = false; unsigned long long end_usec, start_usec; + _cleanup_free_ struct buffer *buf_out = NULL, *buf_err = NULL; fd_ep = epoll_create1(EPOLL_CLOEXEC); if (fd_ep < 0) { @@ -320,6 +371,7 @@ static inline bool test_run_parent_check_outputs(const struct test *t, ERR("could not add fd to epoll: %m\n"); goto out; } + buf_out = calloc(2, sizeof(*buf_out)); } else fdout = -1; @@ -340,6 +392,7 @@ static inline bool test_run_parent_check_outputs(const struct test *t, ERR("could not add fd to epoll: %m\n"); goto out; } + buf_err = calloc(2, sizeof(*buf_err)); } else fderr = -1; @@ -374,76 +427,39 @@ static inline bool test_run_parent_check_outputs(const struct test *t, } for (i = 0; i < fdcount; i++) { - int *fd = ev[i].data.ptr; + int fd = *(int *)ev[i].data.ptr; if (ev[i].events & EPOLLIN) { - ssize_t r, done = 0; - char buf[4096]; - char bufmatch[4096]; int fd_match; + struct buffer *buf, *buf_match; + const char *prefix; - /* - * compare the output from child with the one - * saved as correct - */ - - r = read(*fd, buf, sizeof(buf) - 1); - if (r <= 0) - continue; - - if (*fd == fdout) { + if (fd == fdout) { fd_match = fd_matchout; + buf = buf_out; fd_activityout = true; - } else if (*fd == fderr) { + prefix = "STDOUT"; + } else if (fd == fderr) { fd_match = fd_matcherr; + buf = buf_err; fd_activityerr = true; + prefix = "STDERR"; } else { ERR("Unexpected activity on monitor pipe\n"); err = -EINVAL; goto out; } - for (;;) { - int rmatch = read(fd_match, - bufmatch + done, r - done); - if (rmatch == 0) - break; - - if (rmatch < 0) { - if (errno == EINTR) - continue; - err = -errno; - ERR("could not read match fd %d\n", - fd_match); - goto out; - } - - done += rmatch; - } + buf_match = buf + 1; - buf[r] = '\0'; - bufmatch[r] = '\0'; - - if (t->print_outputs) - printf("%s: %s\n", - fd_match == fd_matchout ? "STDOUT:" : "STDERR:", - buf); - - if (!streq(buf, bufmatch)) { - ERR("Outputs do not match on %s:\n", - fd_match == fd_matchout ? "STDOUT" : "STDERR"); - ERR("correct:\n%s\n", bufmatch); - ERR("wrong:\n%s\n", buf); - err = -1; + if (!cmpbuf_exact(t, prefix, fd, fd_match, + buf, buf_match)) goto out; - } } else if (ev[i].events & EPOLLHUP) { - if (epoll_ctl(fd_ep, EPOLL_CTL_DEL, - *fd, NULL) < 0) { - ERR("could not remove fd %d from epoll: %m\n", - *fd); + if (epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd, NULL) < 0) { + ERR("could not remove fd %d from epoll: %m\n", fd); } - *fd = -1; + *(int *)ev[i].data.ptr = -1; } } } From patchwork Wed Dec 19 00:02:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 10736649 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 64BFF924 for ; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F61D2B0FB for ; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 422F72B104; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE5702B0FB for ; Wed, 19 Dec 2018 00:03:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726956AbeLSADJ (ORCPT ); Tue, 18 Dec 2018 19:03:09 -0500 Received: from mga01.intel.com ([192.55.52.88]:8278 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726614AbeLSADJ (ORCPT ); Tue, 18 Dec 2018 19:03:09 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Dec 2018 16:03:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,370,1539673200"; d="scan'208";a="284784590" Received: from ldmartin-desk.jf.intel.com ([10.7.200.65]) by orsmga005.jf.intel.com with ESMTP; 18 Dec 2018 16:03:05 -0800 From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Yauheni Kaliuta Subject: [PATCH 2/3] testsuite: add support for testing output against regex Date: Tue, 18 Dec 2018 16:02:28 -0800 Message-Id: <20181219000229.10793-2-lucas.demarchi@intel.com> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181219000229.10793-1-lucas.demarchi@intel.com> References: <20181219000229.10793-1-lucas.demarchi@intel.com> MIME-Version: 1.0 Sender: owner-linux-modules@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Allow to test outputs when they don't match exactly, but should follow some regex patterns. This can be used when the info we are printing is randomized or depends on kernel configuration. --- testsuite/testsuite.c | 104 +++++++++++++++++++++++++++++++++++++++++- testsuite/testsuite.h | 6 +++ 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index 550c711..db36324 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -293,8 +294,98 @@ static int check_activity(int fd, bool activity, const char *path, #define BUFSZ 4096 struct buffer { char buf[BUFSZ]; + unsigned int head; }; + +static bool cmpbuf_regex_one(const char *pattern, const char *s) +{ + _cleanup_(regfree) regex_t re = { }; + + return !regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) && + !regexec(&re, s, 0, NULL, 0); +} + +/* + * read fd and fd_match, checking the first matches the regex of the second, + * line by line + */ +static bool cmpbuf_regex(const struct test *t, const char *prefix, + int fd, int fd_match, struct buffer *buf, + struct buffer *buf_match) +{ + char *p, *p_match; + int done = 0, done_match = 0, r; + + r = read(fd, buf->buf + buf->head, sizeof(buf->buf) - buf->head - 1); + if (r <= 0) + return true; + + buf->head += r; + + /* + * Process as many lines as read from fd and that fits in the buffer - + * it's assumed that we we get N lines from fd, we should be able to + * get the same amount from fd_match + */ + for (;;) { + p = memchr(buf->buf + done, '\n', buf->head - done); + if (!p) + break; + *p = 0; + + p_match = memchr(buf_match->buf + done_match, '\n', + buf_match->head - done_match); + if (!p_match) { + /* pump more data from file */ + r = read(fd_match, buf_match->buf + buf_match->head, + sizeof(buf_match->buf) - buf_match->head - 1); + if (r <= 0) { + ERR("could not read match fd %d\n", fd_match); + return false; + } + buf_match->head += r; + p_match = memchr(buf_match->buf + done_match, '\n', + buf_match->head - done_match); + if (!p_match) { + ERR("could not find match line from fd %d\n", fd_match); + return false; + } + } + *p_match = 0; + + if (!cmpbuf_regex_one(buf_match->buf + done_match, buf->buf + done)) { + ERR("Output does not match pattern on %s:\n", prefix); + ERR("pattern: %s\n", buf_match->buf + done_match); + ERR("output : %s\n", buf->buf + done); + return false; + } + + done = p - buf->buf + 1; + done_match = p_match - buf_match->buf + 1; + } + + /* + * Prepare for the next call: anything we processed we remove from the + * buffer by memmoving the remaining bytes up to the beginning + */ + + if (done) { + if (buf->head - done) + memmove(buf->buf, buf->buf + done, buf->head - done); + buf->head -= done; + } + + if (done_match) { + if (buf_match->head - done_match) + memmove(buf_match->buf, buf_match->buf + done_match, + buf_match->head - done_match); + buf_match->head -= done_match; + } + + return true; +} + /* read fd and fd_match, checking they match exactly */ static bool cmpbuf_exact(const struct test *t, const char *prefix, int fd, int fd_match, struct buffer *buf, @@ -428,6 +519,7 @@ static bool test_run_parent_check_outputs(const struct test *t, for (i = 0; i < fdcount; i++) { int fd = *(int *)ev[i].data.ptr; + bool ret; if (ev[i].events & EPOLLIN) { int fd_match; @@ -452,9 +544,17 @@ static bool test_run_parent_check_outputs(const struct test *t, buf_match = buf + 1; - if (!cmpbuf_exact(t, prefix, fd, fd_match, - buf, buf_match)) + if (t->output.regex) + ret = cmpbuf_regex(t, prefix, fd, fd_match, + buf, buf_match); + else + ret = cmpbuf_exact(t, prefix, fd, fd_match, + buf, buf_match); + + if (!ret) { + err = -1; goto out; + } } else if (ev[i].events & EPOLLHUP) { if (epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd, NULL) < 0) { ERR("could not remove fd %d from epoll: %m\n", fd); diff --git a/testsuite/testsuite.h b/testsuite/testsuite.h index 2b31483..7ed96bf 100644 --- a/testsuite/testsuite.h +++ b/testsuite/testsuite.h @@ -88,6 +88,12 @@ struct test { /* File with correct stderr */ const char *err; + /* + * whether to treat the correct files as regex to the real + * output + */ + bool regex; + /* * Vector with pair of files * key = correct file From patchwork Wed Dec 19 00:02:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 10736651 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BB6F213B5 for ; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A8B7A2B0FB for ; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9D0102B104; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5B6D32B105 for ; Wed, 19 Dec 2018 00:03:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726818AbeLSADJ (ORCPT ); Tue, 18 Dec 2018 19:03:09 -0500 Received: from mga01.intel.com ([192.55.52.88]:8278 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726614AbeLSADJ (ORCPT ); Tue, 18 Dec 2018 19:03:09 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Dec 2018 16:03:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,370,1539673200"; d="scan'208";a="284784593" Received: from ldmartin-desk.jf.intel.com ([10.7.200.65]) by orsmga005.jf.intel.com with ESMTP; 18 Dec 2018 16:03:05 -0800 From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Yauheni Kaliuta Subject: [PATCH 3/3] testsuite: move --show-exports test to use regex Date: Tue, 18 Dec 2018 16:02:29 -0800 Message-Id: <20181219000229.10793-3-lucas.demarchi@intel.com> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181219000229.10793-1-lucas.demarchi@intel.com> References: <20181219000229.10793-1-lucas.demarchi@intel.com> MIME-Version: 1.0 Sender: owner-linux-modules@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP This allows it to pass if the kernel is configured with CONFIG_MODVERSIONS. --- .../rootfs-pristine/test-modprobe/show-exports/correct.txt | 2 +- testsuite/test-modprobe.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/testsuite/rootfs-pristine/test-modprobe/show-exports/correct.txt b/testsuite/rootfs-pristine/test-modprobe/show-exports/correct.txt index bc2d045..0d659ef 100644 --- a/testsuite/rootfs-pristine/test-modprobe/show-exports/correct.txt +++ b/testsuite/rootfs-pristine/test-modprobe/show-exports/correct.txt @@ -1 +1 @@ -0x00000000 printA +0x[0-9a-fA-F]+ printA diff --git a/testsuite/test-modprobe.c b/testsuite/test-modprobe.c index 52a6621..1cace82 100644 --- a/testsuite/test-modprobe.c +++ b/testsuite/test-modprobe.c @@ -114,6 +114,7 @@ DEFINE_TEST(modprobe_show_exports, }, .output = { .out = TESTSUITE_ROOTFS "test-modprobe/show-exports/correct.txt", + .regex = true, });