Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
56593f6d6f586e28f44da8fe51f2b45e1337c535
[simgrid.git] / doc / doxygen / inside_tests.doc
1 /*! 
2 @page inside_tests Testing SimGrid
3
4 This page will teach you how to run the tests, selecting the ones you
5 want, and how to add new tests to the archive.
6
7 \tableofcontents
8
9 SimGrid code coverage is usually between 70% and 80%, which is much
10 more than most projects out there. This is because we consider SimGrid
11 to be a rather complex project, and we want to modify it with less fear.
12
13 We have two sets of tests in SimGrid: Each of the 10,000+ unit tests
14 check one specific case for one specific function, while the 500+
15 integration tests run a given simulation specifically intended to
16 exercise a larger amount of functions together. Every example provided
17 in examples/ is used as an integration test, while some other torture
18 tests and corner cases integration tests are located in teshsuite/.
19 For each integration test, we ensure that the output exactly matches
20 the defined expectations. Since SimGrid displays the timestamp of
21 every loggued line, this ensures that every change of the models'
22 prediction will be noticed. All these tests should ensure that SimGrid
23 is safe to use and to depend on.
24
25 \section inside_tests_runintegration Running the tests
26
27 Running the tests is done using the ctest binary that comes with
28 cmake. These tests are run for every commit and the result is publicly
29 <a href="https://ci.inria.fr/simgrid/">available</a>.
30
31 \verbatim
32 ctest                     # Launch all tests
33 ctest -R msg              # Launch only the tests which name match the string "msg"
34 ctest -j4                 # Launch all tests in parallel, at most 4 at the same time
35 ctest --verbose           # Display all details on what's going on
36 ctest --output-on-failure # Only get verbose for the tests that fail
37
38 ctest -R msg- -j5 --output-on-failure # You changed MSG and want to check that you didn't break anything, huh?
39                                       # That's fine, I do so all the time myself.
40 \endverbatim
41
42 \section inside_tests_rununit Running the unit tests
43
44 All unit tests are packed into the testall binary, that lives in src/.
45 These tests are run when you launch ctest, don't worry.
46
47 \verbatim
48 make testall                        # Rebuild the test runner on need
49 ./src/testall                       # Launch all tests
50 ./src/testall --help                # revise how it goes if you forgot
51 ./src/testall --tests=-all          # run no test at all (yeah, that's useless)
52 ./src/testall --dump-only           # Display all existing test suite
53 ./src/testall --tests=-all,+dict    # Only launch the tests from the dict testsuite
54 ./src/testall --tests=-all,+foo:bar # run only the bar test from the foo suite.
55 \endverbatim
56
57
58 \section inside_tests_add_units Adding unit tests
59
60 If you want to test a specific function or set of functions, you need
61 a unit test. Edit
62 <project/directory>/tools/cmake/UnitTesting.cmake to add your
63 source file to the TEST_CFILES list, and add the corresponding unit
64 file to the TEST_UNITS list. For example, if your file is toto.c,
65 your unit file will be toto_unit.c. The full path to your file must be
66 provided, but the unit file will always be in src/ directly.
67
68 If you want to create unit tests in the file src/xbt/toto.c, your
69 changes should look similar to:
70
71 \verbatim
72 --- a/tools/cmake/UnitTesting.cmake
73 +++ b/tools/cmake/UnitTesting.cmake
74 @@ -11,6 +11,7 @@ set(TEST_CFILES
75    src/xbt/xbt_strbuff.c
76    src/xbt/xbt_sha.c
77    src/xbt/config.c
78 +  src/xbt/toto.c
79    )
80  set(TEST_UNITS
81    ${CMAKE_CURRENT_BINARY_DIR}/src/cunit_unit.c
82 @@ -22,6 +23,7 @@ set(TEST_UNITS
83    ${CMAKE_CURRENT_BINARY_DIR}/src/xbt_strbuff_unit.c
84    ${CMAKE_CURRENT_BINARY_DIR}/src/xbt_sha_unit.c
85    ${CMAKE_CURRENT_BINARY_DIR}/src/config_unit.c
86 +  ${CMAKE_CURRENT_BINARY_DIR}/src/toto_unit.c
87  
88    ${CMAKE_CURRENT_BINARY_DIR}/src/simgrid_units_main.c
89    )
90 \endverbatim
91
92 Then, you want to actually add your tests in the source file. All the
93 tests must be protected by "#ifdef SIMGRID_TEST" so that they don't
94 get included in the regular build. Then, you want to add a test suite
95 that will contain a bunch of tests (in Junit, that would be a test
96 unit) with the macro #XBT_TEST_SUITE, and populate it with a bunch of
97 actual tests with the macro #XBT_TEST_UNIT (sorry for the mischosen
98 names if you are used to junit). Just look at the dynar example (or
99 any other) to see how it works in practice. Do not hesitate to stress
100 test your code this way, but make sure that it runs reasonably fast,
101 or nobody will run "ctest" before commiting code.
102
103 For more details on the macro used to write unit tests, see their
104 reference guide: @ref XBT_cunit.  For details on on how the tests are
105 extracted from the module source, check the tools/sg_unit_extractor.pl
106 script directly.
107
108
109 \section inside_tests_add_integration Adding integration tests
110
111 TESH (the TEsting SHell) is the test runner that we wrote for our
112 integration tests. It is distributed with the SimGrid source file, and
113 even comes with a man page. TESH ensures that the output produced by a
114 command perfectly matches the expected output. This is very precious
115 to ensure that no change modifies the timings computed by the models
116 without notice.
117
118 To add a new integration test, you thus have 3 things to do:
119
120  - <b>Write the code exercising the feature you target</b>. You should
121    strive to make this code clear, well documented and informative for
122    the users. If you manage to do so, put this somewhere under
123    examples/ and modify the cmake files as explained on this page:
124    \ref inside_cmake_examples. If you feel like you should write a
125    torture test that is not interesting to the users (because nobody
126    would sainly write something similar in user code), then put it under 
127    teshsuite/ somewhere.
128  - <b>Write the tesh file</b>, containing the command to run, the
129    provided input (if any, but almost no SimGrid test provide such an
130    input) and the expected output. Check the tesh man page for more
131    details. \n
132    Tesh is sometimes annoying as you have to ensure that the expected
133    output will always be exactly the same. In particular, your should
134    not output machine dependent informations, nor memory adresses as
135    they would change on each run. Several steps can be used here, such
136    as the obfucation of the memory adresses unless the verbose logs
137    are displayed (using the #XBT_LOG_ISENABLED() macro), or the
138    modification of the log formats to hide the timings when they
139    depend on the host machine.
140  - <b>Add your test in the cmake infrastructure</b>. For that, modify
141    the file <project/directory>/tools/cmake/Tests.cmake. Make sure to
142    pick a wise name for your test. It is often useful to check a
143    category of tests together. The only way to do so in ctest is to
144    use the -R argument that specifies a regular expression that the
145    test names must match. For example, you can run all MSG test with
146    "ctest -R msg". That explains the importance of the test names.
147
148 Once the name is chosen, create a new test by adding a line similar to
149 the following (assuming that you use tesh as expected).
150
151 \verbatim
152 # Usage: ADD_TEST(test-name ${CMAKE_BINARY_DIR}/bin/tesh <options> <tesh-file>)
153 #  option --setenv bindir set the directory containing the binary
154 #         --setenv srcdir set the directory containing the source file
155 #         --cd set the working directory
156 ADD_TEST(my-test-name ${CMAKE_BINARY_DIR}/bin/tesh 
157          --setenv bindir=${CMAKE_BINARY_DIR}/examples/my-test/
158          --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/my-test/
159          --cd ${CMAKE_HOME_DIRECTORY}/examples/my-test/
160          ${CMAKE_HOME_DIRECTORY}/examples/msg/io/io.tesh
161 )
162 \endverbatim             
163
164 As usual, you must run "make distcheck" after modifying the cmake files,
165 to ensure that you did not forget any files in the distributed archive.
166
167 \section inside_tests_ci Continous Integration
168
169 We use several systems to automatically test SimGrid with a large set
170 of parameters, across as many platforms as possible. 
171 We use <a href="https://ci.inria.fr/simgrid/">Jenkins on Inria
172 servers</a> as a workhorse: it runs all of our tests for many
173 configurations. It takes a long time to answer, and it often reports
174 issues but when it's green, then you know that SimGrid is very fit!
175 We use <a href="https://travis-ci.org/mquinson/simgrid">Travis</a> to
176 quickly run some tests on Linux and Mac. It answers quickly but may
177 miss issues. And we use <a href="https://ci.appveyor.com/project/mquinson/simgrid">AppVeyor</a>
178 to build and somehow test SimGrid on windows. 
179
180 \subsection inside_tests_jenkins Jenkins on the Inria CI servers
181
182 You should not have to change the configuration of the Jenkins tool
183 yourself, although you could have to change the slaves' configuration
184 using the <a href="https://ci.inria.fr">CI interface of INRIA</a> --
185 refer to the <a href="https://wiki.inria.fr/ciportal/">CI documentation</a>.
186
187 The result can be seen here: https://ci.inria.fr/simgrid/
188
189 We have 3 projects on Jenkins:
190 \li <a href="https://ci.inria.fr/simgrid/job/SimGrid-Multi/">SimGrid-Multi</a>
191     is the main project, running the tests that we spoke about.\n It is
192     configured (on Jenkins) to run the script <tt>tools/jenkins/build.sh</tt>
193 \li <a href="https://ci.inria.fr/simgrid/job/SimGrid-DynamicAnalysis/">SimGrid-DynamicAnalysis</a>
194     runs the tests both under valgrind to find the memory errors and
195     under gcovr to report the achieved test coverage.\n It is configured
196     (on Jenkins) to run the script <tt>tools/jenkins/DynamicAnalysis.sh</tt>
197 \li <a href="https://ci.inria.fr/simgrid/job/SimGrid-Windows/">SimGrid-Windows</a>
198     is an ongoing attempt to get Windows tested on Jenkins too.
199
200 In each case, SimGrid gets built in
201 /builds/workspace/$PROJECT/build_mode/$CONFIG/label/$SERVER/build 
202 with $PROJECT being for instance "SimGrid-Multi", $CONFIG "DEBUG" or
203 "ModelChecker" and $SERVER for instance "simgrid-fedora20-64-clang".
204
205 If some configurations are known to fail on some systems (such as
206 model-checking on non-linux systems), go to your Project and click on
207 "Configuration". There, find the field "combination filter" (if your
208 interface language is English) and tick the checkbox; then add a
209 groovy-expression to disable a specific configuration. For example, in
210 order to disable the "ModelChecker" build on host
211 "small-freebsd-64-clang", use:
212
213 \verbatim
214 (label=="small-freebsd-64-clang").implies(build_mode!="ModelChecker")
215 \endverbatim
216
217 \subsection inside_tests_travis Travis
218
219 Travis is a free (as in free beer) Continuous Integration system that
220 open-sourced project can use freely. It is very well integrated in the
221 GitHub ecosystem. There is a plenty of documentation out there. Our
222 configuration is in the file .travis.yml as it should be, and the
223 result is here: https://travis-ci.org/mquinson/simgrid
224
225 \subsection inside_tests_appveyor AppVeyor
226
227 AppVeyor aims at becoming the Travis of Windows. It is maybe less
228 mature than Travis, or maybe it is just that I'm less trained in
229 Windows. Our configuration is in the file appveyor.yml as it should
230 be, and the result is here: https://ci.appveyor.com/project/mquinson/simgrid
231
232 It should be noted that I miserably failed to use the environment
233 provided by AppVeyor, since SimGrid does not build with Microsoft
234 Visual Studio. Instead, we download a whole development environment
235 from the internet at each build. That's an archive of already compiled
236 binaries that are unpacked on the appveyor systems each time we start.
237 We re-use the ones from the 
238 <a href="https://github.com/symengine/symengine">symengine</a>
239 project. Thanks to them for compiling sane tools and constituting that
240 archive, it saved my mind! 
241
242 */