reports/Builder__ReportRunner.st
author Claus Gittinger <cg@exept.de>
Thu, 28 Mar 2019 13:54:38 +0100
changeset 542 aa25a71be62a
parent 243 625f6907682a
permissions -rw-r--r--
#DOCUMENTATION by cg
class: stx_goodies_builder_quickSelfTest
class definition

class: stx_goodies_builder_quickSelfTest class
added:18 methods
jan@72
     1
"{ Package: 'stx:goodies/builder/reports' }"
jan@72
     2
jan@72
     3
"{ NameSpace: Builder }"
jan@72
     4
jan@72
     5
StandaloneStartup subclass:#ReportRunner
jan@72
     6
	instanceVariableNames:''
jan@72
     7
	classVariableNames:''
jan@72
     8
	poolDictionaries:''
jan@72
     9
	category:'Builder-Reports'
jan@72
    10
!
jan@72
    11
jan@217
    12
ReportRunner class instanceVariableNames:'parser report debugging setup teardown ident'
jan@72
    13
jan@72
    14
"
jan@72
    15
 The following class instance variables are inherited by this class:
jan@72
    16
jan@72
    17
	StandaloneStartup - MutexHandle
jan@217
    18
	Object - 
jan@72
    19
"
jan@72
    20
!
jan@72
    21
jan@72
    22
jan@72
    23
!ReportRunner class methodsFor:'initialization'!
jan@72
    24
jan@72
    25
initialize
jan@72
    26
jan@72
    27
    super initialize.
jan@72
    28
    debugging := Transcript notNil and:[Transcript isView].
jan@184
    29
    self setupSignalHandlers.
jan@72
    30
jan@72
    31
    "Created: / 06-11-2011 / 22:07:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
    32
    "Modified: / 28-06-2013 / 01:13:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@72
    33
! !
jan@72
    34
jan@72
    35
!ReportRunner class methodsFor:'command line options'!
jan@72
    36
jan@217
    37
cmdlineOptionIdent
jan@217
    38
jan@217
    39
    ^CmdLineOption new
jan@217
    40
        short: $i;
jan@217
    41
        long: 'ident';
jan@217
    42
        description: 'run/configuration identification';
jan@217
    43
        action:[:option |
jan@217
    44
            ident := option.
jan@217
    45
        ];
jan@217
    46
        yourself
jan@217
    47
jan@217
    48
    "Created: / 22-01-2014 / 10:00:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@217
    49
!
jan@217
    50
jan@72
    51
cmdlineOptionOutputDirectory
jan@72
    52
jan@72
    53
    ^CmdLineOption new
jan@72
    54
        short: $D;
jan@72
    55
        long: 'output-directory';
jan@72
    56
        description: 'Default report output directory';
jan@188
    57
        action:[:outputdir |
jan@72
    58
            Report outputDir: outputdir.
jan@72
    59
            self  verboseInfo:'Report dir: ' , Report outputDir asString.
jan@217
    60
        ];
jan@217
    61
        yourself
jan@72
    62
jan@72
    63
    "Created: / 06-11-2011 / 09:33:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@217
    64
    "Modified: / 22-01-2014 / 10:00:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@72
    65
!
jan@72
    66
jan@72
    67
cmdlineOptionReport
jan@72
    68
jan@72
    69
    ^CmdLineOption new
jan@72
    70
        short: $r;
jan@97
    71
        long: 'report';
jan@72
    72
        description: 'Report to run';
jan@72
    73
        action:[:option |
jan@72
    74
            report := Smalltalk at: option asSymbol.
jan@72
    75
            report isNil ifTrue:[
jan@188
    76
                Stderr nextPutLine:('ERROR: Report class %1 does not exist (forgot to load package?)' bindWith: option).
jan@188
    77
                "/Smalltalk exit: 1.
jan@72
    78
            ].
jan@72
    79
            report := report new.
jan@72
    80
            parser options addAll: (CmdLineOption optionsFor: report)
jan@217
    81
        ];
jan@217
    82
        yourself
jan@72
    83
jan@72
    84
    "Created: / 06-11-2011 / 09:45:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@217
    85
    "Modified: / 22-01-2014 / 10:00:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@147
    86
!
jan@147
    87
jan@147
    88
cmdlineOptionSetup
jan@147
    89
jan@147
    90
    ^CmdLineOption new
jan@225
    91
        short: $S;
jan@147
    92
        long: 'setup';
jan@147
    93
        description: 'Code executed before tests are loaded and executed';
jan@188
    94
        action:[:option |
jan@147
    95
            setup := option
jan@217
    96
        ];
jan@217
    97
        yourself
jan@147
    98
jan@147
    99
    "Created: / 15-05-2013 / 16:50:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@225
   100
    "Modified: / 24-01-2014 / 15:26:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@147
   101
!
jan@147
   102
jan@147
   103
cmdlineOptionTeardown
jan@147
   104
jan@147
   105
    ^CmdLineOption new
jan@217
   106
        short: $T;
jan@217
   107
        long: 'teardown';
jan@147
   108
        description: 'Code executed after all tests are executed';
jan@188
   109
        action:[:option |
jan@147
   110
            teardown := option
jan@217
   111
        ];
jan@217
   112
        yourself
jan@147
   113
jan@147
   114
    "Created: / 15-05-2013 / 16:50:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@217
   115
    "Modified: / 22-01-2014 / 10:01:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@72
   116
! !
jan@72
   117
jan@184
   118
!ReportRunner class methodsFor:'debugging'!
jan@184
   119
jan@184
   120
dumpProcess: aProcess
jan@184
   121
    Stderr cr; cr
jan@184
   122
jan@184
   123
    "Created: / 27-06-2013 / 23:41:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
   124
!
jan@184
   125
jan@184
   126
dumpProcess: aProcess on: aStream
jan@184
   127
    | ctx |
jan@184
   128
    aStream cr; cr.
jan@184
   129
    aStream nextPutAll: '== ['; nextPutAll: aProcess id printString; nextPutAll:'] '; nextPutAll: aProcess name; nextPutAll: ' =='; cr.
jan@184
   130
    aStream cr.
jan@238
   131
    aStream nextPutAll: '  State:   '; nextPutAll: aProcess state printString; cr.
jan@238
   132
    aStream nextPutAll: '  Group:   '; nextPutAll: aProcess processGroupId printString; cr.
jan@238
   133
    aStream nextPutAll: '  Creator: '; nextPutAll: aProcess processGroupId printString; cr.
jan@238
   134
    aStream nextPutAll: '  Stack:   '; cr; cr.
jan@184
   135
jan@188
   136
    aProcess == Processor activeProcess ifTrue:[ctx := thisContext] ifFalse:[ctx := aProcess suspendedContext].
jan@184
   137
    [ ctx notNil ] whileTrue:[
jan@184
   138
        aStream nextPutAll: '  '.
jan@188
   139
        ctx fullPrintOn: aStream.
jan@184
   140
        aStream cr.
jan@184
   141
        ctx := ctx sender.
jan@184
   142
    ].
jan@184
   143
    aStream cr.
jan@184
   144
jan@184
   145
    "
jan@184
   146
        self dumpProcess: Processor activeProcess on: Transcript.
jan@184
   147
    "
jan@184
   148
jan@184
   149
    "Created: / 28-06-2013 / 01:00:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@238
   150
    "Modified: / 06-06-2014 / 09:14:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
   151
!
jan@184
   152
jan@184
   153
dumpProcesses
jan@184
   154
    self dumpProcessesOn: Stderr
jan@184
   155
jan@184
   156
    "
jan@184
   157
    self dumpProcessesOn: Transcript.
jan@184
   158
    "
jan@184
   159
jan@184
   160
    "Created: / 27-06-2013 / 23:41:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
   161
    "Modified (comment): / 28-06-2013 / 01:06:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
   162
!
jan@184
   163
jan@184
   164
dumpProcessesOn: aStream
jan@184
   165
    Process allInstancesDo:[:process|
jan@184
   166
        process isDead ifFalse:[
jan@184
   167
            self dumpProcess: process on: aStream
jan@184
   168
        ]
jan@184
   169
    ]
jan@184
   170
jan@184
   171
    "Created: / 27-06-2013 / 23:42:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
   172
! !
jan@184
   173
jan@72
   174
!ReportRunner class methodsFor:'defaults'!
jan@72
   175
jan@77
   176
allowCoverageMeasurementOption
jan@77
   177
jan@77
   178
    ^false "CoverageReport will do that"
jan@77
   179
jan@77
   180
    "Created: / 13-01-2012 / 11:48:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@77
   181
!
jan@77
   182
jan@72
   183
allowDebugOption
jan@72
   184
jan@72
   185
    ^true
jan@72
   186
jan@72
   187
    "Created: / 21-07-2011 / 09:48:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@72
   188
! !
jan@72
   189
jan@72
   190
!ReportRunner class methodsFor:'multiple applications support'!
jan@72
   191
jan@72
   192
applicationRegistryPath
jan@72
   193
    "the key under which this application stores its process ID in the registry
jan@72
   194
     as a collection of path-components.
jan@72
   195
     i.e. if #('foo' 'bar' 'baz') is returned here, the current applications ID will be stored
jan@72
   196
     in HKEY_CURRENT_USER\Software\foo\bar\baz\CurrentID.
jan@72
   197
     (would also be used as a relative path for a temporary lock file under unix).
jan@72
   198
     Used to detect if another instance of this application is already running."
jan@72
   199
jan@72
   200
    ^ #('exept' 'smalltallx' 'hdreportrunner')
jan@72
   201
jan@72
   202
    "Modified: / 21-07-2011 / 09:43:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@72
   203
!
jan@72
   204
jan@72
   205
applicationUUID
jan@72
   206
    "answer an application-specific unique uuid.
jan@72
   207
     This is used as the name of some exclusive OS-resource, which is used to find out,
jan@72
   208
     if another instance of this application is already running.
jan@72
   209
     Under win32, a mutex is used; under unix, an exclusive file in the tempDir could be used."
jan@72
   210
jan@72
   211
    ^ '99f65c80-b375-11e0-86ad-0013e89c0459' asUUID
jan@72
   212
jan@72
   213
    "Modified: / 21-07-2011 / 09:44:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@72
   214
! !
jan@72
   215
jan@72
   216
!ReportRunner class methodsFor:'startup'!
jan@72
   217
jan@184
   218
handleSIGTERM
jan@184
   219
    self dumpProcesses.
jan@184
   220
    debugging ifFalse:[
jan@184
   221
        Smalltalk exit:127.
jan@184
   222
    ].
jan@184
   223
jan@184
   224
    "Created: / 27-06-2013 / 23:10:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
   225
    "Modified: / 28-06-2013 / 01:08:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
   226
!
jan@184
   227
jan@184
   228
handleSIGUSR2
jan@184
   229
    self dumpProcesses
jan@184
   230
jan@184
   231
    "Created: / 27-06-2013 / 23:10:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
   232
!
jan@184
   233
jan@184
   234
setupSignalHandlers
jan@184
   235
    "On UNIX, this sets up a custom signal handler on SIGUSR2 and SIGTERM that
jan@184
   236
     dumps stacks on all threads"
jan@184
   237
jan@188
   238
    | sigusr2 sigterm |
jan@188
   239
jan@184
   240
    OperatingSystem isUNIXlike ifTrue:[
jan@188
   241
jan@184
   242
jan@184
   243
        sigterm := Signal new.
jan@184
   244
        sigterm handlerBlock: [:ex | self handleSIGTERM].
jan@184
   245
        OperatingSystem operatingSystemSignal:OperatingSystem sigTERM install: sigterm.
jan@184
   246
        OperatingSystem enableSignal: OperatingSystem sigTERM.
jan@184
   247
jan@184
   248
        sigusr2 := Signal new.
jan@184
   249
        sigusr2 handlerBlock: [:ex | self handleSIGUSR2].
jan@184
   250
        OperatingSystem operatingSystemSignal:OperatingSystem sigUSR2 install: sigusr2.
jan@184
   251
        OperatingSystem enableSignal: OperatingSystem sigUSR2.
jan@184
   252
    ].
jan@184
   253
jan@184
   254
    "
jan@188
   255
    OperatingSystem sendSignal: OperatingSystem sigUSR2 to: OperatingSystem getProcessId
jan@184
   256
    "
jan@184
   257
jan@184
   258
    "Created: / 27-06-2013 / 20:57:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
   259
    "Modified: / 28-06-2013 / 01:11:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@184
   260
!
jan@184
   261
jan@72
   262
setupToolsForDebug
jan@72
   263
jan@72
   264
    super setupToolsForDebug.
jan@72
   265
    debugging := true.
jan@72
   266
jan@72
   267
    "Created: / 06-11-2011 / 22:06:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@77
   268
!
jan@77
   269
jan@217
   270
start
jan@217
   271
    Smalltalk silentLoading: true.
jan@217
   272
    ^ super start.
jan@217
   273
jan@217
   274
    "Created: / 22-01-2014 / 09:17:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@217
   275
!
jan@217
   276
jan@77
   277
usage
jan@77
   278
jan@77
   279
    Stderr nextPutAll:'usage: report-runner.';
jan@77
   280
           nextPutAll: (OperatingSystem isMSWINDOWSlike ifTrue:['bat'] ifFalse:['sh']);
jan@77
   281
           nextPutAll: ' [-D <dir>] -r <report> [-p <package1> [-p <package2> [...]]]'; cr.
jan@77
   282
jan@232
   283
    Stderr nextPutLine:'Common options:'; cr.
jan@232
   284
jan@77
   285
    Stderr nextPutLine:'  --help .................. output this message'.
jan@232
   286
"/    Stderr nextPutLine:'  --verbose ............... verbose startup'.
jan@232
   287
"/    Stderr nextPutLine:'  --noBanner .............. no splash screen'.
jan@232
   288
"/    Stderr nextPutLine:'  --newAppInstance ........ start as its own application process (do not reuse'.
jan@232
   289
"/    Stderr nextPutLine:'                            a running instance)'.
jan@232
   290
"/    self allowScriptingOption ifTrue:[
jan@232
   291
"/        Stderr nextPutLine:'  --scripting portNr ...enable scripting via port (or stdin/stdOut if 0)'.
jan@232
   292
"/    ].
jan@77
   293
    self allowDebugOption ifTrue:[
jan@77
   294
        Stderr nextPutLine:'  --debug ................. enable Debugger'.
jan@77
   295
    ].
jan@77
   296
    "/                 '  ......................... '
jan@77
   297
    Stderr nextPutLine:'  -D <dir>'.
jan@77
   298
    Stderr nextPutLine:'  --output-directory=<dir>  directory where report files will go'.
jan@217
   299
    Stderr nextPutLine:'  -S <expr>'.
jan@217
   300
    Stderr nextPutLine:'  --setup=<expr> .......... smalltalk expression that is evaluated before'. 
jan@217
   301
    Stderr nextPutLine:'                            any report is run'.
jan@217
   302
    Stderr nextPutLine:'  -T <expr>'.
jan@217
   303
    Stderr nextPutLine:'  --teardown=<expr> ....... smalltalk expression that is evaluated before'. 
jan@217
   304
    Stderr nextPutLine:'                            after all reports finished'.
jan@217
   305
    Stderr nextPutLine:'  -i <ident>'.
jan@217
   306
    Stderr nextPutLine:'  --ident=<ident> ......... run/configuration identification string to'.
jan@217
   307
    Stderr nextPutLine:'                            use when creating output files'.
jan@77
   308
    Stderr nextPutLine:'  -r <report class>'.
jan@77
   309
    Stderr nextPutLine:'  --report=<report class> . report to run. available reports:'.
jan@77
   310
    Report available do:[:report|
jan@77
   311
        Stderr nextPutAll:'      '; nextPutLine: report name
jan@77
   312
    ].
jan@77
   313
    Stderr nextPutLine:'  -p <package>'.
jan@77
   314
    Stderr nextPutLine:'  --package=<package> ..... package to run report on'.
jan@77
   315
    Stderr nextPutLine:'                            May be specified multiple times.'.
jan@232
   316
jan@232
   317
    Report available do:[:cls|
jan@232
   318
        self usageForReportClass: cls.
jan@232
   319
    ].
jan@232
   320
jan@232
   321
jan@232
   322
    debugging ifFalse:[
jan@217
   323
        Smalltalk exit:1.
jan@232
   324
    ].
jan@77
   325
    "
jan@77
   326
    self usage
jan@77
   327
    "
jan@77
   328
jan@77
   329
    "Created: / 13-01-2012 / 11:48:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@232
   330
    "Modified: / 27-05-2014 / 17:02:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@232
   331
!
jan@232
   332
jan@232
   333
usageForReportClass: class
jan@232
   334
    | options |
jan@232
   335
jan@232
   336
    "/ '.........................' size  25
jan@232
   337
    options := CmdLineOption optionsFor: class new.
jan@232
   338
    options := options reject:[:option | 'pF' includes: option short  ].
jan@232
   339
    options notEmptyOrNil ifTrue:[
jan@232
   340
        Stderr cr.
jan@232
   341
        Stderr nextPutAll: class name; nextPutLine:' options:'; cr.
jan@232
   342
        options do:[:option |                
jan@232
   343
            | optlen |  
jan@232
   344
jan@232
   345
            option short notNil ifTrue:[ 
jan@243
   346
                Stderr nextPutAll: '  '.
jan@232
   347
                Stderr nextPut: $-; nextPut: option short; space.
jan@232
   348
                optlen := 2.
jan@232
   349
                option hasParam ifTrue:[ 
jan@232
   350
                    | paramName |
jan@232
   351
jan@232
   352
                    paramName := 'val'.
jan@232
   353
                    Stderr nextPut:$<; nextPutAll: paramName; nextPut:$>; space.
jan@232
   354
                    optlen := optlen + 3 + paramName size.
jan@232
   355
                ].
jan@232
   356
            ].
jan@232
   357
            option long notNil ifTrue:[ 
jan@232
   358
                 option short notNil ifTrue:[ 
jan@232
   359
                    Stderr cr.
jan@232
   360
                ].
jan@232
   361
                Stderr nextPutAll: '  --'.
jan@232
   362
                Stderr nextPutAll: option long.
jan@232
   363
                optlen := option long size + 2.
jan@232
   364
                option hasParam ifTrue:[ 
jan@232
   365
                    | paramName |
jan@232
   366
jan@232
   367
                    paramName := 'val'.
jan@232
   368
                    Stderr nextPut:$=; nextPut:$<; nextPutAll: paramName; nextPut:$>.
jan@232
   369
                    optlen := optlen + 3 + paramName size.
jan@232
   370
                ].
jan@232
   371
                Stderr space.
jan@232
   372
            ].
jan@232
   373
            Stderr next: (26 - 1"space" -2"--" - optlen) put: $..    
jan@232
   374
            Stderr space.
jan@232
   375
            option description notNil ifTrue:[
jan@232
   376
                Stderr nextPutAll: option description
jan@232
   377
            ].
jan@232
   378
            Stderr cr.
jan@232
   379
        ]
jan@232
   380
    ]
jan@232
   381
jan@243
   382
    "
jan@243
   383
    ReportRunner usageForReportClass: TestReport.
jan@243
   384
    "
jan@243
   385
jan@232
   386
    "Created: / 27-05-2014 / 16:42:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@243
   387
    "Modified: / 16-06-2014 / 11:25:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@72
   388
! !
jan@72
   389
jan@72
   390
!ReportRunner class methodsFor:'startup-to be redefined'!
jan@72
   391
jan@189
   392
main:argv0
sv@143
   393
    "Process command line arguments"
jan@102
   394
jan@189
   395
    | argv |
jan@189
   396
jan@189
   397
    argv := argv0 asOrderedCollection.
jan@232
   398
    argv isEmpty ifTrue:[ 
jan@232
   399
        self usage.
jan@232
   400
    ].
jan@189
   401
    argv remove: '--abortOnSEGV' ifAbsent:[nil].
jan@72
   402
    parser := CmdLineParser new.
sv@144
   403
    CmdLineOptionError autoload.
sv@144
   404
jan@188
   405
    [
jan@188
   406
        parser parse: argv for: self.
sv@143
   407
    ] on:CmdLineOptionError do:[:ex|
jan@72
   408
        Stderr nextPutLine:'Error when processing options: ', ex description.
jan@188
   409
        debugging ifFalse:[
jan@92
   410
            ex suspendedContext fullPrintAllOn: Stderr.
jan@72
   411
            Stderr nextPutLine:'Exiting'.
jan@72
   412
            Smalltalk exit:1.
jan@72
   413
        ] ifTrue:[
jan@72
   414
            ex pass
jan@188
   415
        ]
jan@72
   416
    ].
jan@72
   417
jan@230
   418
    debugging ifFalse:[ 
jan@230
   419
        NoHandlerError emergencyHandler:(NoHandlerError abortingEmergencyHandler)
jan@230
   420
    ].
jan@230
   421
jan@72
   422
    [
jan@147
   423
        setup notNil ifTrue:[Compiler evaluate: setup].
jan@147
   424
        [
jan@217
   425
            report ident: ident.
jan@147
   426
            report run.
jan@147
   427
        ] ensure:[
jan@147
   428
            teardown notNil ifTrue:[Compiler evaluate: teardown].
jan@147
   429
        ].
jan@72
   430
        debugging ifFalse:[
jan@72
   431
            Smalltalk exit:0.
jan@72
   432
        ].
jan@72
   433
    ] on: Error do:[:ex|
jan@72
   434
        Stderr nextPutAll:'Error when running tests: '.
jan@72
   435
        Stderr nextPutAll:ex description; cr.
jan@72
   436
        ex suspendedContext printAllOn:Stderr.
jan@147
   437
jan@147
   438
jan@72
   439
        debugging ifFalse:[
jan@72
   440
            Smalltalk exit:1.
jan@72
   441
        ] ifTrue:[
jan@72
   442
            ex pass
jan@72
   443
        ]
jan@72
   444
    ]
jan@72
   445
jan@232
   446
    "Modified: / 27-05-2014 / 17:05:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
jan@72
   447
! !
jan@72
   448
jan@72
   449
!ReportRunner class methodsFor:'documentation'!
jan@72
   450
jan@72
   451
version
jan@72
   452
    ^ '$Header$'
jan@72
   453
!
jan@72
   454
jan@72
   455
version_CVS
jan@72
   456
    ^ '$Header$'
jan@72
   457
!
jan@72
   458
jan@72
   459
version_SVN
jan@147
   460
    ^ '$Id$'
jan@72
   461
! !
jan@72
   462
sv@143
   463
jan@72
   464
ReportRunner initialize!