[PATCH] getrusage: Add smoke test for getrusage
Ondrej Marek <[email protected]>
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <[email protected]> |
Add smoke test verifying that getrusage returns non-negative user time and fails with invalid who value. Co-authored-by: Frantisek Cech <[email protected]> Signed-off-by: Ondrej Marek <[email protected]> --- v3: - use xunistd.h - use DO_NOT_OPTIMIZE_OUT macro for CPU load - format the file with clang-format resource/Makefile | 1 + resource/tst-getrusage.c | 131 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 resource/tst-getrusage.c diff --git a/resource/Makefile b/resource/Makefile index 589b73f44f..dac48434dd 100644 --- a/resource/Makefile +++ b/resource/Makefile @@ -28,6 +28,7 @@ routines := getrlimit setrlimit getrlimit64 setrlimit64 getrusage ulimit \ tests := \ bug-ulimit1 \ tst-getrlimit \ + tst-getrusage \ # tests diff --git a/resource/tst-getrusage.c b/resource/tst-getrusage.c new file mode 100644 index 0000000000..f591f4ad69 --- /dev/null +++ b/resource/tst-getrusage.c @@ -0,0 +1,131 @@ +/* Test of the getrusage function. + Copyright (C) 2005-2026 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stdio.h> +#include <sys/resource.h> +#include <stdint.h> +#include <support/check.h> +#include <sys/types.h> +#include <support/xunistd.h> +#include <sys/wait.h> +#include <benchtests/bench-util.h> +#include <array_length.h> + +static void +do_work (void) +{ + uint64_t sink = 0; + for (uint64_t i = 0; i < UINT64_C (1000000); i++) + { + sink += i; + DO_NOT_OPTIMIZE_OUT (sink); + } +} + +static int +get_child_elapsed_time (long *result) +{ + pid_t pid; + pid = xfork (); + + if (pid > 0) + { + int status; + xwaitpid (pid, &status, 0); + TEST_VERIFY_EXIT (WIFEXITED (status)); + + struct rusage rusage = { 0 }; + + int ret_val = getrusage (RUSAGE_CHILDREN, &rusage); + TEST_VERIFY_EXIT (ret_val == 0); + long elapsed_time + = (rusage.ru_utime.tv_sec * 1000000L) + rusage.ru_utime.tv_usec; + TEST_VERIFY_EXIT (elapsed_time >= 0); + + *result = elapsed_time; + return 0; + } + else + { + /* Simulate some work */ + do_work (); + _exit (0); + } +} + +static void +test_getrusage_children (void) +{ + long elapsed_time_before; + long elapsed_time_after; + + int ret_val = get_child_elapsed_time (&elapsed_time_before); + TEST_VERIFY_EXIT (ret_val == 0); + int ret_val2 = get_child_elapsed_time (&elapsed_time_after); + TEST_VERIFY_EXIT (ret_val2 == 0); + TEST_VERIFY_EXIT (elapsed_time_after >= elapsed_time_before); +} + +static void +test_getrusage (int who) +{ + struct rusage before_usage = { 0 }; + struct rusage after_usage = { 0 }; + + int ret_val = getrusage (who, &before_usage); + TEST_VERIFY_EXIT (ret_val == 0); + long elapsed_time_before = (before_usage.ru_utime.tv_sec * 1000000L) + + before_usage.ru_utime.tv_usec; + TEST_VERIFY_EXIT (elapsed_time_before >= 0); + + /* Simulate some work */ + do_work (); + + int ret_val2 = getrusage (who, &after_usage); + TEST_VERIFY_EXIT (ret_val2 == 0); + + long elapsed_time_after = (after_usage.ru_utime.tv_sec * 1000000L) + + after_usage.ru_utime.tv_usec; + TEST_VERIFY_EXIT (elapsed_time_after >= elapsed_time_before); +} + +static int +do_test (void) +{ + int whos[] = { RUSAGE_SELF, RUSAGE_THREAD }; + for (int i = 0; i < array_length (whos); i++) + { + int who = whos[i]; + test_getrusage (who); + } + + /* RUSAGE_CHILDREN test case with forking children */ + test_getrusage_children (); + + /* Invalid who value test case */ + struct rusage usage_struct = { 0 }; + int invalid_who = 999; + int ret_val = getrusage (invalid_who, &usage_struct); + TEST_VERIFY (ret_val == -1); + + puts ("Everything OK\n"); + return 0; +} + +#include <support/test-driver.c> -- 2.47.3