Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
get rid of surf_exit()
[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 logged 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 unit-tests binary, that lives at the
45 source root. These tests are run when you launch ctest, don't worry.
46
47 @verbatim
48 make unit-tests                 # Rebuild the test runner on need
49 ./unit-tests                    # Launch all tests
50 ./unit-tests --help             # revise how it goes if you forgot
51 @endverbatim
52
53
54 @section inside_tests_add_units Adding unit tests
55
56 Our unit tests are written using the Catch2 library, that is included
57 in the source tree. Please check for examples, listed at the end of
58 tools/cmake/Tests.cmake.
59
60 It is important to keep your tests fast. We run them very very often,
61 and you should strive to make them as fast as possible, to not bother
62 the other developers. Do not hesitate to stress test your code, but
63 make sure that it runs reasonably fast, or nobody will run "ctest"
64 before committing code.
65
66 @section inside_tests_add_integration Adding integration tests
67
68 TESH (the TEsting SHell) is the test runner that we wrote for our
69 integration tests. It is distributed with the SimGrid source file, and
70 even comes with a man page. TESH ensures that the output produced by a
71 command perfectly matches the expected output. This is very precious
72 to ensure that no change modifies the timings computed by the models
73 without notice. 
74
75 To add a new integration test, you thus have 3 things to do:
76
77  - <b>Write the code exercising the feature you target</b>. You should
78    strive to make this code clear, well documented and informative for
79    the users. If you manage to do so, put this somewhere under
80    examples/ and modify the cmake files as explained on this page:
81    @ref inside_cmake_examples. If you feel like you should write a
82    torture test that is not interesting to the users (because nobody
83    would sanely write something similar in user code), then put it under 
84    teshsuite/ somewhere.
85    
86  - <b>Write the tesh file</b>, containing the command to run, the
87    provided input (if any, but almost no SimGrid test provide such an
88    input) and the expected output. Check the tesh man page for more
89    details.@n
90    Tesh is sometimes annoying as you have to ensure that the expected
91    output will always be exactly the same. In particular, your should
92    not output machine dependent information such as absolute data
93    path, nor memory addresses as they would change on each run. Several
94    steps can be used here, such as the obfucation of the memory
95    addresses unless the verbose logs are displayed (using the
96    #XBT_LOG_ISENABLED() macro), or the modification of the log formats
97    to hide the timings when they depend on the host machine.@n
98    The script located in <project/directory>/tools/tesh/generate_tesh can
99    help you a lot in particular if the output is large (though a smaller output is preferable). 
100    There are also example tesh files in the <project/directory>/tools/tesh/ directory, that can be useful to understand the tesh syntax.
101    
102  - <b>Add your test in the cmake infrastructure</b>. For that, modify
103    the following file:
104    @verbatim
105    <project/directory>/teshsuite/<interface eg msg>/CMakeLists.txt
106    @endverbatim   
107    Make sure to pick a wise name for your test. It is often useful to
108    check a category of tests together. The only way to do so in ctest
109    is to use the -R argument that specifies a regular expression that
110    the test names must match. For example, you can run all MSG test
111    with "ctest -R msg". That explains the importance of the test
112    names.
113
114 Once the name is chosen, create a new test by adding a line similar to
115 the following (assuming that you use tesh as expected).
116
117 @verbatim
118 # Usage: ADD_TEST(test-name ${CMAKE_BINARY_DIR}/bin/tesh <options> <tesh-file>)
119 #  option --setenv bindir set the directory containing the binary
120 #         --setenv srcdir set the directory containing the source file
121 #         --cd set the working directory
122 ADD_TEST(my-test-name ${CMAKE_BINARY_DIR}/bin/tesh 
123          --setenv bindir=${CMAKE_BINARY_DIR}/examples/my-test/
124          --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/my-test/
125          --cd ${CMAKE_HOME_DIRECTORY}/examples/my-test/
126          ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/io/io.tesh
127 )
128 @endverbatim             
129
130 As usual, you must run "make distcheck" after modifying the cmake files,
131 to ensure that you did not forget any files in the distributed archive.
132
133 @section inside_tests_ci Continuous Integration
134
135 We use several systems to automatically test SimGrid with a large set
136 of parameters, across as many platforms as possible. 
137 We use <a href="https://ci.inria.fr/simgrid/">Jenkins on Inria
138 servers</a> as a workhorse: it runs all of our tests for many
139 configurations. It takes a long time to answer, and it often reports
140 issues but when it's green, then you know that SimGrid is very fit!
141 We use <a href="https://ci.appveyor.com/project/mquinson/simgrid">AppVeyor</a>
142 to build and somehow test SimGrid on windows. 
143
144 @subsection inside_tests_jenkins Jenkins on the Inria CI servers
145
146 You should not have to change the configuration of the Jenkins tool
147 yourself, although you could have to change the slaves' configuration
148 using the <a href="https://ci.inria.fr">CI interface of INRIA</a> --
149 refer to the <a href="https://wiki.inria.fr/ciportal/">CI documentation</a>.
150
151 The result can be seen here: https://ci.inria.fr/simgrid/
152
153 We have 2 interesting projects on Jenkins:
154 @li <a href="https://ci.inria.fr/simgrid/job/SimGrid/">SimGrid</a>
155     is the main project, running the tests that we spoke about.@n It is
156     configured (on Jenkins) to run the script <tt>tools/jenkins/build.sh</tt>
157 @li <a href="https://ci.inria.fr/simgrid/job/SimGrid-DynamicAnalysis/">SimGrid-DynamicAnalysis</a>
158     should be called "nightly" because it does not only run dynamic
159     tests, but a whole bunch of long lasting tests: valgrind (memory
160     errors), gcovr (coverage), Sanitizers (bad pointer usage, threading
161     errors, use of unspecified C constructs) and the clang static analyzer.@n It is configured
162     (on Jenkins) to run the script <tt>tools/jenkins/DynamicAnalysis.sh</tt>
163
164 In each case, SimGrid gets built in
165 /builds/workspace/$PROJECT/build_mode/$CONFIG/label/$SERVER/build 
166 with $PROJECT being for instance "SimGrid", $CONFIG "DEBUG" or
167 "ModelChecker" and $SERVER for instance "simgrid-fedora20-64-clang".
168
169 If some configurations are known to fail on some systems (such as
170 model-checking on non-linux systems), go to your Project and click on
171 "Configuration". There, find the field "combination filter" (if your
172 interface language is English) and tick the checkbox; then add a
173 groovy-expression to disable a specific configuration. For example, in
174 order to disable the "ModelChecker" build on host
175 "small-netbsd-64-clang", use:
176
177 @verbatim
178 (label=="small-netbsd-64-clang").implies(build_mode!="ModelChecker")
179 @endverbatim
180
181 Just for the record, the slaves were created from the available
182 template with the following commands:
183 @verbatim
184 #debian/ubuntu
185 apt-get install gcc g++ gfortran automake cmake libboost-dev openjdk-8-jdk openjdk-8-jre libxslt-dev libxml2-dev libevent-dev libunwind-dev libdw-dev htop git python3 xsltproc libboost-context-dev
186 #for dynamicanalysis: 
187 apt-get install jacoco libjacoco-java libns3-dev pcregrep gcovr ant lua5.3-dev sloccount
188
189 #fedora
190 dnf install libboost-devel openjdk-8-jdk openjdk-8-jre libxslt-devel libxml2-devel xsltproc git python3 libdw-devel libevent-devel libunwind-devel htop lua5.3-devel
191
192 #netbsd
193 pkg_add cmake gcc7 boost boost-headers automake openjdk8 libxslt libxml2 libunwind git htop python36
194
195 #opensuse
196 zypper install cmake automake clang boost-devel java-1_8_0-openjdk-devel libxslt-devel libxml2-devel xsltproc git python3 libdw-devel libevent-devel libunwind-devel htop binutils ggc7-fortran
197
198 #freebsd
199 pkg install boost-libs cmake openjdk8 automake libxslt libxml2 libunwind git htop python3  automake gcc6 flang elfutils libevent
200 #+ clang-devel from ports
201
202 #osx
203 brew install cmake boost libunwind-headers libxslt git python3 
204 @endverbatim
205
206 @subsection inside_tests_appveyor AppVeyor
207
208 Our configuration is in the file appveyor.yml as it should
209 be, and the result is here: https://ci.appveyor.com/project/mquinson/simgrid
210
211 We use @c Choco as a package manager on AppVeyor, and it is sufficient
212 for us. In the future, we will probably move to the ubuntu subsystem
213 of Windows 10: SimGrid performs very well under these settings, as
214 tested on Inria's CI servers. For the time being having a native
215 library is still useful for the Java users that don't want to install
216 anything beyond Java on their windows.
217
218 @subsection inside_tests_debian Debian builders
219
220 Since SimGrid is packaged in Debian, we benefit from their huge
221 testing infrastructure. That's an interesting torture test for our
222 code base. The downside is that it's only for the released versions of
223 SimGrid. That is why the Debian build does not stop when the tests
224 fail: post-releases fixes do not fit well in our workflow and we fix
225 only the most important breakages.
226
227 The build results are here:
228 https://buildd.debian.org/status/package.php?p=simgrid
229
230 @subsection inside_tests_sonarqube SonarQube
231
232 SonarQube is an open-source code quality analysis solution. Their nice
233 code scanners are provided as plugin. The one for C++ is not free, but
234 open-source project can use it at no cost. That is what we are doing.
235
236 Don't miss the great looking dashboard here: 
237 https://sonarcloud.io/dashboard?id=simgrid_simgrid
238
239 */