Message ID | 20221024024009.3553633-2-liwang@redhat.com |
---|---|
State | Accepted |
Headers | show |
Series | [v2,1/2] setitimer03: convert to new API | expand |
Hello, Li Wang <liwang@redhat.com> writes: > > -#include "test.h" > - > #include <errno.h> > #include <sys/time.h> > +#include <stdlib.h> > +#include "tst_test.h" > +#include "lapi/syscalls.h" > + > +#define USEC1 10000 > +#define USEC2 20000 > + > +static struct itimerval *value, *ovalue; > + > +static struct tcase { > + int which; > + char *des; > + int signo; > +} tcases[] = { > + {ITIMER_REAL, "ITIMER_REAL", SIGALRM}, > + {ITIMER_VIRTUAL, "ITIMER_VIRTUAL", SIGVTALRM}, > + {ITIMER_PROF, "ITIMER_PROF", SIGPROF}, > +}; > + > +static int sys_setitimer(int which, void *new_value, void *old_value) > +{ > + return tst_syscall(__NR_setitimer, which, new_value, old_value); > +} > + > +static void set_setitimer_value(int usec, int o_usec) > +{ > + value->it_value.tv_sec = 0; > + value->it_value.tv_usec = usec; > + value->it_interval.tv_sec = 0; > + value->it_interval.tv_usec = 0; > + > + ovalue->it_value.tv_sec = o_usec; > + ovalue->it_value.tv_usec = o_usec; > + ovalue->it_interval.tv_sec = 0; > + ovalue->it_interval.tv_usec = 0; > +} > > -void cleanup(void); > -void setup(void); > +static void verify_setitimer(unsigned int i) > +{ > + pid_t pid; > + int status; > + struct tcase *tc = &tcases[i]; > > -char *TCID = "setitimer01"; > -int TST_TOTAL = 1; > + pid = SAFE_FORK(); > > -#define SEC0 0 > -#define SEC1 20 > -#define SEC2 40 > + if (pid == 0) { > + tst_res(TINFO, "tc->which = %s", tc->des); > > -int main(int ac, char **av) > -{ > - int lc; > - struct itimerval *value, *ovalue; > - > - tst_parse_opts(ac, av, NULL, NULL); > - > - setup(); /* global setup */ > - > - /* The following loop checks looping state if -i option given */ > - > - for (lc = 0; TEST_LOOPING(lc); lc++) { > - /* reset tst_count in case we are looping */ > - tst_count = 0; > - > - /* allocate some space for the timer structures */ > - > - if ((value = malloc((size_t)sizeof(struct itimerval))) == > - NULL) { > - tst_brkm(TBROK, cleanup, "value malloc failed"); > - } > - > - if ((ovalue = malloc((size_t)sizeof(struct itimerval))) == > - NULL) { > - tst_brkm(TBROK, cleanup, "ovalue malloc failed"); > - } > - > - /* set up some reasonable values */ > - > - value->it_value.tv_sec = SEC1; > - value->it_value.tv_usec = SEC0; > - value->it_interval.tv_sec = 0; > - value->it_interval.tv_usec = 0; > - /* > - * issue the system call with the TEST() macro > - * ITIMER_REAL = 0, ITIMER_VIRTUAL = 1 and ITIMER_PROF = 2 > - */ > - > - TEST(setitimer(ITIMER_REAL, value, ovalue)); > - > - if (TEST_RETURN != 0) { > - tst_resm(TFAIL, "call failed - errno = %d - %s", > - TEST_ERRNO, strerror(TEST_ERRNO)); > - continue; > - } > - > - /* > - * call setitimer again with new values. > - * the old values should be stored in ovalue > - */ > - value->it_value.tv_sec = SEC2; > - value->it_value.tv_usec = SEC0; > - > - if ((setitimer(ITIMER_REAL, value, ovalue)) == -1) { > - tst_brkm(TBROK, cleanup, "second setitimer " > - "call failed"); > - } > - > - if (ovalue->it_value.tv_sec <= SEC1) { > - tst_resm(TPASS, "functionality is correct"); > - } else { > - tst_brkm(TFAIL, cleanup, "old timer value is " > - "not equal to expected value"); > - } > - } > + tst_no_corefile(0); > > - cleanup(); > - tst_exit(); > -} > + set_setitimer_value(USEC1, 0); > + TST_EXP_PASS(sys_setitimer(tc->which, value, NULL)); > > -/* > - * setup() - performs all the ONE TIME setup for this test. > - */ > -void setup(void) > -{ > + set_setitimer_value(USEC2, USEC2); > + TST_EXP_PASS(sys_setitimer(tc->which, value, ovalue)); > > - tst_sig(NOFORK, DEF_HANDLER, cleanup); > + if (ovalue->it_value.tv_sec != 0 || ovalue->it_value.tv_usec >= USEC2) > + tst_brk(TFAIL, "old timer value is not within > the expected range"); Maybe we could split testing the return value and ovalue from testing the signal is delivered? When testing the return value and ovalue; a very long timeout can be used (which is never hit). When testing the signal a very short one can be used. This way, the test is not racing with the signal and the loop below won't be executed much. In any case LGTM Reviewed-by: Richard Palethorpe <rpalethorpe@suse.com> > > - TEST_PAUSE; > -} > + for (;;) > + ; > + } > > -/* > - * cleanup() - performs all the ONE TIME cleanup for this test at completion > - * or premature exit. > - */ > -void cleanup(void) > -{ > + SAFE_WAITPID(pid, &status, 0); > > + if (WIFSIGNALED(status) && WTERMSIG(status) == tc->signo) > + tst_res(TPASS, "Child received signal: %s", tst_strsig(tc->signo)); > + else > + tst_res(TFAIL, "Child: %s", tst_strstatus(status)); > } > + > +static struct tst_test test = { > + .tcnt = ARRAY_SIZE(tcases), > + .forks_child = 1, > + .test = verify_setitimer, > + .bufs = (struct tst_buffers[]) { > + {&value, .size = sizeof(struct itimerval)}, > + {&ovalue, .size = sizeof(struct itimerval)}, > + {} > + } > +}; > -- > 2.35.3
Richard Palethorpe <rpalethorpe@suse.de> wrote: > -/* > > - * setup() - performs all the ONE TIME setup for this test. > > - */ > > -void setup(void) > > -{ > > + set_setitimer_value(USEC2, USEC2); > > + TST_EXP_PASS(sys_setitimer(tc->which, value, ovalue)); > > > > - tst_sig(NOFORK, DEF_HANDLER, cleanup); > > + if (ovalue->it_value.tv_sec != 0 || > ovalue->it_value.tv_usec >= USEC2) > > + tst_brk(TFAIL, "old timer value is not within > > the expected range"); > > Maybe we could split testing the return value and ovalue from testing > the signal is delivered? > > When testing the return value and ovalue; a very long timeout can be > used (which is never hit). When testing the signal a very short one can > be used. > > This way, the test is not racing with the signal and the loop below > won't be executed much. > Very good point. Also, I plan to add the 'it_interval' check to verify the periodic timer, which will make the functionality test more complete. This will be achieved in a separate patch. > > In any case LGTM > > Reviewed-by: Richard Palethorpe <rpalethorpe@suse.com> > Thanks for the review.
diff --git a/testcases/kernel/syscalls/setitimer/setitimer01.c b/testcases/kernel/syscalls/setitimer/setitimer01.c index 6874b94ad..f04cb5a69 100644 --- a/testcases/kernel/syscalls/setitimer/setitimer01.c +++ b/testcases/kernel/syscalls/setitimer/setitimer01.c @@ -1,157 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* + * Copyright (c) International Business Machines Corp., 2001 + * 03/2001 - Written by Wayne Boyer * - * 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 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 */ -/* - * NAME - * setitimer01.c - * - * DESCRIPTION - * setitimer01 - check that a resonable setitimer() call succeeds. - * - * ALGORITHM - * loop if that option was specified - * allocate needed space and set up needed values - * issue the system call - * check the errno value - * issue a PASS message if we get zero - * otherwise, the tests fails - * issue a FAIL message - * break any remaining tests - * call cleanup - * - * USAGE: <for command-line> - * setitimer01 [-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. +/*\ + * [Description] * - * HISTORY - * 03/2001 - Written by Wayne Boyer - * - * RESTRICTIONS - * none + * Check that a setitimer() call pass with timer seting. + * Check if signal is generated correctly when timer expiration. */ -#include "test.h" - #include <errno.h> #include <sys/time.h> +#include <stdlib.h> +#include "tst_test.h" +#include "lapi/syscalls.h" + +#define USEC1 10000 +#define USEC2 20000 + +static struct itimerval *value, *ovalue; + +static struct tcase { + int which; + char *des; + int signo; +} tcases[] = { + {ITIMER_REAL, "ITIMER_REAL", SIGALRM}, + {ITIMER_VIRTUAL, "ITIMER_VIRTUAL", SIGVTALRM}, + {ITIMER_PROF, "ITIMER_PROF", SIGPROF}, +}; + +static int sys_setitimer(int which, void *new_value, void *old_value) +{ + return tst_syscall(__NR_setitimer, which, new_value, old_value); +} + +static void set_setitimer_value(int usec, int o_usec) +{ + value->it_value.tv_sec = 0; + value->it_value.tv_usec = usec; + value->it_interval.tv_sec = 0; + value->it_interval.tv_usec = 0; + + ovalue->it_value.tv_sec = o_usec; + ovalue->it_value.tv_usec = o_usec; + ovalue->it_interval.tv_sec = 0; + ovalue->it_interval.tv_usec = 0; +} -void cleanup(void); -void setup(void); +static void verify_setitimer(unsigned int i) +{ + pid_t pid; + int status; + struct tcase *tc = &tcases[i]; -char *TCID = "setitimer01"; -int TST_TOTAL = 1; + pid = SAFE_FORK(); -#define SEC0 0 -#define SEC1 20 -#define SEC2 40 + if (pid == 0) { + tst_res(TINFO, "tc->which = %s", tc->des); -int main(int ac, char **av) -{ - int lc; - struct itimerval *value, *ovalue; - - tst_parse_opts(ac, av, NULL, NULL); - - setup(); /* global setup */ - - /* The following loop checks looping state if -i option given */ - - for (lc = 0; TEST_LOOPING(lc); lc++) { - /* reset tst_count in case we are looping */ - tst_count = 0; - - /* allocate some space for the timer structures */ - - if ((value = malloc((size_t)sizeof(struct itimerval))) == - NULL) { - tst_brkm(TBROK, cleanup, "value malloc failed"); - } - - if ((ovalue = malloc((size_t)sizeof(struct itimerval))) == - NULL) { - tst_brkm(TBROK, cleanup, "ovalue malloc failed"); - } - - /* set up some reasonable values */ - - value->it_value.tv_sec = SEC1; - value->it_value.tv_usec = SEC0; - value->it_interval.tv_sec = 0; - value->it_interval.tv_usec = 0; - /* - * issue the system call with the TEST() macro - * ITIMER_REAL = 0, ITIMER_VIRTUAL = 1 and ITIMER_PROF = 2 - */ - - TEST(setitimer(ITIMER_REAL, value, ovalue)); - - if (TEST_RETURN != 0) { - tst_resm(TFAIL, "call failed - errno = %d - %s", - TEST_ERRNO, strerror(TEST_ERRNO)); - continue; - } - - /* - * call setitimer again with new values. - * the old values should be stored in ovalue - */ - value->it_value.tv_sec = SEC2; - value->it_value.tv_usec = SEC0; - - if ((setitimer(ITIMER_REAL, value, ovalue)) == -1) { - tst_brkm(TBROK, cleanup, "second setitimer " - "call failed"); - } - - if (ovalue->it_value.tv_sec <= SEC1) { - tst_resm(TPASS, "functionality is correct"); - } else { - tst_brkm(TFAIL, cleanup, "old timer value is " - "not equal to expected value"); - } - } + tst_no_corefile(0); - cleanup(); - tst_exit(); -} + set_setitimer_value(USEC1, 0); + TST_EXP_PASS(sys_setitimer(tc->which, value, NULL)); -/* - * setup() - performs all the ONE TIME setup for this test. - */ -void setup(void) -{ + set_setitimer_value(USEC2, USEC2); + TST_EXP_PASS(sys_setitimer(tc->which, value, ovalue)); - tst_sig(NOFORK, DEF_HANDLER, cleanup); + if (ovalue->it_value.tv_sec != 0 || ovalue->it_value.tv_usec >= USEC2) + tst_brk(TFAIL, "old timer value is not within the expected range"); - TEST_PAUSE; -} + for (;;) + ; + } -/* - * cleanup() - performs all the ONE TIME cleanup for this test at completion - * or premature exit. - */ -void cleanup(void) -{ + SAFE_WAITPID(pid, &status, 0); + if (WIFSIGNALED(status) && WTERMSIG(status) == tc->signo) + tst_res(TPASS, "Child received signal: %s", tst_strsig(tc->signo)); + else + tst_res(TFAIL, "Child: %s", tst_strstatus(status)); } + +static struct tst_test test = { + .tcnt = ARRAY_SIZE(tcases), + .forks_child = 1, + .test = verify_setitimer, + .bufs = (struct tst_buffers[]) { + {&value, .size = sizeof(struct itimerval)}, + {&ovalue, .size = sizeof(struct itimerval)}, + {} + } +};
Also add signal checking when the timer take effection. Signed-off-by: Li Wang <liwang@redhat.com> --- .../kernel/syscalls/setitimer/setitimer01.c | 214 +++++++----------- 1 file changed, 77 insertions(+), 137 deletions(-)