1--- 2title: Automation of unit-tests of scientific tools using `tfel-check` 3author: Thomas Helfer, Stéphane Bernaud 4date: 21/11/2017 5lang: en-EN 6link-citations: true 7colorlinks: true 8figPrefixTemplate: "$$i$$" 9tabPrefixTemplate: "$$i$$" 10secPrefixTemplate: "$$i$$" 11eqnPrefixTemplate: "($$i$$)" 12--- 13 14`tfel-check` is a tool designed to launch unit-tests and provide tools 15to test the outputs. `tfel-check` mostly targets scientific application 16which does not have in-house abilities to compare their results to 17reference results. 18 19# Overview 20 21## Basic usage 22 23The basic usage of `tfel-check` is simply to call `tfel-check` without 24options: 25 26~~~~{.bash} 27$ tfel-check 28~~~~ 29 30`tfel-check` will then execute the tests and comparisons described in 31every file with the extension `.check` in the current directory and, 32recursively, in all the subdirectories. The syntax of of those files are 33described in Section @sec:tfel_check:input_files. 34 35One may also specify only a set of files to be considered, as follows: 36 37~~~~{.bash} 38$ tfel-check test1.check test2.check 39~~~~ 40 41One may also specify a configuration file using the `--config` command 42line option, as follows: 43 44~~~~{.bash} 45$ tfel-check --config=test.config 46~~~~ 47 48The configuration files are described in Section 49@sec:tfel_check:configuration_files. 50 51Substitution strings can be specified in configuration files or in the 52command line, as follows: 53 54~~~~{.bash} 55$ tfel-check --@python@=python3.5 56~~~~ 57 58With this option, every occurrence of `@python@` will be replaced by 59`python3.5`. 60 61## A first example 62 63Let us consider this simple test file: 64 65~~~~{.cxx} 66@Requires {"tfel::madnex","mfront::python"}; 67@Command "@python@ OverridableImplementation.py"; 68@Command "mfront-query --author --material=A316LN --behaviour=Plasticity_SRMA2022 Plasticity.madnex"{ 69 expected_output : "John Mac Enroe" 70}; 71~~~~ 72 73The first line, which begins with the `@Requires` keywords, provides a 74list of required components. In this case, the components `tfel::madnex` 75and `mfront::python` are required to execute the tests described in this 76file. The tests are skipped if those requirements are not met. The 77definition of components can be done in a configuration file, as 78detailed in Section @sec:tfel_check:configuration_files. The components 79defined by defaults by `tfel-check` is described in Section 80@sec:tfel_check:default_components. 81 82The second line specifies the first command to be run and begins with the 83`@Command` keyword. It is followed by the command to be launched. The 84`@python@` syntax designates that a substitution string must be provided 85to precise the `python` interpreter to be used. 86 87The third line specifies a second command which launches `mfront-query` 88and a first test which compares the command line output to an expected 89one. 90 91This file can can be launched as follows: 92 93~~~~{.bash} 94$ tfel-check --@python@=python3.5 madnex.check 95entering directory '/tmp/madnex' 96* beginning of test './madnex.check' 97** Exec-1 python3.5 MadnexTest.py [SUCCESS] 98** Exec-2 python3.5 OverridableImplementation.py [SUCCESS] 99** Exec-3 mfront-query --author --material=A316LN --behaviour=Plast... [SUCCESS] 100* end of test './madnex.check' [SUCCESS] 101====== 102~~~~ 103 104This command produces several files: 105 106- `tfel-check.log`: this file contains the ouptut of `tfel-check`. This 107 file is created in the directory where `tfel-check` has been invoked. 108- `madnex.checklog`: this file contains a summary of the execution of 109 the commands and test described in the `madnex.check` file. A similar 110 file is created for each file considered by `tfel-check`. 111- Three files `madnex-Exec-1.out`, `madnex-Exec-2.out` and 112 `madnex-Exec-3.out` associated to the three commands listed in the 113 `madnex.check` file. Those files contains the output of each commands 114 and the execution time of the command. 115- `TEST-madnex.xml` is an `XML` file conforming the `JUnit` standard 116 that summarises the results and which is suitable for the integration 117 of the test case in the [`jenkins` automation 118 server](https://www.jenkins.io/). 119 120If the requirements are not met, the executation and the tests are 121marked as skipped: 122 123~~~~{.bash} 124$ tfel-check 125entering directory '/tmp/madnex' 126* beginning of test './madnex.check' 127** Exec-1 @python@ MadnexTest.py [SKIPPED] 128** Exec-2 @python@ OverridableImplementation.py [SKIPPED] 129** Exec-3 mfront-query --author --material=A316LN --behaviour=Plast... [SKIPPED] 130* end of test './madnex.check' [SUCCESS] 131====== 132~~~~ 133 134If the execution of a command fails, this is reported as follows: 135 136~~~~{.bash} 137$ tfel-check --@python@=python2.7 138entering directory '/tmp/madnex' 139* beginning of test './madnex.check' 140** Exec-1 toto MadnexTest.py [ FAILED] 141** Exec-2 toto OverridableImplementation.py [ FAILED] 142** Exec-3 mfront-query --author --material=A316LN --behaviour=Plast... [ FAILED] 143* end of test './madnex.check' [ FAILED] 144====== 145~~~~ 146 147## A more complex example 148 149For this second example, let us consider a tensile test simulated using 150the `Cast3M` finite element solver. The test case uses an `MFront` file 151to define the behaviour and generates a text file called 152`ImplicitSimoMieheElastoPlasticityUniaxialTesting-castem.res` containing 153the evolution of the stress along the tensile axis as a function of 154time. 155 156The `ImplicitSimoMieheElastoPlasticity.check` file has the following 157content: 158 159~~~~{.cxx} 160@Requires {"Cast3M", "mfront::behaviour::castem_interface"}; 161@Command "mfront --obuild --interface=castem ImplicitSimoMieheElastoPlasticity.mfront"; 162@Command "@castem@ ImplicitSimoMieheElastoPlasticityUniaxialTesting.dgibi"; 163 164@Precision 100; // criterion for the check, here a difference of 100Pa is allowed 165@Test "ImplicitSimoMieheElastoPlasticityUniaxialTesting-castem.res" 166 "ImplicitSimoMieheElastoPlasticityUniaxialTesting-castem.ref" 2; 167~~~~ 168 169The first line specifies that the `Cast3M` component must be available 170and that the support of the `Cast3M` interface is available in `MFront`. 171The second line compiles the behaviour. 172 173The third one launches the `Cast3M` simulation. This line assumes that a 174substitution string for the `@castem@` pattern has been defined. 175 176The fifth line specify an absolute criterion to compare the current 177results to the reference ones. The last line defines the test to be 178performed: the values of the second column of the two specified files 179are compared using an absolute criteria. 180 181To trigger those tests, the following config file, called 182`castem.config` can be used: 183 184~~~~{.cxx} 185components : {"Cast3M"}; 186substitutions : {"castem": "castem2019_PLEIADES"}; 187~~~~ 188 189The tests are run as follows: 190 191~~~~{.bash} 192$ tfel-check --config=castem.config 193entering directory '/tmp/tfel-check' 194* beginning of test './ImplicitSimoMieheElastoPlasticity.check' 195** Exec-1 mfront --obuild --interface=castem ImplicitSimoMieheElast... [SUCCESS] 196** Exec-2 castem2019_PLEIADES ImplicitSimoMieheElastoPlasticityUnia... [SUCCESS] 197** Compare-1 'ImplicitSimoMieheElastoPlasticityUniaxialTesting-cast... [SUCCESS] 198* end of test './ImplicitSimoMieheElastoPlasticity.check' [SUCCESS] 199~~~~ 200 201# Description of the input files{#sec:tfel_check:input_files} 202 203## List of available keywords 204 205### The `@Requires` keyword 206 207The `@Requires` keyword specifies the components that are required to 208run the tests described in the considered input file. 209 210### The `@Environment` keyword 211 212The `@Environment` keyword specifies a set of environment variables that 213will be defined accessible to the commands. 214 215### The `@Command` keyword 216 217The `@Command` keyword specifies a command to be launched. 218 219This keyword has the following options: 220 221- `expected_output`: a string specifying the expected output. If the 222 actual output differs from the expected one, the tests is marked as 223 failed. 224 225### The `@Precision` keyword 226 227The `@Precision` keyword specifies the comparison criterion used to 228compare the current values and the reference ones. 229 230~~~~{.cxx} 231@Precision 1.e-6; 232~~~~ 233 234### The `@Test` keyword 235 236The `@Test` keyword specifies two files to compare which represents 237respectively the current simulated values and the reference ones. 238 239### The `@TestType` keyword 240 241The `@TestType` keyword specifies how the comparison between the 242simulated values and the reference values shall be performed. 243 244The following kind of comparison are available: 245 246- `Absolute`: 247- `Relative`: 248- `RelativeAndAbsolute`: 249- `Mixed`: 250- `Area`: 251 252### The `@Interpolation` keyword 253 254The `@Interpolation` keyword specifies how the reference values can be 255interpolated. The following interpolations are available: 256 257- `None`: 258- `Linear`: 259- `Spline`: 260- `LocalSpline`: 261 262# Description of the configuration files{#sec:tfel_check:configuration_files} 263 264Configuration files can be used to define: 265 266- substitution strings 267- available components 268 269The syntax of configuration file is loosely inspired by the `JSON` 270format and looks like: 271 272~~~~{.cxx} 273components : {"pleiades::python"}; 274substitutions : {"python" : "python3.5"}; 275~~~~ 276 277# Default components {#sec:tfel_check:default_components} 278 279Some components are conditionally defined by `tfel-check`. 280 281- If the `python` bindings of the `TFEL` project have been enabled, the 282 following components are declared: `tfel::python` and 283 `mfront::python`. 284- If the `madnex` support has been enabled, the component `tfel::madnex` 285 is declared. 286 287For each `MFront`' interface for material properties, a component called 288`mfront::material_property::<name>_interface` is defined, where `<name>` 289shall be replaced by the name of the interface. 290 291For each behaviour interface, a component named 292`mfront::behaviour::<name>_interface` is declared, where `<name>` is the 293name of the interface. 294 295For each model interface, a component named 296`mfront::model::<name>_interface` is declared, where `<name>` is the 297name of the interface. 298 299Those default components can be listed using the 300`--list-default-components` command line options, as follows: 301 302~~~~{.cxx} 303$ tfel-check --list-default-components 304- tfel::python 305- mfront::python 306- tfel::madnex 307- mfront::material_property::C++_interface 308- mfront::material_property::Cpp_interface 309- mfront::material_property::Cxx_interface 310- mfront::material_property::Python_interface 311- mfront::material_property::c_interface 312- mfront::material_property::c++_interface 313- mfront::material_property::cpp_interface 314- mfront::material_property::cpptest_interface 315- mfront::material_property::cxx_interface 316- mfront::material_property::excel_interface 317- mfront::material_property::excel-internal_interface 318- mfront::material_property::gnuplot_interface 319- mfront::material_property::mfront_interface 320- mfront::material_property::octave_interface 321- mfront::material_property::python_interface 322- mfront::behaviour::generic_interface 323- mfront::model::mfront_interface 324~~~~ 325