From f73f8010133a5bffcc6ae52b0cfdb7315dc52bae Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Thu, 2 Jun 2022 21:41:06 +0300 Subject: [PATCH] Add tests base --- tests/include/random.h | 26 +++++++++ tests/include/test.h | 12 +++++ tests/include/time.h | 24 +++++++++ tests/src/random.c | 80 +++++++++++++++++++++++++++ tests/src/test.c | 41 ++++++++++++++ tests/src/time.c | 120 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 303 insertions(+) create mode 100644 tests/include/random.h create mode 100644 tests/include/test.h create mode 100644 tests/include/time.h create mode 100644 tests/src/random.c create mode 100644 tests/src/test.c create mode 100644 tests/src/time.c diff --git a/tests/include/random.h b/tests/include/random.h new file mode 100644 index 0000000..fa24373 --- /dev/null +++ b/tests/include/random.h @@ -0,0 +1,26 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include "../../include/vtype.h" + +#ifndef LIBCDSB_TESTS_RANDOM_H +#define LIBCDSB_TESTS_RANDOM_H + +extern int random_init(int argc, char** argv); + +extern vtype_bool random_boolean(); +extern vtype_float random_float(); +extern vtype_double random_double(); +extern vtype_ldouble random_ldouble(); + +extern vtype_uint8 random_uint8(); +extern vtype_uint16 random_uint16(); +extern vtype_uint32 random_uint32(); +extern vtype_uint64 random_uint64(); + +extern vtype_int8 random_int8(); +extern vtype_int16 random_int16(); +extern vtype_int32 random_int32(); +extern vtype_int64 random_int64(); + +#endif /* LIBCDSB_TESTS_RANDOM_H */ diff --git a/tests/include/test.h b/tests/include/test.h new file mode 100644 index 0000000..4a6a4c5 --- /dev/null +++ b/tests/include/test.h @@ -0,0 +1,12 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include + +#ifndef LIBCDSB_TESTS_TEST_H +#define LIBCDSB_TESTS_TEST_H + +extern void put_separator(); +extern void test_init(int argc, char** argv); + +#endif /* LIBCDSB_TESTS_TEST_H */ diff --git a/tests/include/time.h b/tests/include/time.h new file mode 100644 index 0000000..0558e5c --- /dev/null +++ b/tests/include/time.h @@ -0,0 +1,24 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include "../../include/vtype.h" + +#ifndef LIBCDSB_TESTS_TIME_H +#define LIBCDSB_TESTS_TIME_H + +typedef struct timer { + void* info; +} TIMER; + + +extern void timer_init (TIMER* timer); +extern void timer_start(TIMER* timer); +extern void timer_stop (TIMER* timer); +extern void timer_free (TIMER* timer); + +extern vtype_ldouble timer_value(TIMER* timer); + +extern void psleep(unsigned long microsec); + + +#endif /* LIBCDSB_TESTS_TIME_H */ diff --git a/tests/src/random.c b/tests/src/random.c new file mode 100644 index 0000000..a09ea4a --- /dev/null +++ b/tests/src/random.c @@ -0,0 +1,80 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include + +#include "../include/test.h" +#include "../include/random.h" + + +static void init(unsigned int seed) { + printf("\e[36mRandom module initialized with seed: \e[m\e[32m%u\n\e[m", seed); + put_separator(); + srand(seed); +} + +int random_init(int argc, char** argv) { + if (argc < 2) { + init(time(0)); + } else init(atol(argv[1])); + + return 0; +} + +vtype_bool random_boolean() { + return rand()&1; +} + +vtype_float random_float() { + if (rand()&1) { + return ((vtype_float)random_uint16() / (vtype_float)random_int16()) * -1; + } + return (vtype_float)random_uint16() / (vtype_float)random_int16(); +} + +vtype_double random_double() { + if (rand()&1) { + return ((vtype_double)random_uint32() / (vtype_double)random_int32()) * -1; + } + return (vtype_double)random_uint32() / (vtype_double)random_int32(); +} + +vtype_ldouble random_ldouble() { + if (rand()&1) { + return ((vtype_ldouble)random_uint64() / (vtype_ldouble)random_int64()) * -1; + } + return (vtype_ldouble)random_uint64() / (vtype_ldouble)random_int64(); +} + +vtype_int8 random_int8() { + return random_uint8(); +} + +vtype_int16 random_int16() { + return random_uint16(); +} + +vtype_int32 random_int32() { + return rand() | ((rand()&1) << 31); +} + +vtype_uint8 random_uint8() { + return rand() % 0x100; +} + +vtype_uint16 random_uint16() { + return rand() % 0x10000; +} + +vtype_uint32 random_uint32() { + return rand() << 1 | rand()&1; +} + +vtype_uint64 random_uint64() { + return random_int32() * random_int32(); +} + +vtype_int64 random_int64() { + return random_uint32() * random_uint32(); +} diff --git a/tests/src/test.c b/tests/src/test.c new file mode 100644 index 0000000..397a067 --- /dev/null +++ b/tests/src/test.c @@ -0,0 +1,41 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include "../include/test.h" +#include "../include/time.h" +#include "../include/random.h" + +static TIMER GLOBAL_TIMER; +static const char* TEST_NAME = 0; + +static void test_uload() __attribute__((destructor)); + +static void test_uload() { + if (TEST_NAME) { + timer_stop(&GLOBAL_TIMER); + puts(""); + put_separator(); + printf("\e[36mTest \"\e[m\e[32;1m%s\e[m\e[36m\" is end.\nExecusion time: \e[m\e[32m%.6Lf sec\e[m\n", TEST_NAME, timer_value(&GLOBAL_TIMER)); + put_separator(); + /////////////////////////// + timer_free(&GLOBAL_TIMER); + } +} + +void put_separator() { puts("\e[37;2m=== === === === === === === ===\e[m"); } + +void test_init(int argc, char** argv) { + timer_init(&GLOBAL_TIMER); + timer_start(&GLOBAL_TIMER); + + TEST_NAME = strrchr(argv[0], '/') ? strrchr(argv[0], '/') + 1 : argv[0]; + + put_separator(); + printf("\e[36mTest \"\e[m\e[32;1m%s\e[m\e[36m\" is loaded\e[m\n", TEST_NAME); + put_separator(); + + random_init(argc, argv); + + puts(""); +} diff --git a/tests/src/time.c b/tests/src/time.c new file mode 100644 index 0000000..1151708 --- /dev/null +++ b/tests/src/time.c @@ -0,0 +1,120 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include +#define __USE_MISC +#include +#include +#include +#include "../include/time.h" + +typedef struct timer_internal { + struct rusage begin; + struct rusage end; + struct rusage br; + unsigned long offset; + struct { + int isbr:1; + int isend:1; + }; +} TIMER_INFO; + + +void timer_init(TIMER* timer) { + TIMER_INFO *t; + if (!(t = timer->info = malloc(sizeof(TIMER_INFO)))) + abort(); + memset(t, 0, sizeof(*t)); +} + +void timer_start(TIMER* timer) { + TIMER_INFO *t = timer->info; + + if (t->isend) + return; + + if (t->isbr) { + struct rusage br; + + if (getrusage(RUSAGE_SELF, &br) < 0) + abort(); + + t->offset += br.ru_utime.tv_sec * 1000000 - t->br.ru_utime.tv_sec * 1000000; + t->offset -= t->br.ru_utime.tv_usec; + t->offset += br.ru_utime.tv_usec; + + memset(&t->br, 0, sizeof(t->br)); + t->isbr = 0; + } else if (getrusage(RUSAGE_SELF, &t->begin) < 0) + abort(); +} + +void timer_pause (TIMER* timer) { + TIMER_INFO *t = timer->info; + + if (t->isend) + return; + + if (!t->isbr) { + if (getrusage(RUSAGE_SELF, &t->br) < 0) + abort(); + + t->isbr = 1; + } +} + +void timer_stop (TIMER* timer) { + TIMER_INFO *t = timer->info; + + if (t->isend) + return; + + if (getrusage(RUSAGE_SELF, &t->end) < 0) + abort(); + + if (t->isbr) { + t->offset += t->end.ru_utime.tv_sec * 1000000 - t->br.ru_utime.tv_sec * 1000000; + t->offset -= t->br.ru_utime.tv_usec; + t->offset += t->end.ru_utime.tv_usec; + + memset(&t->br, 0, sizeof(t->br)); + t->isbr = 0; + } + + t->isend = 1; +} + +void timer_free (TIMER* timer) { + free(timer->info); +} + +vtype_ldouble timer_value(TIMER* timer) { + static char empty[sizeof(struct rusage)] = { 0 }; + + TIMER_INFO *t = timer->info; + + struct rusage _; + struct rusage *end; + vtype_ldouble value; + + if (memcmp(&t->begin, empty, sizeof(struct rusage)) == 0) { + return 0; + } + + if (!t->isend) { + if (getrusage(RUSAGE_SELF, end = &_) < 0) + abort(); + } else end = &t->end; + + value = end->ru_utime.tv_sec * 1000000 - t->begin.ru_utime.tv_sec * 1000000; + value -= t->begin.ru_utime.tv_usec; + value += end->ru_utime.tv_usec; + value -= t->offset; + + return value / 1000000; +} + +void psleep(unsigned long microsec) { + usleep(microsec); +}