From patchwork Thu Apr 5 14:50:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cyril Hrubis X-Patchwork-Id: 895417 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=suse.cz Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40H5Q72WV5z9s0y for ; Fri, 6 Apr 2018 00:51:59 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id C76E13E77BD for ; Thu, 5 Apr 2018 16:51:56 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-7.smtp.seeweb.it (in-7.smtp.seeweb.it [IPv6:2001:4b78:1:20::7]) by picard.linux.it (Postfix) with ESMTP id A90693E605F for ; Thu, 5 Apr 2018 16:51:52 +0200 (CEST) Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by in-7.smtp.seeweb.it (Postfix) with ESMTPS id 411B5200975 for ; Thu, 5 Apr 2018 16:51:51 +0200 (CEST) Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id E41A2AF1F for ; Thu, 5 Apr 2018 14:51:50 +0000 (UTC) From: Cyril Hrubis To: ltp@lists.linux.it Date: Thu, 5 Apr 2018 16:50:11 +0200 Message-Id: <20180405145015.7633-3-chrubis@suse.cz> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180405145015.7633-1-chrubis@suse.cz> References: <20180405145015.7633-1-chrubis@suse.cz> X-Virus-Scanned: clamav-milter 0.99.2 at in-7.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.2 required=7.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, SPF_PASS,T_RP_MATCHES_RCVD autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-7.smtp.seeweb.it Subject: [LTP] [RFC PATCH 2/6] syscalls/pipe11: Rewrite to new library. X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" + Check that the buffer read in the child is correct as well + We got rid of sleep(5) as a side effect Signed-off-by: Cyril Hrubis --- testcases/kernel/syscalls/pipe/pipe11.c | 289 +++++++++----------------------- 1 file changed, 77 insertions(+), 212 deletions(-) diff --git a/testcases/kernel/syscalls/pipe/pipe11.c b/testcases/kernel/syscalls/pipe/pipe11.c index e3b274128..6964f164d 100644 --- a/testcases/kernel/syscalls/pipe/pipe11.c +++ b/testcases/kernel/syscalls/pipe/pipe11.c @@ -1,246 +1,111 @@ /* + * Copyright (c) International Business Machines Corp., 2001 + * 07/2001 Ported by Wayne Boyer + * Copyright (c) 2018 Cyril Hrubis * - * Copyright (c) International Business Machines Corp., 2001 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* - * NAME - * pipe11.c - * - * DESCRIPTION - * Check if many children can read what is written to a pipe by the - * parent. + * Check if many children can read what is written to a pipe by the parent. * * ALGORITHM - * 1. Open a pipe and write to it - * 2. Fork a large number of children - * 3. Have the children read the pipe and check how many characters - * each got - * - * USAGE: - * pipe11 [-c n] [-f] [-i n] [-I x] [-P x] [-t] - * where, -c n : Run n copies concurrently. - * -f : Turn off functionality Testing. - * -i n : Execute test n times. - * -I x : Execute test for x seconds. - * -P x : Pause for x seconds between iterations. - * -t : Turn on syscall timing. - * - * HISTORY - * 07/2001 Ported by Wayne Boyer - * - * RESTRICTIONS - * None + * For a different nchilds number: + * 1. Open a pipe and write nchilds * (PIPE_BUF/nchilds) bytes into it + * 2. Fork nchilds children + * 3. Each child reads PIPE_BUF/nchilds characters and checks that the + * bytes read are correct */ -#include -#include -#include -#include -#include -#include "test.h" - -char *TCID = "pipe11"; -int TST_TOTAL = 1; - -void do_child(void); -void do_child_uclinux(void); -void setup(void); -void cleanup(void); - -#define NUMCHILD 50 -#define NCPERCHILD 50 -char rawchars[] = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; -int kidid; -int numchild; /* no of children to fork */ -int ncperchild; /* no of chars child should read */ -int szcharbuf; /* size of char buf */ -int pipewrcnt; /* chars written to pipe */ -char *wrbuf, *rdbuf; -int fd[2]; /* fds for pipe read/write */ - -ssize_t do_read(int fd, void *buf, size_t count) -{ - ssize_t n; - - do { - n = read(fd, buf, count); - } while (n < 0 && errno == EINTR); +#include +#include "tst_test.h" - return n; -} +static int fd[2]; +static unsigned char buf[PIPE_BUF]; +static size_t read_per_child; -int main(int ac, char **av) +void do_child(void) { - int lc; - - int i; - int fork_ret, status; - int written; /* no of chars read and written */ - - tst_parse_opts(ac, av, NULL, NULL); -#ifdef UCLINUX - maybe_run_child(&do_child_uclinux, "ddddd", &fd[0], &fd[1], &kidid, - &ncperchild, &szcharbuf); -#endif - - setup(); - - for (lc = 0; TEST_LOOPING(lc); lc++) { - - /* reset tst_count in case we are looping */ - tst_count = 0; + size_t nread; + unsigned char rbuf[read_per_child]; + unsigned int i; - TEST(pipe(fd)); + SAFE_CLOSE(fd[1]); - if (TEST_RETURN != 0) { - tst_resm(TFAIL, "pipe creation failed"); - continue; - } - - written = write(fd[1], wrbuf, szcharbuf); - if (written != szcharbuf) { - tst_brkm(TBROK, cleanup, "write to pipe failed"); - } - -refork: - ++kidid; - fork_ret = FORK_OR_VFORK(); - - if (fork_ret < 0) { - tst_brkm(TBROK, cleanup, "fork() failed"); - } - - if ((fork_ret != 0) && (fork_ret != -1) && (kidid < numchild)) { - goto refork; - } + nread = SAFE_READ(0, fd[0], rbuf, sizeof(rbuf)); - if (fork_ret == 0) { /* child */ -#ifdef UCLINUX - if (self_exec(av[0], "ddddd", fd[0], fd[1], kidid, - ncperchild, szcharbuf) < 0) { - tst_brkm(TBROK, cleanup, "self_exec failed"); - } -#else - do_child(); -#endif - } + if (nread != read_per_child) { + tst_res(TFAIL, "Invalid read size child %i size %zu", + getpid(), nread); + return; + } - /* parent */ - sleep(5); - tst_resm(TINFO, "There are %d children to wait for", kidid); - for (i = 1; i <= kidid; ++i) { - wait(&status); - if (status == 0) { - tst_resm(TPASS, "child %d exited successfully", - i); - } else { - tst_resm(TFAIL, "child %d exited with bad " - "status", i); - } + for (i = 0; i < read_per_child; i++) { + if (rbuf[i] != (i % 256)) { + tst_res(TFAIL, + "Invalid byte read child %i byte %i have %i expected %i", + getpid(), i, rbuf[i], i % 256); + return; } } - cleanup(); - - tst_exit(); -} - -/* - * do_child() - */ -void do_child(void) -{ - int nread; - if (close(fd[1])) { - tst_resm(TINFO, "child %d " "could not close pipe", kidid); - exit(0); - } - nread = do_read(fd[0], rdbuf, ncperchild); - if (nread == ncperchild) { - tst_resm(TINFO, "child %d " "got %d chars", kidid, nread); - exit(0); - } else { - tst_resm(TFAIL, "child %d did not receive expected no of " - "characters, got %d characters", kidid, nread); - exit(1); - } + tst_res(TPASS, "Child %i read pipe buffer correctly", getpid()); } -/* - * do_child_uclinux() - as above, but mallocs rdbuf first - */ -void do_child_uclinux(void) -{ - if ((rdbuf = malloc(szcharbuf)) == NULL) { - tst_brkm(TBROK, cleanup, "malloc of rdbuf failed"); - } - - do_child(); -} +static unsigned int childs[] = { + 1, + 2, + 3, + 4, + 10, + 50 +}; -/* - * setup() - performs all ONE TIME setup for this test. - */ -void setup(void) +static void run(unsigned int tcase) { - int i; - unsigned int j; + pid_t pid; + unsigned int nchilds = childs[tcase]; + read_per_child = PIPE_BUF/nchilds; + unsigned int i, j; - tst_sig(FORK, DEF_HANDLER, cleanup); + tst_res(TINFO, "Reading %zu per each of %u children", + read_per_child, nchilds); - TEST_PAUSE; - - numchild = NUMCHILD; - ncperchild = NCPERCHILD; + for (i = 0; i < nchilds; i++) { + for (j = 0; j < read_per_child; j++) { + buf[i * read_per_child + j] = j % 256; + } + } - kidid = 0; + SAFE_PIPE(fd); - /* allocate read and write buffers */ - szcharbuf = numchild * ncperchild; + SAFE_WRITE(1, fd[1], buf, read_per_child * nchilds); - /* make sure pipe write doesn't block */ - if (szcharbuf == PIPE_BUF) { - /* adjust number of characters per child */ - ncperchild = szcharbuf / numchild; - } + for (i = 0; i < nchilds; i++) { + pid = SAFE_FORK(); - if ((wrbuf = malloc(szcharbuf)) == NULL) { - tst_brkm(TBROK, cleanup, "malloc failed"); - } - - if ((rdbuf = malloc(szcharbuf)) == NULL) { - tst_brkm(TBROK, cleanup, "malloc of rdbuf failed"); + if (!pid) { + do_child(); + exit(0); + } } - /* initialize wrbuf */ - j = 0; - for (i = 0; i < szcharbuf;) { - wrbuf[i++] = rawchars[j++]; - if (j >= sizeof(rawchars)) - j = 0; - } + tst_reap_children(); } -/* - * cleanup() - performs all ONE TIME cleanup for this test at - * completion or premature exit. - */ -void cleanup(void) -{ - -} +static struct tst_test test = { + .forks_child = 1, + .test = run, + .tcnt = ARRAY_SIZE(childs), +};