From c6fde023a12428762790a74a09a715ec16439d84 Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Fri, 1 Feb 2019 15:03:47 +0100 Subject: [PATCH] RIP cunit. --- CMakeLists.txt | 1 - ChangeLog | 1 + doc/doxygen/inside_doxygen.doc | 8 +- doc/doxygen/inside_tests.doc | 112 +----- doc/doxygen/module-xbt.doc | 2 - include/xbt.h | 1 - include/xbt/cunit.h | 141 ------- src/xbt/cunit.cpp | 630 ------------------------------- tools/CMakeLists.txt | 1 - tools/cmake/DefinePackages.cmake | 3 - tools/cmake/Distrib.cmake | 9 - tools/cmake/UnitTesting.cmake | 43 --- tools/sg_unit_extractor.pl | 291 -------------- 13 files changed, 9 insertions(+), 1234 deletions(-) delete mode 100644 include/xbt/cunit.h delete mode 100644 src/xbt/cunit.cpp delete mode 100644 tools/cmake/UnitTesting.cmake delete mode 100755 tools/sg_unit_extractor.pl diff --git a/CMakeLists.txt b/CMakeLists.txt index f9f8356ef6..681c4cf74c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -752,7 +752,6 @@ add_custom_target(tests COMMENT "Recompiling the tests") ### Build some Maintainer files include(${CMAKE_HOME_DIRECTORY}/tools/cmake/MaintainerMode.cmake) -include(${CMAKE_HOME_DIRECTORY}/tools/cmake/UnitTesting.cmake) ### Make Libs if(NOT WIN32) diff --git a/ChangeLog b/ChangeLog index 01754c7796..5b8e53a061 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,6 +29,7 @@ XBT: -fsplit-stack is the way to go nowadays when using threads. - Drop the xbt_os_thread_t module (now unused) - Drop xbt_ex_display(), use simgrid::xbt::log_exception() instead. + - Drop cunit, use Catch2 instead. Fixed bugs: - #261: Document the parameters of parallel execution's constructor diff --git a/doc/doxygen/inside_doxygen.doc b/doc/doxygen/inside_doxygen.doc index 2f6f6e8ca2..eec1065d69 100644 --- a/doc/doxygen/inside_doxygen.doc +++ b/doc/doxygen/inside_doxygen.doc @@ -32,17 +32,17 @@ needed in this file: your sub-module there. For that, simply add something like the following. The dash (-) will help building item lists. The ref command requests for a link to your module, that is identified - with the word after that (here, I used xbt_cunit as a sub-module + with the word after that (here, I used XBT_str as a sub-module identifier. @verbatim - - @ref XBT_cunit + - @ref XBT_str @endverbatim @li Create your module below in the file as follows. the first world after the defgroup keyword must be the sub-module identifier you used above. @verbatim - /** @defgroup XBT_cunit Unit testing support */ + /** @defgroup XBT_str String related functions */ @endverbatim Warning, the location of this block decides where it appears in the documentation. In particular, the order of the defgroups is not @@ -54,7 +54,7 @@ Once your group is created and referenced from the group containing it, you must populate it. For that, edit the corresponding header file to add something like this near the top. @verbatim -/** @addtogroup XBT_cunit +/** @addtogroup XBT_str * @brief * * diff --git a/doc/doxygen/inside_tests.doc b/doc/doxygen/inside_tests.doc index 48756cc8d5..bbbd49727d 100644 --- a/doc/doxygen/inside_tests.doc +++ b/doc/doxygen/inside_tests.doc @@ -41,17 +41,13 @@ ctest -R msg- -j5 --output-on-failure # You changed MSG and want to check that y @section inside_tests_rununit Running the unit tests -All unit tests are packed into the testall binary, that lives at the +All unit tests are packed into the unit-tests binary, that lives at the source root. These tests are run when you launch ctest, don't worry. @verbatim -make testall # Rebuild the test runner on need -./testall # Launch all tests -./testall --help # revise how it goes if you forgot -./testall --tests=-all # run no test at all (yeah, that's useless) -./testall --dump-only # Display all existing test suites -./testall --tests=-all,+dict # Only launch the tests from the dict test suite -./testall --tests=-all,+foo:bar # run only the bar test from the foo suite. +make unit-tests # Rebuild the test runner on need +./unit-tests # Launch all tests +./unit-tests --help # revise how it goes if you forgot @endverbatim @@ -60,106 +56,6 @@ make testall # Rebuild the test runner on need @warning this section is outdated. New unit tests should be written using the Catch2 library, that is included in the source tree. Please check for examples, listed at the end of tools/cmake/Tests.cmake. -STOP USING XBT. - -If you want to test a specific function or set of functions, you need -a unit test. Edit the file tools/cmake/UnitTesting.cmake to -add your source file to the FILES_CONTAINING_UNITTESTS list. For -example, if you want to create unit tests in the file src/xbt/plouf.c, -your changes should look like that: - -@verbatim ---- a/tools/cmake/UnitTesting.cmake -+++ b/tools/cmake/UnitTesting.cmake -@@ -11,6 +11,7 @@ set(FILES_CONTAINING_UNITTESTS - src/xbt/xbt_sha.c - src/xbt/config.c -+ src/xbt/plouf.c - ) - - if(SIMGRID_HAVE_MC) -@endverbatim - -Then, you want to actually add your tests in the source file. All the -tests must be protected by "#ifdef SIMGRID_TEST" so that they don't -get included in the regular build. The line SIMGRID_TEST must also be -written on the endif line for the extraction script to work properly. - -Tests are subdivided in three levels. The top-level, called test -suite, is created with the macro #XBT_TEST_SUITE. There can be -only one suite per source file. A suite contains test units -that you create with the #XBT_TEST_UNIT macro. Finally, you start -actual tests with #xbt_test_add. There is no closing marker of -any sort, and an unit is closed when the next unit starts, or when the -end of file is reached. - -Once a given test is started with #xbt_test_add, you use -#xbt_test_assert to specify that it was actually an assert, or -#xbt_test_fail to specify that it failed (if your test cannot easily -be written as an assert). #xbt_test_exception can be used to report -that it failed with an exception. There is nothing to do to report -that a given test succeeded, just start the next test without -reporting any issue. Finally, #xbt_test_log can be used to report -intermediate steps. The messages will be shown only if the -corresponding test fails. - -Here is a recaping example, inspired from src/xbt/dynar.h (see that -file for details). -@code -/* The rest of your module implementation */ - -#ifdef SIMGRID_TEST - -XBT_TEST_SUITE("dynar", "Dynar data container"); -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(xbt_dyn); // Just the regular logging stuff - -XBT_TEST_UNIT("int", test_dynar_int, "Dynars of integers") -{ - int i, cpt; - unsigned int cursor; - - xbt_test_add("==== Traverse the empty dynar"); - xbt_dynar_t d = xbt_dynar_new(sizeof(int), NULL); - xbt_dynar_foreach(d, cursor, i) { - xbt_test_fail( "Damnit, there is something in the empty dynar"); - } - xbt_dynar_free(&d); - - xbt_test_add("==== Push %d int and re-read them", NB_ELEM); - d = xbt_dynar_new(sizeof(int), NULL); - for (cpt = 0; cpt < NB_ELEM; cpt++) { - xbt_test_log("Push %d, length=%lu", cpt, xbt_dynar_length(d)); - xbt_dynar_push_as(d, int, cpt); - } - - for (cursor = 0; cursor < NB_ELEM; cursor++) { - int *iptr = xbt_dynar_get_ptr(d, cursor); - xbt_test_assert(cursor == *iptr, - "The retrieved value is not the same than the injected one (%u!=%d)",cursor, cpt); - } - - xbt_test_add("==== Check the size of that %d-long dynar", NB_ELEM); - xbt_test_assert(xbt_dynar_size(d) == NB_ELEM); - xbt_dynar_free(&d); -} - -XBT_TEST_UNIT("insert",test_dynar_insert,"Using the xbt_dynar_insert and xbt_dynar_remove functions") -{ - xbt_dynar_t d = xbt_dynar_new(sizeof(unsigned int), NULL); - unsigned int cursor; - int cpt; - - xbt_test_add("==== Insert %d int, traverse them, remove them",NB_ELEM); - // BLA BLA BLA -} - -#endif /* SIMGRID_TEST <-- that string must appear on the endif line */ -@endcode - -For more details on the macro used to write unit tests, see their -reference guide: @ref XBT_cunit. For details on on how the tests are -extracted from the module source, check the tools/sg_unit_extractor.pl -script directly. Last note: please try to keep your tests fast. We run them very very very often, and you should strive to make it as fast as possible, to diff --git a/doc/doxygen/module-xbt.doc b/doc/doxygen/module-xbt.doc index c9b0295445..f418de9edb 100644 --- a/doc/doxygen/module-xbt.doc +++ b/doc/doxygen/module-xbt.doc @@ -11,7 +11,6 @@ - @ref XBT_error - @ref XBT_config - @ref XBT_mallocator - - @ref XBT_cunit - Data structures - @ref XBT_dynar - @ref XBT_dict @@ -44,7 +43,6 @@ /** @defgroup XBT_error Assert macro familly */ /** @defgroup XBT_config Configuration support */ /** @defgroup XBT_mallocator Mallocators */ - /** @defgroup XBT_cunit Unit testing support */ /** @} */ diff --git a/include/xbt.h b/include/xbt.h index ac535c89ac..20815aad0f 100644 --- a/include/xbt.h +++ b/include/xbt.h @@ -26,7 +26,6 @@ #ifdef __cplusplus #include #endif -#include #include diff --git a/include/xbt/cunit.h b/include/xbt/cunit.h deleted file mode 100644 index 5b9ee2df29..0000000000 --- a/include/xbt/cunit.h +++ /dev/null @@ -1,141 +0,0 @@ -/* cunit - A little C Unit facility */ - -/* Copyright (c) 2005-2019. 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. */ - -/* This is partially inspired from the OSSP ts (Test Suite Library) */ - -#ifndef XBT_CUNIT_H_ -#define XBT_CUNIT_H_ - -#ifdef __cplusplus -#include -#endif -#include /* XBT_ATTRIB_PRINTF */ - -SG_BEGIN_DECL() - -/* note that the internals of testall, that follow, are not publicly documented */ - -/* test suite object type */ -typedef struct s_xbt_test_suite *xbt_test_suite_t; - -/* test object type */ -typedef struct s_xbt_test_unit *xbt_test_unit_t; - -/* test callback function type */ -typedef void (*ts_test_cb_t) (); - -/* test suite operations */ -XBT_PUBLIC xbt_test_suite_t xbt_test_suite_by_name(const char* name, const char* fmt, ...); -XBT_PUBLIC void xbt_test_suite_push(xbt_test_suite_t suite, const char* name, ts_test_cb_t func, const char* fmt, ...); - -/* Run all the specified tests. what_to_do allows to disable some tests. - * It is a coma (,) separated list of directives. They are applied from left to right. - * - * Each of them of form: - * - * [-|+]suitename[:unitname[:testname]] - * - * * First char: - * if it's a '-', the directive disables something - * if it's a '+', the directive enables something - * By default, everything is enabled, but you can disable a suite and reenable some parts - * * Suitename: the suite on which the directive acts - * * unitname: if given, the unit on which the directive acts. If not, acts on any units. - * * testname: if given, the test on which the directive acts. If not, acts on any tests. - */ - -XBT_PUBLIC int xbt_test_run(char* selection, int verbosity); -/* Show information about the selection of tests */ -XBT_PUBLIC void xbt_test_dump(char* selection); -/* Cleanup the mess */ -XBT_PUBLIC void xbt_test_exit(); - -/** - * @addtogroup XBT_cunit - * @brief Unit testing implementation (see @ref inside_tests_add_units) - * - * This module is mainly intended to allow the tests of SimGrid itself and may lack the level of genericity that you - * would expect as a user. Only use it in external projects at your own risk (but it works rather well for us). We play - * with the idea of migrating to an external solution for our unit tests, possibly offering more features, but having - * absolutely no dependencies is a nice feature of SimGrid (and this code is sufficient to cover our needs, actually, - * so why should we bother switching?) - * - * Unit testing is not intended to write integration tests. - * Please refer to @ref inside_tests_add_integration for that instead. - * - * @{ - */ -/** @brief Provide information about the suite declared in this file - * @hideinitializer - * - * Actually, this macro is only used by the script extracting the test units, but that should be transparent for you. - * - * @param suite_name the short name of this suite, to be used in the --tests argument of testall afterward. Avoid - * spaces and any other strange chars - * @param suite_title instructive title that testall should display when your suite is run - */ -#define XBT_TEST_SUITE(suite_name,suite_title) - -/** @brief Declare a new test units (containing individual tests) - * @hideinitializer - * - * @param name the short name that will be used in test all to enable/disable this test - * @param func a valid function name that will be used to contain all code of this unit - * @param title human informative description of your test (displayed in testall) - */ -#ifdef __cplusplus -#define XBT_TEST_UNIT(name,func,title) \ - extern "C" void func(void); /*prototype*/ \ - void func(void) -#else -#define XBT_TEST_UNIT(name,func,title) \ - void func(void); /*prototype*/ \ - void func(void) -#endif - -/* test operations */ -XBT_PUBLIC void _xbt_test_add(const char* file, int line, const char* fmt, ...) XBT_ATTRIB_PRINTF(3, 4); -XBT_PUBLIC void _xbt_test_fail(const char* file, int line, const char* fmt, ...) XBT_ATTRIB_PRINTF(3, 4); -XBT_PUBLIC void _xbt_test_log(const char* file, int line, const char* fmt, ...) XBT_ATTRIB_PRINTF(3, 4); -/** @brief Declare that a new test begins (printf-like parameters, describing the test) - * @hideinitializer */ -#define xbt_test_add(...) _xbt_test_add(__FILE__, __LINE__, __VA_ARGS__) -/** @brief Declare that the lastly started test failed (printf-like parameters, describing failure cause) - * @hideinitializer */ -#define xbt_test_fail(...) _xbt_test_fail(__FILE__, __LINE__, __VA_ARGS__) -/** @brief The lastly started test is actually an assert - * @hideinitializer - * - * - If provided a uniq parameter, this is assumed to be a condition that is expected to be true - * - If provided more parameters, the first one is a condition, and the other ones are printf-like arguments that are - * to be displayed when the condition fails. - */ -#define xbt_test_assert(...) _XBT_IF_ONE_ARG(_xbt_test_assert_ARG1, \ - _xbt_test_assert_ARGN, \ - __VA_ARGS__)(__VA_ARGS__) -#define _xbt_test_assert_ARG1(cond) _xbt_test_assert_CHECK(cond, "%s", #cond) -#define _xbt_test_assert_ARGN(cond, ...) _xbt_test_assert_CHECK(cond, __VA_ARGS__) -#define _xbt_test_assert_CHECK(cond, ...) \ - do { if (!(cond)) xbt_test_fail(__VA_ARGS__); } while (0) -/** @brief Report some details to help debugging when the test fails (shown only on failure) - * @hideinitializer */ -#define xbt_test_log(...) _xbt_test_log(__FILE__, __LINE__, __VA_ARGS__) - -#ifdef __cplusplus -/** @brief Declare that the lastly started test failed because of the provided exception */ -XBT_PUBLIC void xbt_test_exception(xbt_ex e); -#endif - -/** @brief Declare that the lastly started test was expected to fail (and actually failed) */ -XBT_PUBLIC void xbt_test_expect_failure(); -/** @brief Declare that the lastly started test should be skipped today */ -XBT_PUBLIC void xbt_test_skip(); - -/** @} */ - -SG_END_DECL() -#endif /* XBT_CUNIT_H_ */ diff --git a/src/xbt/cunit.cpp b/src/xbt/cunit.cpp deleted file mode 100644 index 5076c2ee9f..0000000000 --- a/src/xbt/cunit.cpp +++ /dev/null @@ -1,630 +0,0 @@ -/* cunit - A little C Unit facility */ - -/* Copyright (c) 2005-2019. 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. */ - -/* This is partially inspirated from the OSSP ts (Test Suite Library) */ -/* At some point we should use https://github.com/google/googletest instead */ - -#include "src/internal_config.h" -#include -#include -#include -#include - -#include "simgrid/Exception.hpp" -#include -#include - -/* output stream to use everywhere */ -static std::ostream& _xbt_test_out = std::cerr; - -/* collection of all suites */ -static std::vector _xbt_test_suites; -/* global statistics */ -static int _xbt_test_nb_tests = 0; -static int _xbt_test_test_failed = 0; -static int _xbt_test_test_ignore = 0; -static int _xbt_test_test_expect = 0; - -static int _xbt_test_nb_units = 0; -static int _xbt_test_unit_failed = 0; -static int _xbt_test_unit_ignore = 0; -static int _xbt_test_unit_disabled = 0; - -static int _xbt_test_nb_suites = 0; -static int _xbt_test_suite_failed = 0; -static int _xbt_test_suite_ignore = 0; -static int _xbt_test_suite_disabled = 0; - -/* Context */ -xbt_test_unit_t _xbt_test_current_unit = nullptr; - -/* test suite test log */ -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_; -}; - -void s_xbt_test_log::dump() const -{ - _xbt_test_out << " log " << this << "(" << file_ << ":" << line_ << ")=" << text_ << "\n"; -} - -/* test suite test check */ -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_; -}; - -void s_xbt_test_test::dump() const -{ - _xbt_test_out << " test " << this << "(" << file_ << ":" << line_ << ")=" << title_ << " (" - << (failed_ ? "failed" : "not failed") << ")\n"; - for (s_xbt_test_log const& log : this->logs_) - log.dump(); -} - -/* test suite test unit */ -class s_xbt_test_unit { -public: - s_xbt_test_unit(std::string name, std::string title, ts_test_cb_t func) - : name_(std::move(name)), title_(std::move(title)), func_(func) - { - } - void dump() const; - - std::string name_; - std::string title_; - ts_test_cb_t func_; - std::vector tests_; - - bool enabled_ = true; - int nb_tests_ = 0; - int test_failed_ = 0; - int test_ignore_ = 0; - int test_expect_ = 0; -}; - -void s_xbt_test_unit::dump() const -{ - _xbt_test_out << " UNIT " << name_ << ": " << title_ << " (" << (this->enabled_ ? "enabled" : "disabled") << ")\n"; - if (this->enabled_) { - for (s_xbt_test_test const& test : this->tests_) - test.dump(); - } -} - -/* test suite */ -class s_xbt_test_suite { -public: - s_xbt_test_suite(std::string name, std::string title) : name_(std::move(name)), title_(std::move(title)) {} - void dump() const; - void push(s_xbt_test_unit unit) { units_.emplace_back(std::move(unit)); } - int run(int verbosity); - - std::string name_; - std::string title_; - std::vector units_; - - bool enabled_ = true; - int nb_tests_ = 0; - int nb_units_ = 0; - int test_failed_ = 0; - int test_ignore_ = 0; - int test_expect_ = 0; - int unit_failed_ = 0; - int unit_ignore_ = 0; - int unit_disabled_ = 0; -}; - -/** @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, ...) -{ - auto res = std::find_if(begin(_xbt_test_suites), end(_xbt_test_suites), - [&name](xbt_test_suite_t const& suite) { return suite->name_ == name; }); - if (res != end(_xbt_test_suites)) - return *res; - - va_list ap; - va_start(ap, fmt); - xbt_test_suite_t suite = new s_xbt_test_suite(name, simgrid::xbt::string_vprintf(fmt, ap)); - va_end(ap); - - _xbt_test_suites.push_back(suite); - - return suite; -} - -void s_xbt_test_suite::dump() const -{ - _xbt_test_out << "TESTSUITE " << name_ << ": " << title_ << " (" << (this->enabled_ ? "enabled" : "disabled") - << ")\n"; - if (this->enabled_) { - for (s_xbt_test_unit const& unit : this->units_) - unit.dump(); - } -} - -/* add test case to test suite */ -void xbt_test_suite_push(xbt_test_suite_t suite, const char *name, ts_test_cb_t func, const char *fmt, ...) -{ - xbt_assert(suite); - xbt_assert(func); - xbt_assert(fmt); - - va_list ap; - va_start(ap, fmt); - s_xbt_test_unit unit(name, simgrid::xbt::string_vprintf(fmt, ap), func); - va_end(ap); - suite->push(unit); -} - -/* run test one suite */ -int s_xbt_test_suite::run(int verbosity) -{ - /* suite title pretty-printing */ - int suite_len = this->title_.length(); - xbt_assert(suite_len < 68, "suite title \"%s\" too long (%d should be less than 68", this->title_.c_str(), suite_len); - - std::string suite_title = " "; - suite_title.resize(40 - (suite_len + 4) / 2, '='); - suite_title += std::string("[ ") + this->title_ + " ]"; - suite_title.resize(79, '='); - if (not this->enabled_) - suite_title.replace(70, std::string::npos, " DISABLED"); - _xbt_test_out << "\n" << suite_title << "\n"; - - if (this->enabled_) { - /* iterate through all tests */ - for (s_xbt_test_unit& unit : this->units_) { - /* init unit case counters */ - unit.nb_tests_ = 0; - unit.test_ignore_ = 0; - unit.test_failed_ = 0; - unit.test_expect_ = 0; - - /* display unit title */ - std::string cp = std::string(" Unit: ") + unit.title_ + " "; - cp.resize(70, '.'); - _xbt_test_out << cp; - - /* run the test case function */ - _xbt_test_current_unit = &unit; - if (unit.enabled_) - unit.func_(); - - /* iterate through all performed tests to determine status */ - for (s_xbt_test_test const& test : unit.tests_) { - if (test.ignored_) { - unit.test_ignore_++; - } else { - unit.nb_tests_++; - - if ((test.failed_ && not test.expected_failure_) || (not test.failed_ && test.expected_failure_)) - unit.test_failed_++; - if (test.expected_failure_) - unit.test_expect_++; - } - } - /* Display whether this unit went well */ - if (unit.test_failed_ > 0 || unit.test_expect_ || (verbosity && unit.nb_tests_ > 0)) { - /* some tests failed (or were supposed to), so do detailed reporting of test case */ - if (unit.test_failed_ > 0) { - _xbt_test_out << ".. failed\n"; - } else if (unit.nb_tests_) { - _xbt_test_out << "...... ok\n"; /* successful, but show about expected */ - } else { - _xbt_test_out << ".... skip\n"; /* shouldn't happen, but I'm a bit lost with this logic */ - } - for (s_xbt_test_test const& test : unit.tests_) { - std::string file = test.file_; - int line = test.line_; - std::string resname; - if (test.ignored_) - resname = " SKIP"; - else if (test.expected_failure_) { - if (test.failed_) - resname = "EFAIL"; - else - resname = "EPASS"; - } else { - if (test.failed_) - resname = " FAIL"; - else - resname = " PASS"; - } - _xbt_test_out << " " << resname << ": " << test.title_ << " [" << file << ":" << line << "]\n"; - - 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_); - _xbt_test_out << " " << file << ":" << line << ": " << log.text_ << "\n"; - } - } - } - _xbt_test_out << " Summary: " << unit.test_failed_ << " of " << unit.nb_tests_ << " tests failed"; - if (unit.test_ignore_) { - _xbt_test_out << " (" << unit.test_ignore_ << " tests ignored)\n"; - } else { - _xbt_test_out << "\n"; - } - } else if (not unit.enabled_) { - _xbt_test_out << " disabled\n"; /* no test were run */ - } else if (unit.nb_tests_) { - _xbt_test_out << "...... ok\n"; /* successful */ - } else { - _xbt_test_out << ".... skip\n"; /* no test were run */ - } - - /* Accumulate test counts into the suite */ - this->nb_tests_ += unit.nb_tests_; - this->test_failed_ += unit.test_failed_; - this->test_ignore_ += unit.test_ignore_; - this->test_expect_ += unit.test_expect_; - - _xbt_test_nb_tests += unit.nb_tests_; - _xbt_test_test_failed += unit.test_failed_; - _xbt_test_test_ignore += unit.test_ignore_; - _xbt_test_test_expect += unit.test_expect_; - - /* What's the conclusion of this test anyway? */ - if (unit.nb_tests_) { - this->nb_units_++; - if (unit.test_failed_) - this->unit_failed_++; - } else if (not unit.enabled_) { - this->unit_disabled_++; - } else { - this->unit_ignore_++; - } - } - } - _xbt_test_nb_units += this->nb_units_; - _xbt_test_unit_failed += this->unit_failed_; - _xbt_test_unit_ignore += this->unit_ignore_; - _xbt_test_unit_disabled += this->unit_disabled_; - - if (this->nb_units_) { - _xbt_test_nb_suites++; - if (this->test_failed_) - _xbt_test_suite_failed++; - } else if (not this->enabled_) { - _xbt_test_suite_disabled++; - } else { - _xbt_test_suite_ignore++; - } - - /* print test suite summary */ - if (this->enabled_) { - bool first = true; /* for result pretty printing */ - - _xbt_test_out << " ====================================================================="; - if (this->nb_units_) - _xbt_test_out << (this->unit_failed_ ? "== FAILED\n" : "====== OK\n"); - else - _xbt_test_out << (this->unit_disabled_ ? " DISABLED\n" : "==== SKIP\n"); - _xbt_test_out.setf(std::ios::fixed); - _xbt_test_out.precision(0); - _xbt_test_out << " Summary: Units: " - << (this->nb_units_ ? ((1 - (double)this->unit_failed_ / (double)this->nb_units_) * 100.0) : 100.0) - << "% ok (" << this->nb_units_ << " units: "; - if (this->nb_units_ != this->unit_failed_) { - _xbt_test_out << (first ? "" : ", ") << (this->nb_units_ - this->unit_failed_) << " ok"; - first = false; - } - if (this->unit_failed_) { - _xbt_test_out << (first ? "" : ", ") << this->unit_failed_ << " failed"; - first = false; - } - if (this->unit_ignore_) { - _xbt_test_out << (first ? "" : ", ") << this->unit_ignore_ << " ignored"; - first = false; - } - if (this->unit_disabled_) { - _xbt_test_out << (first ? "" : ", ") << this->unit_disabled_ << " disabled"; - } - _xbt_test_out << ")\n Tests: " - << (this->nb_tests_ ? ((1 - (double)this->test_failed_ / (double)this->nb_tests_) * 100.0) : 100.0) - << "% ok (" << this->nb_tests_ << " tests: "; - first = true; - if (this->nb_tests_ != this->test_failed_) { - _xbt_test_out << (first ? "" : ", ") << (this->nb_tests_ - this->test_failed_) << " ok"; - first = false; - } - if (this->test_failed_) { - _xbt_test_out << (first ? "" : ", ") << this->test_failed_ << " failed"; - first = false; - } - if (this->test_ignore_) { - _xbt_test_out << (first ? "" : "; ") << this->test_ignore_ << " ignored"; - first = false; - } - if (this->test_expect_) { - _xbt_test_out << (first ? "" : "; ") << this->test_expect_ << " expected to fail"; - } - _xbt_test_out << ")\n"; - } - return this->unit_failed_; -} - -static void apply_selection(char *selection) -{ - if (not selection || selection[0] == '\0') - return; - - /* for the parsing */ - std::string sel = selection; - bool done = false; - std::string dir; /* the directive */ - std::string suitename; - std::string unitname; - - /* First apply the selection */ - size_t p0 = 0; - while (not done) { - bool enabling = true; - - size_t p = sel.find(',', p0); - if (p != std::string::npos) { - dir = sel.substr(p0, p - p0); - p0 = p + 1; - } else { - dir = sel.substr(p0); - done = true; - } - - if (dir[0] == '-') { - enabling = false; - dir.erase(0, 1); - } - if (dir[0] == '+') { - enabling = true; - dir.erase(0, 1); - } - - p = dir.find(':'); - if (p != std::string::npos) { - suitename = dir.substr(0, p); - unitname = dir.substr(p + 1); - } else { - suitename = dir; - unitname = ""; - } - - /* Deal with the specific case of 'all' pseudo serie */ - if (suitename == "all") { - xbt_assert(unitname.empty(), "The 'all' pseudo-suite does not accept any unit specification\n"); - - for (xbt_test_suite_t& suite : _xbt_test_suites) { - for (s_xbt_test_unit& unit : suite->units_) { - unit.enabled_ = enabling; - } - suite->enabled_ = enabling; - } - } else { - bool suitefound = false; - for (xbt_test_suite_t& thissuite : _xbt_test_suites) { - if (suitename == thissuite->name_) { - /* Do not disable the whole suite when we just want to disable a child */ - if (enabling || unitname.empty()) - thissuite->enabled_ = enabling; - - if (unitname.empty()) { - for (s_xbt_test_unit& unit : thissuite->units_) { - unit.enabled_ = enabling; - } - } else { /* act on one child only */ - /* search relevant unit */ - auto unit = std::find_if(begin(thissuite->units_), end(thissuite->units_), - [&unitname](s_xbt_test_unit const& unit) { return unit.name_ == unitname; }); - if (unit == end(thissuite->units_)) - xbt_die("Suite '%s' has no unit of name '%s'. Cannot apply the selection\n", suitename.c_str(), - unitname.c_str()); - unit->enabled_ = enabling; - } /* act on childs (either all or one) */ - suitefound = true; - break; /* found the relevant serie. We are happy */ - } - } /* search relevant series */ - xbt_assert(suitefound, "No suite of name '%s' found. Cannot apply the selection\n", suitename.c_str()); - } - } -} - -void xbt_test_dump(char *selection) -{ - apply_selection(selection); - - if (not _xbt_test_suites.empty()) { - for (xbt_test_suite_t suite : _xbt_test_suites) - suite->dump(); - } else { - _xbt_test_out << " No suite defined."; - } -} - -int xbt_test_run(char *selection, int verbosity) -{ - apply_selection(selection); - - if (not _xbt_test_suites.empty()) { - bool first = true; - - /* Run all the suites */ - for (xbt_test_suite_t& suite : _xbt_test_suites) - if (suite) - suite->run(verbosity); - - /* Display some more statistics */ - _xbt_test_out.setf(std::ios::fixed); - _xbt_test_out.precision(0); - _xbt_test_out << "\n\n TOTAL: Suites: " - << (_xbt_test_nb_suites ? ((1 - (double)_xbt_test_suite_failed / (double)_xbt_test_nb_suites) * 100.0) - : 100.0) - << "% ok (" << _xbt_test_nb_suites << " suites: "; - if (_xbt_test_nb_suites != _xbt_test_suite_failed) { - _xbt_test_out << (_xbt_test_nb_suites - _xbt_test_suite_failed) << " ok"; - first = false; - } - if (_xbt_test_suite_failed) { - _xbt_test_out << (first ? "" : ", ") << _xbt_test_suite_failed << " failed"; - first = false; - } - - if (_xbt_test_suite_ignore) { - _xbt_test_out << (first ? "" : ", ") << _xbt_test_suite_ignore << " ignored"; - } - _xbt_test_out << ")\n Units: " - << (_xbt_test_nb_units ? ((1 - (double)_xbt_test_unit_failed / (double)_xbt_test_nb_units) * 100.0) - : 100.0) - << "% ok (" << _xbt_test_nb_units << " units: "; - first = true; - if (_xbt_test_nb_units != _xbt_test_unit_failed) { - _xbt_test_out << (_xbt_test_nb_units - _xbt_test_unit_failed) << " ok"; - first = false; - } - if (_xbt_test_unit_failed) { - _xbt_test_out << (first ? "" : ", ") << _xbt_test_unit_failed << " failed"; - first = false; - } - if (_xbt_test_unit_ignore) { - _xbt_test_out << (first ? "" : ", ") << _xbt_test_unit_ignore << " ignored"; - } - _xbt_test_out << ")\n Tests: " - << (_xbt_test_nb_tests ? ((1 - (double)_xbt_test_test_failed / (double)_xbt_test_nb_tests) * 100.0) - : 100.0) - << "% ok (" << _xbt_test_nb_tests << " tests: "; - first = true; - if (_xbt_test_nb_tests != _xbt_test_test_failed) { - _xbt_test_out << (_xbt_test_nb_tests - _xbt_test_test_failed) << " ok"; - first = false; - } - if (_xbt_test_test_failed) { - _xbt_test_out << (first ? "" : ", ") << _xbt_test_test_failed << " failed"; - first = false; - } - if (_xbt_test_test_ignore) { - _xbt_test_out << (first ? "" : ", ") << _xbt_test_test_ignore << " ignored"; - first = false; - } - if (_xbt_test_test_expect) { - _xbt_test_out << (first ? "" : ", ") << _xbt_test_test_expect << " expected to fail"; - } - - _xbt_test_out << ")\n"; - } else { - _xbt_test_out << "No unit to run!\n"; - _xbt_test_unit_failed++; - } - return _xbt_test_unit_failed; -} - -void xbt_test_exit() -{ - for (xbt_test_suite_t suite : _xbt_test_suites) - delete suite; - _xbt_test_suites.clear(); -} - -/* annotate test case with test */ -void _xbt_test_add(const char *file, int line, const char *fmt, ...) -{ - xbt_test_unit_t unit = _xbt_test_current_unit; - xbt_assert(unit); - - va_list ap; - va_start(ap, fmt); - unit->tests_.emplace_back(simgrid::xbt::string_vprintf(fmt, ap), file, line); - va_end(ap); -} - -/* annotate test case with log message and failure */ -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(not _xbt_test_current_unit->tests_.empty(), "Test failed even before being declared (broken unit: %s)", - unit->title_.c_str()); - - s_xbt_test_test& test = unit->tests_.back(); - va_list ap; - va_start(ap, fmt); - test.logs_.emplace_back(simgrid::xbt::string_vprintf(fmt, ap), file, line); - va_end(ap); - - test.failed_ = true; -} - -void xbt_test_exception(xbt_ex e) -{ - _xbt_test_fail(e.throw_point().file_, e.throw_point().line_, "Exception %s raised: %s", xbt_ex_catname(e.category), - e.what()); -} - -void xbt_test_expect_failure() -{ - 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_.c_str()); - _xbt_test_current_unit->tests_.back().expected_failure_ = true; -} - -void xbt_test_skip() -{ - xbt_assert(not _xbt_test_current_unit->tests_.empty(), "Test skipped even before being declared (broken unit: %s)", - _xbt_test_current_unit->title_.c_str()); - _xbt_test_current_unit->tests_.back().ignored_ = true; -} - -/* annotate test case with log message only */ -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(not _xbt_test_current_unit->tests_.empty(), - "Test logged into even before being declared (broken test unit: %s)", unit->title_.c_str()); - - va_list ap; - va_start(ap, fmt); - unit->tests_.back().logs_.emplace_back(simgrid::xbt::string_vprintf(fmt, ap), file, line); - va_end(ap); -} - -#ifdef SIMGRID_TEST -XBT_TEST_SUITE("cunit", "Testsuite mechanism autotest"); - -XBT_TEST_UNIT("expect", test_expected_failure, "expected failures") -{ - xbt_test_add("Skipped test"); - xbt_test_skip(); - - xbt_test_add("%s %s", "EXPECTED", "FAILURE"); - xbt_test_expect_failure(); - xbt_test_log("%s %s", "Test", "log"); - xbt_test_fail("EXPECTED FAILURE"); -} -#endif /* SIMGRID_TEST */ diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 68e38e1370..32308f6cd3 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,7 +1,6 @@ set(bin_files ${bin_files} ${CMAKE_CURRENT_SOURCE_DIR}/fix-paje-trace.sh ${CMAKE_CURRENT_SOURCE_DIR}/generate-dwarf-functions ${CMAKE_CURRENT_SOURCE_DIR}/normalize-pointers.py - ${CMAKE_CURRENT_SOURCE_DIR}/sg_unit_extractor.pl ${CMAKE_CURRENT_SOURCE_DIR}/sg_xml_unit_converter.py ${CMAKE_CURRENT_SOURCE_DIR}/simgrid_update_xml.pl ${CMAKE_CURRENT_SOURCE_DIR}/simgrid_convert_TI_traces.py diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 3041c00cbf..4128383879 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -270,7 +270,6 @@ set(XBT_SRC src/xbt/automaton/automatonparse_promela.c src/xbt/backtrace.cpp src/xbt/config.cpp - src/xbt/cunit.cpp src/xbt/dict.cpp src/xbt/dict_cursor.c src/xbt/dict_elm.c @@ -751,7 +750,6 @@ set(headers_to_install include/xbt/base.h include/xbt/config.h include/xbt/config.hpp - include/xbt/cunit.h include/xbt/dict.h include/xbt/dynar.h include/xbt/ex.h @@ -1075,7 +1073,6 @@ set(CMAKE_SOURCE_FILES tools/cmake/scripts/fixup_simgrid_dtd_l.pl tools/cmake/scripts/my_valgrind.pl tools/cmake/scripts/update_tesh.pl - tools/cmake/UnitTesting.cmake tools/cmake/test_prog/prog_asan.cpp tools/cmake/test_prog/prog_makecontext.c tools/cmake/test_prog/prog_stackgrowth.c diff --git a/tools/cmake/Distrib.cmake b/tools/cmake/Distrib.cmake index c5b9925d9e..91b516c33c 100644 --- a/tools/cmake/Distrib.cmake +++ b/tools/cmake/Distrib.cmake @@ -344,15 +344,6 @@ add_dependencies(check tests) ####################################### add_custom_target(maintainer-clean - COMMAND ${CMAKE_COMMAND} -E remove -f src/config_unit.c - COMMAND ${CMAKE_COMMAND} -E remove -f src/cunit_unit.c - COMMAND ${CMAKE_COMMAND} -E remove -f src/dict_unit.c - COMMAND ${CMAKE_COMMAND} -E remove -f src/dynar_unit.c - COMMAND ${CMAKE_COMMAND} -E remove -f src/ex_unit.c - COMMAND ${CMAKE_COMMAND} -E remove -f src/set_unit.c - COMMAND ${CMAKE_COMMAND} -E remove -f src/simgrid_units_main.c - COMMAND ${CMAKE_COMMAND} -E remove -f src/xbt_str_unit.c - COMMAND ${CMAKE_COMMAND} -E remove -f src/xbt_synchro_unit.c COMMAND ${CMAKE_COMMAND} -E remove -f src/mpif.f90 WORKING_DIRECTORY "${CMAKE_HOME_DIRECTORY}") diff --git a/tools/cmake/UnitTesting.cmake b/tools/cmake/UnitTesting.cmake deleted file mode 100644 index 93a7d777d8..0000000000 --- a/tools/cmake/UnitTesting.cmake +++ /dev/null @@ -1,43 +0,0 @@ -# This file is in charge of the unit testing in SimGrid. -# See http://simgrid.gforge.inria.fr/simgrid/3.13/doc/inside_tests.html#inside_tests_add_units - -# To register a file containing unit tests, simply add it to -# FILES_CONTAINING_UNITTESTS and have a pleasant day. - -set(FILES_CONTAINING_UNITTESTS - src/xbt/cunit.cpp -) - -#### Nothing to change below this line to add a new tested file -################################################################ - -foreach(file ${FILES_CONTAINING_UNITTESTS}) - get_filename_component(basename ${file} NAME_WE) - get_filename_component(ext ${file} EXT) - set(EXTRACTED_TEST_SOURCE_FILES ${EXTRACTED_TEST_SOURCE_FILES} ${CMAKE_CURRENT_BINARY_DIR}/src/${basename}_unit${ext}) -endforeach() - -set(EXTRACTED_TEST_SOURCE_FILES ${EXTRACTED_TEST_SOURCE_FILES} ${CMAKE_CURRENT_BINARY_DIR}/src/simgrid_units_main.c) - -set_source_files_properties(${EXTRACTED_TEST_SOURCE_FILES} PROPERTIES GENERATED true) - -ADD_CUSTOM_COMMAND( - OUTPUT ${EXTRACTED_TEST_SOURCE_FILES} - DEPENDS ${CMAKE_HOME_DIRECTORY}/tools/sg_unit_extractor.pl ${FILES_CONTAINING_UNITTESTS} - COMMENT "Generating *_units files for testall..." - - WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY} - COMMAND ${CMAKE_COMMAND} -E remove -f ${EXTRACTED_TEST_SOURCE_FILES} - COMMAND chmod +x ${CMAKE_HOME_DIRECTORY}/tools/sg_unit_extractor.pl - COMMAND ${CMAKE_HOME_DIRECTORY}/tools/sg_unit_extractor.pl --root=src/ --outdir=${CMAKE_CURRENT_BINARY_DIR}/src/ ${FILES_CONTAINING_UNITTESTS} -) - -add_executable (testall EXCLUDE_FROM_ALL ${EXTRACTED_TEST_SOURCE_FILES}) -add_dependencies(tests testall) -target_link_libraries(testall simgrid) -set_property( - TARGET testall - APPEND PROPERTY - INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}" - ) - diff --git a/tools/sg_unit_extractor.pl b/tools/sg_unit_extractor.pl deleted file mode 100755 index 638ba49b5e..0000000000 --- a/tools/sg_unit_extractor.pl +++ /dev/null @@ -1,291 +0,0 @@ -#! /usr/bin/env perl - -# Copyright (c) 2005-2019. 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. - -use strict; -use Getopt::Long qw(GetOptions); - -my $progname="sg_unit_extractor"; -# Get the args - -sub usage($) { - my $ret; - print "USAGE: $progname [--root=part/to/cut] [--outdir=where/to/generate/files] infile [infile+]\n\n"; - print "This program is in charge of extracting the unit tests out of the SimGrid source code.\n"; - print "See http://simgrid.gforge.inria.fr/doc/latest/inside_tests.html for more details.\n"; - exit $ret; -} - -my $outdir=undef; -my $root; -my $help; - -Getopt::Long::config('permute','no_getopt_compat', 'no_auto_abbrev'); -GetOptions( - 'help|h' => sub {usage(0)}, - 'root=s' =>\$root, - 'outdir=s' =>\$outdir) or usage(1); - -usage(1) if (scalar @ARGV == 0); - -map {process_one($_)} @ARGV; - -sub process_one($) { - my $infile = shift; - my $outfile; - - $infile =~ s|src/|| unless (-e $infile); - - $outfile = $infile; - $outfile =~ s/\.c$/_unit.c/; - $outfile =~ s/\.cpp$/_unit.cpp/; - $outfile =~ s|.*/([^/]*)$|$1| if $outfile =~ m|/|; - $outfile = "$outdir$outfile"; - - print "$progname: processing $infile (generating $outfile)...\n"; - - # Get the unit data - my ($unit_source,$suite_name,$suite_title)=("","",""); - my (%tests); # to detect multiple definition - my (@tests); # actual content - - open IN, "$infile" || die "$progname: Cannot open input file '$infile': $!\n"; - $infile =~ s|$root|| if defined($root); - - my $takeit=0; - my $line=0; - my $beginline=0; - while () { - $line++; - if (m/ifdef +SIMGRID_TEST/) { - $beginline = $line; - $takeit = 1; - next; - } - if (m/endif.*SIMGRID_TEST/) { - $takeit = 0; - next - } - - if (m/XBT_TEST_SUITE\(\w*"([^"]*)"\w*, *(.*?)\);/) { #" { - die "$progname: Multiple suites in the same file ($infile) are not supported yet\n" if length($suite_name); - ($suite_name,$suite_title)=($1,$2); - die "$progname: Empty suite name in $infile" unless length($suite_name); - die "$progname: Empty suite title in $infile" unless length($suite_title); - next; - } elsif (m/XBT_TEST_SUITE/) { - die "$progname: Parse error: This line seem to be a test suite declaration, but failed to parse it\n$_\n"; - } - - if (m/XBT_TEST_UNIT\(\w*"([^"]*)"\w*, *([^,]*), *(.*?)\)/) { #"{ - die "$progname: multiply defined unit in file $infile: $1\n" if (defined($tests{$1})); - - my @t=($1,$2,$3); - push @tests,\@t; - $tests{$1} = 1; - } elsif (m/XBT_TEST_UNIT/) { - die "$progname: Parse error: This line seem to be a test unit, but failed to parse it\n$_\n"; - } - $unit_source .= $_ if $takeit; - } - close IN || die "$progname: cannot close input file '$infile': $!\n"; - - - if ($takeit) { - die "$progname: end of file reached in SIMGRID_TEST block.\n". - "You should end each of the with a line matching: /endif.*SIMGRID_TEST/\n". - "Example:\n". - "#endif /* SIMGRID_TEST */\n" - } - - die "$progname: no suite defined in $infile\n" unless (length($suite_name)); - - # Write the test - - my ($GENERATED)=("/*******************************/\n". - "/* GENERATED FILE, DO NOT EDIT */\n". - "/*******************************/\n\n"); - $beginline+=2; - open OUT,">$outfile" || die "$progname: Cannot open output file '$outfile': $!\n"; - print OUT $GENERATED; - print OUT "#include \n"; - print OUT "#include \"xbt.h\"\n"; - print OUT $GENERATED; - print OUT "#line $beginline \"$infile\" \n"; - print OUT "$unit_source"; - print OUT $GENERATED; - close OUT || die "$progname: Cannot close output file '$outfile': $!\n"; - - # write the main skeleton if needed - if (! -e "${outdir}simgrid_units_main.c") { - open OUT,">${outdir}simgrid_units_main.c" || die "$progname: Cannot open main file '${outdir}simgrid_units_main.c': $!\n"; - print OUT $GENERATED; - print OUT "#include \n\n"; - print OUT "#include \"xbt.h\"\n\n"; - print OUT "extern xbt_test_unit_t _xbt_current_unit;\n\n"; - print OUT "#define STRLEN 1024\n"; - print OUT "/* SGU: BEGIN PROTOTYPES */\n"; - print OUT "/* SGU: END PROTOTYPES */\n\n"; - print OUT $GENERATED; - # print OUT "# 93 \"sg_unit_extractor.pl\"\n"; - print OUT <) { - $newmain .= $_; - # print "Look for proto: $_"; - last if /SGU: BEGIN PROTOTYPES/; - } - - # search my prototype - while () { - # print "Seek protos: $_"; - last if (/SGU: END PROTOTYPES/ || /SGU: BEGIN FILE $infile/); - $newmain .= $_; - } - if (/SGU: BEGIN FILE $infile/) { # found an old section for this file. Kill it - while () { - last if /SGU: END FILE/; - } - $_ = ; # pass extra blank line - chomp; - die "this line should be blank ($_). Did you edit the file?" if /\W/; - } - my ($old_)=($_); - # add my section - $newmain .= " /* SGU: BEGIN FILE $infile */\n"; - map { - my ($name,$func,$title) = @{$_}; - $newmain .= " void $func(void);\n" - } @tests; - - $newmain .= " /* SGU: END FILE */\n\n"; - if ($old_ =~ /SGU: BEGIN FILE/ || $old_ =~ /SGU: END PROTOTYPES/) { - $newmain .= $old_; - } - - # pass remaining prototypes, search declarations - while () { - $newmain .= $_ unless /SGU: END PROTOTYPES/; - last if /SGU: BEGIN SUITES DECLARATION/; - } - - ### Done with prototypes. And now, the actual code - - # search my prototype - while () { - last if (/SGU: END SUITES DECLARATION/ || /SGU: BEGIN FILE $infile/); - $newmain .= $_; - } - if (/SGU: BEGIN FILE $infile/) { # found an old section for this file. Kill it - while () { - last if /SGU: END FILE/; - } - $_ = ; # pass extra blank line - chomp; - die "this line should be blank ($_). Did you edit the file?" if /\W/; - } - my ($old_)=($_); - # add my section - $newmain .= " /* SGU: BEGIN FILE $infile */\n"; - $newmain .= " suite = xbt_test_suite_by_name(\"$suite_name\",$suite_title);\n"; - map { - my ($name,$func,$title) = @{$_}; - $newmain .= " xbt_test_suite_push(suite, \"$name\", &$func, $title);\n"; - } @tests; - - $newmain .= " /* SGU: END FILE */\n\n"; - if ($old_ =~ /SGU: BEGIN FILE/ || $old_ =~ /SGU: END SUITES DECLARATION/) { - $newmain .= $old_; - } - - # pass the remaining - while () { - $newmain .= $_; - } - close IN || die "$progname: Cannot close main file '${outdir}simgrid_units_main.c': $!\n"; - - # write it back to main - open OUT,">${outdir}simgrid_units_main.c" || die "$progname: Cannot open main file '${outdir}simgrid_units_main.c': $!\n"; - print OUT $newmain; - close OUT || die "$progname: Cannot close main file '${outdir}simgrid_units_main.c': $!\n"; -} # end if process_one($) - -0; -- 2.20.1