Index: dashboard.scm ================================================================== --- dashboard.scm +++ dashboard.scm @@ -239,10 +239,11 @@ test1-older) (if same-time (string>? test-name1 test-name2) test1-older)))) +;; create a virtual table of all the tests ;; keypatts: ( (KEY1 "abc%def")(KEY2 "%") ) (define (update-rundat runnamepatt numruns testnamepatt keypatts) (let* ((referenced-run-ids '()) (allruns (if *useserver* (rmt:get-runs runnamepatt numruns *start-run-offset* keypatts) Index: docs/manual/Makefile ================================================================== --- docs/manual/Makefile +++ docs/manual/Makefile @@ -1,8 +1,8 @@ ASCPATH = $(shell which asciidoc) -EXEPATH = $(shell realpath $(ASCPATH)) +EXEPATH = $(shell readlink -f $(ASCPATH)) BINPATH = $(shell dirname $(EXEPATH)) DISPATH = $(shell dirname $(BINPATH)) # broad_goals.csv needed_features.csv : tables/*.dat # ./refdb2csv tables Index: docs/manual/megatest_manual.html ================================================================== --- docs/manual/megatest_manual.html +++ docs/manual/megatest_manual.html @@ -1177,17 +1177,15 @@

Requirements section

-
-

Header

+
Header
[requirements]
-

Wait on Other Tests

# A normal waiton waits for the prior tests to be COMPLETED
@@ -1218,10 +1216,25 @@
 
[requirements]
 mode itemmatch
+
+
+

Overriding Enviroment Variables

+

Override variables before starting the test. Can include files (perhaps generated by megatest -envdelta or similar).

+
+
+
[pre-launch-env-vars]
+VAR1 value1
+
+# Get some generated settings
+[include ../generated-vars.config]
+
+# Use this trick to unset variables
+#{scheme (unsetenv "FOOBAR")}
+

Itemmap Handling

For cases were the dependent test has a similar but not identical itempath to the downstream test an itemmap can allow for itemmatch @@ -1291,11 +1304,11 @@

[requirements]
 waiton A B
 
 [itemmap]
 A (\d+)/aa aa/\1
-B (\d+)/bb bb/\1
+B (\d+)/bb
Testconfig for Test D
[requirements]
@@ -1317,18 +1330,19 @@
 
[requirements]
 # With a toplevel test you may wish to generate your list
 # of tests to run dynamically
 #
-# waiton #{shell get-valid-tests-to-run.sh}
+waiton #{shell get-valid-tests-to-run.sh}

Run time limit

-
runtimelim 1h 2m 3s  # this will automatically kill the test if it runs for more than 1h 2m and 3s
+
[requirements]
+runtimelim 1h 2m 3s  # this will automatically kill the test if it runs for more than 1h 2m and 3s

Skip

A test with a skip section will conditional skip running.

@@ -1485,10 +1499,53 @@ # <testsuite>/<creationdate> # Within the archive the data is structured like this: # <target>/<runname>/<test>/ archive0 /mfs/myarchive-data/adisk1
+ + +
+

Handling Environment Variables

+
+

It is often necessary to capture and or manipulate environment +variables. Megatest has some facilities built in to help.

+
+

Capture variables

+
+
Commands
+
+
# capture the current enviroment into a db called envdat.db under
+# the context "before"
+megatest -envcap before
+
+# capture the current environment into a db called startup.db with
+# context "after"
+megatest -envcap after startup.db
+
+# write the diff from before to after
+megatest -envdelta before-after -dumpmode bash
+
+

Dump modes include bash, csh and config. You can include config data +into megatest.config or runconfigs.config.

+
+
Example of generating and using config data
+
+
megatest -envcap original
+# do some stuff here
+megatest -envcap munged
+megatest -envdelta original-munged -dumpmode ini -o modified.config
+
+

Then in runconfigs.config

+
+
Example of using modified.config in a testconfig
+
+
cat testconfig
+
+[pre-launch-env-vars]
+[include modified.config]
+
+

Programming API

@@ -1656,11 +1713,10 @@

Index: docs/manual/reference.txt ================================================================== --- docs/manual/reference.txt +++ docs/manual/reference.txt @@ -89,13 +89,11 @@ ------------------- Requirements section ~~~~~~~~~~~~~~~~~~~~ -Header -^^^^^^ - +.Header ------------------- [requirements] ------------------- Wait on Other Tests @@ -132,10 +130,26 @@ ------------------- [requirements] mode itemmatch ------------------- + +Overriding Enviroment Variables +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Override variables before starting the test. Can include files (perhaps generated by megatest -envdelta or similar). + +-------------------- +[pre-launch-env-vars] +VAR1 value1 + +# Get some generated settings +[include ../generated-vars.config] + +# Use this trick to unset variables +#{scheme (unsetenv "FOOBAR")} +-------------------- Itemmap Handling ~~~~~~~~~~~~~~~~ For cases were the dependent test has a similar but not identical @@ -186,11 +200,12 @@ [requirements] waiton A B [itemmap] A (\d+)/aa aa/\1 -B (\d+)/bb -------------------- +B (\d+)/bb +---------------------- .Testconfig for Test D ---------------------- [requirements] waiton C @@ -384,10 +399,54 @@ # / # Within the archive the data is structured like this: # /// archive0 /mfs/myarchive-data/adisk1 -------------- + +Handling Environment Variables +------------------------------ + +It is often necessary to capture and or manipulate environment +variables. Megatest has some facilities built in to help. + +Capture variables +~~~~~~~~~~~~~~~~~ + +.Commands +------------------------------ +# capture the current enviroment into a db called envdat.db under +# the context "before" +megatest -envcap before + +# capture the current environment into a db called startup.db with +# context "after" +megatest -envcap after startup.db + +# write the diff from before to after +megatest -envdelta before-after -dumpmode bash +------------------------------ + +Dump modes include bash, csh and config. You can include config data +into megatest.config or runconfigs.config. + +.Example of generating and using config data +------------------------------ +megatest -envcap original +# do some stuff here +megatest -envcap munged +megatest -envdelta original-munged -dumpmode ini -o modified.config +------------------------------ + +Then in runconfigs.config + +.Example of using modified.config in a testconfig +------------------------------ +cat testconfig + +[pre-launch-env-vars] +[include modified.config] +------------------------------ Programming API --------------- These routines can be called from the megatest repl. Index: docs/manual/server.png ================================================================== --- docs/manual/server.png +++ docs/manual/server.png cannot compute difference between binary files Index: env.scm ================================================================== --- env.scm +++ env.scm @@ -27,11 +27,11 @@ (set-busy-handler! db (busy-timeout 10000)) db)) ;; save vars in given context, this is NOT incremental by default ;; -(define (env:save-env-vars db context #!key (incremental #f)) +(define (env:save-env-vars db context #!key (incremental #f)(vardat #f)) (with-transaction db (lambda () ;; first clear out any vars for this context (if (not incremental)(exec (sql db "DELETE FROM envvars WHERE context=?") context)) @@ -39,11 +39,13 @@ (lambda (varval) (let ((var (car varval)) (val (cdr varval))) (if incremental (exec (sql db "DELETE FROM envvars WHERE context=? AND var=?") context var)) (exec (sql db "INSERT INTO envvars (context,var,val) VALUES (?,?,?)") context var val))) - (get-environment-variables))))) + (if vardat + (hash-table->alist vardat) + (get-environment-variables)))))) ;; merge contexts in the order given ;; - each context is applied in the given order ;; - variables in the paths list are split on the separator and the components ;; merged using simple delta addition @@ -76,11 +78,11 @@ (query (for-each-row (lambda (row) (let ((var (car row)) (val (cadr row))) - (hash-table-set! result var valb)))) + (hash-table-set! result var val)))) (sql db "SELECT var,val FROM envvars WHERE context=? AND var NOT IN (SELECT var FROM envvars WHERE context=?)") contexta contextb) result)) ;; get list of variables added to contextb from contexta @@ -90,11 +92,11 @@ (query (for-each-row (lambda (row) (let ((var (car row)) (val (cadr row))) - (hash-table-set! result var valb)))) + (hash-table-set! result var val)))) (sql db "SELECT var,val FROM envvars WHERE context=? AND var NOT IN (SELECT var FROM envvars WHERE context=?)") contextb contexta) result)) ;; get list of variables in both contexta and contexb that have been changed @@ -105,13 +107,13 @@ (for-each-row (lambda (row) (let ((var (car row)) (val (cadr row))) (hash-table-set! result var val)))) - (sql db "SELECT var,val FROM envvars WHERE context=? AND val != (SELECT val FROM envvars WHERE var=? AND context=?)") - contexta contextb)) - result) + (sql db "SELECT var,val FROM envvars AS a WHERE context=? AND val != (SELECT val FROM envvars WHERE var=a.var AND context=?)") + contexta contextb) + result)) ;; (define (env:blind-merge l1 l2) (if (null? l1) l2 (if (null? l2) l1 @@ -139,5 +141,71 @@ 0)) ;; this is so the calling block does not need to import sql-de-lite (define (env:close-database db) (close-database db)) + +(define (env:lazy-hash-table->alist indat) + (if (hash-table? indat) + (let ((dat (hash-table->alist indat))) + (if (null? dat) + #f + dat)) + #f)) + +(define (env:print added removed changed) + (let ((a (env:lazy-hash-table->alist added)) + (r (env:lazy-hash-table->alist removed)) + (c (env:lazy-hash-table->alist changed))) + (case (if (args:get-arg "-dumpmode") + (string->symbol (args:get-arg "-dumpmode")) + 'bash) + ((bash) + (if a + (begin + (print "# Added vars") + (map (lambda (dat)(print "export " (car dat) "=" (cdr dat))) + (hash-table->alist added)))) + (if r + (begin + (print "# Removed vars") + (map (lambda (dat)(print "unset " (car dat))) + (hash-table->alist removed)))) + (if c + (begin + (print "# Changed vars") + (map (lambda (dat)(print "export " (car dat) "=" (cdr dat))) + (hash-table->alist changed))))) + ((csh) + (if a + (begin + (print "# Added vars") + (map (lambda (dat)(print "setenv " (car dat) " " (cdr dat))) + (hash-table->alist added)))) + (if r + (begin + (print "# Removed vars") + (map (lambda (dat)(print "unsetenv " (car dat))) + (hash-table->alist removed)))) + (if c + (begin + (print "# Changed vars") + (map (lambda (dat)(print "setenv " (car dat) " " (cdr dat))) + (hash-table->alist changed))))) + ((config ini) + (if a + (begin + (print "# Added vars") + (map (lambda (dat)(print (car dat) " " (cdr dat))) + (hash-table->alist added)))) + (if r + (begin + (print "# Removed vars") + (map (lambda (dat)(print "#{scheme (unsetenv \"" (car dat) "\")}")) + (hash-table->alist removed)))) + (if c + (begin + (print "# Changed vars") + (map (lambda (dat)(print (car dat) " " (cdr dat))) + (hash-table->alist changed))))) + (else + (debug:print 0 "ERROR: No dumpmode specified, use -dumpmode [bash|csh|config]"))))) Index: megatest.scm ================================================================== --- megatest.scm +++ megatest.scm @@ -233,10 +233,11 @@ "-port" "-extract-ods" "-pathmod" "-env2file" "-envcap" + "-envdelta" "-setvars" "-set-state-status" "-set-run-status" "-debug" ;; for *verbosity* > 2 "-gen-megatest-test" @@ -314,11 +315,14 @@ args:arg-hash 0)) (if (and (not (null? remargs)) (not (or - (args:get-arg "-runstep")) + (args:get-arg "-runstep") + (args:get-arg "-envcap") + (args:get-arg "-envdelta") + ) ;; add more args that use remargs here )) (debug:print 0 "ERROR: Unrecognised arguments: " (string-intersperse (if (list? remargs) remargs (argv)) " "))) ;; immediately set MT_TARGET if -reqtarg or -target are available @@ -1885,35 +1889,42 @@ ;; Capture, save and manipulate environments ;;====================================================================== (let ((envcap (args:get-arg "-envcap"))) (if envcap - (if (substring-index "=" envcap) - (let* ((parts (string-split envcap "=")) - (fname (car parts)) - (context (cadr parts)) - (db (env:open-db fname))) - (env:save-env-vars db context) - (env:close-database db) - (set! *didsomething* #t)) - (begin - (debug:print 0 "ERROR: Parameter to -envcap should be =. E.G. envdat=original, got: " envcap) - (set! *didsomething* #t))))) + (let* ((db (env:open-db (if (null? remargs) "envdat.db" (car remargs))))) + (env:save-env-vars db envcap) + (env:close-database db) + (set! *didsomething* #t)))) ;; delta "language" will eventually be res=a+b-c but for now it is just res=a-b ;; (let ((envdelta (args:get-arg "-envdelta"))) (if envdelta - (let ((match (string-match "([a-z]+)=([a-z\-,]+)" envdelta))) - (if match - (let* ((resctx (cadr match)) - (equn (caddr match)) - (parts (string-split equn "-")) + (let ((match (string-split envdelta "-")));; (string-match "([a-z0-9_]+)=([a-z0-9_\\-,]+)" envdelta))) + (if (not (null? match)) + (let* ((db (env:open-db (if (null? remargs) "envdat.db" (car remargs)))) + ;; (resctx (cadr match)) + ;; (equn (caddr match)) + (parts match) ;; (string-split equn "-")) (minuend (car parts)) (subtraend (cadr parts)) - ( - + (added (env:get-added db minuend subtraend)) + (removed (env:get-removed db minuend subtraend)) + (changed (env:get-changed db minuend subtraend))) + ;; (pp (hash-table->alist added)) + ;; (pp (hash-table->alist removed)) + ;; (pp (hash-table->alist changed)) + (if (args:get-arg "-o") + (with-output-to-file + (args:get-arg "-o") + (lambda () + (env:print added removed changed))) + (env:print added removed changed)) + (env:close-database db) + (set! *didsomething* #t)) + (debug:print 0 "ERROR: Parameter to -envdelta should be new=star-end"))))) ;;====================================================================== ;; Exit and clean up ;;====================================================================== Index: tests/fullrun/megatest.config ================================================================== --- tests/fullrun/megatest.config +++ tests/fullrun/megatest.config @@ -93,10 +93,13 @@ # -runtests automatically deletes the records for tests with the listed states on starting up a run allowing them to re-run # (nb// this is in addition to NOT_STARTED which is automatically re-run) # allow-auto-rerun INCOMPLETE ZERO_ITEMS # could add: STUCK STUCK/DEAD UNKNOWN KILLED KILLREQ PREQ_DISCARD + +# Try this +reruns 0 [validvalues] state start end 0 1 - 2 status pass fail n/a 0 1 running - 2