Index: configf.scm ================================================================== --- configf.scm +++ configf.scm @@ -53,11 +53,11 @@ (define configf:include-rx (regexp "^\\[include\\s+(.*)\\]\\s*$")) (define configf:section-rx (regexp "^\\[(.*)\\]\\s*$")) (define configf:blank-l-rx (regexp "^\\s*$")) (define configf:key-sys-pr (regexp "^(\\S+)\\s+\\[system\\s+(\\S+.*)\\]\\s*$")) -(define configf:key-val-pr (regexp "^(\\S+)\\s+(.*)$")) +(define configf:key-val-pr (regexp "^(\\S+)(\\s+(.*)|())$")) (define configf:comment-rx (regexp "^\\s*#.*")) (define configf:cont-ln-rx (regexp "^(\\s+)(\\S+.*)$")) ;; read a line and process any #{ ... } constructs @@ -181,11 +181,11 @@ ((return-procs) val-proc) ((return-string) cmd) (else (val-proc))))) (loop (configf:read-line inp res) curr-section-name #f #f)) (loop (configf:read-line inp res) curr-section-name #f #f))) - (configf:key-val-pr ( x key val ) (let* ((alist (hash-table-ref/default res curr-section-name '())) + (configf:key-val-pr ( x key unk1 val unk2 ) (let* ((alist (hash-table-ref/default res curr-section-name '())) (envar (and environ-patt (string-search (regexp environ-patt) curr-section-name))) (realval (if envar (config:eval-string-in-environment val) val))) (debug:print 6 "INFO: read-config env setting, envar: " envar " realval: " realval " val: " val " key: " key " curr-section-name: " curr-section-name) Index: dashboard-tests.scm ================================================================== --- dashboard-tests.scm +++ dashboard-tests.scm @@ -11,11 +11,11 @@ ;;====================================================================== ;; Test info panel ;;====================================================================== -(use format) +(use format fmt) (require-library iup) (import (prefix iup iup:)) (use canvas-draw) @@ -81,10 +81,14 @@ ))))) ;;====================================================================== ;; Test meta panel ;;====================================================================== + +(define (test-meta-panel-get-description testmeta) + (fmt #f (with-width 40 (wrap-lines (db:testmeta-get-description testmeta))))) + (define (test-meta-panel testmeta store-meta) (iup:frame #:title "Test Meta Data" ; #:expand "YES" (iup:hbox ; #:expand "YES" (apply iup:vbox ; #:expand "YES" @@ -111,12 +115,13 @@ (lambda (testmeta)(db:testmeta-get-reviewed testmeta))) (store-meta "tags" (iup:label (db:testmeta-get-tags testmeta) #:expand "HORIZONTAL") (lambda (testmeta)(db:testmeta-get-tags testmeta))) (store-meta "description" - (iup:label (db:testmeta-get-description testmeta) #:size "x50"); #:expand "HORIZONTAL") - (lambda (testmeta)(db:testmeta-get-description testmeta))) + (iup:label (test-meta-panel-get-description testmeta) #:size "x50"); #:expand "HORIZONTAL") + (lambda (testmeta) + (test-meta-panel-get-description testmeta))) ))))) ;;====================================================================== ;; Run info panel @@ -128,16 +133,18 @@ (apply iup:vbox ; #:expand "YES" (append (map (lambda (keyval) (iup:label (conc (car keyval) " ") ; #:expand "HORIZONTAL" )) keydat) - (list (iup:label "runname ")))) + (list (iup:label "runname ")(iup:label "run-id")))) (apply iup:vbox (append (map (lambda (keyval) (iup:label (cadr keyval) #:expand "HORIZONTAL")) keydat) - (list (iup:label runname)(iup:label "" #:expand "VERTICAL"))))))) + (list (iup:label runname) + (iup:label (conc (db:test-get-run_id testdat))) + (iup:label "" #:expand "VERTICAL"))))))) ;;====================================================================== ;; Host info panel ;;====================================================================== (define (host-info-panel testdat store-label) @@ -343,22 +350,22 @@ (let ((cmd (iup:attribute command-text-box "VALUE"))) (system (conc cmd " &")))))) (run-test (lambda (x) (iup:attribute-set! command-text-box "VALUE" - (conc "xterm -geometry 180x20 -e \"megatest -runtests " testname " -target " keystring " :runname " runname - " -itempatt " (if (equal? item-path "") - "%" - item-path) + (conc "xterm -geometry 180x20 -e \"megatest -target " keystring " :runname " runname + " -runtests " (conc testname "/" (if (equal? item-path "") + "%" + item-path)) ";echo Press any key to continue;bash -c 'read -n 1 -s'\"")))) (remove-test (lambda (x) (iup:attribute-set! command-text-box "VALUE" - (conc "xterm -geometry 180x20 -e \"megatest -remove-runs -target " keystring " :runname " runname " -testpatt " testname " -itempatt " - (if (equal? item-path "") - "%" - item-path) + (conc "xterm -geometry 180x20 -e \"megatest -remove-runs -target " keystring " :runname " runname + " -testpatt " (conc testname "/" (if (equal? item-path "") + "%" + item-path)) " -v;echo Press any key to continue;bash -c 'read -n 1 -s'\""))))) (cond ((not testdat)(begin (print "ERROR: bad test info for " test-id)(exit 1))) ((not rundat)(begin (print "ERROR: found test info but there is a problem with the run info for " run-id)(exit 1))) (else Index: dashboard.scm ================================================================== --- dashboard.scm +++ dashboard.scm @@ -161,17 +161,17 @@ (c2 (map string->number (string-split color2))) (delta (map (lambda (a b)(abs (- a b))) c1 c2))) (null? (filter (lambda (x)(> x 3)) delta)))) ;; keypatts: ( (KEY1 "abc%def")(KEY2 "%") ) -(define (update-rundat runnamepatt numruns testnamepatt itemnamepatt keypatts) +(define (update-rundat runnamepatt numruns testnamepatt keypatts) (let ((modtime (file-modification-time *db-file-path*))) (if (or (and (> modtime *last-db-update-time*) (> (current-seconds)(+ *last-db-update-time* 5))) (> *delayed-update* 0)) (begin - (debug:print 4 "INFO: update-rundat runnamepatt: " runnamepatt " numruns: " numruns " testnamepatt: " testnamepatt " itemnamepatt: " itemnamepatt " keypatts: " keypatts) + (debug:print 4 "INFO: update-rundat runnamepatt: " runnamepatt " numruns: " numruns " testnamepatt: " testnamepatt " keypatts: " keypatts) (set! *please-update-buttons* #t) (set! *last-db-update-time* modtime) (set! *delayed-update* (- *delayed-update* 1)) (let* ((allruns (open-run-close db:get-runs *db* runnamepatt numruns ;; (+ numruns 1) ;; (/ numruns 2)) *start-run-offset* keypatts)) @@ -186,11 +186,11 @@ (begin (set! *last-update* (current-seconds)) (set! *tot-run-count* (length runs)))) ;; (rdb:get-num-runs *db* runnamepatt)))) (for-each (lambda (run) (let* ((run-id (db:get-value-by-header run header "id")) - (tests (let ((tsts (open-run-close db:get-tests-for-run *db* run-id testnamepatt itemnamepatt states statuses))) + (tests (let ((tsts (open-run-close db:get-tests-for-run *db* run-id testnamepatt states statuses))) (if *tests-sort-reverse* (reverse tsts) tsts))) (key-vals (open-run-close db:get-key-vals *db* run-id))) (if (> (length tests) maxtests) (set! maxtests (length tests))) (if (or (not *hide-empty-runs*) ;; this reduces the data burden when set @@ -429,18 +429,19 @@ (iup:hbox (iup:vbox (iup:frame #:title "filter test and items" (iup:hbox - (iup:textbox #:size "60x15" #:fontsize "10" #:value "%" + (iup:textbox #:size "120x15" #:fontsize "10" #:value "%" #:action (lambda (obj unk val) (mark-for-update) (update-search "test-name" val))) - (iup:textbox #:size "60x15" #:fontsize "10" #:value "%" - #:action (lambda (obj unk val) - (mark-for-update) - (update-search "item-name" val))))) + ;;(iup:textbox #:size "60x15" #:fontsize "10" #:value "%" + ;; #:action (lambda (obj unk val) + ;; (mark-for-update) + ;; (update-search "item-name" val)) + )) (iup:vbox (iup:hbox (iup:button "Sort" #:action (lambda (obj) (set! *tests-sort-reverse* (not *tests-sort-reverse*)) (iup:attribute-set! obj "TITLE" (if *tests-sort-reverse* "+Sort" "-Sort")) @@ -601,12 +602,12 @@ (if (or (args:get-arg "-rows") (get-environment-variable "DASHBOARDROWS" )) (begin (set! *num-tests* (string->number (or (args:get-arg "-rows") (get-environment-variable "DASHBOARDROWS")))) - (update-rundat "%" *num-runs* "%" "%" '())) - (set! *num-tests* (min (max (update-rundat "%" *num-runs* "%" "%" '()) 8) 20))) + (update-rundat "%" *num-runs* "%/%" '())) + (set! *num-tests* (min (max (update-rundat "%" *num-runs* "%/%" '()) 8) 20))) (define *tim* (iup:timer)) (define *ord* #f) (iup:attribute-set! *tim* "TIME" 300) (iup:attribute-set! *tim* "RUN" "YES") @@ -622,12 +623,12 @@ (define (run-update x) (update-buttons uidat *num-runs* *num-tests*) ;; (if (db:been-changed) (begin (update-rundat (hash-table-ref/default *searchpatts* "runname" "%") *num-runs* - (hash-table-ref/default *searchpatts* "test-name" "%") - (hash-table-ref/default *searchpatts* "item-name" "%") + (hash-table-ref/default *searchpatts* "test-name" "%/%") + ;; (hash-table-ref/default *searchpatts* "item-name" "%") (let ((res '())) (for-each (lambda (key) (if (not (equal? key "runname")) (let ((val (hash-table-ref/default *searchpatts* key #f))) (if val (set! res (cons (list key val) res)))))) Index: db.scm ================================================================== --- db.scm +++ db.scm @@ -49,11 +49,11 @@ (else (debug:print 0 "ERROR: synchronous must be 0,1,2,OFF,NORMAL or FULL, you provided: " syncval) #f)))) (if val (begin - (debug:print 2 "INFO: Setting pragma synchronous to " val) + (debug:print 4 "INFO: Setting pragma synchronous to " val) (sqlite3:execute db (conc "PRAGMA synchronous = '" val "';")))))) (define (open-db) ;; (conc *toppath* "/megatest.db") (car *configinfo*))) (let* ((dbpath (conc *toppath* "/megatest.db")) ;; fname) (dbexists (file-exists? dbpath)) @@ -449,11 +449,11 @@ "SELECT fieldname,fieldtype FROM keys ORDER BY id DESC;") (set! *db-keys* res) res))) (define (db:get-value-by-header row header field) - ;; (debug:print 2 "db:get-value-by-header row: " row " header: " header " field: " field) + (debug:print 4 "INFO: db:get-value-by-header row: " row " header: " header " field: " field) (if (null? header) #f (let loop ((hed (car header)) (tal (cdr header)) (n 0)) (if (equal? hed field) @@ -475,11 +475,12 @@ (define (db:patt->like fieldname pattstr #!key (comparator " OR ")) (let ((patts (if (string? pattstr) (string-split pattstr ",") '("%")))) (string-intersperse (map (lambda (patt) - (conc fieldname " LIKE '" patt "'")) + (let ((wildtype (if (substring-index "%" patt) "LIKE" "GLOB"))) + (conc fieldname " " wildtype " '" patt "'"))) (if (null? patts) '("") patts)) comparator))) @@ -649,32 +650,40 @@ ;; states and statuses are lists, turn them into ("PASS","FAIL"...) and use NOT IN ;; i.e. these lists define what to NOT show. ;; states and statuses are required to be lists, empty is ok ;; not-in #t = above behaviour, #f = must match -(define (db:get-tests-for-run db run-id testpatt itempatt states statuses +(define (db:get-tests-for-run db run-id testpatt states statuses #!key (not-in #t) (sort-by #f) ;; 'rundir 'event_time ) (let* ((res '()) ;; if states or statuses are null then assume match all when not-in is false - (states-str (conc " state in ('" (string-intersperse states "','") "')")) - (statuses-str (conc " status in ('" (string-intersperse statuses "','") "')")) - (state-status-qry (if (or (not (null? states)) - (not (null? states))) - (conc " AND " (if not-in "NOT" "") " (" states-str " AND " statuses-str ") ") - "")) - (qry (conc "SELECT id,run_id,testname,state,status,event_time,host,cpuload,diskfree,uname,rundir,item_path,run_duration,final_logf,comment " - " FROM tests WHERE run_id=? AND " - ;; testname like ? AND item_path LIKE ? " - (db:patt->like "testname" testpatt) " AND " - (db:patt->like "item_path" itempatt) - state-status-qry - (case sort-by - ((rundir) " ORDER BY length(rundir) DESC;") - ((event_time) " ORDER BY event_time ASC;") - (else ";")) + (states-qry (if (null? states) + #f + (conc " state " + (if not-in "NOT" "") + " IN ('" + (string-intersperse states "','") + "')"))) + (statuses-qry (if (null? statuses) + #f + (conc " status " + (if not-in "NOT" "") + " IN ('" + (string-intersperse statuses "','") + "')"))) + (tests-match-qry (tests:match->sqlqry testpatt)) + (qry (conc "SELECT id,run_id,testname,state,status,event_time,host,cpuload,diskfree,uname,rundir,item_path,run_duration,final_logf,comment " + " FROM tests WHERE run_id=? " + (if states-qry (conc " AND " states-qry) "") + (if statuses-qry (conc " AND " statuses-qry) "") + (if tests-match-qry (conc " AND (" tests-match-qry ") ") "") + (case sort-by + ((rundir) " ORDER BY length(rundir) DESC;") + ((event_time) " ORDER BY event_time ASC;") + (else ";")) ))) (debug:print 8 "INFO: db:get-tests-for-run qry=" qry) (sqlite3:for-each-row (lambda (a . b) ;; id run-id testname state status event-time host cpuload diskfree uname rundir item-path run-duration final-logf comment) (set! res (cons (apply vector a b) res))) ;; id run-id testname state status event-time host cpuload diskfree uname rundir item-path run-duration final-logf comment) res))) @@ -739,11 +748,11 @@ (define (db:test-set-state-status-by-id db test-id newstate newstatus newcomment) (cond ((and newstate newstatus newcomment) (sqlite3:exectute db "UPDATE tests SET state=?,status=?,comment=? WHERE id=?;" newstate newstatus test-id)) ((and newstate newstatus) - (sqlite3:exectute db "UPDATE tests SET state=?,status=? WHERE id=?;" newstate newstatus test-id)) + (sqlite3:execute db "UPDATE tests SET state=?,status=? WHERE id=?;" newstate newstatus test-id)) (else (if newstate (sqlite3:execute db "UPDATE tests SET state=? WHERE id=?;" newstate test-id)) (if newstatus (sqlite3:execute db "UPDATE tests SET status=? WHERE id=?;" newstatus test-id)) (if newcomment (sqlite3:execute db "UPDATE tests SET comment=? WHERE id=?;" newcomment test-id))))) @@ -948,25 +957,25 @@ ;;====================================================================== ;; Misc. test related queries ;;====================================================================== (define (db:test-get-paths-matching db keynames target fnamepatt #!key (res '())) - (let* ((itempatt (if (args:get-arg "-itempatt")(args:get-arg "-itempatt") "%")) - (testpatt (if (args:get-arg "-testpatt")(args:get-arg "-testpatt") "%")) + (let* ((testpatt (if (args:get-arg "-testpatt")(args:get-arg "-testpatt") "%")) (statepatt (if (args:get-arg ":state") (args:get-arg ":state") "%")) (statuspatt (if (args:get-arg ":status") (args:get-arg ":status") "%")) (runname (if (args:get-arg ":runname") (args:get-arg ":runname") "%")) (keystr (string-intersperse (map (lambda (key val) (conc "r." key " like '" val "'")) keynames (string-split target "/")) " AND ")) + (testqry (tests:match->sqlqry testpatt)) (qrystr (conc "SELECT t.rundir FROM tests AS t INNER JOIN runs AS r ON t.run_id=r.id WHERE " - keystr " AND r.runname LIKE '" runname "' AND item_path LIKE '" itempatt "' AND testname LIKE '" - testpatt "' AND t.state LIKE '" statepatt "' AND t.status LIKE '" statuspatt - "'ORDER BY t.event_time ASC;"))) + keystr " AND r.runname LIKE '" runname "' AND " testqry + " AND t.state LIKE '" statepatt "' AND t.status LIKE '" statuspatt + "' ORDER BY t.event_time ASC;"))) (debug:print 3 "qrystr: " qrystr) (sqlite3:for-each-row (lambda (p) (set! res (cons p res))) db @@ -1476,11 +1485,11 @@ (result '())) (for-each (lambda (waitontest-name) ;; by getting the tests with matching name we are looking only at the matching test ;; and related sub items - (let ((tests (db:get-tests-for-run db run-id waitontest-name #f '() '())) + (let ((tests (db:get-tests-for-run db run-id waitontest-name '() '())) (ever-seen #f) (parent-waiton-met #f) (item-waiton-met #f)) (for-each (lambda (test) Index: megatest-version.scm ================================================================== --- megatest-version.scm +++ megatest-version.scm @@ -1,7 +1,7 @@ ;; Always use two digit decimal ;; 1.01, 1.02...1.10,1.11 ... 1.99,2.00.. (declare (unit megatest-version)) -(define megatest-version 1.4611) +(define megatest-version 1.501) Index: megatest.scm ================================================================== --- megatest.scm +++ megatest.scm @@ -40,24 +40,23 @@ Launching and managing runs -runall : run all tests that are not state COMPLETED and status PASS, CHECK or KILLED -runtests tst1,tst2 ... : run tests - -remove-runs : remove the data for a run, requires :runname, -testpatt and - -itempatt be set. Optionally use :state and :status + -remove-runs : remove the data for a run, requires :runname and -testpatt + Optionally use :state and :status -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) - -rollup : fill run (set by :runname) with latest test(s) from - prior runs with same keys + -rollup : (currently disabled) fill run (set by :runname) with latest test(s) + from prior runs with same keys -lock : lock run specified by target and runname -unlock : unlock run specified by target and runname Selectors (e.g. use for -runtests, -remove-runs, -set-state-status, -list-runs etc.) -target key1/key2/... : run for key1, key2, etc. -reqtarg key1/key2/... : run for key1, key2, etc. but key1/key2 must be in runconfig - -testpatt patt : % is wildcard - -itempatt patt : % is wildcard + -testpatt patt1/patt2,patt3/... : % is wildcard :runname : required, name for this particular test run :state : Applies to runs, tests or steps depending on context :status : Applies to runs, tests or steps depending on context Test helpers (for use inside tests) @@ -96,12 +95,10 @@ -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 -repl : start a repl (useful for extending megatest) - -debug N : increase verbosity to N. (try 10 for lots of noise) - -logging : turn on logging all debug output to logging.db 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 @@ -192,11 +189,10 @@ "-update-meta" "-gen-megatest-area" "-v" ;; verbose 2, more than normal (normal is 1) "-q" ;; quiet 0, errors/warnings only - "-logging" ) args:arg-hash 0)) (if (args:get-arg "-h") @@ -218,12 +214,28 @@ (if (not (number? *verbosity*)) (begin (print "ERROR: Invalid debug value " (args:get-arg "-debug")) (exit))) - + (if (args:get-arg "-logging")(set! *logging* #t)) + +(if (> *verbosity* 3) ;; we are obviously debugging + (set! open-run-close open-run-close-no-exception-handling)) + +;; to try and not burden Kim too much... +(if (args:get-arg "-itempatt") + (let ((old-testpatt (args:get-arg "-testpatt"))) + (debug:print 0 "ERROR: parameter \"-itempatt\" has been deprecated. For now I will tweak your -testpatt for you") + (hash-table-set! args:arg-hash "-testpatt" (conc old-testpatt "/" (args:get-arg "-itempatt"))) + (debug:print 0 " old: " old-testpatt ", new: " (args:get-arg "-testpatt")) + (if (args:get-arg "-runtests") + (begin + (debug:print 0 "NOTE: Also modifying -runtests") + (hash-table-set! args:arg-hash "-runtests" (conc (args:get-arg "-runtests") "/" + (args:get-arg "-itempatt"))))) + )) ;;====================================================================== ;; Misc general calls ;;====================================================================== @@ -244,23 +256,19 @@ (debug:print 0 "ERROR: Missing required parameter for " action ", you must specify the run name pattern with :runname patt") (exit 2)) ((not (args:get-arg "-testpatt")) (debug:print 0 "ERROR: Missing required parameter for " action ", you must specify the test pattern with -testpatt") (exit 3)) - ((not (args:get-arg "-itempatt")) - (print "ERROR: Missing required parameter for " action ", you must specify the items with -itempatt") - (exit 4)) (else (if (not (car *configinfo*)) (begin (debug:print 0 "ERROR: Attempted " action "on test(s) but run area config file not found") (exit 1)) ;; put test parameters into convenient variables (runs:operate-on action (args:get-arg ":runname") (args:get-arg "-testpatt") - (args:get-arg "-itempatt") state: (args:get-arg ":state") status: (args:get-arg ":status") new-state-status: (args:get-arg "-set-state-status"))) (set! *didsomething* #t)))) @@ -285,11 +293,10 @@ (if (args:get-arg "-list-runs") (if (setup-for-run) (let* ((db #f) (runpatt (args:get-arg "-list-runs")) (testpatt (args:get-arg "-testpatt")) - (itempatt (args:get-arg "-itempatt")) (runsdat (open-run-close db:get-runs db runpatt #f #f '())) (runs (db:get-rows runsdat)) (header (db:get-header runsdat)) (keys (open-run-close db:get-keys db)) (keynames (map key:get-fieldname keys))) @@ -302,11 +309,11 @@ keynames) "/") "/" (db:get-value-by-header run header "runname") " status: " (db:get-value-by-header run header "state")) (let ((run-id (open-run-close db:get-value-by-header run header "id"))) - (let ((tests (open-run-close db:get-tests-for-run db run-id testpatt itempatt '() '()))) + (let ((tests (open-run-close db:get-tests-for-run db run-id testpatt '() '()))) ;; Each test (for-each (lambda (test) (format #t " Test: ~25a State: ~15a Status: ~15a Runtime: ~5@as Time: ~22a Host: ~10a\n" @@ -422,18 +429,21 @@ ;;====================================================================== ;; Rollup into a run ;;====================================================================== (if (args:get-arg "-rollup") - (general-run-call - "-rollup" - "rollup tests" - (lambda (target runname keys keynames keyvallst) - (runs:rollup-run keys - (keys->alist keys "na") - (args:get-arg ":runname") - user)))) + (begin + (debug:print 0 "ERROR: Rollup is currently not working. If you need it please submit a ticket at http://www.kiatoa.com/fossils/megatest") + (exit 4))) +;; (general-run-call +;; "-rollup" +;; "rollup tests" +;; (lambda (target runname keys keynames keyvallst) +;; (runs:rollup-run keys +;; (keys->alist keys "na") +;; (args:get-arg ":runname") +;; user)))) ;;====================================================================== ;; Lock or unlock a run ;;====================================================================== @@ -477,12 +487,11 @@ (exit 1))) (if (not (setup-for-run)) (begin (debug:print 0 "Failed to setup, giving up on -test-paths or -test-files, exiting") (exit 1))) - (let* ((itempatt (args:get-arg "-itempatt")) - (keys (open-run-close db:get-keys db)) + (let* ((keys (open-run-close db:get-keys db)) (keynames (map key:get-fieldname keys)) (paths (open-run-close db:test-get-paths-matching db keynames target (args:get-arg "-test-files")))) (set! *didsomething* #t) (for-each (lambda (path) (print path)) Index: runs.scm ================================================================== --- runs.scm +++ runs.scm @@ -1,7 +1,7 @@ -;; Copyright 2006-2011, Matthew Welland. +;; Copyright 2006-2012, Matthew Welland. ;; ;; This program is made available under the GNU GPL version 2.0 or ;; greater. See the accompanying file COPYING for details. ;; ;; This program is distributed WITHOUT ANY WARRANTY; without even the @@ -32,32 +32,37 @@ ;; register a test run with the db ;; ;; Use: (db-get-value-by-header (db:get-header runinfo)(db:get-row runinfo)) ;; to extract info from the structure returned ;; -(define (runs:get-runs-by-patt db keys runnamepatt . params) ;; test-name) +(define (runs:get-runs-by-patt db keys runnamepatt) ;; test-name) (let* ((keyvallst (keys->vallist keys)) (tmp (runs:get-std-run-fields keys '("id" "runname" "state" "status" "owner" "event_time"))) (keystr (car tmp)) (header (cadr tmp)) (res '()) - (key-patt "")) + (key-patt "") + (runwildtype (if (substring-index "%" runnamepatt) "like" "glob")) + (qry-str #f)) (for-each (lambda (keyval) (let* ((key (vector-ref keyval 0)) (fulkey (conc ":" key)) - (patt (args:get-arg fulkey))) + (patt (args:get-arg fulkey)) + (wildtype (if (substring-index "%" patt) "like" "glob"))) (if patt - (set! key-patt (conc key-patt " AND " key " like '" patt "'")) + (set! key-patt (conc key-patt " AND " key " " wildtype " '" patt "'")) (begin (debug:print 0 "ERROR: searching for runs with no pattern set for " fulkey) (exit 6))))) keys) + (set! qry-str (conc "SELECT " keystr " FROM runs WHERE runname " runwildtype " ? " key-patt ";")) + (debug:print 4 "INFO: runs:get-runs-by-patt qry=" qry-str " " runnamepatt) (sqlite3:for-each-row (lambda (a . r) (set! res (cons (list->vector (cons a r)) res))) db - (conc "SELECT " keystr " FROM runs WHERE runname like ? " key-patt ";") + qry-str runnamepatt) (vector header res))) (define (runs:test-get-full-path test) (let* ((testname (db:test-get-testname test)) @@ -203,21 +208,12 @@ (open-run-close setup-env-defaults db runconfigf run-id *already-seen-runconfig-info* "pre-launch-env-vars") (debug:print 0 "WARNING: You do not have a run config file: " runconfigf)) ;; look up all tests matching the comma separated list of globs in ;; test-patts (using % as wildcard) - (for-each - (lambda (patt) - (let ((tests (glob (conc *toppath* "/tests/" (string-translate patt "%" "*"))))) - (set! tests (filter (lambda (test)(file-exists? (conc test "/testconfig"))) tests)) - (set! test-names (append test-names - (map (lambda (testp) - (last (string-split testp "/"))) - tests))))) - (if test-patts (string-split test-patts ",")(list "%"))) - - ;; now remove duplicates + + (set! test-names (tests:get-valid-tests *toppath* test-patts test-names: test-names)) (set! test-names (delete-duplicates test-names)) (debug:print 0 "INFO: test names " test-names) ;; on the first pass or call to run-tests set FAILS to NOT_STARTED if @@ -299,11 +295,11 @@ (if (not (null? required-tests)) (debug:print 1 "INFO: Adding " required-tests " to the run queue")) ;; NOTE: these are all parent tests, items are not expanded yet. (debug:print 4 "INFO: test-records=" (hash-table->alist test-records)) - (runs:run-tests-queue run-id runname test-records keyvallst flags) + (runs:run-tests-queue run-id runname test-records keyvallst flags test-patts) (debug:print 4 "INFO: All done by here"))) (define (runs:calc-fails prereqs-not-met) (filter (lambda (test) (and (vector? test) ;; not (string? test)) @@ -328,16 +324,15 @@ (define (runs:make-full-test-name testname itempath) (if (equal? itempath "") testname (conc testname "/" itempath))) ;; test-records is a hash table testname:item_path => vector < testname testconfig waitons priority items-info ... > -(define (runs:run-tests-queue run-id runname test-records keyvallst flags) +(define (runs:run-tests-queue run-id runname test-records keyvallst flags test-patts) ;; At this point the list of parent tests is expanded ;; NB// Should expand items here and then insert into the run queue. (debug:print 5 "test-records: " test-records ", keyvallst: " keyvallst " flags: " (hash-table->alist flags)) (let ((sorted-test-names (tests:sort-by-priority-and-waiton test-records)) - (item-patts (hash-table-ref/default flags "-itempatt" #f)) (test-registery (make-hash-table)) (num-retries 0) (max-retries (config-lookup *configdat* "setup" "maxretries"))) (set! max-retries (if (and max-retries (string->number max-retries))(string->number max-retries) 100)) (if (not (null? sorted-test-names)) @@ -399,15 +394,14 @@ ;; Don't know at this time if the test have been launched at some time in the past ;; i.e. is this a re-launch? (debug:print 4 "INFO: run-limits-info = " run-limits-info) (cond ;; INNER COND #1 for a launchable test ;; Check item path against item-patts - ((and (not (patt-list-match item-path item-patts)) - (not (equal? item-path ""))) + ((not (tests:match test-patts (tests:testqueue-get-testname test-record) item-path)) ;; This test/itempath is not to be run ;; else the run is stuck, temporarily or permanently ;; but should check if it is due to lack of resources vs. prerequisites - (debug:print 1 "INFO: Skipping " (tests:testqueue-get-testname test-record) " " item-path " as it doesn't match " item-patts) + (debug:print 1 "INFO: Skipping " (tests:testqueue-get-testname test-record) " " item-path " as it doesn't match " test-patts) (thread-sleep! *global-delta*) (if (not (null? tal)) (loop (car tal)(cdr tal) reruns))) ((and (not (hash-table-ref/default test-registery (runs:make-full-test-name test-name item-path) #f)) (and max-concurrent-jobs (> (- max-concurrent-jobs num-running) 5))) @@ -462,11 +456,11 @@ (lambda (my-itemdat) (let* ((new-test-record (let ((newrec (make-tests:testqueue))) (vector-copy! test-record newrec) newrec)) (my-item-path (item-list->path my-itemdat))) - (if (patt-list-match my-item-path item-patts) ;; yes, we want to process this item, NOTE: Should not need this check here! + (if (tests:match test-patts hed my-item-path) ;; (patt-list-match my-item-path item-patts) ;; yes, we want to process this item, NOTE: Should not need this check here! (let ((newtestname (runs:make-full-test-name hed my-item-path))) ;; test names are unique on testname/item-path (tests:testqueue-set-items! new-test-record #f) (tests:testqueue-set-itemdat! new-test-record my-itemdat) (tests:testqueue-set-item_path! new-test-record my-item-path) (hash-table-set! test-records newtestname new-test-record) @@ -708,84 +702,99 @@ ;; 'remove-runs ;; 'set-state-status ;; ;; NB// should pass in keys? ;; -(define (runs:operate-on action runnamepatt testpatt itempatt #!key (state #f)(status #f)(new-state-status #f)) +(define (runs:operate-on action runnamepatt testpatt #!key (state #f)(status #f)(new-state-status #f)) (let* ((db #f) (keys (open-run-close db:get-keys db)) (rundat (open-run-close runs:get-runs-by-patt db keys runnamepatt)) (header (vector-ref rundat 0)) (runs (vector-ref rundat 1)) (states (if state (string-split state ",") '())) (statuses (if status (string-split status ",") '())) (state-status (if (string? new-state-status) (string-split new-state-status ",") '(#f #f)))) - (debug:print 2 "Header: " header " action: " action " new-state-status: " new-state-status) + (debug:print 4 "INFO: runs:operate-on => Header: " header " action: " action " new-state-status: " new-state-status) + (if (> 2 (length state-status)) + (begin + (debug:print 0 "ERROR: the parameter to -set-state-status is a comma delimited string. E.g. COMPLETED,FAIL") + (exit))) (for-each (lambda (run) (let ((runkey (string-intersperse (map (lambda (k) (db:get-value-by-header run header (vector-ref k 0))) keys) "/")) (dirs-to-remove (make-hash-table))) (let* ((run-id (db:get-value-by-header run header "id")) (run-state (db:get-value-by-header run header "state")) (tests (if (not (equal? run-state "locked")) - (open-run-close db:get-tests-for-run db (db:get-value-by-header run header "id") - testpatt itempatt states statuses + (open-run-close db:get-tests-for-run db run-id + testpatt states statuses not-in: #f sort-by: (case action ((remove-runs) 'rundir) (else 'event_time))) '())) (lasttpath "/does/not/exist/I/hope")) - + (debug:print 4 "INFO: runs:operate-on run=" run ", header=" header) (if (not (null? tests)) (begin (case action ((remove-runs) (debug:print 1 "Removing tests for run: " runkey " " (db:get-value-by-header run header "runname"))) ((set-state-status) (debug:print 1 "Modifying state and staus for tests for run: " runkey " " (db:get-value-by-header run header "runname"))) + ((print-run) + (debug:print 1 "Printing info for run " runkey ", run=" run ", tests=" tests ", header=" header) + action) (else (print "INFO: action not recognised " action))) (for-each (lambda (test) (let* ((item-path (db:test-get-item-path test)) (test-name (db:test-get-testname test)) - (run-dir (db:test-get-rundir test)) + (run-dir (db:test-get-rundir test)) ;; run dir is from the link tree + (real-dir (if (file-exists? run-dir) + (resolve-pathname run-dir) + #f)) (test-id (db:test-get-id test))) ;; (tdb (db:open-test-db run-dir))) - (debug:print 1 " " (db:test-get-testname test) " id: " (db:test-get-id test) " " item-path " action: " action) + (debug:print 4 "INFO: test=" test) ;; " (db:test-get-testname test) " id: " (db:test-get-id test) " " item-path " action: " action) (case action ((remove-runs) ;; the tdb is for future possible. (open-run-close db:delete-test-records db #f (db:test-get-id test)) - (debug:print 1 "INFO: Attempting to remove dir " run-dir) - (if (and (> (string-length run-dir) 5) - (file-exists? run-dir)) ;; bad heuristic but should prevent /tmp /home etc. - (let* ((realpath (resolve-pathname run-dir))) - (debug:print 1 "INFO: Real path of is " realpath) - (if (file-exists? realpath) - (if (> (system (conc "rm -rf " realpath)) 0) - (debug:print 0 "ERROR: There was a problem removing " realpath " with rm -f")) - (debug:print 0 "WARNING: test run dir " realpath " appears to not exist")) - (if (file-exists? run-dir) ;; the link - (if (symbolic-link? run-dir) - (delete-file run-dir) - (if (directory? run-dir) - (if (> (directory-fold (lambda (f x)(+ 1 x)) 0 run-dir) 0) - (debug:print 0 "WARNING: refusing to remove " run-dir " as it is not empty") - (delete-directory run-dir)) ;; it should be empty by here BUG BUG, add error catch - (debug:print 0 "ERROR: refusing to remove " run-dir " as it is neither a symlink nor a directory") - )))) - (debug:print 0 "WARNING: directory already removed " run-dir))) + (debug:print 1 "INFO: Attempting to remove dir " real-dir " and link " run-dir) + (if (and real-dir + (> (string-length real-dir) 5) + (file-exists? real-dir)) ;; bad heuristic but should prevent /tmp /home etc. + (begin ;; let* ((realpath (resolve-pathname run-dir))) + (debug:print 1 "INFO: Recursively removing " real-dir) + (if (file-exists? real-dir) + (if (> (system (conc "rm -rf " real-dir)) 0) + (debug:print 0 "ERROR: There was a problem removing " real-dir " with rm -f")) + (debug:print 0 "WARNING: test run dir " real-dir " appears to not exist"))) + (debug:print 0 "WARNING: directory " real-dir " does not exist")) + (if (symbolic-link? run-dir) + (begin + (debug:print 1 "INFO: Removing symlink " run-dir) + (delete-file run-dir)) + (if (directory? run-dir) + (if (> (directory-fold (lambda (f x)(+ 1 x)) 0 run-dir) 0) + (debug:print 0 "WARNING: refusing to remove " run-dir " as it is not empty") + (delete-directory run-dir)) ;; it should be empty by here BUG BUG, add error catch + (debug:print 0 "ERROR: refusing to remove " run-dir " as it either doesn't exist or is not a symlink or directory") + ))) ((set-state-status) (debug:print 2 "INFO: new state " (car state-status) ", new status " (cadr state-status)) (open-run-close db:test-set-state-status-by-id db (db:test-get-id test) (car state-status)(cadr state-status) #f))))) - tests))) - + (sort tests (lambda (a b)(let ((dira (db:test-get-rundir a)) + (dirb (db:test-get-rundir b))) + (if (and (string? dira)(string? dirb)) + (> (string-length dira)(string-length dirb)) + #f))))))) ;; remove the run if zero tests remain (if (eq? action 'remove-runs) - (let ((remtests (open-run-close db:get-tests-for-run db (db:get-value-by-header run header "id") #f #f '("DELETED") '("n/a") not-in: #t))) + (let ((remtests (open-run-close db:get-tests-for-run db (db:get-value-by-header run header "id") #f '("DELETED") '("n/a") not-in: #t))) (if (null? remtests) ;; no more tests remaining (let* ((dparts (string-split lasttpath "/")) (runpath (conc "/" (string-intersperse (take dparts (- (length dparts) 1)) "/")))) @@ -800,11 +809,12 @@ ;; (begin ;; (debug:print 1 "Removing run dir " runpath) ;; (system (conc "rmdir -p " runpath)))) ))))) )) - runs))) + runs)) + #t) ;;====================================================================== ;; Routines for manipulating runs ;;====================================================================== @@ -921,11 +931,11 @@ (define (runs:rollup-run keys keyvallst runname user) ;; was target, now keyvallst (debug:print 4 "runs:rollup-run, keys: " keys " keyvallst: " keyvallst " :runname " runname " user: " user) (let* ((db #f) ;; (keyvalllst (keys:target->keyval keys target)) (new-run-id (open-run-close runs:register-run db keys keyvallst runname "new" "n/a" user)) (prev-tests (open-run-close test:get-matching-previous-test-run-records db new-run-id "%" "%")) - (curr-tests (open-run-close db:get-tests-for-run db new-run-id "%" "%" '() '())) + (curr-tests (open-run-close db:get-tests-for-run db new-run-id "%/%" '() '())) (curr-tests-hash (make-hash-table))) (open-run-close db:update-run-event_time db new-run-id) ;; index the already saved tests by testname and itemdat in curr-tests-hash (for-each (lambda (testdat) @@ -949,11 +959,11 @@ (apply sqlite3:execute db (conc "INSERT OR REPLACE INTO tests (run_id,testname,state,status,event_time,host,cpuload,diskfree,uname,rundir,item_path,run_duration,final_logf,comment) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?);") new-run-id (cddr (vector->list testdat))) - (set! new-testdat (car (open-run-close db:get-tests-for-run db new-run-id testname item-path '() '()))) + (set! new-testdat (car (open-run-close db:get-tests-for-run db new-run-id (conc testname "/" item-path) '() '()))) (hash-table-set! curr-tests-hash full-name new-testdat) ;; this could be confusing, which record should go into the lookup table? ;; Now duplicate the test steps (debug:print 4 "Copying records in test_steps from test_id=" (db:test-get-id testdat) " to " (db:test-get-id new-testdat)) (open-run-close (lambda () Index: tests.scm ================================================================== --- tests.scm +++ tests.scm @@ -26,10 +26,81 @@ (include "common_records.scm") (include "key_records.scm") (include "db_records.scm") (include "run_records.scm") (include "test_records.scm") + +(define (tests:get-valid-tests testsdir test-patts #!key (test-names '())) + (let ((tests (glob (conc testsdir "/tests/*")))) ;; " (string-translate patt "%" "*"))))) + (set! tests (filter (lambda (test)(file-exists? (conc test "/testconfig"))) tests)) + (delete-duplicates + (append test-names + (filter (lambda (testname) + (tests:match test-patts testname #f)) + (map (lambda (testp) + (last (string-split testp "/"))) + tests)))))) + +;; tests:glob-like-match +(define (tests:glob-like-match patt str) + (let ((like (substring-index "%" patt))) + (let* ((notpatt (equal? (substring-index "~" patt) 0)) + (newpatt (if notpatt (substring patt 1) patt)) + (finpatt (if like + (string-substitute (regexp "%") ".*" newpatt) + (string-substitute (regexp "\\*") ".*" newpatt))) + (res #f)) + ;; (print "tests:glob-like-match => notpatt: " notpatt ", newpatt: " newpatt ", finpatt: " finpatt) + (set! res (string-match (regexp finpatt (if like #t #f)) str)) + (if notpatt (not res) res)))) + +;; if itempath is #f then look only at the testname part +;; +(define (tests:match patterns testname itempath) + (if (string? patterns) + (let ((patts (string-split patterns ","))) + (if (null? patts) ;;; no pattern(s) means no match + #f + (let loop ((patt (car patts)) + (tal (cdr patts))) + ;; (print "loop: patt: " patt ", tal " tal) + (if (string=? patt "") + #f ;; nothing ever matches empty string - policy + (let* ((patt-parts (string-match (regexp "^([^\\/]*)(\\/(.*)|)$") patt)) + (test-patt (cadr patt-parts)) + (item-patt (cadddr patt-parts))) + ;; (print "tests:match => patt-parts: " patt-parts ", test-patt: " test-patt ", item-patt: " item-patt) + (if (and (tests:glob-like-match test-patt testname) + (or (not itempath) + (tests:glob-like-match (if item-patt item-patt "") itempath))) + #t + (if (null? tal) + #f + (loop (car tal)(cdr tal))))))))))) + +;; if itempath is #f then look only at the testname part +;; +(define (tests:match->sqlqry patterns) + (if (string? patterns) + (let ((patts (string-split patterns ","))) + (if (null? patts) ;;; no pattern(s) means no match, we will do no query + #f + (let loop ((patt (car patts)) + (tal (cdr patts)) + (res '())) + ;; (print "loop: patt: " patt ", tal " tal) + (let* ((patt-parts (string-match (regexp "^([^\\/]*)(\\/(.*)|)$") patt)) + (test-patt (cadr patt-parts)) + (item-patt (cadddr patt-parts)) + (test-qry (db:patt->like "testname" test-patt)) + (item-qry (db:patt->like "item_path" item-patt)) + (qry (conc "(" test-qry " AND " item-qry ")"))) + ;; (print "tests:match => patt-parts: " patt-parts ", test-patt: " test-patt ", item-patt: " item-patt) + (if (null? tal) + (string-intersperse (append (reverse res)(list qry)) " OR ") + (loop (car tal)(cdr tal)(cons qry res))))))) + #f)) ;; get the previous record for when this test was run where all keys match but runname ;; returns #f if no such test found, returns a single test record if found (define (test:get-previous-test-run-record db run-id test-name item-path) (let* ((keys (db:get-keys db)) @@ -54,11 +125,11 @@ ;; if found then return that matching test record (debug:print 4 "selstr: " selstr ", qrystr: " qrystr ", keyvals: " keyvals ", previous run ids found: " prev-run-ids) (if (null? prev-run-ids) #f (let loop ((hed (car prev-run-ids)) (tal (cdr prev-run-ids))) - (let ((results (db:get-tests-for-run db hed test-name item-path '() '()))) + (let ((results (db:get-tests-for-run db hed (conc test-name "/" item-path)'() '()))) (debug:print 4 "Got tests for run-id " run-id ", test-name " test-name ", item-path " item-path ": " results) (if (and (null? results) (not (null? tal))) (loop (car tal)(cdr tal)) (if (null? results) #f @@ -92,11 +163,11 @@ (debug:print 4 "selstr: " selstr ", qrystr: " qrystr ", keyvals: " keyvals ", previous run ids found: " prev-run-ids) (if (null? prev-run-ids) '() ;; no previous runs? return null (let loop ((hed (car prev-run-ids)) (tal (cdr prev-run-ids))) - (let ((results (db:get-tests-for-run db hed test-name item-path '() '()))) + (let ((results (db:get-tests-for-run db hed (conc test-name "/" item-path) '() '()))) (debug:print 4 "Got tests for run-id " run-id ", test-name " test-name ", item-path " item-path " results: " (intersperse results "\n")) ;; Keep only the youngest of any test/item combination (for-each (lambda (testdat) Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -26,11 +26,13 @@ mkdir -p simplelinks simpleruns cd simplerun;cp ../../*_records.scm .;perl -pi.bak -e 's/define-inline/define/' *_records.scm cd simplerun;echo '(load "../tests.scm")' | $(MEGATEST) -repl -debug $(DEBUG) test2 : fullprep - cd fullrun;$(MEGATEST) -runtests ez_pass,runfirst -reqtarg ubuntu/nfs/none -itempatt a/1 :runname $(RUNNAME)_a $(SERVER) + cd fullrun;$(MEGATEST) -runtests ez_pass,runfirst/a/% -reqtarg ubuntu/nfs/none :runname $(RUNNAME) $(SERVER) -debug $(DEBUG) $(LOGGING) + sleep 40;cd fullrun;megatest -target ubuntu/nfs/none :runname $(RUNNAME) -set-state-status COMPLETED,FORCED :state COMPLETED :status PASS -testpatt ez_p%s,runfirst/ -debug $(DEBUG) $(LOGGING) + test3 : fullprep cd fullrun;$(MEGATEST) -runtests runfirst -reqtarg ubuntu/nfs/none :runname $(RUNNAME)_b $(SERVER) -debug 10 test4 : fullprep @@ -42,16 +44,18 @@ cd fullrun;$(MEGATEST) $(SERVER) & cd fullrun;sleep 10;$(MEGATEST) -runall $(TARGET) :runname $(RUNNAME)_aa -debug $(DEBUG) $(LOGGING) > aa.log 2> aa.log & cd fullrun;sleep 10;$(MEGATEST) -runall $(TARGET) :runname $(RUNNAME)_ab -debug $(DEBUG) $(LOGGING) > ab.log 2> ab.log & cd fullrun;sleep 10;$(MEGATEST) -runall $(TARGET) :runname $(RUNNAME)_ac -debug $(DEBUG) $(LOGGING) > ac.log 2> ac.log & cd fullrun;sleep 10;$(MEGATEST) -runall $(TARGET) :runname $(RUNNAME)_ad -debug $(DEBUG) $(LOGGING) > ad.log 2> ad.log & -# cd fullrun;sleep 10;$(MEGATEST) -runall $(TARGET) :runname $(RUNNAME)_ae -debug $(DEBUG) $(LOGGING) > ae.log 2> ae.log & -# cd fullrun;sleep 10;$(MEGATEST) -runall $(TARGET) :runname $(RUNNAME)_af -debug $(DEBUG) $(LOGGING) > af.log 2> af.log & + cd fullrun;sleep 10;$(MEGATEST) -runall $(TARGET) :runname $(RUNNAME)_ae -debug $(DEBUG) $(LOGGING) > ae.log 2> ae.log & + cd fullrun;sleep 10;$(MEGATEST) -runall $(TARGET) :runname $(RUNNAME)_af -debug $(DEBUG) $(LOGGING) > af.log 2> af.log & test6: fullprep - cd fullrun;$(MEGATEST) -runtests runfirst -itempatt %/1 -reqtarg ubuntu/nfs/none :runname $(RUNNAME)_itempatt -v - cd fullrun;$(MEGATEST) -runtests runfirst -itempatt %blahha% -reqtarg ubuntu/nfs/none :runname $(RUNNAME)_itempatt -debug 10 + cd fullrun;$(MEGATEST) -runtests runfirst -testpatt %/1 -reqtarg ubuntu/nfs/none :runname $(RUNNAME)_itempatt -v + cd fullrun;$(MEGATEST) -runtests runfirst -testpatt %blahha% -reqtarg ubuntu/nfs/none :runname $(RUNNAME)_itempatt -debug 10 + cd fullrun;$(MEGATEST) -rollup :runname newrun -target ubuntu/nfs/none -debug 10 + cleanprep : ../*.scm Makefile */*.config # if [ -e fullrun/megatest.db ]; then sqlite3 fullrun/megatest.db "delete from metadat where var='SERVER';";fi mkdir -p /tmp/mt_runs /tmp/mt_links cd ..;make install Index: tests/fullrun/megatest.config ================================================================== --- tests/fullrun/megatest.config +++ tests/fullrun/megatest.config @@ -36,10 +36,12 @@ WACKYVAR4 #{scheme (+ 5 6 7)} WACKYVAR5 #{getenv sysname}/#{getenv fsname}/#{getenv datapath} WACKYVAR6 #{scheme (args:get-arg "-target")} PREDICTABLE the_ans MRAH MT_RUN_AREA_HOME=#{getenv MT_RUN_AREA_HOME} +# The empty var should have a definition with null string +EMPTY_VAR # XTERM [system xterm] # RUNDEAD [system exit 56] ## disks are: ADDED tests/fullrun/tests/test_mt_vars/empty_var.sh Index: tests/fullrun/tests/test_mt_vars/empty_var.sh ================================================================== --- /dev/null +++ tests/fullrun/tests/test_mt_vars/empty_var.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +if [ x$EMPTY_VAR != "x" ];then + echo BAD EMPTY VAR! + exit 1 +fi ADDED tests/fullrun/tests/test_mt_vars/test-path-file.sh Index: tests/fullrun/tests/test_mt_vars/test-path-file.sh ================================================================== --- /dev/null +++ tests/fullrun/tests/test_mt_vars/test-path-file.sh @@ -0,0 +1,28 @@ +#!/bin/bash + + +# get a previous test +export EZFAILPATH=`$MT_MEGATEST -test-files envfile.txt -target $MT_TARGET :runname $MT_RUNNAME -testpatt runfirst/a%` + +echo Found $EZFAILPATH + +if [[ -e $EZFAILPATH ]];then + echo All good! +else + echo NOT good! + exit 1 +fi + +export EZFAILPATH=`$MT_MEGATEST -test-paths -target $MT_TARGET :runname $MT_RUNNAME -testpatt runfirst/a%` + +echo Found $EZFAILPATH + +if [[ -e $EZFAILPATH ]];then + echo All good! +else + echo NOT good! + exit 1 +fi + + +exit 0 Index: tests/fullrun/tests/test_mt_vars/testconfig ================================================================== --- tests/fullrun/tests/test_mt_vars/testconfig +++ tests/fullrun/tests/test_mt_vars/testconfig @@ -9,10 +9,16 @@ # $BOGOUS should NOT be set bogousnotset bogousnotset.sh # ALT_VAR should NOT be set altvarnotset altvarnotset.sh + +# EMPTY_VAR should be an empty string +empty_var empty_var.sh + +# test-path and test-file +test-path test-path-file.sh [requirements] waiton runfirst priority 0 Index: tests/tests.scm ================================================================== --- tests/tests.scm +++ tests/tests.scm @@ -16,10 +16,49 @@ ;;====================================================================== (test "cmd-run-with-stderr->list" '("No such file or directory") (let ((reslst (cmd-run-with-stderr->list "ls" "/tmp/ihadbetternotexist"))) (string-search (regexp "No such file or directory")(car reslst)))) + +;;====================================================================== +;; T E S T M A T C H I N G +;;====================================================================== + +;; tests:glob-like-match +(test #f '("abc") (tests:glob-like-match "abc" "abc")) +(for-each + (lambda (patt str expected) + (test (conc patt " " str "=>" expected) expected (tests:glob-like-match patt str))) + (list "abc" "~abc" "~abc" "a*c" "a%c") + (list "abc" "abcd" "abc" "ABC" "ABC") + (list '("abc") #t #f #f '("ABC")) + ) + +;; tests:match +(test #f #t (tests:match "abc/def" "abc" "def")) +(for-each + (lambda (patterns testname itempath expected) + (test (conc patterns " " testname "/" itempath "=>" expected) + expected + (tests:match patterns testname itempath))) + (list "abc" "abc/%" "ab%/c%" "~abc/c%" "abc/~c%" "a,b/c,%/d") + (list "abc" "abc" "abcd" "abc" "abc" "a" ) + (list "" "" "cde" "cde" "cde" "" ) + (list #t #t #t #f #f #t)) + +;; db:patt->like +(test #f "testname LIKE 't%'" (db:patt->like "testname" "t%" comparator: " AND ")) +(test #f "testname LIKE 't%' AND testname LIKE '%t'" (db:patt->like "testname" "t%,%t" comparator: " AND ")) +(test #f "item_path GLOB ''" (db:patt->like "item_path" "")) + +;; test:match->sqlqry +(test #f "(testname GLOB 'a' AND item_path GLOB 'b') OR (testname LIKE 'a%' AND item_path LIKE '%') OR (testname GLOB '' AND item_path LIKE 'b%')" + (tests:match->sqlqry "a/b,a%,/b%")) +(test #f "(testname GLOB 'a' AND item_path GLOB 'b') OR (testname LIKE 'a%' AND item_path LIKE '%') OR (testname LIKE '%' AND item_path LIKE 'b%')" + (tests:match->sqlqry "a/b,a%,%/b%")) + +;; (exit) ;;====================================================================== ;; C O N F I G F I L E S ;;====================================================================== @@ -86,24 +125,33 @@ (vector-ref (open-run-close db:get-test-info #f 1 "nada" "") 3))) (test "get-keys" "SYSTEM" (vector-ref (car (db:get-keys *db*)) 0));; (key:get-fieldname (car (sort (db-get-keys *db*)(lambda (a b)(string>=? (vector-ref a 0)(vector-ref b 0))))))) (define remargs (args:get-args - '("bar" "foo" ":runname" "bob" ":sysname" "ubuntu" ":fsname" "nfs" ":datapath" "blah/foo" "nada") + '("bar" "foo" ":runname" "bob" ":SYSTEM" "ubuntu" ":RELEASE" "v1.2" ":datapath" "blah/foo" "nada") (list ":runname" ":state" ":status") (list "-h") args:arg-hash 0)) (test "register-run" #t (number? (runs:register-run *db* (db:get-keys *db*) - '(("SYSTEM" "key1")("OS" "key2")) + '(("SYSTEM" "key1")("RELEASE" "key2")) "myrun" "new" "n/a" "bob"))) (define keys (db:get-keys *db*)) + +;;====================================================================== +;; D B +;;====================================================================== +(test #f "FOO LIKE 'abc%def'" (db:patt->like "FOO" "abc%def")) +(test #f (vector '("SYSTEM" "RELEASE" "id" "runname" "state" "status" "owner" "event_time") '()) + (runs:get-runs-by-patt db keys "%")) +(test #f "SYSTEM,RELEASE,id,runname,state,status,owner,event_time" (car (runs:get-std-run-fields keys '("id" "runname" "state" "status" "owner" "event_time")))) +(test #f #t (runs:operate-on 'print "%" "%" "%")) ;;(test "update-test-info" #t (test-update-meta-info *db* 1 "nada" (setenv "BLAHFOO" "1234") (unsetenv "NADAFOO") (test "env temp overrides" "xyz" (let ((prevvals (alist->env-vars '(("BLAHFOO" 4321)("NADAFOO" xyz)))) @@ -184,23 +232,25 @@ (test "Add a step" #t (begin (db:teststep-set-status! db 2 "step1" "start" 0 "This is a comment" "mylogfile.html") (sleep 2) (db:teststep-set-status! db 2 "step1" "end" "pass" "This is a different comment" "finallogfile.html") - (set! test-id (db:test-get-id (car (db:get-tests-for-run db 1 "test1" "" '() '())))) + (set! test-id (db:test-get-id (car (db:get-tests-for-run db 1 "test1" '() '())))) (number? test-id))) (test "Get rundir" #t (let ((rundir (db:test-get-rundir-from-test-id db test-id))) (print "Rundir" rundir) (string? rundir))) (test "Create a test db" "../simpleruns/key1/key2/myrun/test1/testdat.db" (let ((tdb (db:open-test-db-by-test-id db test-id))) (sqlite3#finalize! tdb) (file-exists? "../simpleruns/key1/key2/myrun/test1/testdat.db"))) (test "Get steps for test" #t (> (length (db:get-steps-for-test db test-id)) 0)) -(test "Get nice table for steps" "2s" +(test "Get nice table for steps" "2.0s" (begin (vector-ref (hash-table-ref (db:get-steps-table db test-id) "step1") 4))) + +;; (exit) ;;====================================================================== ;; R E M O T E C A L L S ;;====================================================================== @@ -257,11 +307,11 @@ ("KILLED" "UNKNOWN" "More testing") ("KILLED" "UNKNOWN" "More testing") )) ;; now set all tests to completed (rdb:flush-queue) -(let ((tests (open-run-close db:get-tests-for-run #f 1 "%" "%" '() '()))) +(let ((tests (open-run-close db:get-tests-for-run #f 1 "%" '() '()))) (print "Setting " (length tests) " to COMPLETED/PASS") (for-each (lambda (test) (rdb:test-set-status-state (db:test-get-id test) "COMPLETED" "PASS" "Forced pass")) tests))