diff mbox series

[V6,01/17] syscalls/timer_gettime: Add support for time64 tests

Message ID 9621b4f97b539f2e080b00491eb9ba4973878028.1591760262.git.viresh.kumar@linaro.org
State Superseded
Headers show
Series [V6,01/17] syscalls/timer_gettime: Add support for time64 tests | expand

Commit Message

Viresh Kumar June 10, 2020, 3:38 a.m. UTC
This adds support for time64 tests to the existing timer_gettime()
syscall tests.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
V6: Drop the binary files included by mistake.

 include/tst_timer.h                           |  45 +++++++
 .../syscalls/timer_gettime/timer_gettime01.c  | 124 ++++++++----------
 2 files changed, 97 insertions(+), 72 deletions(-)

Comments

Cyril Hrubis June 24, 2020, 2:23 p.m. UTC | #1
Hi!
> This adds support for time64 tests to the existing timer_gettime()
> syscall tests.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> V6: Drop the binary files included by mistake.
> 
>  include/tst_timer.h                           |  45 +++++++
>  .../syscalls/timer_gettime/timer_gettime01.c  | 124 ++++++++----------
>  2 files changed, 97 insertions(+), 72 deletions(-)
> 
> diff --git a/include/tst_timer.h b/include/tst_timer.h
> index 256e1d71e1bc..708a1e9e9a7a 100644
> --- a/include/tst_timer.h
> +++ b/include/tst_timer.h
> @@ -15,6 +15,7 @@
>  #include <sys/time.h>
>  #include <time.h>
>  #include "tst_test.h"
> +#include "lapi/common_timers.h"
>  #include "lapi/syscalls.h"
>  
>  /*
> @@ -112,6 +113,16 @@ struct __kernel_timespec {
>  	__kernel_time64_t       tv_sec;                 /* seconds */
>  	long long               tv_nsec;                /* nanoseconds */
>  };
> +
> +struct __kernel_old_itimerspec {
> +	struct __kernel_old_timespec it_interval;    /* timer period */
> +	struct __kernel_old_timespec it_value;       /* timer expiration */
> +};
> +
> +struct __kernel_itimerspec {
> +	struct __kernel_timespec it_interval;    /* timer period */
> +	struct __kernel_timespec it_value;       /* timer expiration */
> +};
>  #endif
>  
>  enum tst_ts_type {
> @@ -129,6 +140,14 @@ struct tst_ts {
>  	} ts;
>  };
>  
> +struct tst_its {
> +	enum tst_ts_type type;
> +	union {
> +		struct __kernel_old_itimerspec kern_old_its;
> +		struct __kernel_itimerspec kern_its;
> +	} ts;
> +};
> +
>  static inline void *tst_ts_get(struct tst_ts *t)
>  {
>  	if (!t)
> @@ -147,6 +166,22 @@ static inline void *tst_ts_get(struct tst_ts *t)
>  	}
>  }
>  
> +static inline void *tst_its_get(struct tst_its *t)
> +{
> +	if (!t)
> +		return NULL;
> +
> +	switch (t->type) {
> +	case TST_KERN_OLD_TIMESPEC:
> +		return &t->ts.kern_old_its;
> +	case TST_KERN_TIMESPEC:
> +		return &t->ts.kern_its;
> +	default:
> +		tst_brk(TBROK, "Invalid type: %d", t->type);
> +		return NULL;
> +	}
> +}
> +
>  static inline int libc_clock_getres(clockid_t clk_id, void *ts)
>  {
>  	return clock_getres(clk_id, ts);
> @@ -212,6 +247,16 @@ static inline int sys_clock_nanosleep64(clockid_t clk_id, int flags,
>  			   request, remain);
>  }
>  
> +static inline int sys_timer_gettime(timer_t timerid, void *its)
> +{
> +	return tst_syscall(__NR_timer_gettime, timerid, its);
> +}
> +
> +static inline int sys_timer_gettime64(timer_t timerid, void *its)
> +{
> +	return tst_syscall(__NR_timer_gettime64, timerid, its);
> +}
> +
>  /*
>   * Returns tst_ts seconds.
>   */
> diff --git a/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c b/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
> index 1c75f1cf0e45..d2b89eab4223 100644
> --- a/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
> +++ b/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
> @@ -1,24 +1,5 @@
> -/******************************************************************************
> - * Copyright (c) Crackerjack Project., 2007                                   *
> - * Porting from Crackerjack to LTP is done by:                                *
> - *              Manas Kumar Nayak <maknayak@in.ibm.com>                       *
> - * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>                          *
> - *                                                                            *
> - * 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           *
> - *                                                                            *
> - ******************************************************************************/
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/* Copyright (c) Crackerjack Project., 2007 */

You have dropped two copyright from there...

>  #include <time.h>
>  #include <signal.h>
> @@ -26,71 +7,70 @@
>  #include <stdio.h>
>  #include <errno.h>
>  
> -#include "test.h"
> -#include "lapi/syscalls.h"
> +#include "tst_timer.h"
>  
> -char *TCID = "timer_gettime01";
> -int TST_TOTAL = 3;
> +static struct test_variants {
> +	int (*func)(timer_t timer, void *its);
> +	enum tst_ts_type type;
> +	char *desc;
> +} variants[] = {
> +#if (__NR_timer_gettime != __LTP__NR_INVALID_SYSCALL)
> +	{ .func = sys_timer_gettime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"},
> +#endif
>  
> -static void cleanup(void)
> -{
> -	tst_rmdir();
> -}
> +#if (__NR_timer_gettime64 != __LTP__NR_INVALID_SYSCALL)
> +	{ .func = sys_timer_gettime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"},
> +#endif
> +};
>  
> -static void setup(void)
> -{
> -	TEST_PAUSE;
> -	tst_tmpdir();
> -}
> +static timer_t timer;
>  
> -int main(int ac, char **av)
> +static void setup(void)
>  {
> -	int lc;
> -
>  	struct sigevent ev;
> -	struct itimerspec spec;
> -	int timer;
>  
> -	tst_parse_opts(ac, av, NULL, NULL);
> -
> -	setup();
> +	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
>  
>  	ev.sigev_value = (union sigval) 0;
>  	ev.sigev_signo = SIGALRM;
>  	ev.sigev_notify = SIGEV_SIGNAL;
> -	TEST(ltp_syscall(__NR_timer_create, CLOCK_REALTIME, &ev, &timer));
> -
> -	if (TEST_RETURN != 0)
> -		tst_brkm(TBROK | TERRNO, cleanup, "Failed to create timer");
>  
> -	for (lc = 0; TEST_LOOPING(lc); ++lc) {
> -		tst_count = 0;
> +	TEST(tst_syscall(__NR_timer_create, CLOCK_REALTIME, &ev, &timer));
>  
> -		TEST(ltp_syscall(__NR_timer_gettime, timer, &spec));
> -		if (TEST_RETURN == 0) {
> -			tst_resm(TPASS, "timer_gettime(CLOCK_REALTIME) Passed");
> -		} else {
> -			tst_resm(TFAIL | TERRNO,
> -			         "timer_gettime(CLOCK_REALTIME) Failed");
> -		}
> -
> -		TEST(ltp_syscall(__NR_timer_gettime, -1, &spec));
> -		if (TEST_RETURN == -1 && TEST_ERRNO == EINVAL) {
> -			tst_resm(TPASS,	"timer_gettime(-1) Failed: EINVAL");
> -		} else {
> -			tst_resm(TFAIL | TERRNO,
> -			         "timer_gettime(-1) = %li", TEST_RETURN);
> -		}
> +	if (TST_RET) {
> +		tst_res(TFAIL | TTERRNO, "timer_create() failed");
> +		return;
> +	}
> +}
>  
> -		TEST(ltp_syscall(__NR_timer_gettime, timer, NULL));
> -		if (TEST_RETURN == -1 && TEST_ERRNO == EFAULT) {
> -			tst_resm(TPASS,	"timer_gettime(NULL) Failed: EFAULT");
> -		} else {
> -			tst_resm(TFAIL | TERRNO,
> -			         "timer_gettime(-1) = %li", TEST_RETURN);
> -		}
> +static void verify(void)
> +{
> +	struct test_variants *tv = &variants[tst_variant];
> +	struct tst_its spec = {.type = tv->type, };
> +
> +	TEST(tv->func(timer, tst_its_get(&spec)));
> +	if (TST_RET == 0) {
> +		tst_res(TPASS, "timer_gettime() Passed");
> +	} else {
> +		tst_res(TFAIL | TTERRNO, "timer_gettime() Failed");
>  	}

Looking at manuals it seems that:

* Newly created timer is disarmed

* For disarmed timers the clock_gettime() should get itimer with zeroes

So we check here that the returned itimer has zeroes for both oneshoot
and interval timers here.


Other than that it looks good.
Viresh Kumar June 25, 2020, 9:50 a.m. UTC | #2
On 24-06-20, 16:23, Cyril Hrubis wrote:
> > +static void verify(void)
> > +{
> > +	struct test_variants *tv = &variants[tst_variant];
> > +	struct tst_its spec = {.type = tv->type, };
> > +
> > +	TEST(tv->func(timer, tst_its_get(&spec)));
> > +	if (TST_RET == 0) {
> > +		tst_res(TPASS, "timer_gettime() Passed");
> > +	} else {
> > +		tst_res(TFAIL | TTERRNO, "timer_gettime() Failed");
> >  	}
> 
> Looking at manuals it seems that:
> 
> * Newly created timer is disarmed
> 
> * For disarmed timers the clock_gettime() should get itimer with zeroes
> 
> So we check here that the returned itimer has zeroes for both oneshoot
> and interval timers here.

I am not sure what oneshoot/interval timers you are talking about :)

This is what I came to, is this sufficient ?

diff --git a/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c b/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
index ea7cc6b59f7e..4a949486a920 100644
--- a/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
+++ b/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
@@ -55,7 +55,19 @@ static void verify(void)
 
        TEST(tv->func(timer, tst_its_get(&spec)));
        if (TST_RET == 0) {
-               tst_res(TPASS, "timer_gettime() Passed");
+               if ((spec.type == TST_KERN_OLD_TIMESPEC &&
+                       (spec.ts.kern_old_its.it_interval.tv_sec ||
+                        spec.ts.kern_old_its.it_interval.tv_nsec ||
+                        spec.ts.kern_old_its.it_value.tv_sec ||
+                        spec.ts.kern_old_its.it_value.tv_nsec)) ||
+                   (spec.type == TST_KERN_TIMESPEC &&
+                       (spec.ts.kern_its.it_interval.tv_sec ||
+                        spec.ts.kern_its.it_interval.tv_nsec ||
+                        spec.ts.kern_its.it_value.tv_sec ||
+                        spec.ts.kern_its.it_value.tv_nsec)))
+                       tst_res(TFAIL, "timespec should have been zeroed");
+               else
+                       tst_res(TPASS, "timer_gettime() Passed");
        } else {
                tst_res(TFAIL | TTERRNO, "timer_gettime() Failed");
        }
Cyril Hrubis June 25, 2020, 11:07 a.m. UTC | #3
Hi!
> > > +static void verify(void)
> > > +{
> > > +	struct test_variants *tv = &variants[tst_variant];
> > > +	struct tst_its spec = {.type = tv->type, };
> > > +
> > > +	TEST(tv->func(timer, tst_its_get(&spec)));
> > > +	if (TST_RET == 0) {
> > > +		tst_res(TPASS, "timer_gettime() Passed");
> > > +	} else {
> > > +		tst_res(TFAIL | TTERRNO, "timer_gettime() Failed");
> > >  	}
> > 
> > Looking at manuals it seems that:
> > 
> > * Newly created timer is disarmed
> > 
> > * For disarmed timers the clock_gettime() should get itimer with zeroes
> > 
> > So we check here that the returned itimer has zeroes for both oneshoot
> > and interval timers here.
> 
> I am not sure what oneshoot/interval timers you are talking about :)

These are the two timerspec structures inside of the itimerspec, one of
them is for oneshoot timer/alarm and the second one is for reocurring
timer/alarm and called interval.

> This is what I came to, is this sufficient ?
> 
> diff --git a/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c b/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
> index ea7cc6b59f7e..4a949486a920 100644
> --- a/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
> +++ b/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
> @@ -55,7 +55,19 @@ static void verify(void)
>  
>         TEST(tv->func(timer, tst_its_get(&spec)));
>         if (TST_RET == 0) {
> -               tst_res(TPASS, "timer_gettime() Passed");
> +               if ((spec.type == TST_KERN_OLD_TIMESPEC &&
> +                       (spec.ts.kern_old_its.it_interval.tv_sec ||
> +                        spec.ts.kern_old_its.it_interval.tv_nsec ||
> +                        spec.ts.kern_old_its.it_value.tv_sec ||
> +                        spec.ts.kern_old_its.it_value.tv_nsec)) ||
> +                   (spec.type == TST_KERN_TIMESPEC &&
> +                       (spec.ts.kern_its.it_interval.tv_sec ||
> +                        spec.ts.kern_its.it_interval.tv_nsec ||
> +                        spec.ts.kern_its.it_value.tv_sec ||
> +                        spec.ts.kern_its.it_value.tv_nsec)))
> +                       tst_res(TFAIL, "timespec should have been zeroed");

Indeed that's what I had in mind, can we please abstract this properly
as well? I guess that we can add helpers such as tst_its_interval_sec()
tst_its_inverval_nsec, etc.

> +               else
> +                       tst_res(TPASS, "timer_gettime() Passed");
>         } else {
>                 tst_res(TFAIL | TTERRNO, "timer_gettime() Failed");
>         }
> 
> -- 
> viresh
Viresh Kumar June 25, 2020, 11:10 a.m. UTC | #4
On 25-06-20, 13:07, Cyril Hrubis wrote:
> >         TEST(tv->func(timer, tst_its_get(&spec)));
> >         if (TST_RET == 0) {
> > -               tst_res(TPASS, "timer_gettime() Passed");
> > +               if ((spec.type == TST_KERN_OLD_TIMESPEC &&
> > +                       (spec.ts.kern_old_its.it_interval.tv_sec ||
> > +                        spec.ts.kern_old_its.it_interval.tv_nsec ||
> > +                        spec.ts.kern_old_its.it_value.tv_sec ||
> > +                        spec.ts.kern_old_its.it_value.tv_nsec)) ||
> > +                   (spec.type == TST_KERN_TIMESPEC &&
> > +                       (spec.ts.kern_its.it_interval.tv_sec ||
> > +                        spec.ts.kern_its.it_interval.tv_nsec ||
> > +                        spec.ts.kern_its.it_value.tv_sec ||
> > +                        spec.ts.kern_its.it_value.tv_nsec)))
> > +                       tst_res(TFAIL, "timespec should have been zeroed");
> 
> Indeed that's what I had in mind, can we please abstract this properly
> as well? I guess that we can add helpers such as tst_its_interval_sec()
> tst_its_inverval_nsec, etc.

I preferred it this way as no one else uses it and so maybe we can
live without adding those helpers ?
Cyril Hrubis June 25, 2020, 11:13 a.m. UTC | #5
Hi!
> > Indeed that's what I had in mind, can we please abstract this properly
> > as well? I guess that we can add helpers such as tst_its_interval_sec()
> > tst_its_inverval_nsec, etc.
> 
> I preferred it this way as no one else uses it and so maybe we can
> live without adding those helpers ?

I'm pretty sure we will need them for the timer_settime() tests anyway,
i.e. test that would do timer_settime() and then timer_gettime() to
check that the timer is read back correclty.
diff mbox series

Patch

diff --git a/include/tst_timer.h b/include/tst_timer.h
index 256e1d71e1bc..708a1e9e9a7a 100644
--- a/include/tst_timer.h
+++ b/include/tst_timer.h
@@ -15,6 +15,7 @@ 
 #include <sys/time.h>
 #include <time.h>
 #include "tst_test.h"
+#include "lapi/common_timers.h"
 #include "lapi/syscalls.h"
 
 /*
@@ -112,6 +113,16 @@  struct __kernel_timespec {
 	__kernel_time64_t       tv_sec;                 /* seconds */
 	long long               tv_nsec;                /* nanoseconds */
 };
+
+struct __kernel_old_itimerspec {
+	struct __kernel_old_timespec it_interval;    /* timer period */
+	struct __kernel_old_timespec it_value;       /* timer expiration */
+};
+
+struct __kernel_itimerspec {
+	struct __kernel_timespec it_interval;    /* timer period */
+	struct __kernel_timespec it_value;       /* timer expiration */
+};
 #endif
 
 enum tst_ts_type {
@@ -129,6 +140,14 @@  struct tst_ts {
 	} ts;
 };
 
+struct tst_its {
+	enum tst_ts_type type;
+	union {
+		struct __kernel_old_itimerspec kern_old_its;
+		struct __kernel_itimerspec kern_its;
+	} ts;
+};
+
 static inline void *tst_ts_get(struct tst_ts *t)
 {
 	if (!t)
@@ -147,6 +166,22 @@  static inline void *tst_ts_get(struct tst_ts *t)
 	}
 }
 
+static inline void *tst_its_get(struct tst_its *t)
+{
+	if (!t)
+		return NULL;
+
+	switch (t->type) {
+	case TST_KERN_OLD_TIMESPEC:
+		return &t->ts.kern_old_its;
+	case TST_KERN_TIMESPEC:
+		return &t->ts.kern_its;
+	default:
+		tst_brk(TBROK, "Invalid type: %d", t->type);
+		return NULL;
+	}
+}
+
 static inline int libc_clock_getres(clockid_t clk_id, void *ts)
 {
 	return clock_getres(clk_id, ts);
@@ -212,6 +247,16 @@  static inline int sys_clock_nanosleep64(clockid_t clk_id, int flags,
 			   request, remain);
 }
 
+static inline int sys_timer_gettime(timer_t timerid, void *its)
+{
+	return tst_syscall(__NR_timer_gettime, timerid, its);
+}
+
+static inline int sys_timer_gettime64(timer_t timerid, void *its)
+{
+	return tst_syscall(__NR_timer_gettime64, timerid, its);
+}
+
 /*
  * Returns tst_ts seconds.
  */
diff --git a/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c b/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
index 1c75f1cf0e45..d2b89eab4223 100644
--- a/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
+++ b/testcases/kernel/syscalls/timer_gettime/timer_gettime01.c
@@ -1,24 +1,5 @@ 
-/******************************************************************************
- * Copyright (c) Crackerjack Project., 2007                                   *
- * Porting from Crackerjack to LTP is done by:                                *
- *              Manas Kumar Nayak <maknayak@in.ibm.com>                       *
- * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>                          *
- *                                                                            *
- * 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           *
- *                                                                            *
- ******************************************************************************/
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Copyright (c) Crackerjack Project., 2007 */
 
 #include <time.h>
 #include <signal.h>
@@ -26,71 +7,70 @@ 
 #include <stdio.h>
 #include <errno.h>
 
-#include "test.h"
-#include "lapi/syscalls.h"
+#include "tst_timer.h"
 
-char *TCID = "timer_gettime01";
-int TST_TOTAL = 3;
+static struct test_variants {
+	int (*func)(timer_t timer, void *its);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if (__NR_timer_gettime != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_timer_gettime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"},
+#endif
 
-static void cleanup(void)
-{
-	tst_rmdir();
-}
+#if (__NR_timer_gettime64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_timer_gettime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"},
+#endif
+};
 
-static void setup(void)
-{
-	TEST_PAUSE;
-	tst_tmpdir();
-}
+static timer_t timer;
 
-int main(int ac, char **av)
+static void setup(void)
 {
-	int lc;
-
 	struct sigevent ev;
-	struct itimerspec spec;
-	int timer;
 
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
 
 	ev.sigev_value = (union sigval) 0;
 	ev.sigev_signo = SIGALRM;
 	ev.sigev_notify = SIGEV_SIGNAL;
-	TEST(ltp_syscall(__NR_timer_create, CLOCK_REALTIME, &ev, &timer));
-
-	if (TEST_RETURN != 0)
-		tst_brkm(TBROK | TERRNO, cleanup, "Failed to create timer");
 
-	for (lc = 0; TEST_LOOPING(lc); ++lc) {
-		tst_count = 0;
+	TEST(tst_syscall(__NR_timer_create, CLOCK_REALTIME, &ev, &timer));
 
-		TEST(ltp_syscall(__NR_timer_gettime, timer, &spec));
-		if (TEST_RETURN == 0) {
-			tst_resm(TPASS, "timer_gettime(CLOCK_REALTIME) Passed");
-		} else {
-			tst_resm(TFAIL | TERRNO,
-			         "timer_gettime(CLOCK_REALTIME) Failed");
-		}
-
-		TEST(ltp_syscall(__NR_timer_gettime, -1, &spec));
-		if (TEST_RETURN == -1 && TEST_ERRNO == EINVAL) {
-			tst_resm(TPASS,	"timer_gettime(-1) Failed: EINVAL");
-		} else {
-			tst_resm(TFAIL | TERRNO,
-			         "timer_gettime(-1) = %li", TEST_RETURN);
-		}
+	if (TST_RET) {
+		tst_res(TFAIL | TTERRNO, "timer_create() failed");
+		return;
+	}
+}
 
-		TEST(ltp_syscall(__NR_timer_gettime, timer, NULL));
-		if (TEST_RETURN == -1 && TEST_ERRNO == EFAULT) {
-			tst_resm(TPASS,	"timer_gettime(NULL) Failed: EFAULT");
-		} else {
-			tst_resm(TFAIL | TERRNO,
-			         "timer_gettime(-1) = %li", TEST_RETURN);
-		}
+static void verify(void)
+{
+	struct test_variants *tv = &variants[tst_variant];
+	struct tst_its spec = {.type = tv->type, };
+
+	TEST(tv->func(timer, tst_its_get(&spec)));
+	if (TST_RET == 0) {
+		tst_res(TPASS, "timer_gettime() Passed");
+	} else {
+		tst_res(TFAIL | TTERRNO, "timer_gettime() Failed");
 	}
 
-	cleanup();
-	tst_exit();
+	TEST(tv->func((timer_t)-1, tst_its_get(&spec)));
+	if (TST_RET == -1 && TST_ERR == EINVAL)
+		tst_res(TPASS, "timer_gettime(-1) Failed: EINVAL");
+	else
+		tst_res(TFAIL | TTERRNO, "timer_gettime(-1) = %li", TST_RET);
+
+	TEST(tv->func(timer, NULL));
+	if (TST_RET == -1 && TST_ERR == EFAULT)
+		tst_res(TPASS, "timer_gettime(NULL) Failed: EFAULT");
+	else
+		tst_res(TFAIL | TTERRNO, "timer_gettime(-1) = %li", TST_RET);
 }
+
+static struct tst_test test = {
+	.test_all = verify,
+	.test_variants = ARRAY_SIZE(variants),
+	.setup = setup,
+	.needs_tmpdir = 1,
+};