| 31 | | to get uptodate and install the currently non-default '''nosebit''' external. Which provides the tools : |
| 32 | | || nosetests || test running entry point || |
| 33 | | || easy_install || install python packages into NuWa python || |
| 34 | | || bitten-slave || communicates with bitten-master for instructions on tests (or builds) to be performed || |
| 35 | | |
| 36 | | Check your installation by getting into the CMT controlled environment of your default package, and trying these |
| | 36 | to get uptodate and install the '''nosebit''' external. |
| | 37 | |
| | 38 | == Check the '''nosebit''' installation == |
| | 39 | |
| | 40 | Check your installation by getting into the CMT controlled environment of any package that uses python, and trying these |
| 175 | | = Automated Test Running = |
| | 180 | = Automated Build/Test Running = |
| | 181 | |
| | 182 | The results of automated testing are reported by the Bitten Trac plugin at |
| | 183 | * i:build summary of all configurations |
| | 184 | * i:build/dybinst details for the '''dybinst''' configuration |
| | 185 | |
| | 186 | Some documentation on test triggering criteria are given on the above pages. |
| | 187 | |
| | 188 | == Adding a script to automated testing == |
| | 189 | |
| | 190 | === Create the test === |
| | 191 | |
| | 192 | * Create a '''tests''' directory as sibling to the cmt directory of the project |
| | 193 | * Add a interface script at path {{{tests/test_myscript.py}}} |
| | 194 | * NB the directory must be called '''tests''' and the filename must be of form '''test_*.py''' |
| | 195 | |
| | 196 | Example of {{{tests/test_myscript.py}}} : |
| | 197 | {{{ |
| | 198 | #!py |
| | 199 | from dybtest import Matcher, Run |
| | 200 | """ |
| | 201 | Example of interfacing : |
| | 202 | "python share/myscript.py myarg1 myarg2" |
| | 203 | into the automated testing system, without modifcation to the script. |
| | 204 | |
| | 205 | The script is run in a subprocess and the stdout/stderr is piped out and examined by the |
| | 206 | matcher using python regular expressions that are matched against every line of output |
| | 207 | providing line return codes when a match is found. |
| | 208 | The maximum return code from all the lines of output is the matcher return code, |
| | 209 | which if greater than zero causes the test to fail |
| | 210 | |
| | 211 | If the running time of subprocess script exceeds the configured maxtime (in seconds), |
| | 212 | the subprocess is killed. |
| | 213 | |
| | 214 | """ |
| | 215 | |
| | 216 | checks = { |
| | 217 | '.*FATAL':2, |
| | 218 | '.*ERROR':1, |
| | 219 | '.*\*\*\* Break \*\*\* segmentation violation':3, |
| | 220 | '^\#\d':None |
| | 221 | } |
| | 222 | |
| | 223 | m = Matcher( checks, verbose=False ) |
| | 224 | |
| | 225 | opts = { 'maxtime':300 } |
| | 226 | |
| | 227 | def test_myscript(): |
| | 228 | Run( "python share/myscript.py myarg1 myarg2" , parser=m , opts=opts )().assert_() |
| | 229 | |
| | 230 | if __name__=='__main__': |
| | 231 | test_myscript() |
| | 232 | }}} |
| | 233 | |
| | 234 | This uses functionality provided in i:source:installation/trunk/dybtest/python/dybtest which is |
| | 235 | made globally available via '''nosebit_dybtest'''. |
| | 236 | |
| | 237 | |
| | 238 | === Introduce the test to the automated testing system === |
| | 239 | |
| | 240 | * Add a '''step''' element to the relevant recipes : |
| | 241 | * i:source:installation/trunk/dybtest/recipes/dybinst.xml |
| | 242 | |
| | 243 | {{{ |
| | 244 | #!xml |
| | 245 | <step id="test-myproject" description="test-myproject" onerror="continue" > |
| | 246 | <sh:exec executable="bash" output="test-myproject.out" |
| | 247 | args=" -c " &env; export BUILD_TEST=myproject ; export BUILD_PATH=dybgaudi/trunk/Simulation/MyProject ; &test; " " /> |
| | 248 | <python:unittest file="test-myproject.xml" /> |
| | 249 | </step> |
| | 250 | }}} |
| | 251 | |
| | 252 | Note that two variables must be exported : |
| | 253 | * BUILD_TEST : name of test that must match that used in the '''python:unittest''' element |
| | 254 | * BUILD_PATH : repository path (including the trunk) of your project |
| | 255 | |
| | 256 | To follow what is happening examine the entity definitions at the top of the recipe. |
| | 257 | |
| | 258 | After committing the updated recipe, all the slaves should being to perform your additional tests. |
| | 259 | |
| | 260 | |
| 203 | | <!-- |
| 204 | | the NUWA_HOME is needed to work with older bash that does not have BASH_SOURCE |
| 205 | | --> |
| 206 | | |
| 207 | | <step id="update" description="dybinst checkout and rebuild " onerror="continue" > |
| 208 | | <sh:exec executable="bash" output="hello.out" |
| 209 | | args=" -c " &env; dyb__hello ; echo it returned $? " " /> |
| 210 | | <sh:exec executable="bash" output="update.out" |
| 211 | | args=" -c " &env; dyb__update ; echo it returned $? " " /> |
| 212 | | </step> |
| 213 | | |
| 214 | | <step id="txttest" description="Run tests with txt output " onerror="continue" > |
| 215 | | <sh:exec executable="bash" output="txttest.out" |
| 216 | | args=" -c " &env; dyb__test " " /> |
| 217 | | </step> |
| 218 | | |
| 219 | | <step id="xmltest" description="Run tests with xml output " onerror="continue" > |
| 220 | | <sh:exec executable="bash" output="xmltest.out" |
| 221 | | args=" -c " &env; dyb__test --with-xml-output --xml-outfile=$iwd/nosetests.xml " " /> |
| 222 | | <python:unittest file="nosetests.xml" /> |
| 223 | | </step> |
| | 289 | <step id="checkout" description="checkout" onerror="continue" > <sh:exec executable="bash" output="checkout.out" args=" -c " &env; dyb__checkout " " /> </step> |
| | 290 | <step id="external" description="external" onerror="continue" > <sh:exec executable="bash" output="external.out" args=" -c " &env; dyb__external " " /> </step> |
| | 291 | <step id="relax" description="relax" onerror="continue" > <sh:exec executable="bash" output="relax.out" args=" -c " &env; dyb__projects relax " " /> </step> |
| | 292 | <step id="gaudi" description="gaudi" onerror="continue" > <sh:exec executable="bash" output="gaudi.out" args=" -c " &env; dyb__projects gaudi " " /> </step> |
| | 293 | <step id="lhcb" description="lhcb" onerror="continue" > <sh:exec executable="bash" output="lhcb.out" args=" -c " &env; dyb__projects lhcb " " /> </step> |
| | 294 | <step id="dybgaudi" description="dybgaudi" onerror="continue" > <sh:exec executable="bash" output="dybgaudi.out" args=" -c " &env; dyb__projects dybgaudi " " /> </step> |
| | 295 | |
| | 296 | |
| | 297 | <step id="test-gentools" description="test-gentools" onerror="continue" > |
| | 298 | <sh:exec executable="bash" output="test-gentools.out" |
| | 299 | args=" -c " &env; test=gentools ; export BUILD_PATH=dybgaudi/trunk/Simulation/GenTools ; &test; " " /> |
| | 300 | <python:unittest file="test-gentools.xml" /> |
| | 301 | </step> |
| | 302 | |
| | 303 | <step id="test-rootio" description="test-rootio" onerror="continue" > |
| | 304 | <sh:exec executable="bash" output="test-rootio.out" |
| | 305 | args=" -c " &env; test=rootio ; export BUILD_PATH=dybgaudi/trunk/RootIO/RootIOTest ; &test; " " /> |
| | 306 | <python:unittest file="test-rootio.xml" /> |
| | 307 | </step> |
| | 308 | |
| 245 | | the master $HOME/.bitrunrc : |
| 246 | | {{{ |
| 247 | | # |
| 248 | | # name used for logfile and tmp directory identification |
| 249 | | # |
| 250 | | local name=trialrun |
| | 333 | the master $HOME/.slaverc : |
| | 334 | {{{ |
| | 335 | |
| | 336 | # |
| | 337 | # generated on : Thu Sep 11 17:39:04 CST 2008 |
| | 338 | # by function : slave-demorc |
| | 339 | # from script : /data/env/local/dyb/trunk_dbg/installation/trunk/dybtest/scripts/slave.bash |
| | 340 | # |
| | 341 | # |
| | 342 | # name used for logfile and tmp directory identification and identification of the |
| | 343 | # slave on the server ... convention is to use the NEWCMTCONFIG string |
| | 344 | # |
| | 345 | local name=i686-slc46-gcc346 |