Path: blob/main/lib/iolog/regress/iolog_timing/check_iolog_timing.c
1532 views
/*1* SPDX-License-Identifier: ISC2*3* Copyright (c) 2018 Todd C. Miller <[email protected]>4*5* Permission to use, copy, modify, and distribute this software for any6* purpose with or without fee is hereby granted, provided that the above7* copyright notice and this permission notice appear in all copies.8*9* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES10* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF11* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR12* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES13* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN14* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF15* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.16*/1718#include <config.h>1920#include <stdio.h>21#include <stdlib.h>22#include <string.h>23#include <time.h>24#include <unistd.h>2526#define SUDO_ERROR_WRAP 02728#include <sudo_compat.h>29#include <sudo_util.h>30#include <sudo_fatal.h>31#include <sudo_iolog.h>3233sudo_dso_public int main(int argc, char *argv[]);3435static struct parse_delay_test {36const char *input;37const char *next_field;38struct timespec expected_delay;39} parse_delay_tests[] = {40{ "10.99999999999 X", "X", { 10, 999999999 } }, /* clamp to nsec */41{ "10.999999999 X", "X", { 10, 999999999 } }, /* nsec */42{ "10.999999 X", "X", { 10, 999999000 } }, /* usec -> nsec */43{ "10.000999999 X", "X", { 10, 999999 } },44{ "10.9 X", "X", { 10, 900000000 } },45{ "10.0 X", "X", { 10, 0 } }46};4748/*49* Test iolog_parse_delay()50*/51static void52test_parse_delay(int *ntests, int *nerrors)53{54unsigned int i;5556for (i = 0; i < nitems(parse_delay_tests); i++) {57struct timespec delay;58struct parse_delay_test *test = &parse_delay_tests[i];59char *cp = iolog_parse_delay(test->input, &delay, ".");60if (cp == NULL) {61sudo_warnx("%s:%u failed to parse delay: %s", __func__,62i, test->input);63(*nerrors)++;64continue;65}66if (strcmp(cp, test->next_field) != 0) {67sudo_warnx("%s:%u next field (want \"%s\", got \"%s\"", __func__,68i, test->next_field, cp);69(*nerrors)++;70continue;71}72if (delay.tv_sec != test->expected_delay.tv_sec) {73sudo_warnx("%s:%u wrong seconds (want %lld, got %lld)", __func__,74i, (long long)test->expected_delay.tv_sec,75(long long)delay.tv_sec);76(*nerrors)++;77continue;78}79if (delay.tv_nsec != test->expected_delay.tv_nsec) {80sudo_warnx("%s:%u wrong nanoseconds (want %ld, got %ld)", __func__,81i, test->expected_delay.tv_nsec, delay.tv_nsec);82(*nerrors)++;83continue;84}85}86(*ntests) += (int)i;87}8889static struct adjust_delay_test {90struct timespec in_delay;91struct timespec out_delay;92struct timespec max_delay;93double scale_factor;94} adjust_delay_tests[] = {95{ { 10, 300 }, { 10, 300 }, { 0, 0 }, 1.0 },96{ { 10, 300 }, { 5, 150 }, { 0, 0 }, 2.0 },97{ { 5, 300 }, { 2, 500000150 }, { 0, 0 }, 2.0 },98{ { 0, 1000000 }, { 0, 333333 }, { 0, 0 }, 3 },99{ { 10, 1000000 }, { 3, 333666666 }, { 0, 0 }, 3 },100{ { 5, 150 }, { 10, 300 }, { 0, 0 }, 0.5 },101{ { 5, 500000000 }, { 11, 0 }, { 0, 0 }, 0.5 },102{ { 5, 150 }, { 5, 0 }, { 5, 0 }, 0.5 }103};104105/*106* Test iolog_adjust_delay()107*/108static void109test_adjust_delay(int *ntests, int *nerrors)110{111unsigned int i;112113for (i = 0; i < nitems(adjust_delay_tests); i++) {114struct adjust_delay_test *test = &adjust_delay_tests[i];115116iolog_adjust_delay(&test->in_delay,117sudo_timespecisset(&test->max_delay) ? &test->max_delay : NULL,118test->scale_factor);119if (!sudo_timespeccmp(&test->in_delay, &test->out_delay, ==)) {120sudo_warnx("%s:%u want {%lld, %ld}, got {%lld, %ld}", __func__, i,121(long long)test->out_delay.tv_sec, test->out_delay.tv_nsec,122(long long)test->in_delay.tv_sec, test->in_delay.tv_nsec);123(*nerrors)++;124}125}126(*ntests) += (int)i;127}128129int130main(int argc, char *argv[])131{132int ch, ntests = 0, errors = 0;133134initprogname(argc > 0 ? argv[0] : "check_iolog_timing");135136while ((ch = getopt(argc, argv, "v")) != -1) {137switch (ch) {138case 'v':139/* ignore */140break;141default:142fprintf(stderr, "usage: %s [-v]\n", getprogname());143return EXIT_FAILURE;144}145}146argc -= optind;147argv += optind;148149test_parse_delay(&ntests, &errors);150151test_adjust_delay(&ntests, &errors);152153if (ntests != 0) {154printf("iolog_timing: %d test%s run, %d errors, %d%% success rate\n",155ntests, ntests == 1 ? "" : "s", errors,156(ntests - errors) * 100 / ntests);157}158159return errors;160}161162163