X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/09b888098e2c4e1c0af0bbae4ad034806f37d95f..fcb5d351a63c53030b694087b299fc199ca5898d:/doc/doxygen/inside_tests.doc diff --git a/doc/doxygen/inside_tests.doc b/doc/doxygen/inside_tests.doc index bd1c5f89ef..9b0cc7740b 100644 --- a/doc/doxygen/inside_tests.doc +++ b/doc/doxygen/inside_tests.doc @@ -18,7 +18,7 @@ in examples/ is used as an integration test, while some other torture tests and corner cases integration tests are located in teshsuite/. For each integration test, we ensure that the output exactly matches the defined expectations. Since SimGrid displays the timestamp of -every loggued line, this ensures that every change of the models' +every logged line, this ensures that every change of the models' prediction will be noticed. All these tests should ensure that SimGrid is safe to use and to depend on. @@ -41,69 +41,128 @@ 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 in src/. -These tests are run when you launch ctest, don't worry. +All unit tests are packed into the testall 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 -./src/testall # Launch all tests -./src/testall --help # revise how it goes if you forgot -./src/testall --tests=-all # run no test at all (yeah, that's useless) -./src/testall --dump-only # Display all existing test suite -./src/testall --tests=-all,+dict # Only launch the tests from the dict testsuite -./src/testall --tests=-all,+foo:bar # run only the bar test from the foo suite. +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. \endverbatim \section inside_tests_add_units Adding unit tests If you want to test a specific function or set of functions, you need -a unit test. Edit -/tools/cmake/UnitTesting.cmake to add your -source file to the TEST_CFILES list, and add the corresponding unit -file to the TEST_UNITS list. For example, if your file is toto.c, -your unit file will be toto_unit.c. The full path to your file must be -provided, but the unit file will always be in src/ directly. - -If you want to create unit tests in the file src/xbt/toto.c, your -changes should look similar to: +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(TEST_CFILES +@@ -11,6 +11,7 @@ set(FILES_CONTAINING_UNITTESTS src/xbt/xbt_strbuff.c src/xbt/xbt_sha.c src/xbt/config.c -+ src/xbt/toto.c - ) - set(TEST_UNITS - ${CMAKE_CURRENT_BINARY_DIR}/src/cunit_unit.c -@@ -22,6 +23,7 @@ set(TEST_UNITS - ${CMAKE_CURRENT_BINARY_DIR}/src/xbt_strbuff_unit.c - ${CMAKE_CURRENT_BINARY_DIR}/src/xbt_sha_unit.c - ${CMAKE_CURRENT_BINARY_DIR}/src/config_unit.c -+ ${CMAKE_CURRENT_BINARY_DIR}/src/toto_unit.c - - ${CMAKE_CURRENT_BINARY_DIR}/src/simgrid_units_main.c ++ src/xbt/plouf.c ) + + if(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. Then, you want to add a test suite -that will contain a bunch of tests (in Junit, that would be a test -unit) with the macro #XBT_TEST_SUITE, and populate it with a bunch of -actual tests with the macro #XBT_TEST_UNIT (sorry for the mischosen -names if you are used to junit). Just look at the dynar example (or -any other) to see how it works in practice. Do not hesitate to stress -test your code this way, but make sure that it runs reasonably fast, +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 +not upset the other developers. Do not hesitate to stress test your +code with such unit tests, but make sure that it runs reasonably fast, or nobody will run "ctest" before commiting code. -For more details on how the tests are extracted from the module -source, check the tools/sg_unit_extractor.pl script directly. - - \section inside_tests_add_integration Adding integration tests TESH (the TEsting SHell) is the test runner that we wrote for our @@ -111,7 +170,7 @@ integration tests. It is distributed with the SimGrid source file, and even comes with a man page. TESH ensures that the output produced by a command perfectly matches the expected output. This is very precious to ensure that no change modifies the timings computed by the models -without notice. +without notice. To add a new integration test, you thus have 3 things to do: @@ -121,20 +180,25 @@ To add a new integration test, you thus have 3 things to do: examples/ and modify the cmake files as explained on this page: \ref inside_cmake_examples. If you feel like you should write a torture test that is not interesting to the users (because nobody - would sainly write something similar in user code), then put it under + would sanely write something similar in user code), then put it under teshsuite/ somewhere. + - Write the tesh file, containing the command to run, the provided input (if any, but almost no SimGrid test provide such an input) and the expected output. Check the tesh man page for more - details. \n + details.\n Tesh is sometimes annoying as you have to ensure that the expected output will always be exactly the same. In particular, your should - not output machine dependent informations, nor memory adresses as + not output machine dependent informations such as absolute data path, nor memory adresses as they would change on each run. Several steps can be used here, such as the obfucation of the memory adresses unless the verbose logs are displayed (using the #XBT_LOG_ISENABLED() macro), or the modification of the log formats to hide the timings when they - depend on the host machine. + depend on the host machine.\n + The script located in /tools/tesh/generate_tesh can + help you a lot in particular if the output is large (though a smaller output is preferable). + There are also example tesh files in the /tools/tesh/ directory, that can be useful to understand the tesh syntax. + - Add your test in the cmake infrastructure. For that, modify the file /tools/cmake/Tests.cmake. Make sure to pick a wise name for your test. It is often useful to check a @@ -170,9 +234,9 @@ We use Jenkins on Inria servers as a workhorse: it runs all of our tests for many configurations. It takes a long time to answer, and it often reports issues but when it's green, then you know that SimGrid is very fit! -We use Travis to +We use Travis to quickly run some tests on Linux and Mac. It answers quickly but may -miss issues. And we use AppVeyor +miss issues. And we use AppVeyor to build and somehow test SimGrid on windows. \subsection inside_tests_jenkins Jenkins on the Inria CI servers @@ -218,14 +282,14 @@ Travis is a free (as in free beer) Continuous Integration system that open-sourced project can use freely. It is very well integrated in the GitHub ecosystem. There is a plenty of documentation out there. Our configuration is in the file .travis.yml as it should be, and the -result is here: https://travis-ci.org/mquinson/simgrid +result is here: https://travis-ci.org/simgrid/simgrid \subsection inside_tests_appveyor AppVeyor AppVeyor aims at becoming the Travis of Windows. It is maybe less mature than Travis, or maybe it is just that I'm less trained in Windows. Our configuration is in the file appveyor.yml as it should -be, and the result is here: https://ci.appveyor.com/project/mquinson/simgrid +be, and the result is here: https://ci.appveyor.com/project/simgrid/simgrid It should be noted that I miserably failed to use the environment provided by AppVeyor, since SimGrid does not build with Microsoft @@ -237,4 +301,28 @@ We re-use the ones from the project. Thanks to them for compiling sane tools and constituting that archive, it saved my mind! +\subsection inside_tests_debian Debian builders + +Since SimGrid is packaged in Debian, we benefit from their huge +testing infrastructure. That's an interesting torture test for our +code base. The downside is that it's only for the released versions of +SimGrid. That is why the Debian build does not stop when the tests +fail: post-releases fixes do not fit well in our workflow and we fix +only the most important breakages. + +The build results are here: +https://buildd.debian.org/status/package.php?p=simgrid + +\subsection inside_tests_sonarqube SonarQube + +SonarQube is an open-source code quality analysis solution. Their nice +code scanners are provided as plugin. The one for C++ is not free, but +open-source project can use it at no cost. That is what we are doing. + +Don't miss the great looking dashboard here: +https://nemo.sonarqube.org/overview?id=simgrid + +This tool is enriched by the script @c tools/internal/travis-sonarqube.sh +that is run from @c .travis.yml + */