︙ | | |
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
|
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Megatest. If not, see <http://www.gnu.org/licenses/>.
;;
;; (include "common.scm")
;; (include "megatest-version.scm")
(include "megatest-version.scm")
;; fake out readline usage of toplevel-command
(define (toplevel-command . a) #f)
(use (prefix sqlite3 sqlite3:) srfi-1 posix regex regex-case srfi-69 (prefix base64 base64:)
readline apropos json http-client directory-utils typed-records
http-client srfi-18 extras format)
;; Added for csv stuff - will be removed
;;
(use sparse-vectors)
(require-library mutils)
;; (use zmq)
(declare (uses common))
(declare (uses megatest-version))
;; (declare (uses megatest-version))
(declare (uses margs))
(declare (uses runs))
(declare (uses launch))
(declare (uses server))
(declare (uses client))
(declare (uses tests))
(declare (uses genexample))
;; (declare (uses daemon))
(declare (uses db))
;; (declare (uses dcommon))
(declare (uses tdb))
(declare (uses mt))
(declare (uses api))
(declare (uses tasks)) ;; only used for debugging.
(declare (uses env))
(declare (uses diff-report))
(declare (uses ftail))
(import ftail)
;; (declare (uses ftail))
;; (import ftail)
(define *db* #f) ;; this is only for the repl, do not use in general!!!!
(include "common_records.scm")
(include "key_records.scm")
(include "db_records.scm")
(include "run_records.scm")
(include "megatest-fossil-hash.scm")
(use (prefix sqlite3 sqlite3:) srfi-1 posix regex regex-case srfi-69 (prefix base64 base64:)
readline apropos json http-client directory-utils typed-records
http-client srfi-18 extras format)
;; Added for csv stuff - will be removed
;;
(use sparse-vectors)
(require-library mutils)
(define *usage-log-file* #f) ;; put path to file for logging usage in this var in the ~/.megatestrc file
(define *usage-use-seconds* #t) ;; for Epoc seconds in usage logging change this to #t in ~/.megatestrc file
;; load the ~/.megatestrc file, put (use trace)(trace-call-sites #t)(trace function-you-want-to-trace) in this file
;;
(let ((debugcontrolf (conc (get-environment-variable "HOME") "/.megatestrc")))
|
︙ | | |
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
-
+
|
-version : print megatest version (currently " megatest-version ")
Launching and managing runs
-run : run all tests or as specified by -testpatt
-remove-runs : remove the data for a run, requires -runname and -testpatt
Optionally use :state and :status, use -keep-records to remove only
the run data. Use -kill-wait to override the 10 second
per test wait after kill delay.
per test wait after kill delay (e.g. -kill-wait 0).
-kill-runs : kill existing run(s) (all incomplete tests killed)
-kill-rerun : kill an existing run (all incomplete tests killed and run is rerun)
-set-state-status X,Y : set state to X and status to Y, requires controls per -remove-runs
-rerun FAIL,WARN... : force re-run for tests with specificed status(s)
-rerun-clean : set all tests not COMPLETED+PASS,WARN,WAIVED to NOT_STARTED,n/a
and then run the specified testpatt with -preclean
-rerun-all : set all tests to NOT_STARTED,n/a and run with -preclean
|
︙ | | |
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
|
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
|
+
+
+
-
+
-
+
+
+
-
-
+
+
|
-sync-to-megatest.db : pull data from cache files in /tmp/$USER to megatest.db
-sync-to dest : sync to new postgresql central style database
-update-meta : update the tests metadata for all tests
-setvars VAR1=val1,VAR2=val2 : Add environment variables to a run NB// these are
overwritten by values set in config files.
-server -|hostname : start the server (reduces contention on megatest.db), use
- to automatically figure out hostname
-adjutant C,M : start the server/adjutant with allocated cores C and Mem M (Gig),
use 0,0 to auto use full machine
-transport http|rpc : use http or rpc for transport (default is http)
-log logfile : send stdout and stderr to logfile
-list-servers : list the servers
-kill-servers : kill all servers
-repl : start a repl (useful for extending megatest)
-load file.scm : load and run file.scm
-mark-incompletes : find and mark incomplete tests
-ping run-id|host:port : ping server, exit with 0 if found
-debug N|N,M,O... : enable debug 0-N or N and M and O ...
-debug-noprop N|M,M,O...: enable debug but do not propagate to subprocesses via MT_DEBUG
-config fname : override the megatest.config file with fname
-append-config fname : append fname to the megatest.config file
Utilities
-env2file fname : write the environment to fname.csh and fname.sh
-envcap a : save current variables labeled as context 'a' in file envdat.db
-envdelta a-b : output enviroment delta from context a to context b to -o fname
set the output mode with -dumpmode csh, bash or ini
note: ini format will use calls to use curr and minimize path
-refdb2dat refdb : convert refdb to sexp or to format specified by s-dumpmode
formats: perl, ruby, sqlite3, csv (for csv the -o param
will substitute %s for the sheet name in generating
multiple sheets)
-o : output file for refdb2dat (defaults to stdout)
-archive cmd : archive runs specified by selectors to one of disks specified
in the [archive-disks] section.
cmd: keep-html, restore, save, save-remove, get,replicate-db (use
cmd: keep-html, restore, save, save-remove, get, replicate-db (use
-dest to set destination), -include path1,path2... to get or save specific files
-generate-html : create a simple html dashboard for browsing your runs
-generate-html-structure : create a top level html veiw to list targets/runs and a Run view within each run directory.
-list-run-time : list time requered to complete runs. It supports following switches
-run-patt <patt> -target-patt <patt> -dumpmode <csv,json,plain-text>
-list-test-time : list time requered to complete each test in a run. It following following arguments
-runname <patt> -target <patt> -dumpmode <csv,json,plain-text>
-extract-skeleton targd : extract a skeleton area based on the current area. Use median step run times.
-syscheck : do some very basic checks; write access and space in tmp, home, runs, links and
is $DISPLAY valid
-list-waivers : dump waivers for specified target, runname, testpatt to stdout
Diff report
-diff-rep : generate diff report (must include -src-target, -src-runname, -target, -runname
and either -diff-email or -diff-html)
-src-target <target>
-src-runname <target>
-diff-email <emails> : comma separated list of email addresses to send diff report
-diff-html <rep.html> : path to html file to generate
Spreadsheet generation
-extract-ods fname.ods : extract an open document spreadsheet from the database
-pathmod path : insert path, i.e. path/runame/itempath/logfile.html
will clear the field if no rundir/testname/itempath/logfile
if it contains forward slashes the path will be converted
to windows style
Getting started
-create-megatest-area : create a skeleton megatest area. You will be prompted for paths
-create-test testname : create a skeleton megatest test. You will be prompted for info
-create-megatest-area : create a skeleton megatest area. You will be prompted for paths
-create-test testname : create a skeleton megatest test. You will be prompted for info
Examples
# Get test path, use '.' to get a single path or a specific path/file pattern
megatest -test-files 'logs/*.log' -target ubuntu/n%/no% -runname w49% -testpatt test_mt%
Called as " (string-intersperse (argv) " ") "
|
︙ | | |
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
|
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
+
+
|
;; values and messages
":category"
":variable"
":value"
":expected"
":tol"
":units"
;; misc
"-start-dir"
"-run-patt"
"-target-patt"
"-contour"
"-area-tag"
"-area"
"-run-tag"
"-server"
"-adjutant"
"-transport"
"-port"
"-extract-ods"
"-pathmod"
"-env2file"
"-envcap"
"-envdelta"
|
︙ | | |
339
340
341
342
343
344
345
346
347
348
349
350
351
352
|
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
|
+
|
"-actions"
"-precmd"
"-include"
"-exclude-rx"
"-exclude-rx-from"
"-debug" ;; for *verbosity* > 2
"-debug-noprop"
"-create-test"
"-override-timeout"
"-test-files" ;; -test-paths is for listing all
"-load" ;; load and exectute a scheme file
"-section"
"-var"
"-dumpmode"
|
︙ | | |
417
418
419
420
421
422
423
424
425
426
427
428
429
430
|
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
|
+
|
"-list-disks"
"-list-targets"
"-list-db-targets"
"-show-runconfig"
"-show-config"
"-show-cmdinfo"
"-get-run-status"
"-list-waivers"
;; queries
"-test-paths" ;; get path(s) to a test, ordered by youngest first
"-runall" ;; run all tests, respects -testpatt, defaults to %
"-run" ;; alias for -runall
"-remove-runs"
|
︙ | | |
445
446
447
448
449
450
451
452
453
454
455
456
457
458
|
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
|
+
|
"-sync-brute-force"
"-logging"
"-v" ;; verbose 2, more than normal (normal is 1)
"-q" ;; quiet 0, errors/warnings only
"-diff-rep"
"-syscheck"
"-obfuscate"
;; junk placeholder
;; "-:p"
)
args:arg-hash
0))
|
︙ | | |
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
|
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
|
-
+
+
|
;; TODO: for multiple areas, we will have multiple watchdogs; and multiple threads to manage
(define *watchdog* (make-thread
(lambda ()
(handle-exceptions
exn
(begin
(print-call-chain)
(print " message: " ((condition-property-accessor 'exn 'message) exn)))
(print " message: " ((condition-property-accessor 'exn 'message) exn) ", exn=" exn))
(common:watchdog)))
"Watchdog thread"))
;;(if (not (args:get-arg "-server"))
;; (thread-start! *watchdog*)) ;; if starting a server; wait till we get to running state before kicking off watchdog
(let* ((no-watchdog-args
'("-list-runs"
"-testdata-csv"
"-list-servers"
"-server"
"-adjutant"
"-list-disks"
"-list-targets"
"-show-runconfig"
;;"-list-db-targets"
"-show-runconfig"
"-show-config"
"-show-cmdinfo"
|
︙ | | |
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
|
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
|
-
+
|
;; manually started and thus should never be started in a non-megatest area. Thus no need to handle situation
;; where (launch:setup) returns #f?
;;
(if (or (args:get-arg "-log")(args:get-arg "-server")) ;; redirect the log always when a server
(handle-exceptions
exn
(begin
(print "ERROR: Failed to switch to log output. " ((condition-property-accessor 'exn 'message) exn))
(print "ERROR: Failed to switch to log output. " ((condition-property-accessor 'exn 'message) exn) ", exn=" exn)
)
(let* ((tl (or (args:get-arg "-log")(launch:setup))) ;; run launch:setup if -server, ensure we do NOT run launch:setup if -log specified
(logf (or (args:get-arg "-log") ;; use -log unless we are a server, then craft a logfile name
(conc tl "/logs/server-" (current-process-id) "-" (get-host-name) ".log")))
(oup (open-logfile logf)))
(if (not (args:get-arg "-log"))
(hash-table-set! args:arg-hash "-log" logf)) ;; fake out future queries of -log
|
︙ | | |
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
|
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
|
-
-
+
+
+
+
|
(let ((original-exit (exit-handler)))
(exit-handler (lambda (#!optional (exit-code 0))
(printf "Preparing to exit with exit code ~A ...\n" exit-code)
(for-each
(lambda (pid)
(handle-exceptions
exn
#t
exn
(begin
(printf "process reap failed. exn=~A\n" exn)
#t)
(let-values (((pid-val exit-status exit-code) (process-wait pid #t)))
(if (or (eq? pid-val pid)
(eq? pid-val 0))
(begin
(printf "Sending signal/term to ~A\n" pid)
(process-signal pid signal/term))))))
(process:children #f))
|
︙ | | |
894
895
896
897
898
899
900
901
902
903
904
905
906
907
|
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
|
+
+
+
+
+
+
+
+
|
;; Server? Start up here.
;;
(if (args:get-arg "-server")
(let ((tl (launch:setup))
(transport-type (string->symbol (or (args:get-arg "-transport") "http"))))
(server:launch 0 transport-type)
(set! *didsomething* #t)))
;; The adjutant is a bit different, it does NOT run (launch:setup) as it is not necessarily tied to
;; a specific Megatest area. Detail are being hashed out and this may change.
;;
(if (args:get-arg "-adjutant")
(begin
(adjutant-run)
(set! *didsomething* #t)))
(if (or (args:get-arg "-list-servers")
(args:get-arg "-kill-servers"))
(let ((tl (launch:setup)))
(if tl ;; all roads from here exit
(let* ((servers (server:get-list *toppath*))
(fmtstr "~8a~22a~20a~20a~8a\n"))
|
︙ | | |
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
|
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
|
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
|
;; (system (conc "rm -rf " tempdir))
(set! *didsomething* #t)
(set! *time-to-exit* #t)
) ;; end if true branch (end of a let)
) ;; end if
) ;; end if -list-runs
;; Don't think I need this. Incorporated into -list-runs instead
;;
;; (if (and (args:get-arg "-since")
;; (launch:setup))
;; (let* ((since-time (string->number (args:get-arg "-since")))
;; (run-ids (db:get-changed-run-ids since-time)))
;; ;; (rmt:get-tests-for-runs-mindata run-ids testpatt states status not-in)
;; (print (sort run-ids <))
;; (set! *didsomething* #t)))
;; list-waivers
(if (and (args:get-arg "-list-waivers")
(launch:setup))
(let* ((runpatt (or (args:get-arg "-runname") "%"))
(testpatt (common:args-get-testpatt #f))
(keys (rmt:get-keys))
(runsdat (rmt:get-runs-by-patt
keys runpatt
(common:args-get-target) #f #f
'("id" "runname" "state" "status" "owner" "event_time" "comment") 0))
(runs (db:get-rows runsdat))
(header (db:get-header runsdat))
(results (make-hash-table)) ;; [target] ( (testname/itempath . "comment") ... )
(addtest (lambda (target testname itempath comment)
(hash-table-set! results target (cons (cons (conc testname "/" itempath) comment)
(hash-table-ref/default results target '())))))
(last-target #f))
(for-each
(lambda (run)
(let* ((run-id (db:get-value-by-header run header "id"))
(target (rmt:get-target run-id))
(runname (db:get-value-by-header run header "runname"))
(tests (rmt:get-tests-for-run
run-id testpatt '("COMPLETED") '("WAIVED") #f #f #f 'testname 'asc ;; use qryvals if test-spec provided
#f #f #f)))
(if (not (equal? target last-target))
(print "[" target "]"))
(set! last-target target)
(print "# " runname)
(for-each
(lambda (testdat)
(let* ((testfullname (conc (db:test-get-testname testdat)
(if (equal? "" (db:test-get-item-path testdat))
""
(conc "/" (db:test-get-item-path testdat)))
)))
(print testfullname " " (db:test-get-comment testdat))))
tests)))
runs)
(set! *didsomething* #t)))
;;======================================================================
;; full run
;;======================================================================
(define (handle-run-requests target runname keys keyvals need-clean)
(if (or (args:get-arg "-kill-rerun") (args:get-arg "-rerun-clean")) ;; first set states/statuses correct
|
︙ | | |
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
|
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
|
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
|
(string-search "%" runname)) ;; we are being asked to re-run multiple runs
(let* ((run-specs (rmt:simple-get-runs runname #f #f target #f))) ;; list of simple-run records
(debug:print-info 0 *default-log-port* "Pattern supplied for target or runname with "
(length run-specs) " matches round. Running each in turn.")
(if (null? run-specs)
(debug:print 0 *default-log-port* "WARNING: No runs match target " target " and runname " runname))
(for-each (lambda (spec)
(let* ((precmd (if (args:get-arg "-precmd")(conc (args:get-arg "-precmd") " ") ""))
(newcmdline (conc
precmd
(let* ((newcmdline (string-substitute
(conc "target " target)
(conc "target " (simple-run-target spec))
(string-substitute
(conc "runname " runname)
(conc "runname " (simple-run-runname spec))
orig-cmdline))))
(string-substitute
(conc "target " target)
(conc "target " (simple-run-target spec))
(string-substitute
(conc "runname " runname)
(conc "runname " (simple-run-runname spec))
orig-cmdline)))))
(debug:print 0 *default-log-port* "ORIG: " orig-cmdline)
(debug:print 0 *default-log-port* "NEW: " newcmdline)
(system newcmdline)))
run-specs))
(handle-run-requests target runname keys keyvals need-clean))))))
;;======================================================================
|
︙ | | |
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
|
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
|
+
+
+
+
+
+
+
|
(let* ((toppath (launch:setup)))
;(if (tests:create-html-tree #f)
(if (tests:create-html-summary #f)
(debug:print-info 0 *default-log-port* "HTML output created in " toppath "/lt/targets.html")
(debug:print 0 *default-log-port* "Failed to create HTML output in " toppath "/lt/runs-index.html"))
(set! *didsomething* #t)))
(if (args:get-arg "-syscheck")
(begin
(mutils:syscheck common:raw-get-remote-host-load
server:get-best-guess-address
read-config)
(set! *didsomething* #t)))
(if (args:get-arg "-extract-skeleton")
(let* ((toppath (launch:setup)))
(genexample:extract-skeleton-area (args:get-arg "-extract-skeleton"))
(set! *didsomething* #t)))
;;======================================================================
;; Exit and clean up
|
︙ | | |