X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/04ad4b7ab779a793f594e0910632f12a511d419a..30cf990a90d000d80bf21cc1b886e3eb01553a5d:/src/xbt/cunit.cpp diff --git a/src/xbt/cunit.cpp b/src/xbt/cunit.cpp index 94e16a6638..70090dc90f 100644 --- a/src/xbt/cunit.cpp +++ b/src/xbt/cunit.cpp @@ -1,7 +1,6 @@ /* cunit - A little C Unit facility */ -/* Copyright (c) 2005-2014. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2005-2017. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,13 +9,20 @@ /* At some point we should use https://github.com/google/googletest instead */ #include "src/internal_config.h" -#include +#include +#include +#include +#include +#include #include +#include + #include "xbt/sysdep.h" /* bvprintf */ -#include "xbt/cunit.h" #include "xbt/dynar.h" +#define STRLEN 1024 + /* collection of all suites */ static xbt_dynar_t _xbt_test_suites = nullptr; /* global statistics */ @@ -39,42 +45,48 @@ static int _xbt_test_suite_disabled = 0; xbt_test_unit_t _xbt_test_current_unit = nullptr; /* test suite test log */ -typedef struct s_xbt_test_log { - char *text; - const char *file; - int line; -} *xbt_test_log_t; +class s_xbt_test_log { +public: + s_xbt_test_log(std::string text, std::string file, int line) + : text_(std::move(text)), file_(std::move(file)), line_(line) + { + } + void dump() const; + + std::string text_; + std::string file_; + int line_; +}; -static void xbt_test_log_dump(xbt_test_log_t log) +void s_xbt_test_log::dump() const { - if (log) - fprintf(stderr, " log %p(%s:%d)=%s\n", log, log->file, log->line, log->text); - else - fprintf(stderr, " log=nullptr\n"); + fprintf(stderr, " log %p(%s:%d)=%s\n", this, this->file_.c_str(), this->line_, this->text_.c_str()); } /* test suite test check */ -typedef struct s_xbt_test_test { - char *title; - int failed; - int expected_failure; - int ignored; - const char *file; - int line; - xbt_dynar_t logs; -} *xbt_test_test_t; +class s_xbt_test_test { +public: + s_xbt_test_test(std::string title, std::string file, int line) + : title_(std::move(title)), file_(std::move(file)), line_(line) + { + } + void dump() const; + + std::string title_; + bool failed_ = false; + bool expected_failure_ = false; + bool ignored_ = false; + std::string file_; + int line_; + std::vector logs_; +}; -static void xbt_test_test_dump(xbt_test_test_t test) +void s_xbt_test_test::dump() const { - if (test) { - xbt_test_log_t log; - unsigned int it_log; - fprintf(stderr, " test %p(%s:%d)=%s (%s)\n", test, test->file, test->line, test->title, - test->failed ? "failed" : "not failed"); - xbt_dynar_foreach(test->logs, it_log, log) - xbt_test_log_dump(log); - } else - fprintf(stderr, " test=nullptr\n"); + fprintf(stderr, " test %p(%s:%d)=%s (%s)\n", this, this->file_.c_str(), this->line_, this->title_.c_str(), + this->failed_ ? "failed" : "not failed"); + for (s_xbt_test_log const& log : this->logs_) + log.dump(); } /* test suite test unit */ @@ -85,7 +97,7 @@ struct s_xbt_test_unit { ts_test_cb_t func; const char *file; int line; - xbt_dynar_t tests; /* of xbt_test_test_t */ + std::vector tests; int nb_tests; int test_failed; @@ -96,12 +108,11 @@ struct s_xbt_test_unit { static void xbt_test_unit_dump(xbt_test_unit_t unit) { if (unit) { - xbt_test_test_t test; - unsigned int it_test; fprintf(stderr, " UNIT %s: %s (%s)\n", unit->name, unit->title, (unit->enabled ? "enabled" : "disabled")); - if (unit->enabled) - xbt_dynar_foreach(unit->tests, it_test, test) - xbt_test_test_dump(test); + if (unit->enabled) { + for (s_xbt_test_test const& test : unit->tests) + test.dump(); + } } else { fprintf(stderr, " unit=nullptr\n"); } @@ -140,40 +151,30 @@ static void xbt_test_unit_free(void *unit) { xbt_test_unit_t u = *(xbt_test_unit_t *) unit; /* name is static */ - free(u->title); - xbt_dynar_free(&u->tests); - free(u); + xbt_free(u->title); + delete u; } -static void xbt_test_test_free(void *test) -{ - xbt_test_test_t t = *(xbt_test_test_t *) test; - free(t->title); - xbt_dynar_free(&(t->logs)); - free(t); -} - -static void xbt_test_log_free(void *log) -{ - xbt_test_log_t l = *(xbt_test_log_t *) log; - free(l->text); - free(l); -} - -/** @brief create test suite */ -xbt_test_suite_t xbt_test_suite_new(const char *name, const char *fmt, ...) +/** @brief retrieve a testsuite from name, or create a new one */ +xbt_test_suite_t xbt_test_suite_by_name(const char *name, const char *fmt, ...) { - xbt_test_suite_t suite = xbt_new0(struct s_xbt_test_suite, 1); - va_list ap; - - if (!_xbt_test_suites) + if (_xbt_test_suites == nullptr) { _xbt_test_suites = xbt_dynar_new(sizeof(xbt_test_suite_t), xbt_test_suite_free); + } else { + xbt_test_suite_t suite; + unsigned int it_suite; + xbt_dynar_foreach(_xbt_test_suites, it_suite, suite) + if (not strcmp(suite->name, name)) + return suite; + } + xbt_test_suite_t suite = xbt_new0(s_xbt_test_suite, 1); + va_list ap; va_start(ap, fmt); suite->title = bvprintf(fmt, ap); suite->units = xbt_dynar_new(sizeof(xbt_test_unit_t), &xbt_test_unit_free); va_end(ap); - suite->name = name; + suite->name = name; suite->enabled = 1; xbt_dynar_push(_xbt_test_suites, &suite); @@ -181,40 +182,18 @@ xbt_test_suite_t xbt_test_suite_new(const char *name, const char *fmt, ...) return suite; } -/** @brief retrieve a testsuite from name, or create a new one */ -xbt_test_suite_t xbt_test_suite_by_name(const char *name, const char *fmt, ...) -{ - xbt_test_suite_t suite; - unsigned int it_suite; - - char *bufname; - va_list ap; - - if (_xbt_test_suites) - xbt_dynar_foreach(_xbt_test_suites, it_suite, suite) - if (!strcmp(suite->name, name)) - return suite; - - va_start(ap, fmt); - bufname = bvprintf(fmt, ap); - va_end(ap); - suite = xbt_test_suite_new(name, bufname, nullptr); - free(bufname); - - return suite; -} - -void xbt_test_suite_dump(xbt_test_suite_t suite) +static void xbt_test_suite_dump(xbt_test_suite_t suite) { if (suite) { - xbt_test_unit_t unit; - unsigned int it_unit; fprintf(stderr, "TESTSUITE %s: %s (%s)\n", suite->name, suite->title, suite->enabled ? "enabled" : "disabled"); - if (suite->enabled) + if (suite->enabled) { + xbt_test_unit_t unit; + unsigned int it_unit; xbt_dynar_foreach(suite->units, it_unit, unit) xbt_test_unit_dump(unit); + } } else { - fprintf(stderr, "TESTSUITE IS nullptr!\n"); + fprintf(stderr, "TESTSUITE IS NULL!\n"); } } @@ -228,7 +207,7 @@ void xbt_test_suite_push(xbt_test_suite_t suite, const char *name, ts_test_cb_t xbt_assert(func); xbt_assert(fmt); - unit = xbt_new0(struct s_xbt_test_unit, 1); + unit = xbt_new0(s_xbt_test_unit, 1); va_start(ap, fmt); unit->title = bvprintf(fmt, ap); va_end(ap); @@ -237,7 +216,6 @@ void xbt_test_suite_push(xbt_test_suite_t suite, const char *name, ts_test_cb_t unit->file = nullptr; unit->line = 0; unit->enabled = 1; - unit->tests = xbt_dynar_new(sizeof(xbt_test_test_t), xbt_test_test_free); xbt_dynar_push(suite->units, &unit); } @@ -246,17 +224,6 @@ void xbt_test_suite_push(xbt_test_suite_t suite, const char *name, ts_test_cb_t static int xbt_test_suite_run(xbt_test_suite_t suite, int verbosity) { xbt_test_unit_t unit; - xbt_test_test_t test; - xbt_test_log_t log; - - const char *file; - int line; - char *cp; - unsigned int it_unit; - unsigned int it_test; - unsigned int it_log; - - int first = 1; /* for result pretty printing */ if (suite == nullptr) return 0; @@ -275,12 +242,13 @@ static int xbt_test_suite_run(xbt_test_suite_t suite, int verbosity) snprintf(suite_title + 40 - (suite_len + 4) / 2, 81 - (40 - (suite_len + 4) / 2), "[ %s ]", suite->title); suite_title[40 + (suite_len + 5) / 2] = '='; - if (!suite->enabled) + if (not suite->enabled) snprintf(suite_title + 70, 11, " DISABLED "); fprintf(stderr, "\n%s\n", suite_title); if (suite->enabled) { /* iterate through all tests */ + unsigned int it_unit; xbt_dynar_foreach(suite->units, it_unit, unit) { /* init unit case counters */ unit->nb_tests = 0; @@ -289,8 +257,9 @@ static int xbt_test_suite_run(xbt_test_suite_t suite, int verbosity) unit->test_expect = 0; /* display unit title */ - cp = bprintf(" Unit: %s ......................................" - "......................................", unit->title); + char* cp = bprintf(" Unit: %s ......................................" + "......................................", + unit->title); cp[70] = '\0'; fprintf(stderr, "%s", cp); free(cp); @@ -301,17 +270,15 @@ static int xbt_test_suite_run(xbt_test_suite_t suite, int verbosity) unit->func(); /* iterate through all performed tests to determine status */ - xbt_dynar_foreach(unit->tests, it_test, test) { - if (test->ignored) { + for (s_xbt_test_test const& test : unit->tests) { + if (test.ignored_) { unit->test_ignore++; } else { unit->nb_tests++; - if (test->failed && !test->expected_failure) + if ((test.failed_ && not test.expected_failure_) || (not test.failed_ && test.expected_failure_)) unit->test_failed++; - if (!test->failed && test->expected_failure) - unit->test_failed++; - if (test->expected_failure) + if (test.expected_failure_) unit->test_expect++; } } @@ -325,30 +292,30 @@ static int xbt_test_suite_run(xbt_test_suite_t suite, int verbosity) } else { fprintf(stderr, ".... skip\n"); /* shouldn't happen, but I'm a bit lost with this logic */ } - xbt_dynar_foreach(unit->tests, it_test, test) { - file = (test->file != nullptr ? test->file : unit->file); - line = (test->line != 0 ? test->line : unit->line); + for (s_xbt_test_test const& test : unit->tests) { + std::string file = (test.file_.empty() ? unit->file : test.file_); + int line = (test.line_ == 0 ? unit->line : test.line_); const char* resname; - if (test->ignored) + if (test.ignored_) resname = " SKIP"; - else if (test->expected_failure) { - if (test->failed) + else if (test.expected_failure_) { + if (test.failed_) resname = "EFAIL"; else resname = "EPASS"; } else { - if (test->failed) + if (test.failed_) resname = " FAIL"; else resname = " PASS"; } - fprintf(stderr, " %s: %s [%s:%d]\n", resname, test->title, file, line); + fprintf(stderr, " %s: %s [%s:%d]\n", resname, test.title_.c_str(), file.c_str(), line); - if ((test->expected_failure && !test->failed) || (!test->expected_failure && test->failed)) { - xbt_dynar_foreach(test->logs, it_log, log) { - file = (log->file != nullptr ? log->file : file); - line = (log->line != 0 ? log->line : line); - fprintf(stderr, " %s:%d: %s\n", file, line, log->text); + if ((test.expected_failure_ && not test.failed_) || (not test.expected_failure_ && test.failed_)) { + for (s_xbt_test_log const& log : test.logs_) { + file = (log.file_.empty() ? file : log.file_); + line = (log.line_ == 0 ? line : log.line_); + fprintf(stderr, " %s:%d: %s\n", file.c_str(), line, log.text_.c_str()); } } } @@ -358,7 +325,7 @@ static int xbt_test_suite_run(xbt_test_suite_t suite, int verbosity) } else { fprintf(stderr, "\n"); } - } else if (!unit->enabled) { + } else if (not unit->enabled) { fprintf(stderr, " disabled\n"); /* no test were run */ } else if (unit->nb_tests) { fprintf(stderr, "...... ok\n"); /* successful */ @@ -382,7 +349,7 @@ static int xbt_test_suite_run(xbt_test_suite_t suite, int verbosity) suite->nb_units++; if (unit->test_failed) suite->unit_failed++; - } else if (!unit->enabled) { + } else if (not unit->enabled) { suite->unit_disabled++; } else { suite->unit_ignore++; @@ -398,7 +365,7 @@ static int xbt_test_suite_run(xbt_test_suite_t suite, int verbosity) _xbt_test_nb_suites++; if (suite->test_failed) _xbt_test_suite_failed++; - } else if (!suite->enabled) { + } else if (not suite->enabled) { _xbt_test_suite_disabled++; } else { _xbt_test_suite_ignore++; @@ -406,6 +373,8 @@ static int xbt_test_suite_run(xbt_test_suite_t suite, int verbosity) /* print test suite summary */ if (suite->enabled) { + int first = 1; /* for result pretty printing */ + fprintf(stderr," =====================================================================%s\n", (suite->nb_units ? (suite->unit_failed ? "== FAILED" : "====== OK") : (suite->unit_disabled ? " DISABLED" : "==== SKIP"))); @@ -456,32 +425,29 @@ static void apply_selection(char *selection) /* for the parsing */ char *sel = selection; int done = 0; - char dir[1024]; /* the directive */ + char dir[STRLEN]; /* the directive */ /* iterators */ unsigned int it_suite; xbt_test_suite_t suite; xbt_test_unit_t unit; unsigned int it_unit; - char suitename[512]; - char unitname[512]; + char suitename[STRLEN]; + char unitname[STRLEN]; - if (!selection || selection[0] == '\0') + if (not selection || selection[0] == '\0') return; - /*printf("Test selection: %s\n", selection); */ - /* First apply the selection */ - while (!done) { + while (not done) { int enabling = 1; char *p = strchr(sel, ','); if (p) { - strncpy(dir, sel, p - sel); - dir[p - sel] = '\0'; + snprintf(dir, STRLEN, "%.*s", (int)(p - sel), sel); sel = p + 1; } else { - strncpy(dir, sel,1024); + snprintf(dir, STRLEN, "%s", sel); done = 1; } @@ -496,16 +462,15 @@ static void apply_selection(char *selection) p = strchr(dir, ':'); if (p) { - strncpy(unitname, p + 1,512); - strncpy(suitename, dir, p - dir); - suitename[p - dir] = '\0'; + snprintf(suitename, STRLEN, "%.*s", (int)(p - dir), dir); + snprintf(unitname, STRLEN, "%s", p + 1); } else { - strncpy(suitename, dir,512); + snprintf(suitename, STRLEN, "%s", dir); unitname[0] = '\0'; } /* Deal with the specific case of 'all' pseudo serie */ - if (!strcmp("all", suitename)) { + if (not strcmp("all", suitename)) { xbt_assert(unitname[0] == '\0', "The 'all' pseudo-suite does not accept any unit specification\n"); xbt_dynar_foreach(_xbt_test_suites, it_suite, suite) { @@ -519,7 +484,7 @@ static void apply_selection(char *selection) for (it = 0; it < xbt_dynar_length(_xbt_test_suites); it++) { xbt_test_suite_t thissuite = xbt_dynar_get_as(_xbt_test_suites, it, xbt_test_suite_t); - if (!strcmp(suitename, thissuite->name)) { + if (not strcmp(suitename, thissuite->name)) { /* Do not disable the whole suite when we just want to disable a child */ if (enabling || (unitname[0] == '\0')) thissuite->enabled = enabling; @@ -535,7 +500,7 @@ static void apply_selection(char *selection) it2_unit < xbt_dynar_length(thissuite->units); it2_unit++) { xbt_test_unit_t thisunit = xbt_dynar_get_as(thissuite->units, it2_unit, xbt_test_unit_t); - if (!strcmp(thisunit->name, unitname)) { + if (not strcmp(thisunit->name, unitname)) { thisunit->enabled = enabling; break; } @@ -650,17 +615,9 @@ void _xbt_test_add(const char *file, int line, const char *fmt, ...) xbt_assert(unit); va_list ap; - xbt_test_test_t test = xbt_new0(struct s_xbt_test_test, 1); va_start(ap, fmt); - test->title = bvprintf(fmt, ap); + unit->tests.emplace_back(simgrid::xbt::string_vprintf(fmt, ap), file, line); va_end(ap); - test->failed = 0; - test->expected_failure = 0; - test->ignored = 0; - test->file = file; - test->line = line; - test->logs = xbt_dynar_new(sizeof(xbt_test_log_t), xbt_test_log_free); - xbt_dynar_push(unit->tests, &test); } /* annotate test case with log message and failure */ @@ -668,21 +625,16 @@ void _xbt_test_fail(const char *file, int line, const char *fmt, ...) { xbt_test_unit_t unit = _xbt_test_current_unit; xbt_assert(unit); - xbt_assert(xbt_dynar_length(_xbt_test_current_unit->tests), - "Test failed even before being declared (broken unit: %s)", unit->title); + xbt_assert(not _xbt_test_current_unit->tests.empty(), "Test failed even before being declared (broken unit: %s)", + unit->title); + s_xbt_test_test& test = unit->tests.back(); va_list ap; - xbt_test_log_t log = xbt_new(struct s_xbt_test_log, 1); va_start(ap, fmt); - log->text = bvprintf(fmt, ap); + test.logs_.emplace_back(simgrid::xbt::string_vprintf(fmt, ap), file, line); va_end(ap); - log->file = file; - log->line = line; - - xbt_test_test_t test = xbt_dynar_getlast_as(unit->tests, xbt_test_test_t); - xbt_dynar_push(test->logs, &log); - test->failed = 1; + test.failed_ = true; } void xbt_test_exception(xbt_ex_t e) @@ -692,18 +644,17 @@ void xbt_test_exception(xbt_ex_t e) void xbt_test_expect_failure() { - xbt_assert(xbt_dynar_length(_xbt_test_current_unit->tests), - "Cannot expect the failure of a test before declaring it (broken unit: %s)", _xbt_test_current_unit->title); - xbt_test_test_t test = xbt_dynar_getlast_as(_xbt_test_current_unit->tests, xbt_test_test_t); - test->expected_failure = 1; + xbt_assert(not _xbt_test_current_unit->tests.empty(), + "Cannot expect the failure of a test before declaring it (broken unit: %s)", + _xbt_test_current_unit->title); + _xbt_test_current_unit->tests.back().expected_failure_ = true; } void xbt_test_skip() { - xbt_assert(xbt_dynar_length(_xbt_test_current_unit->tests), - "Test skipped even before being declared (broken unit: %s)", _xbt_test_current_unit->title); - xbt_test_test_t test = xbt_dynar_getlast_as(_xbt_test_current_unit->tests, xbt_test_test_t); - test->ignored = 1; + xbt_assert(not _xbt_test_current_unit->tests.empty(), "Test skipped even before being declared (broken unit: %s)", + _xbt_test_current_unit->title); + _xbt_test_current_unit->tests.back().ignored_ = true; } /* annotate test case with log message only */ @@ -711,19 +662,13 @@ void _xbt_test_log(const char *file, int line, const char *fmt, ...) { xbt_test_unit_t unit = _xbt_test_current_unit; xbt_assert(unit); - xbt_assert(xbt_dynar_length(_xbt_test_current_unit->tests), - "Test logged into even before being declared (broken test unit: %s)", unit->title); + xbt_assert(not _xbt_test_current_unit->tests.empty(), + "Test logged into even before being declared (broken test unit: %s)", unit->title); va_list ap; - xbt_test_log_t log = xbt_new(struct s_xbt_test_log, 1); va_start(ap, fmt); - log->text = bvprintf(fmt, ap); + unit->tests.back().logs_.emplace_back(simgrid::xbt::string_vprintf(fmt, ap), file, line); va_end(ap); - log->file = file; - log->line = line; - - xbt_test_test_t test = xbt_dynar_getlast_as(unit->tests, xbt_test_test_t); - xbt_dynar_push(test->logs, &log); } #ifdef SIMGRID_TEST