diff --git a/common/tests/CMakeLists.txt b/common/tests/CMakeLists.txt index b78165cf0..450b9e5ca 100644 --- a/common/tests/CMakeLists.txt +++ b/common/tests/CMakeLists.txt @@ -24,19 +24,18 @@ set(SOURCES main.cpp logging.cpp + advio.cpp + bitset.cpp graph.cpp - - advio.c - bitset.c - hash_table.c - hist.c - kernel.c - list.c - log.c - task.c - timing.c - tsc.c - utils.c + hash_table.cpp + hist.cpp + kernel.cpp + list.cpp + log.cpp + task.cpp + timing.cpp + tsc.cpp + utils.cpp ) add_executable(unit-tests-common ${SOURCES}) diff --git a/common/tests/advio.cpp b/common/tests/advio.cpp new file mode 100644 index 000000000..e625648e8 --- /dev/null +++ b/common/tests/advio.cpp @@ -0,0 +1,263 @@ +/** Unit tests for advio + * + * @author Steffen Vogel + * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLAScommon + * + * 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 3 of the License, or + * 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, see . + *********************************************************************************/ + +#include + +#include +#include + +#include +#include + +/** This URI points to a Sciebo share which contains some test files. + * The Sciebo share is read/write accessible via WebDAV. */ +#define BASE_URI "https://1Nrd46fZX8HbggT:badpass@rwth-aachen.sciebo.de/public.php/webdav/node/tests" + +void init_logging(); + +TestSuite(advio, + .description = "Advanced file IO", + .init = init_logging +); + + +Test(advio, islocal) +{ + int ret; + + ret = aislocal("/var/log/villas/dta.dat"); + cr_assert_eq(ret, 1); + + ret = aislocal("http://www.google.de"); + cr_assert_eq(ret, 0); + + ret = aislocal("torrent://www.google.de"); + cr_assert_eq(ret, -1); +} + +Test(advio, local) +{ + AFILE *af; + int ret; + char *buf = NULL; + size_t buflen = 0; + + /* We open this file and check the first line */ + af = afopen(__FILE__, "r"); + cr_assert(af, "Failed to open local file"); + + ret = getline(&buf, &buflen, af->file); + cr_assert_gt(ret, 1); + cr_assert_str_eq(buf, "/** Unit tests for advio\n"); +} + +Test(advio, download) +{ + AFILE *af; + int ret; + size_t len; + char buffer[65]; + char expect[65] = "ook4iekohC2Teegoghu6ayoo1OThooregheebaet8Zod1angah0che7quai4ID7A"; + + af = afopen(BASE_URI "/download" , "r"); + cr_assert(af, "Failed to download file"); + + len = afread(buffer, 1, sizeof(buffer), af); + cr_assert_gt(len, 0, "len=%zu, feof=%u", len, afeof(af)); + + cr_assert_arr_eq(buffer, expect, sizeof(expect)); + + ret = afclose(af); + cr_assert_eq(ret, 0, "Failed to close file"); +} + +Test(advio, download_large) +{ + AFILE *af; + int ret; + + af = afopen(BASE_URI "/download-large" , "r"); + cr_assert(af, "Failed to download file"); + + char line[4096]; + + char *f; + + f = afgets(line, 4096, af); + cr_assert_not_null(f); + + /* Check first line */ + cr_assert_str_eq(line, "# VILLASnode signal params: type=mixed, values=4, rate=1000.000000, limit=100000, amplitude=1.000000, freq=1.000000\n"); + + while(afgets(line, 4096, af)); + + /* Check last line */ + cr_assert_str_eq(line, "1497710478.862332239(99999) 0.752074 -0.006283 1.000000 0.996000\n"); + + ret = afclose(af); + cr_assert_eq(ret, 0, "Failed to close file"); +} + +Test(advio, resume) +{ + int ret; + char *retp; + AFILE *af1, *af2; + char *fn, dir[] = "/tmp/temp.XXXXXX"; + char line1[32]; + char *line2 = NULL; + size_t linelen = 0; + + retp = mkdtemp(dir); + cr_assert_not_null(retp); + + ret = asprintf(&fn, "%s/file", dir); + cr_assert_gt(ret, 0); + + af1 = afopen(fn, "w+"); + cr_assert_not_null(af1); + + /* We flush once the empty file in order to upload an empty file. */ + aupload(af1, 0); + + af2 = afopen(fn, "r"); + cr_assert_not_null(af2); + + for (int i = 0; i < 100; i++) { + snprintf(line1, sizeof(line1), "This is line %d\n", i); + + afputs(line1, af1); + aupload(af1, 1); + + adownload(af2, 1); + + ret = agetline(&line2, &linelen, af2); + cr_assert_gt(ret, 0); + + cr_assert_str_eq(line1, line2); + } + + ret = afclose(af1); + cr_assert_eq(ret, 0); + + ret = afclose(af2); + cr_assert_eq(ret, 0); + + ret = unlink(fn); + cr_assert_eq(ret, 0); + + ret = rmdir(dir); + cr_assert_eq(ret, 0); + + free(line2); +} + +Test(advio, upload) +{ + AFILE *af; + int ret; + size_t len; + + char upload[64]; + char buffer[64]; + + /* Get some random data to upload */ + len = read_random(upload, sizeof(upload)); + cr_assert_eq(len, sizeof(upload)); + + /* Open file for writing */ + af = afopen(BASE_URI "/upload", "w+"); + cr_assert(af, "Failed to download file"); + + len = afwrite(upload, 1, sizeof(upload), af); + cr_assert_eq(len, sizeof(upload)); + + ret = afclose(af); + cr_assert_eq(ret, 0, "Failed to close/upload file"); + + /* Open for reading and comparison */ + af = afopen(BASE_URI "/upload", "r"); + cr_assert(af, "Failed to download file"); + + len = afread(buffer, 1, sizeof(upload), af); + cr_assert_eq(len, sizeof(upload)); + + cr_assert_arr_eq(buffer, upload, len); + + ret = afclose(af); + cr_assert(ret == 0, "Failed to close file"); +} + +Test(advio, append) +{ + AFILE *af; + int ret; + size_t len; + + char append1[65] = "xa5gieTohlei9iu1uVaePae6Iboh3eeheeme5iejue5sheshae4uzisha9Faesei"; + char append2[65] = "bitheeRae7igee2miepahJaefoGad1Ooxeif0Mooch4eojoumueYahn4ohc9poo2"; + char expect[129] = "xa5gieTohlei9iu1uVaePae6Iboh3eeheeme5iejue5sheshae4uzisha9FaeseibitheeRae7igee2miepahJaefoGad1Ooxeif0Mooch4eojoumueYahn4ohc9poo2"; + char buffer[129]; + + /* Open file for writing first chunk */ + af = afopen(BASE_URI "/append", "w+"); + cr_assert(af, "Failed to download file"); + + /* The append file might already exist and be not empty from a previous run. */ + ret = ftruncate(afileno(af), 0); + cr_assert_eq(ret, 0); + + char c; + fseek(af->file, 0, SEEK_SET); + if (af->file) { + while ((c = getc(af->file)) != EOF) + putchar(c); + } + + len = afwrite(append1, 1, 64, af); + cr_assert_eq(len, 64); + + ret = afclose(af); + cr_assert_eq(ret, 0, "Failed to close/upload file"); + + /* Open file for writing second chunk */ + af = afopen(BASE_URI "/append", "a"); + cr_assert(af, "Failed to download file"); + + len = afwrite(append2, 1, 64, af); + cr_assert_eq(len, 64); + + ret = afclose(af); + cr_assert_eq(ret, 0, "Failed to close/upload file"); + + /* Open for reading and comparison */ + af = afopen(BASE_URI "/append", "r"); + cr_assert(af, "Failed to download file"); + + len = afread(buffer, 1, sizeof(buffer), af); + cr_assert_eq(len, 128); + + ret = afclose(af); + cr_assert(ret == 0, "Failed to close file"); + + cr_assert_arr_eq(buffer, expect, 128); +} diff --git a/common/tests/bitset.cpp b/common/tests/bitset.cpp new file mode 100644 index 000000000..ad0ae7e37 --- /dev/null +++ b/common/tests/bitset.cpp @@ -0,0 +1,137 @@ +/** Unit tests for advio + * + * @author Steffen Vogel + * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLAScommon + * + * 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 3 of the License, or + * 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, see . + *********************************************************************************/ + +#include + +#include +#include + +#define LEN 1027 + +void init_logging(); + +TestSuite(bitset, + .description = "Bitset datastructure", + .init = init_logging +); + +Test(bitset, simple) +{ + int ret; + struct bitset bs; + + int bits[] = { 23, 223, 25, 111, 252, 86, 222, 454, LEN-1 }; + + ret = bitset_init(&bs, LEN); + cr_assert_eq(ret, 0); + + for (unsigned i = 0; i < ARRAY_LEN(bits); i++) { + bitset_set(&bs, bits[i]); + cr_assert_eq(ret, 0); + } + + for (unsigned i = 0; i < ARRAY_LEN(bits); i++) { + ret = bitset_test(&bs, bits[i]); + cr_assert_eq(ret, 1, "Failed at bit %d", i); + } + + for (unsigned i = 0; i < ARRAY_LEN(bits); i++) { + ret = bitset_clear(&bs, bits[i]); + cr_assert_eq(ret, 0, "Failed at bit %d", i); + } + + for (unsigned i = 0; i < LEN; i++) { + ret = bitset_test(&bs, i); + cr_assert_eq(ret, 0); + } + + ret = bitset_destroy(&bs); + cr_assert_eq(ret, 0); +} + +Test(bitset, outofbounds) +{ + int ret; + struct bitset bs; + + ret = bitset_init(&bs, LEN); + cr_assert_eq(ret, 0); + + ret = bitset_set(&bs, LEN+1); + cr_assert_eq(ret, -1); + + ret = bitset_test(&bs, LEN+1); + cr_assert_eq(ret, -1); + + ret = bitset_destroy(&bs); + cr_assert_eq(ret, 0); +} + +Test(bitset, cmp) +{ + int ret; + struct bitset bs1, bs2; + + ret = bitset_init(&bs1, LEN); + cr_assert_eq(ret, 0); + + ret = bitset_init(&bs2, LEN); + cr_assert_eq(ret, 0); + + ret = bitset_set(&bs1, 525); + cr_assert_eq(ret, 0); + + ret = bitset_set(&bs2, 525); + cr_assert_eq(ret, 0); + + ret = bitset_cmp(&bs1, &bs2); + cr_assert_eq(ret, 0); + + ret = bitset_clear(&bs2, 525); + cr_assert_eq(ret, 0); + + ret = bitset_cmp(&bs1, &bs2); + cr_assert_neq(ret, 0); + + ret = bitset_destroy(&bs1); + cr_assert_eq(ret, 0); + + ret = bitset_destroy(&bs2); + cr_assert_eq(ret, 0); +} + +Test(bitset, all) +{ + int ret; + struct bitset bs; + + ret = bitset_init(&bs, LEN); + cr_assert_eq(ret, 0); + + for (unsigned i = 0; i < LEN; i++) { + bitset_test(&bs, i); + cr_assert_eq(ret, 0); + } + + ret = bitset_destroy(&bs); + cr_assert_eq(ret, 0); +} diff --git a/common/tests/graph.cpp b/common/tests/graph.cpp index 3d5a4cc7e..22b5a91d3 100644 --- a/common/tests/graph.cpp +++ b/common/tests/graph.cpp @@ -27,15 +27,11 @@ #include #include -static void init_graph() -{ - spdlog::set_pattern("[%T] [%l] [%n] %v"); - spdlog::set_level(spdlog::level::debug); -} +void init_logging(); TestSuite(graph, - .description = "Graph library", - .init = init_graph + .init = init_logging, + .description = "Graph library" ); Test(graph, basic, .description = "DirectedGraph") @@ -67,8 +63,6 @@ Test(graph, basic, .description = "DirectedGraph") g.dump(); cr_assert(g.getVertexCount() == 2); cr_assert(g.vertexGetEdges(v2id).size() == 0); - - logger->info(TXT_GREEN("Passed")); } Test(graph, path, .description = "Find path") @@ -133,8 +127,6 @@ Test(graph, path, .description = "Find path") for(auto& edge : path4) { logger->info(" -> edge {}", edge); } - - logger->info(TXT_GREEN("Passed")); } Test(graph, memory_manager, .description = "Global Memory Manager") @@ -154,6 +146,4 @@ Test(graph, memory_manager, .description = "Global Memory Manager") logger->info(" found: {}", vertex); mm.dump(); - - logger->info(TXT_GREEN("Passed")); } diff --git a/common/tests/hash_table.c b/common/tests/hash_table.cpp similarity index 51% rename from common/tests/hash_table.c rename to common/tests/hash_table.cpp index 6e511e4f9..660b1dc3b 100644 --- a/common/tests/hash_table.c +++ b/common/tests/hash_table.cpp @@ -25,31 +25,39 @@ #include #include -static char *keys[] = { "able", "achieve", "acoustics", "action", "activity", "aftermath", "afternoon", "afterthought", "apparel", "appliance", "beginner", "believe", "bomb", "border", "boundary", "breakfast", "cabbage", "cable", "calculator", "calendar", "caption", "carpenter", "cemetery", "channel", "circle", "creator", "creature", "education", "faucet", "feather", "friction", "fruit", "fuel", "galley", "guide", "guitar", "health", "heart", "idea", "kitten", "laborer", "language" }; -static char *values[] = { "lawyer", "linen", "locket", "lumber", "magic", "minister", "mitten", "money", "mountain", "music", "partner", "passenger", "pickle", "picture", "plantation", "plastic", "pleasure", "pocket", "police", "pollution", "railway", "recess", "reward", "route", "scene", "scent", "squirrel", "stranger", "suit", "sweater", "temper", "territory", "texture", "thread", "treatment", "veil", "vein", "volcano", "wealth", "weather", "wilderness", "wren" }; +static const char *keys[] = { "able", "achieve", "acoustics", "action", "activity", "aftermath", "afternoon", "afterthought", "apparel", "appliance", "beginner", "believe", "bomb", "border", "boundary", "breakfast", "cabbage", "cable", "calculator", "calendar", "caption", "carpenter", "cemetery", "channel", "circle", "creator", "creature", "education", "faucet", "feather", "friction", "fruit", "fuel", "galley", "guide", "guitar", "health", "heart", "idea", "kitten", "laborer", "language" }; +static const char *values[] = { "lawyer", "linen", "locket", "lumber", "magic", "minister", "mitten", "money", "mountain", "music", "partner", "passenger", "pickle", "picture", "plantation", "plastic", "pleasure", "pocket", "police", "pollution", "railway", "recess", "reward", "route", "scene", "scent", "squirrel", "stranger", "suit", "sweater", "temper", "territory", "texture", "thread", "treatment", "veil", "vein", "volcano", "wealth", "weather", "wilderness", "wren" }; + +void init_logging(); + +TestSuite(hash_table, + .description = "Hash table datastructure", + .init = init_logging +); Test(hash_table, hash_table_lookup) { int ret; - struct hash_table ht = { .state = STATE_DESTROYED }; + struct hash_table ht; + ht.state = STATE_DESTROYED; ret = hash_table_init(&ht, 20); cr_assert(!ret); /* Insert */ - for (int i = 0; i < ARRAY_LEN(keys); i++) { - ret = hash_table_insert(&ht, keys[i], values[i]); + for (unsigned i = 0; i < ARRAY_LEN(keys); i++) { + ret = hash_table_insert(&ht, keys[i], (void *) values[i]); cr_assert(!ret); } /* Lookup */ - for (int i = 0; i < ARRAY_LEN(keys); i++) { - char *value = hash_table_lookup(&ht, keys[i]); + for (unsigned i = 0; i < ARRAY_LEN(keys); i++) { + char *value = (char *) hash_table_lookup(&ht, keys[i]); cr_assert_eq(values[i], value); } /* Inserting the same key twice should fail */ - ret = hash_table_insert(&ht, keys[0], values[0]); + ret = hash_table_insert(&ht, keys[0], (void *) values[0]); cr_assert(ret); hash_table_dump(&ht); @@ -63,7 +71,7 @@ Test(hash_table, hash_table_lookup) cr_assert(ret); /* After removing, we should be able to insert it again */ - ret = hash_table_insert(&ht, keys[0], values[0]); + ret = hash_table_insert(&ht, keys[0], (void *) values[0]); cr_assert(!ret); ret = hash_table_destroy(&ht, NULL, false); diff --git a/common/tests/hist.c b/common/tests/hist.cpp similarity index 91% rename from common/tests/hist.c rename to common/tests/hist.cpp index a4ecac241..cfbd9d2a6 100644 --- a/common/tests/hist.c +++ b/common/tests/hist.cpp @@ -30,6 +30,13 @@ const double test_data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; /* Histogram of test_data with 200 buckets between -100 and 100 */ const int hist_result[] = {}; +void init_logging(); + +TestSuite(hist, + .description = "Histogram", + .init = init_logging +); + Test(hist, simple) { struct hist h; int ret; @@ -37,7 +44,7 @@ Test(hist, simple) { ret = hist_init(&h, 0, 0); cr_assert_eq(ret, 0); - for (int i = 0; i < ARRAY_LEN(test_data); i++) + for (unsigned i = 0; i < ARRAY_LEN(test_data); i++) hist_put(&h, test_data[i]); cr_assert_float_eq(hist_mean(&h), 5.5, 1e-6); diff --git a/common/tests/kernel.c b/common/tests/kernel.cpp similarity index 91% rename from common/tests/kernel.c rename to common/tests/kernel.cpp index fc9689c69..00ac24eeb 100644 --- a/common/tests/kernel.c +++ b/common/tests/kernel.cpp @@ -25,6 +25,13 @@ #include #include +void init_logging(); + +TestSuite(kernel, + .description = "Kernel features", + .init = init_logging +); + #ifdef __linux__ #if defined(__x86_64__) || defined(__i386__) @@ -77,14 +84,16 @@ Test(kernel, version) int ret; struct version ver; + struct version ver1 = { 100, 5 }; + struct version ver2 = { 2, 6 }; ret = kernel_get_version(&ver); cr_assert_eq(ret, 0); - ret = version_cmp(&ver, &(struct version) { 100, 5 }); + ret = version_cmp(&ver, &ver1); cr_assert_lt(ret, 0); - ret = version_cmp(&ver, &(struct version) { 2, 6 }); + ret = version_cmp(&ver, &ver2); cr_assert_gt(ret, 0); } diff --git a/common/tests/list.c b/common/tests/list.cpp similarity index 76% rename from common/tests/list.c rename to common/tests/list.cpp index 626a8b414..7714d5d6b 100644 --- a/common/tests/list.c +++ b/common/tests/list.cpp @@ -27,21 +27,29 @@ #include #include -static char *nouns[] = { "time", "person", "year", "way", "day", "thing", "man", "world", "life", "hand", "part", "child", "eye", "woman", "place", "work", "week", "case", "point", "government", "company", "number", "group", "problem", "fact" }; +static const char *nouns[] = { "time", "person", "year", "way", "day", "thing", "man", "world", "life", "hand", "part", "child", "eye", "woman", "place", "work", "week", "case", "point", "government", "company", "number", "group", "problem", "fact" }; struct data { - char *tag; + const char *tag; int data; }; +void init_logging(); + +TestSuite(list, + .description = "List datastructure", + .init = init_logging +); + Test(list, list_lookup) { - struct list l = { .state = STATE_DESTROYED }; + struct list l; + l.state = STATE_DESTROYED; list_init(&l); - for (int i = 0; i < ARRAY_LEN(nouns); i++) { - struct data *d = malloc(sizeof(struct data)); + for (unsigned i = 0; i < ARRAY_LEN(nouns); i++) { + struct data *d = new struct data; d->tag = nouns[i]; d->data = i; @@ -49,7 +57,7 @@ Test(list, list_lookup) list_push(&l, d); } - struct data *found = list_lookup(&l, "woman"); + struct data *found = (struct data *) list_lookup(&l, "woman"); cr_assert_eq(found->data, 13); @@ -58,13 +66,14 @@ Test(list, list_lookup) Test(list, list_search) { - struct list l = { .state = STATE_DESTROYED }; + struct list l; + l.state = STATE_DESTROYED; list_init(&l); /* Fill list */ - for (int i = 0; i < ARRAY_LEN(nouns); i++) - list_push(&l, nouns[i]); + for (unsigned i = 0; i < ARRAY_LEN(nouns); i++) + list_push(&l, (void *) nouns[i]); cr_assert_eq(list_length(&l), ARRAY_LEN(nouns)); @@ -72,7 +81,7 @@ Test(list, list_search) char positive[] = "woman"; char negative[] = "dinosaurrier"; - char *found = list_search(&l, (cmp_cb_t) strcmp, positive); + char *found = (char *) list_search(&l, (cmp_cb_t) strcmp, positive); cr_assert_not_null(found); cr_assert_eq(found, nouns[13], "found = %p, nouns[13] = %p", found, nouns[13]); cr_assert_str_eq(found, positive); @@ -98,8 +107,11 @@ static int dtor(void *ptr) Test(list, destructor) { - struct list l = { .state = STATE_DESTROYED }; - struct content elm = { .destroyed = 0 }; + struct list l; + l.state = STATE_DESTROYED; + + struct content elm; + elm.destroyed = 0; list_init(&l); list_push(&l, &elm); @@ -112,14 +124,15 @@ Test(list, destructor) } static int compare(const void *a, const void *b) { - return b - a; + return (intptr_t) b - (intptr_t) a; } Test(list, basics) { intptr_t i; int ret; - struct list l = { .state = STATE_DESTROYED }; + struct list l; + l.state = STATE_DESTROYED; list_init(&l); diff --git a/common/tests/log.c b/common/tests/log.cpp similarity index 78% rename from common/tests/log.c rename to common/tests/log.cpp index 32df36ab8..3f2a47fbf 100644 --- a/common/tests/log.c +++ b/common/tests/log.cpp @@ -27,22 +27,32 @@ #include struct param { - char *expression; + const char *expression; long expected; }; -static struct log l; +static struct log log; + +void init_logging(); static void init() { - log_init(&l, V, LOG_ALL); + log_init(&log, "test_logger", V, LOG_ALL); + + init_logging(); } static void fini() { - log_destroy(&l); + log_destroy(&log); } +TestSuite(log, + .description = "Log system", + .init = init, + .fini = fini +); + ParameterizedTestParameters(log, facility_expression) { static struct param params[] = { @@ -59,9 +69,9 @@ ParameterizedTestParameters(log, facility_expression) return cr_make_param_array(struct param, params, ARRAY_LEN(params)); } -ParameterizedTest(struct param *p, log, facility_expression, .init = init, .fini = fini) +ParameterizedTest(struct param *p, log, facility_expression) { - log_set_facility_expression(&l, p->expression); + log_set_facility_expression(&log, p->expression); - cr_assert_eq(l.facilities, p->expected, "log.faciltities is %#lx not %#lx", l.facilities, p->expected); + cr_assert_eq(log.facilities, p->expected, "log.faciltities is %#lx not %#lx", log.facilities, p->expected); } diff --git a/common/tests/logging.cpp b/common/tests/logging.cpp index 12dc144dc..f8cb8b23e 100644 --- a/common/tests/logging.cpp +++ b/common/tests/logging.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -36,6 +37,8 @@ extern "C" { void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list args); } +static const char *color_reset = "\e[0m"; + struct criterion_prefix_data { const char *prefix; const char *color; @@ -58,10 +61,6 @@ void criterion_log_noformat(enum criterion_severity severity, const char *msg) auto logger = loggerGetOrCreate("criterion"); switch (severity) { - case CR_LOG_INFO: - logger->info(msg); - break; - case CR_LOG_WARNING: logger->warn(msg); break; @@ -69,57 +68,102 @@ void criterion_log_noformat(enum criterion_severity severity, const char *msg) case CR_LOG_ERROR: logger->error(msg); break; - } + + case CR_LOG_INFO: + default: + logger->info(msg); + break; } } -void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list args) +void criterion_vlog(enum criterion_logging_level /* level */, const char *msg, va_list args) { char formatted_msg[1024]; - if (level < criterion_options.logging_threshold) - return; + //if (level < criterion_options.logging_threshold) + // return; format_msg(formatted_msg, sizeof(formatted_msg), msg, args); - auto logger = loggerGetOrCreate("criterion"); + auto logger = loggerGetOrCreate("tests"); logger->info(formatted_msg); } -void criterion_plog(enum criterion_logging_level level, const struct criterion_prefix_data *prefix, const char *msg, ...) +void criterion_plog(enum criterion_logging_level /* level */, const struct criterion_prefix_data *prefix, const char *msg, ...) { char formatted_msg[1024]; va_list args; - if (level < criterion_options.logging_threshold) - return; + //if (level < criterion_options.logging_threshold) + // return; va_start(args, msg); format_msg(formatted_msg, sizeof(formatted_msg), msg, args); va_end(args); - auto logger = loggerGetOrCreate("criterion"); + auto logger = loggerGetOrCreate("tests"); - if (strstr(formatted_msg, "Warning")) - logger->warn(formatted_msg); - else if (strstr(formatted_msg, "Failed")) - logger->error(formatted_msg); - else if(!strcmp(prefix->prefix, "----") && !strcmp(prefix->color, "\33[0;34m")) - logger->info(formatted_msg); + if (!strcmp(prefix->prefix, "----") && !strcmp(prefix->color, "\33[0;34m")) + logger->info(formatted_msg); else if (!strcmp(prefix->prefix, "----") && !strcmp(prefix->color, "\33[1;30m")) logger->debug(formatted_msg); else if (!strcmp(prefix->prefix, "====")) logger->info(formatted_msg); - else if (!strcmp(prefix->prefix, "RUN ")) - logger->info("Run: {}", formatted_msg); - else if (!strcmp(prefix->prefix, "SKIP")) - logger->info("Skip: {}", formatted_msg); - else if (!strcmp(prefix->prefix, "PASS")) - logger->info("Pass: {}", formatted_msg); - else if (!strcmp(prefix->prefix, "FAIL")) - logger->error("Fail: {}", formatted_msg); - else if (!strcmp(prefix->prefix, "WARN")) + else if (!strcmp(prefix->prefix, "WARN") || strstr(formatted_msg, "Warning")) logger->warn(formatted_msg); - else if (!strcmp(prefix->prefix, "ERR ")) + else if (!strcmp(prefix->prefix, "ERR ") || strstr(formatted_msg, "Failed")) logger->error(formatted_msg); + else if (!strcmp(prefix->prefix, "RUN ")) + logger->info("{}Run:{} {}", prefix->color, color_reset, formatted_msg); + else if (!strcmp(prefix->prefix, "SKIP")) + logger->info("{}Skip:{} {}", prefix->color, color_reset, formatted_msg); + else if (!strcmp(prefix->prefix, "PASS")) + logger->info("{}Pass:{} {}", prefix->color, color_reset, formatted_msg); + else if (!strcmp(prefix->prefix, "FAIL")) + logger->error("{}Fail:{} {}", prefix->color, color_reset, formatted_msg); + else + logger->info(formatted_msg); +} + +extern "C" +void log_cb(struct log *l, enum log_level lvl, const char *fmt, va_list args) +{ + char formatted_msg[1024]; + + auto logger = loggerGetOrCreate(l->name); + + //if (level < criterion_options.logging_threshold) + // return; + + format_msg(formatted_msg, sizeof(formatted_msg), fmt, args); + + switch (lvl) { + case LOG_LVL_DEBUG: + logger->debug(formatted_msg); + break; + + case LOG_LVL_INFO: + logger->info(formatted_msg); + break; + + case LOG_LVL_WARN: + logger->warn(formatted_msg); + break; + + case LOG_LVL_ERROR: + logger->error(formatted_msg); + break; + + case LOG_LVL_STATS: + logger->info("Stats: {}", formatted_msg); + break; + } +} + +void init_logging() +{ + log_set_callback(global_log, log_cb); + + spdlog::set_level(spdlog::level::trace); + spdlog::set_pattern("[%T] [%^%l%$] [%n] %v"); } diff --git a/common/tests/main.cpp b/common/tests/main.cpp index 3f7b8ea27..ea1e4ae78 100644 --- a/common/tests/main.cpp +++ b/common/tests/main.cpp @@ -27,12 +27,13 @@ #include +void init_logging(); + int main(int argc, char *argv[]) { int ret; - spdlog::set_level(spdlog::level::debug); - spdlog::set_pattern("[%T] [%l] [%n] %v"); + init_logging(); /* Run criterion tests */ auto tests = criterion_initialize(); diff --git a/common/tests/task.c b/common/tests/task.cpp similarity index 95% rename from common/tests/task.c rename to common/tests/task.cpp index 547303196..f74059127 100644 --- a/common/tests/task.c +++ b/common/tests/task.cpp @@ -27,6 +27,13 @@ #include #include +void init_logging(); + +TestSuite(task, + .description = "Periodic timer tasks", + .init = init_logging +); + Test(task, rate, .timeout = 10) { int ret; diff --git a/common/tests/timing.c b/common/tests/timing.cpp similarity index 96% rename from common/tests/timing.c rename to common/tests/timing.cpp index 7ac3c8f4e..ff860b9d7 100644 --- a/common/tests/timing.c +++ b/common/tests/timing.cpp @@ -26,6 +26,13 @@ #include +void init_logging(); + +TestSuite(timing, + .description = "Time measurements", + .init = init_logging +); + Test(timing, time_now) { struct timespec now1 = time_now(); diff --git a/common/tests/tsc.c b/common/tests/tsc.cpp similarity index 89% rename from common/tests/tsc.c rename to common/tests/tsc.cpp index 2e843b231..771cc8e78 100644 --- a/common/tests/tsc.c +++ b/common/tests/tsc.cpp @@ -28,6 +28,13 @@ #define CNT (1 << 18) +void init_logging(); + +TestSuite(tsc, + .description = "Timestamp counters", + .init = init_logging +); + Test(tsc, increasing) { int ret; @@ -37,16 +44,16 @@ Test(tsc, increasing) ret = tsc_init(&tsc); cr_assert_eq(ret, 0); - cntrs = alloc(sizeof(uint64_t) * CNT); + cntrs = new uint64_t[CNT]; cr_assert_not_null(cntrs); - for (int i = 0; i < CNT; i++) + for (unsigned i = 0; i < CNT; i++) cntrs[i] = tsc_now(&tsc); - for (int i = 1; i < CNT; i++) + for (unsigned i = 1; i < CNT; i++) cr_assert_lt(cntrs[i-1], cntrs[i]); - free(cntrs); + delete cntrs; } Test(tsc, sleep) diff --git a/common/tests/utils.c b/common/tests/utils.cpp similarity index 95% rename from common/tests/utils.c rename to common/tests/utils.cpp index ed06c86b3..f8cb80f9d 100644 --- a/common/tests/utils.c +++ b/common/tests/utils.cpp @@ -25,6 +25,13 @@ #include #include +void init_logging(); + +TestSuite(utils, + .description = "Utilities", + .init = init_logging +); + /* Simple normality test for 1,2,3s intervals */ Test(utils, box_muller) { @@ -32,7 +39,7 @@ Test(utils, box_muller) unsigned sigma[3] = { 0 }; unsigned iter = 1000000; - for (int i = 0; i < iter; i++) { + for (unsigned i = 0; i < iter; i++) { n = box_muller(0, 1); if (n > 2 || n < -2) sigma[2]++; @@ -89,7 +96,7 @@ Test(utils, memdup) len = read_random(orig, sizeof(orig)); cr_assert_eq(len, sizeof(orig)); - copy = memdup(orig, sizeof(orig)); + copy = (char *) memdup(orig, sizeof(orig)); cr_assert_not_null(copy); cr_assert_arr_eq(copy, orig, sizeof(orig)); @@ -133,7 +140,7 @@ Test(utils, strf) { char *buf = NULL; - buf = strf("Hallo %s", "Steffen."); + buf = strcatf(&buf, "Hallo %s", "Steffen."); cr_assert_str_eq(buf, "Hallo Steffen."); strcatf(&buf, " Its Monday %uth %s %u.", 13, "August", 2018);