Index: Makefile
==================================================================
--- Makefile
+++ Makefile
@@ -27,11 +27,11 @@
process.scm runs.scm tasks.scm tests.scm genexample.scm \
http-transport.scm filedb.scm tdb.scm \
client.scm mt.scm \
ezsteps.scm lock-queue.scm sdb.scm \
rmt.scm api.scm subrun.scm \
- portlogger.scm archive.scm env.scm diff-report.scm cgisetup/models/pgdb.scm
+ portlogger.scm archive.scm env.scm diff-report.scm cgisetup/models/pgdb.scm
# module source files
MSRCFILES = ftail.scm
# Eggs to install (straightforward ones)
@@ -165,12 +165,12 @@
echo "(define megatest-fossil-hash \"$(MTESTHASH)\")" > megatest-fossil-hash.new
if ! diff -q megatest-fossil-hash.new megatest-fossil-hash.scm ; then echo copying .new to .scm;cp -f megatest-fossil-hash.new megatest-fossil-hash.scm;fi
$(OFILES) $(GOFILES) : common_records.scm
-%.o : %.scm
- csc $(CSCOPTS) -c $<
+%.o : %.scm $(MOFILES)
+ csc $(CSCOPTS) -c $< $(MOFILES)
$(PREFIX)/bin/.$(ARCHSTR)/mtest : mtest utils/mk_wrapper
@echo Installing to PREFIX=$(PREFIX)
$(INSTALL) mtest $(PREFIX)/bin/.$(ARCHSTR)/mtest
utils/mk_wrapper $(PREFIX) mtest $(PREFIX)/bin/megatest
@@ -216,10 +216,14 @@
chmod a+x $@
$(PREFIX)/bin/mt_runstep : utils/mt_runstep
$(INSTALL) $< $@
chmod a+x $@
+
+$(PREFIX)/bin/serialize-env: serialize-env.scm
+ csc serialize-env.scm
+ $(INSTALL) serialize-env $@
$(PREFIX)/bin/mt_ezstep : utils/mt_ezstep
$(INSTALL) $< $@
chmod a+x $@
@@ -274,10 +278,11 @@
chmod a+x $(PREFIX)/bin/dashboard
$(INSTALL) dboard $(PREFIX)/bin/.$(ARCHSTR)/dboard
install : $(PREFIX)/bin/.$(ARCHSTR) $(PREFIX)/bin/.$(ARCHSTR)/mtest $(PREFIX)/bin/megatest \
$(PREFIX)/bin/.$(ARCHSTR)/dboard $(PREFIX)/bin/dashboard $(HELPERS) $(PREFIX)/bin/nbfake \
+ $(PREFIX)/bin/serialize-env \
$(PREFIX)/bin/nbfind $(PREFIX)/bin/loadrunner $(PREFIX)/bin/viewscreen $(PREFIX)/bin/mt_xterm \
$(PREFIX)/share/docs/megatest_manual.html $(PREFIX)/bin/remrun \
$(PREFIX)/share/docs/megatest_manual.html $(PREFIX)/bin/remrun $(PREFIX)/bin/mtutil \
$(PREFIX)/bin/tcmt $(PREFIX)/share/db/mt-pg.sql \
$(PREFIX)/share/js/jquery-3.1.0.slim.min.js
@@ -356,24 +361,27 @@
xterm : sd
(export BASEPATH=/tmp/$(USER)/basepath ; export PATH="$(PWD)/datashare-testing:$(PATH)" ; xterm &)
datashare-testing/spublish : spublish.scm $(OFILES)
- csc $(CSCOPTS) spublish.scm $(OFILES) -o datashare-testing/spublish
+ csc $(CSCOPTS) spublish.scm megatest-version.o margs.o process.o common.o -o datashare-testing/spublish
datashare-testing/sretrieve : sretrieve.scm $(OFILES)
- csc $(CSCOPTS) sretrieve.scm $(OFILES) -o datashare-testing/sretrieve
+ csc $(CSCOPTS) sretrieve.scm megatest-version.o margs.o process.o common.o -o datashare-testing/sretrieve
datashare-testing/sauthorize : sauthorize.scm $(OFILES)
- csc $(CSCOPTS) sauthorize.scm $(OFILES) -o datashare-testing/sauthorize
+ csc $(CSCOPTS) sauthorize.scm megatest-version.o margs.o process.o common.o -o datashare-testing/sauthorize
+sauth-init:
+ mkdir -p datashare-testing
+ rm datashare-testing/sauthorize
+ rm datashare-testing/sretrieve
+ rm datashare-testing/spublish
-sretrieve/sretrieve : datashare-testing/sretrieve
- csc $(CSCOPTS) -deploy -deployed sretrieve.scm megatest-version.o margs.o configf.o process.o
- chicken-install -keep-installed $(PROXY) -deploy -prefix sretrieve defstruct srfi-18 format sql-de-lite \
- srfi-1 posix regex regex-case srfi-69
+sauth : sauth-init datashare-testing/sauthorize datashare-testing/sretrieve datashare-testing/spublish
+
# base64 dot-locking \
# csv-xml z3
# "(define (toplevel-command . a) #f)"
Index: TODO
==================================================================
--- TODO
+++ TODO
@@ -28,5 +28,7 @@
. Re-work the dbstruct data structure?
.. Move main.db to global?
.. [ run-id.db inmemdb last-mod last-read last-sync inuse ]
. Re-work all queries to use run-id to dereference server
. Open main.db directly in calls to -runtests etc. No need to talk remote?
+. remove common:faux-lock
+
Index: api.scm
==================================================================
--- api.scm
+++ api.scm
@@ -78,11 +78,12 @@
login
tasks-get-last
testmeta-get-record
have-incompletes?
synchash-get
- get-changed-record-ids
+ get-changed-record-ids
+ get-run-record-ids
))
(define api:write-queries
'(
get-keys-write ;; dummy "write" query to force server start
@@ -156,10 +157,15 @@
(params (vector-ref dat 1))
(start-t (current-milliseconds))
(readonly-mode (dbr:dbstruct-read-only dbstruct))
(readonly-command (member cmd api:read-only-queries))
(writecmd-in-readonly-mode (and readonly-mode (not readonly-command)))
+ (foo (begin
+ (common:telemetry-log (conc "api-in:"(->string cmd))
+ payload: `((params . ,params)))
+
+ #t))
(res
(if writecmd-in-readonly-mode
(conc "attempt to run write command "cmd" on a read-only database")
(case cmd
;;===============================================
@@ -316,29 +322,38 @@
(run-id (cadr params))
(realparams (cddr params)))
(db:general-call dbstruct stmtname realparams)))
((sdb-qry) (apply sdb:qry params))
((ping) (current-process-id))
- ((get-changed-record-ids) (apply db:get-changed-record-ids dbstruct params))
-
+ ((get-changed-record-ids) (apply db:get-changed-record-ids dbstruct params))
+ ((get-run-record-ids) (apply db:get-run-record-ids dbstruct params))
;; TESTMETA
((testmeta-get-record) (apply db:testmeta-get-record dbstruct params))
;; TASKS
((find-task-queue-records) (apply tasks:find-task-queue-records dbstruct params))
(else
(debug:print 0 *default-log-port* "ERROR: bad api call " cmd)
(conc "ERROR: BAD api call " cmd))))))
+
;; save all stats
(let ((delta-t (- (current-milliseconds)
start-t)))
(hash-table-set! *db-api-call-time* cmd
(cons delta-t (hash-table-ref/default *db-api-call-time* cmd '()))))
(if writecmd-in-readonly-mode
- (vector #f res)
- (vector #t res)))))))
+ (begin
+ (common:telemetry-log (conc "api-out:"(->string cmd))
+ payload: `((params . ,params)
+ (ok-res . #t)))
+ (vector #f res))
+ (begin
+ (common:telemetry-log (conc "api-out:"(->string cmd))
+ payload: `((params . ,params)
+ (ok-res . #f)))
+ (vector #t res))))))))
;; http-server send-response
;; api:process-request
;; db:*
;;
Index: cgisetup/models/pgdb.scm
==================================================================
--- cgisetup/models/pgdb.scm
+++ cgisetup/models/pgdb.scm
@@ -137,10 +137,17 @@
;; if no run found return #f
;;
(define (pgdb:get-run-id dbh spec-id target run-name area-id)
(dbi:get-one dbh "SELECT id FROM runs WHERE ttype_id=? AND target=? AND run_name=? and area_id=?;"
spec-id target run-name area-id))
+
+;; given a target spec id, target and run-name return the run-id
+;; if no run found return #f
+;;
+(define (pgdb:get-run-last-update dbh id )
+ (dbi:get-one dbh "SELECT last_update FROM runs WHERE id=?;"
+ id))
;; given a run-id return all the run info
;;
(define (pgdb:get-run-info dbh run-id ) ;; to join ttype or not?
(dbi:get-one-row
@@ -148,26 +155,26 @@
"SELECT id,target,ttype_id,run_name,state,status,owner,event_time,comment,fail_count,pass_count,last_update,area_id
FROM runs WHERE id=? ;" run-id ))
;; refresh the data in a run record
;;
-(define (pgdb:refresh-run-info dbh run-id state status owner event-time comment fail-count pass-count area-id) ;; area-id)
+(define (pgdb:refresh-run-info dbh run-id state status owner event-time comment fail-count pass-count area-id last_update) ;; area-id)
(dbi:exec
dbh
"UPDATE runs SET
- state=?,status=?,owner=?,event_time=?,comment=?,fail_count=?,pass_count=?
+ state=?,status=?,owner=?,event_time=?,comment=?,fail_count=?,pass_count=?,last_update=?
WHERE id=? and area_id=?;"
- state status owner event-time comment fail-count pass-count run-id area-id))
+ state status owner event-time comment fail-count pass-count last_update run-id area-id ))
;; given all needed info create run record
;;
-(define (pgdb:insert-run dbh ttype-id target run-name state status owner event-time comment fail-count pass-count area-id)
+(define (pgdb:insert-run dbh ttype-id target run-name state status owner event-time comment fail-count pass-count area-id last-update)
(dbi:exec
dbh
- "INSERT INTO runs (ttype_id,target,run_name,state,status,owner,event_time,comment,fail_count,pass_count,area_id )
- VALUES (?,?,?,?,?,?,?,?,?,?,?);"
- ttype-id target run-name state status owner event-time comment fail-count pass-count area-id))
+ "INSERT INTO runs (ttype_id,target,run_name,state,status,owner,event_time,comment,fail_count,pass_count,area_id,last_update)
+ VALUES (?,?,?,?,?,?,?,?,?,?,?,?);"
+ ttype-id target run-name state status owner event-time comment fail-count pass-count area-id last-update))
;;======================================================================
;; T E S T - S T E P S
;;======================================================================
@@ -175,24 +182,30 @@
(dbi:get-one
dbh
"SELECT id FROM test_steps WHERE test_id=? AND stepname=? and state = ? ;"
test-id stepname state))
-(define (pgdb:insert-test-step dbh test-id stepname state status event_time comment logfile)
+(define (pgdb:get-test-step-last-update dbh id )
+ (dbi:get-one
+ dbh
+ "SELECT last_update FROM test_steps WHERE id=? ;"
+ id))
+
+(define (pgdb:insert-test-step dbh test-id stepname state status event_time comment logfile last-update)
(dbi:exec
dbh
- "INSERT INTO test_steps (test_id,stepname,state,status,event_time,logfile,comment)
- VALUES (?,?,?,?,?,?,?);"
- test-id stepname state status event_time logfile comment))
+ "INSERT INTO test_steps (test_id,stepname,state,status,event_time,logfile,comment,last_update)
+ VALUES (?,?,?,?,?,?,?, ? );"
+ test-id stepname state status event_time logfile comment last-update))
-(define (pgdb:update-test-step dbh step-id test-id stepname state status event_time comment logfile)
+(define (pgdb:update-test-step dbh step-id test-id stepname state status event_time comment logfile last-update)
(dbi:exec
dbh
"UPDATE test_steps SET
- test_id=?,stepname=?,state=?,status=?,event_time=?,logfile=?,comment=?
+ test_id=?,stepname=?,state=?,status=?,event_time=?,logfile=?,comment=?,last_update=?
WHERE id=?;"
- test-id stepname state status event_time logfile comment step-id))
+ test-id stepname state status event_time logfile comment last-update step-id))
;;======================================================================
;; T E S T - D A T A
;;======================================================================
@@ -201,11 +214,17 @@
(dbi:get-one
dbh
"SELECT id FROM test_data WHERE test_id=? AND category=? and variable = ? ;"
test-id category variable))
-(define (pgdb:insert-test-data dbh test-id category variable value expected tol units comment status type)
+(define (pgdb:get-test-data-last-update dbh test-data-id )
+ (dbi:get-one
+ dbh
+ "SELECT last_update FROM test_data WHERE id=? ;"
+ test-data-id))
+
+(define (pgdb:insert-test-data dbh test-id category variable value expected tol units comment status type last-update)
; (print "INSERT INTO test_data (test_id, category, variable, value, expected, tol, units, comment, status, type)
; VALUES (?,?,?,?,?,?,?,?,?,?) " test-id " " category " " variable " " value " " expected " " tol " " units " " comment " " status " " type)
(if (not (string? units))
(set! units "" ))
(if (not (string? variable))
@@ -217,21 +236,21 @@
(if (not (real? tol))
(set! tol 0 ))
(dbi:exec
dbh
- "INSERT INTO test_data (test_id, category, variable, value, expected, tol, units, comment, status, type)
- VALUES (?,?,?,?,?,?,?,?,?,?);"
- test-id category variable value expected tol units comment status type))
+ "INSERT INTO test_data (test_id, category, variable, value, expected, tol, units, comment, status, type, last_update)
+ VALUES (?,?,?,?,?,?,?,?,?,?, ?);"
+ test-id category variable value expected tol units comment status type last-update))
-(define (pgdb:update-test-data dbh data-id test-id category variable value expected tol units comment status type)
+(define (pgdb:update-test-data dbh data-id test-id category variable value expected tol units comment status type last-update)
(dbi:exec
dbh
"UPDATE test_data SET
- test_id=?, category=?, variable=?, value=?, expected=?, tol=?, units=?, comment=?, status=?, type=?
+ test_id=?, category=?, variable=?, value=?, expected=?, tol=?, units=?, comment=?, status=?, type=?, last_update=?
WHERE id=?;"
- test-id category variable value expected tol units comment status type data-id ))
+ test-id category variable value expected tol units comment status type last-update data-id ))
;;======================================================================
;; T E S T S
@@ -242,33 +261,40 @@
(define (pgdb:get-test-id dbh run-id test-name item-path)
(dbi:get-one
dbh
"SELECT id FROM tests WHERE run_id=? AND test_name=? AND item_path=?;"
run-id test-name item-path))
+
+(define (pgdb:get-test-last-update dbh id)
+ (dbi:get-one
+ dbh
+ "SELECT last_update FROM tests WHERE id=? ;"
+ id ))
+
;; create new test record
;;
-(define (pgdb:insert-test dbh run-id test-name item-path state status host cpuload diskfree uname run-dir log-file run-duration comment event-time archived)
+(define (pgdb:insert-test dbh run-id test-name item-path state status host cpuload diskfree uname run-dir log-file run-duration comment event-time archived last-update)
(dbi:exec
dbh
- "INSERT INTO tests (run_id,test_name,item_path,state,status,host,cpuload,diskfree,uname,rundir,final_logf,run_duration,comment,event_time,archived)
- VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"
+ "INSERT INTO tests (run_id,test_name,item_path,state,status,host,cpuload,diskfree,uname,rundir,final_logf,run_duration,comment,event_time,archived,last_update)
+ VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"
run-id test-name item-path state status host cpuload diskfree uname
- run-dir log-file run-duration comment event-time archived))
+ run-dir log-file run-duration comment event-time archived last-update))
;; update existing test record
;;
-(define (pgdb:update-test dbh test-id run-id test-name item-path state status host cpuload diskfree uname run-dir log-file run-duration comment event-time archived)
+(define (pgdb:update-test dbh test-id run-id test-name item-path state status host cpuload diskfree uname run-dir log-file run-duration comment event-time archived last-update)
(dbi:exec
dbh
"UPDATE tests SET
- run_id=?,test_name=?,item_path=?,state=?,status=?,host=?,cpuload=?,diskfree=?,uname=?,rundir=?,final_logf=?,run_duration=?,comment=?,event_time=?,archived=?
+ run_id=?,test_name=?,item_path=?,state=?,status=?,host=?,cpuload=?,diskfree=?,uname=?,rundir=?,final_logf=?,run_duration=?,comment=?,event_time=?,archived=?,last_update=?
WHERE id=?;"
run-id test-name item-path state status host cpuload diskfree uname
- run-dir log-file run-duration comment event-time archived test-id))
+ run-dir log-file run-duration comment event-time archived last-update test-id))
(define (pgdb:get-tests dbh target-patt)
(dbi:get-rows
dbh
"SELECT t.id,t.run_id,t.test_name,t.item_path,t.state,t.status,t.host,t.cpuload,t.diskfree,t.uname,t.rundir,t.final_logf,t.run_duration,t.comment,t.event_time,t.archived,
Index: common.scm
==================================================================
--- common.scm
+++ common.scm
@@ -17,11 +17,11 @@
;; along with Megatest. If not, see .
;;======================================================================
(use srfi-1 data-structures posix regex-case (prefix base64 base64:)
- format dot-locking csv-xml z3 ;; sql-de-lite
+ format dot-locking csv-xml z3 udp ;; sql-de-lite
hostinfo md5 message-digest typed-records directory-utils stack
matchable regex posix (srfi 18) extras ;; tcp
(prefix nanomsg nmsg:)
(prefix sqlite3 sqlite3:)
pkts (prefix dbi dbi:)
@@ -81,10 +81,11 @@
(length (glob (conc "/proc/" pid "/fd/*")))
(length (filter identity (map socket? (glob (conc "/proc/" pid "/fd/*")))))
)
)
+
;; GLOBALS
;; CONTEXTS
(defstruct cxt
@@ -337,10 +338,92 @@
;; '())
)
(if (common:api-changed?)
(common:set-last-run-version)))
+(define (common:snapshot-file filepath #!key (subdir ".") )
+ (if (file-exists? filepath)
+ (let* ((age-sec (lambda (file)
+ (if (file-exists? file)
+ (- (current-seconds) (file-modification-time file))
+ 1000000000))) ;; return really old value if file doesn't exist. we want to clobber it if old or not exist.
+ (ok-flag #t)
+ (age-mins (lambda (file) (/ (age-sec file) 60)))
+ (age-hrs (lambda (file) (/ (age-mins file) 60)))
+ (age-days (lambda (file) (/ (age-hrs file) 24)))
+ (age-wks (lambda (file) (/ (age-days file) 7)))
+ (docmd (lambda (cmd)
+ (cond
+ (ok-flag
+ (let ((res (system cmd)))
+ (cond
+ ((eq? 0 res)
+ #t)
+ (else
+ (set! ok-flag #f)
+ (debug:print 0 *default-log-port* "ERROR: ["(common:human-time)"] Command failed with exit code "
+ (if (< res 0)
+ res
+ (/ res 8)) " ["cmd"]" )
+ #f))))
+ (else
+ (debug:print 0 *default-log-port* "ERROR: ["(common:human-time)"] Not runnining command due to prior error. ["cmd"]")
+ #f))))
+ (copy (lambda (src dest) (docmd (conc "/bin/cp '"src"' '"dest"'"))))
+ (copy+zip (lambda (src dest) (docmd (conc "gzip -c - < '"src"' > '"dest"'"))))
+ (fullpath (realpath filepath))
+ (basedir (pathname-directory fullpath))
+ (basefile (pathname-strip-directory fullpath))
+ ;;(prevfile (conc filepath ".prev.gz"))
+ (minsfile (conc basedir "/" subdir "/" basefile ".mins.gz"))
+ (hrsfile (conc basedir "/" subdir "/" basefile ".hrs.gz"))
+ (daysfile (conc basedir "/" subdir "/" basefile ".days.gz"))
+ (wksfile (conc basedir "/" subdir "/" basefile ".weeks.gz")))
+
+ ;; create subdir it not exists
+ (if (not (directory-exists? (conc basedir "/" subdir)))
+ (docmd (conc "/bin/mkdir -p '"(conc basedir "/" subdir)"'")))
+
+ ;; copy&zip to .mins if not exists
+ (if (not (file-exists? minsfile))
+ (copy+zip filepath minsfile))
+ ;; copy .mins to .hrs if not exists
+ (if (not (file-exists? hrsfile))
+ (copy minsfile hrsfile))
+ ;; copy .hrs to .days if not exists
+ (if (not (file-exists? daysfile))
+ (copy hrsfile daysfile))
+ ;; copy .days to .weeks if not exists
+ (if (not (file-exists? wksfile))
+ (copy daysfile wksfile))
+
+
+ ;; if age(.mins.gz) >= 1h:
+ ;; copy .mins.gz .hrs.gz
+ ;; copy .mins.gz
+ (when (>= (age-mins minsfile) 1)
+ (copy minsfile hrsfile)
+ (copy+zip filepath minsfile))
+
+ ;; if age(.hrs.gz) >= 1d:
+ ;; copy .hrs.gz .days.gz
+ ;; copy .mins.gz .hrs.gz
+ (when (>= (age-days hrsfile) 1)
+ (copy hrsfile daysfile)
+ (copy minsfile hrsfile))
+
+ ;; if age(.days.gz) >= 1w:
+ ;; copy .days.gz .weeks.gz
+ ;; copy .hrs.gz .days.gz
+ (when (>= (age-wks daysfile) 1)
+ (copy daysfile wksfile)
+ (copy hrsfile daysfile))
+ #t)
+ #f))
+
+
+
;; Rotate logs, logic:
;; if > 500k and older than 1 week:
;; remove previous compressed log and compress this log
;; WARNING: This proc operates assuming that it is in the directory above the
;; logs directory you wish to log-rotate.
@@ -749,15 +832,19 @@
(define *wdnum* 0)
(define *wdnum*mutex (make-mutex))
+
+
+(define (common:human-time)
+ (time->string (seconds->local-time (current-seconds)) "%Y-%m-%d %H:%M:%S"))
+
+
;; currently the primary job of the watchdog is to run the sync back to megatest.db from the db in /tmp
;; if we are on the homehost and we are a server (by definition we are on the homehost if we are a server)
;;
-
-
(define (common:readonly-watchdog dbstruct)
(thread-sleep! 0.05) ;; delay for startup
(debug:print-info 13 *default-log-port* "common:readonly-watchdog entered.")
;; sync megatest.db to /tmp/.../megatst.db
(let* ((sync-cool-off-duration 3)
@@ -801,10 +888,11 @@
(debug:print-info 13 *default-log-port* "watchdog done."))
(debug:print-info 13 *default-log-port* "no need for watchdog on non-homehost"))))
(define (std-exit-procedure)
+ ;;(common:telemetry-log-close)
(on-exit (lambda () 0))
;;(debug:print-info 13 *default-log-port* "std-exit-procedure called; *time-to-exit*="*time-to-exit*)
(let ((no-hurry (if *time-to-exit* ;; hurry up
#f
(begin
@@ -1160,16 +1248,16 @@
(handle-exceptions
exn
(if (> trynum 0)
(let ((delay-time (* (- 5 trynum) 5)))
(mutex-unlock! *homehost-mutex*)
- (debug:print 0 *default-log-port* "ERROR: Failed to read .homehost file, delaying " delay-time " seconds and trying again, message: " ((condition-property-accessor 'exn 'message) exn))
+ (debug:print 0 *default-log-port* "ERROR: ["(common:human-time)"] Failed to read .homehost file, delaying " delay-time " seconds and trying again, message: " ((condition-property-accessor 'exn 'message) exn))
(thread-sleep! delay-time)
(common:get-homehost trynum: (- trynum 1)))
(begin
(mutex-unlock! *homehost-mutex*)
- (debug:print 0 *default-log-port* "ERROR: Failed to read .homehost file after trying five times. Giving up and exiting, message: " ((condition-property-accessor 'exn 'message) exn))
+ (debug:print 0 *default-log-port* "ERROR: ["(common:human-time)"] Failed to read .homehost file after trying five times. Giving up and exiting, message: " ((condition-property-accessor 'exn 'message) exn))
(exit 1)))
(let ((hhf (conc *toppath* "/.homehost")))
(if (common:file-exists? hhf)
(with-input-from-file hhf read-line)
(if (file-write-access? *toppath*)
@@ -1505,22 +1593,25 @@
(with-output-to-file fullpath (lambda ()(pp dat))))))
;; get cpu load by reading from /proc/loadavg, return all three values
;;
(define (common:get-cpu-load remote-host)
- (let* ((actual-hostname (or remote-host (get-host-name) "localhost")))
- (or (common:get-cached-info actual-hostname "cpu-load")
- (let ((result (if remote-host
- (map (lambda (res)
- (if (eof-object? res) 9e99 res))
- (with-input-from-pipe
- (conc "ssh " remote-host " cat /proc/loadavg")
+ (handle-exceptions
+ exn
+ '(99 99 99)
+ (let* ((actual-hostname (or remote-host (get-host-name) "localhost")))
+ (or (common:get-cached-info actual-hostname "cpu-load")
+ (let ((result (if remote-host
+ (map (lambda (res)
+ (if (eof-object? res) 9e99 res))
+ (with-input-from-pipe
+ (conc "ssh " remote-host " cat /proc/loadavg")
(lambda ()(list (read)(read)(read)))))
- (with-input-from-file "/proc/loadavg"
- (lambda ()(list (read)(read)(read)))))))
- (common:write-cached-info actual-hostname "cpu-load" result)
- result))))
+ (with-input-from-file "/proc/loadavg"
+ (lambda ()(list (read)(read)(read)))))))
+ (common:write-cached-info actual-hostname "cpu-load" result)
+ result)))))
;; get normalized cpu load by reading from /proc/loadavg and /proc/cpuinfo return all three values and the number of real cpus and the number of threads
;; returns alist '((adj-cpu-load . normalized-proc-load) ... etc.
;; keys: adj-proc-load, adj-core-load, 1m-load, 5m-load, 15m-load
;;
@@ -2081,10 +2172,33 @@
;; clear vars matching pattern, run proc, set vars back
;; if proc is a string run that string as a command with
;; system.
;;
+(define *common:orig-env*
+ (let ((envvars (get-environment-variables)))
+ (if (get-environment-variable "MT_ORIG_ENV")
+ (with-input-from-string
+ (z3:decode-buffer (base64:base64-decode (get-environment-variable "MT_ORIG_ENV")))
+ read)
+ (filter-map (lambda (x)
+ (if (string-match "^MT_.*" (car x))
+ #f
+ x))
+ envvars))))
+
+(define (common:with-orig-env proc)
+ (let ((current-env (get-environment-variables)))
+ (for-each (lambda (x) (unsetenv (car x))) current-env)
+ (for-each (lambda (x) (setenv (car x) (cdr x))) *common:orig-env*)
+ (let ((rv (cond
+ ((string? proc)(system proc))
+ (proc (proc)))))
+ (for-each (lambda (x) (unsetenv (car x))) *common:orig-env*)
+ (for-each (lambda (x) (setenv (car x) (cdr x))) current-env)
+ rv)))
+
(define (common:without-vars proc . var-patts)
(let ((vars (make-hash-table)))
(for-each
(lambda (vardat) ;; each env var
(for-each
@@ -2104,20 +2218,21 @@
(lambda (var val)
(setenv var val)))
vars))
-(define (common:run-a-command cmd #!key (with-vars #f))
+(define (common:run-a-command cmd #!key (with-vars #f) (with-orig-env #f))
(let* ((pre-cmd (dtests:get-pre-command))
(post-cmd (dtests:get-post-command))
(fullcmd (if (or pre-cmd post-cmd)
(conc pre-cmd cmd post-cmd)
(conc "viewscreen " cmd))))
(debug:print-info 02 *default-log-port* "Running command: " fullcmd)
- (if with-vars
- (common:without-vars cmd)
- (common:without-vars fullcmd "MT_.*"))))
+ (cond
+ (with-vars (common:without-vars fullcmd))
+ (with-orig-env (common:with-orig-env fullcmd))
+ (else (common:without-vars fullcmd "MT_.*")))))
;;======================================================================
;; T I M E A N D D A T E
;;======================================================================
@@ -2459,10 +2574,14 @@
;; simple lock. improve and converge on this one.
;;
(define (common:simple-lock keyname)
(rmt:no-sync-get-lock keyname))
+
+(define (common:simple-unlock keyname #!key (force #f))
+ (rmt:no-sync-del! keyname))
+
;;======================================================================
;;
;;======================================================================
@@ -2658,11 +2777,11 @@
command: command
host-port: host-port
params: params)))
(queue-push cmddat) ;; put request into the queue
(nn-send soc "queued")) ;; reply with "queued"
- (print "ERROR: BAD request " dat))
+ (print "ERROR: ["(common:human-time)"] BAD request " dat))
(loop (nn-recv soc)))))
(nn-close soc)))
@@ -2935,5 +3054,69 @@
exn
#t ;; just ignore it, it might have died in the meantime so joining it will throw an exception
(thread-join! thread))
)))
(hash-table-keys *common:thread-punchlist*)))
+
+(define *common:telemetry-log-state* 'startup)
+(define *common:telemetry-log-socket* #f)
+
+(define (common:telemetry-log-open)
+ (if (eq? *common:telemetry-log-state* 'startup)
+ (let* ((serverhost (configf:lookup *configdat* "telemetry" "host"))
+ (serverport (configf:lookup-number *configdat* "telemetry" "port"))
+ (user (or (get-environment-variable "USER") "unknown"))
+ (host (or (get-environment-variable "HOST") "unknown")))
+ (set! *common:telemetry-log-state*
+ (handle-exceptions
+ exn
+ (begin
+ (debug:print-info 0 *default-log-port* "common-telemetry-log open udp port failure")
+ 'broken)
+ (if (and serverhost serverport user host)
+ (let* ((s (udp-open-socket)))
+ ;;(udp-bind! s #f 0)
+ (udp-connect! s serverhost serverport)
+ (set! *common:telemetry-log-socket* s)
+ 'open)
+ 'not-needed))))))
+
+(define (common:telemetry-log event #!key (payload '()))
+ (if (eq? *common:telemetry-log-state* 'startup)
+ (common:telemetry-log-open))
+
+ (if (eq? 'open *common:telemetry-log-state*)
+ (handle-exceptions
+ exn
+ (begin
+ (debug:print-info 0 *default-log-port* "common-telemetry-log comms failure ; disabled (no server?)")
+ ;;(define *common:telemetry-log-state* 'broken-or-no-server-preclose)
+ ;;(common:telemetry-log-close)
+ (define *common:telemetry-log-state* 'broken-or-no-server)
+ (set! *common:telemetry-log-socket* #f)
+ )
+ (if (and *common:telemetry-log-socket* event) ;; TODO - filter on event against telemetry.want-events
+ (let* ((user (or (get-environment-variable "USER") "unknown"))
+ (host (or (get-environment-variable "HOST") "unknown"))
+ (start (conc "[megatest "event"]"))
+ (toppath (or *toppath* "/dev/null"))
+ (payload-serialized
+ (base64:base64-encode
+ (z3:encode-buffer
+ (with-output-to-string (lambda () (pp payload))))))
+ (msg (conc user":"host":"start":"(current-process-id)":"(car (argv))":"
+ toppath":"payload-serialized)))
+ (udp-send *common:telemetry-log-socket* msg))))))
+
+(define (common:telemetry-log-close)
+ (when (or (member *common:telemetry-log-state* '(broken-or-no-server-preclose open)) *common:telemetry-log-socket*)
+ (handle-exceptions
+ exn
+ (begin
+ (define *common:telemetry-log-state* 'closed-fail)
+ (debug:print-info 0 *default-log-port* "common-telemetry-log closure failure")
+ )
+ (begin
+ (define *common:telemetry-log-state* 'closed)
+ (udp-close-socket *common:telemetry-log-socket*)
+ (set! *common:telemetry-log-socket* #f)))))
+
Index: configf.scm
==================================================================
--- configf.scm
+++ configf.scm
@@ -774,14 +774,14 @@
ht))
;; if
(define (configf:read-alist fname)
(handle-exceptions
- exn
- #f
- (configf:alist->config
- (with-input-from-file fname read))))
+ exn
+ #f
+ (configf:alist->config
+ (with-input-from-file fname read))))
(define (configf:write-alist cdat fname)
(if (not (common:faux-lock fname))
(debug:print 0 *default-log-port* "INFO: Could not get lock on " fname))
(let* ((dat (configf:config->alist cdat))
Index: dashboard-tests.scm
==================================================================
--- dashboard-tests.scm
+++ dashboard-tests.scm
@@ -360,34 +360,53 @@
btns))))))
(define (dashboard-tests:run-a-step info)
#t)
-(define (dashboard-tests:step-run-control testdat stepname testconfig)
- (iup:dialog ;; #:close_cb (lambda (a)(exit)) ; #:expand "YES"
- #:title stepname
- (iup:vbox ; #:expand "YES"
- (iup:label (conc "Step: " stepname "\nNB// These buttons only run the test step\nfor the purpose of debugging.\nNot all database updates are done."))
- (iup:button "Re-run"
- #:expand "HORIZONTAL"
- #:action (lambda (obj)
- (thread-start!
- (make-thread (lambda ()
- (ezsteps:run-from testdat stepname #t))
- (conc "ezstep run single step " stepname)))))
- (iup:button "Re-run and continue"
- #:expand "HORIZONTAL"
- #:action (lambda (obj)
- (thread-start!
- (make-thread (lambda ()
- (ezsteps:run-from testdat stepname #f))
- (conc "ezstep run from step " stepname)))))
- ;; (iup:button "Refresh test data"
- ;; #:expand "HORIZONTAL"
- ;; #:action (lambda (obj)
- ;; (print "Refresh test data " stepname))
- )))
+;; (define (dashboard-tests:step-run-control testdat stepname testconfig)
+;; (let* ((mutex (make-mutex)))
+;; (letrec ((dlg
+;; (iup:dialog ;; #:close_cb (lambda (a)(exit)) ; #:expand "YES"
+;; #:title stepname
+;; (iup:vbox ; #:expand "YES"
+;; (iup:label (conc "Step: " stepname "\nNB// These buttons only run the test step\nfor the purpose of debugging.\nNot all database updates are done."))
+;; (iup:button "Re-run"
+;; #:expand "HORIZONTAL"
+;; #:action (lambda (obj)
+;; (debug:catch-and-dump (lambda ()
+;; (thread-start!
+;; (make-thread
+;; (lambda ()
+;; (print "BB> started ezsteps:run-from")
+;; (debug:catch-and-dump
+;; (lambda ()
+;; (ezsteps:run-from testdat stepname #t))
+;; "dashboard-tests:step-run-control -> ezstep:run-from (1)")
+;; (print "BB> done ezsteps:run-from")
+;; 'foo)
+;; (conc "ezstep run single step " stepname)))
+;; )
+;; "step-run-control action")))
+;; (iup:button "Re-run and continue"
+;; #:expand "HORIZONTAL"
+;; #:action (lambda (obj)
+;; (debug:catch-and-dump
+;; (lambda ()
+;; (thread-start!
+;; (make-thread (lambda ()
+;; (ezsteps:run-from testdat stepname #f))
+;; (conc "ezstep run from step " stepname))))
+;; "dashboard-tests:step-run-control -> ezstep:run-from (2)")))
+;; (iup:button "Close"
+;; #:action (lambda (obj)
+;; (iup:destroy! dlg)))
+;; ;; (iup:button "Refresh test data"
+;; ;; #:expand "HORIZONTAL"
+;; ;; #:action (lambda (obj)
+;; ;; (print "Refresh test data " stepname))
+;; ))))
+;; dlg)))
(define (dashboard-tests:waiver run-id testdat ovrdval cmtcmd)
(let* ((wpatt (configf:lookup *configdat* "setup" "waivercommentpatt"))
(wregx (if (string? wpatt)(regexp wpatt) #f))
(wmesg (iup:label (if wpatt (conc "Comment must match pattern " wpatt) "")))
@@ -459,11 +478,19 @@
(logfile "/this/dir/better/not/exist")
(rundir (if testdat
(db:test-get-rundir testdat)
logfile))
;; (testdat-path (conc rundir "/testdat.db")) ;; this gets recalculated until found
- (teststeps (if testdat (tests:get-compressed-steps run-id test-id) '()))
+ (augment-teststeps (lambda (inlov)
+ (map
+ (lambda (invec)
+ (list->vector
+ `(
+ ,@(reverse (cdr (reverse (vector->list invec))))
+ "rerun this step" "restart from here" )))
+ inlov)))
+ (teststeps (if testdat (augment-teststeps (tests:get-compressed-steps run-id test-id)) '()))
(testfullname (if testdat (db:test-get-fullname testdat) "Gathering data ..."))
(testname (if testdat (db:test-get-testname testdat) "n/a"))
;; (tests:get-testconfig testdat testname 'return-procs))
(testmeta (if testdat
(let ((tm (rmt:testmeta-get-record testname)))
@@ -535,11 +562,11 @@
(rmt:get-test-info-by-id run-id test-id )))))
;; (print "INFO: need-update= " need-update " curr-mod-time = " curr-mod-time)
(cond
((and need-update newtestdat)
(set! testdat newtestdat)
- (set! teststeps (tests:get-compressed-steps run-id test-id))
+ (set! teststeps (augment-teststeps (tests:get-compressed-steps run-id test-id)))
(set! logfile (conc (db:test-get-rundir testdat) "/" (db:test-get-final_logf testdat)))
(set! rundir ;; (filedb:get-path *fdb*
(db:test-get-rundir testdat)) ;; )
(set! testfullname (db:test-get-fullname testdat))
;; (debug:print 0 *default-log-port* "INFO: teststeps=" (intersperse teststeps "\n "))
@@ -594,11 +621,11 @@
)))))
lbl))
(store-button store-label)
(command-proc (lambda (command-text-box)
(let* ((cmd (iup:attribute command-text-box "VALUE")))
- (common:run-a-command cmd))))
+ (common:run-a-command cmd with-orig-env: #t))))
(command-text-box (iup:textbox
#:expand "HORIZONTAL"
#:font "Courier New, -10"
#:action (lambda (obj cnum val)
;; (print "cnum=" cnum)
@@ -706,25 +733,25 @@
;; Replace here with matrix
(let ((steps-matrix (iup:matrix
#:font "Courier New, -8"
#:expand "YES"
#:scrollbar "YES"
- #:numcol 7
+ #:numcol 9
#:numlin 100
- #:numcol-visible 7
+ #:numcol-visible 9
#:numlin-visible 5
#:click-cb (lambda (obj lin col status)
;; (if (equal? col 6)
- (let* ((mtrx-rc (conc lin ":" 6))
- (fname (iup:attribute obj mtrx-rc))) ;; col))))
- (if (eq? col 6)
- (view-a-log fname)
- (iup:show
- (dashboard-tests:step-run-control
- testdat
- (iup:attribute obj (conc lin ":" 1))
- teststeps))))))))
+ (let* ((mtrx-rc (conc lin ":" 6))
+ (fname (iup:attribute obj mtrx-rc))
+ (stepname (iup:attribute obj (conc lin ":" 1))) (comment (iup:attribute obj (conc lin ":" 7))))
+ (case col
+
+ ((7) (print "Comment from step "stepname": "comment))
+ ((8) (ezsteps:spawn-run-from testdat stepname #t))
+ ((9) (ezsteps:spawn-run-from testdat stepname #f))
+ (else (view-a-log fname))))))))
;; (let loop ((count 0))
;; (iup:attribute-set! steps-matrix "FITTOTEXT" (conc "L" count))
;; (if (< count 30)
;; (loop (+ count 1))))
(iup:attribute-set! steps-matrix "0:1" "Step Name")
@@ -734,10 +761,15 @@
(iup:attribute-set! steps-matrix "0:4" "Status")
(iup:attribute-set! steps-matrix "WIDTH4" "50")
(iup:attribute-set! steps-matrix "0:5" "Duration")
(iup:attribute-set! steps-matrix "0:6" "Log File")
(iup:attribute-set! steps-matrix "0:7" "Comment")
+ (iup:attribute-set! steps-matrix "0:8" "rerun only")
+ (iup:attribute-set! steps-matrix "BGCOLOR0:9" "149 208 252")
+ (iup:attribute-set! steps-matrix "BGCOLOR0:8" "149 208 252")
+ (iup:attribute-set! steps-matrix "BGCOLOR0:7" "149 208 252")
+ (iup:attribute-set! steps-matrix "0:9" "rerun & continue")
(iup:attribute-set! steps-matrix "ALIGNMENT1" "ALEFT")
;; (iup:attribute-set! steps-matrix "FIXTOTEXT" "C1")
(iup:attribute-set! steps-matrix "RESIZEMATRIX" "YES")
(let ((proc
(lambda (testdat)
Index: dashboard.scm
==================================================================
--- dashboard.scm
+++ dashboard.scm
@@ -1424,16 +1424,19 @@
;; (iup:split
;; #:value 300
;; Target, testpatt, state and status input boxes
;;
- (iup:vbox
- ;; Command to run, placed over the top of the canvas
- (dcommon:command-action-selector commondat tabdat tab-num: tab-num)
- (dboard:runs-tree-browser commondat tabdat)
- (dcommon:command-runname-selector commondat tabdat tab-num: tab-num)
- (dcommon:command-testname-selector commondat tabdat update-keyvals))
+ (iup:split
+ #:orientation "HORIZONTAL"
+ (iup:vbox
+ ;; Command to run, placed over the top of the canvas
+ (dcommon:command-action-selector commondat tabdat tab-num: tab-num)
+ (dboard:runs-tree-browser commondat tabdat))
+ (iup:vbox
+ (dcommon:command-runname-selector commondat tabdat tab-num: tab-num)
+ (dcommon:command-testname-selector commondat tabdat update-keyvals)))
;; key-listboxes))
(dcommon:command-tests-tasks-canvas tabdat test-records sorted-testnames tests-draw-state))))
(tb (dboard:tabdat-runs-tree tabdat)))
(dboard:commondat-add-updater
commondat
Index: db.scm
==================================================================
--- db.scm
+++ db.scm
@@ -332,10 +332,15 @@
;(tmpdbmodtime (if dbfexists (common:lazy-sqlite-db-modification-time tmpdbfname) #f))
;if wal mode is on -WAL and -shm file get created when db:open-megatest-db is called. modtimedelta will always be < 10 so db in tmp not get synced
;(tmpdbmodtime (if dbfexists (db:get-last-update-time (car tmpdb)) #f))
;(fmt (file-modification-time tmpdbfname))
(modtimedelta (and mtdbmodtime tmpdbmodtime (- mtdbmodtime tmpdbmodtime))))
+
+ (when write-access
+ (sqlite3:execute (car mtdb) "drop trigger if exists update_tests_trigger")
+ (sqlite3:execute (car mtdb) "drop trigger if exists update_runs_trigger"))
+
;(print "mtdbmodtime " mtdbmodtime " tmpdbmodtime " tmpdbmodtime " mtdbpath " mtdbpath " " (conc *toppath* "/megatest.db"))
;;(debug:print-info 13 *default-log-port* "db:open-db>> mtdbpath="mtdbpath" mtdbexists="mtdbexists" and write-access="write-access)
(if (and dbexists (not write-access))
(begin
(set! *db-write-access* #f)
@@ -401,10 +406,13 @@
;; Open the classic megatest.db file (defaults to open in toppath)
;;
;; NOTE: returns a dbdat not a dbstruct!
;;
+
+;;(define (db:reopen-megatest-db
+
(define (db:open-megatest-db #!key (path #f)(name #f))
(let* ((dbdir (or path *toppath*))
(dbpath (conc dbdir "/" (or name "megatest.db")))
(dbexists (common:file-exists? dbpath))
(db (db:lock-create-open dbpath
@@ -510,20 +518,22 @@
'("run_duration" #f)
'("comment" #f)
'("event_time" #f)
'("fail_count" #f)
'("pass_count" #f)
- '("archived" #f))
+ '("archived" #f)
+ '("last_update" #f))
(list "test_steps"
'("id" #f)
'("test_id" #f)
'("stepname" #f)
'("state" #f)
'("status" #f)
'("event_time" #f)
'("comment" #f)
- '("logfile" #f))
+ '("logfile" #f)
+ '("last_update" #f))
(list "test_data"
'("id" #f)
'("test_id" #f)
'("category" #f)
'("variable" #f)
@@ -531,11 +541,12 @@
'("expected" #f)
'("tol" #f)
'("units" #f)
'("comment" #f)
'("status" #f)
- '("type" #f))))
+ '("type" #f)
+ '("last_update" #f))))
;; needs db to get keys, this is for syncing all tables
;;
(define (db:sync-main-list dbstruct)
(let ((keys (db:get-keys dbstruct)))
@@ -547,11 +558,11 @@
(list "metadat" '("var" #f) '("val" #f))
(append (list "runs"
'("id" #f))
(map (lambda (k)(list k #f))
(append keys
- (list "runname" "state" "status" "owner" "event_time" "comment" "fail_count" "pass_count" "contour" ))))
+ (list "runname" "state" "status" "owner" "event_time" "comment" "fail_count" "pass_count" "contour" "last_update"))))
(list "test_meta"
'("id" #f)
'("testname" #f)
'("owner" #f)
'("description" #f)
@@ -728,11 +739,11 @@
"last_update"
(car last-update))
#f))
(num-fields (length fields))
(field->num (make-hash-table))
- (num->field (apply vector (map car fields)))
+ (num->field (apply vector (map car fields))) ;; BBHERE
(full-sel (conc "SELECT " (string-intersperse (map car fields) ",")
" FROM " tablename (if use-last-update ;; apply last-update criteria
(conc " WHERE " last-update-field " >= " last-update-value)
"")
";"))
@@ -741,11 +752,14 @@
(fromdat '())
(fromdats '())
(totrecords 0)
(batch-len (string->number (or (configf:lookup *configdat* "sync" "batchsize") "100")))
(todat (make-hash-table))
- (count 0))
+ (count 0)
+
+ (delay-handicap (string->number (or (configf:lookup *configdat* "sync" "delay-handicap") "0")))
+ )
;; set up the field->num table
(for-each
(lambda (field)
(hash-table-set! field->num field count)
@@ -769,17 +783,23 @@
(set! fromdats (cons fromdat fromdats)))
(if (common:low-noise-print 120 "sync-records")
(debug:print-info 4 *default-log-port* "found " totrecords " records to sync"))
- ;; read the target table
+ ;; read the target table; BBHERE
(sqlite3:for-each-row
(lambda (a . b)
(hash-table-set! todat a (apply vector a b)))
(db:dbdat-get-db todb)
full-sel)
+ (when (and delay-handicap (> delay-handicap 0))
+ (debug:print-info 0 *default-log-port* "imposing synthetic sync delay of "delay-handicap" seconds since sync/delay-handicap is configured")
+ (thread-sleep! delay-handicap)
+ (debug:print-info 0 *default-log-port* "synthetic sync delay of "delay-handicap" seconds completed")
+ )
+
;; first pass implementation, just insert all changed rows
(for-each
(lambda (targdb)
(let* ((db (db:dbdat-get-db targdb))
(stmth (sqlite3:prepare db full-ins)))
@@ -1315,11 +1335,16 @@
fail_count INTEGER DEFAULT 0,
pass_count INTEGER DEFAULT 0,
archived INTEGER DEFAULT 0, -- 0=no, > 1=archive block id where test data can be found
last_update INTEGER DEFAULT (strftime('%s','now')),
CONSTRAINT testsconstraint UNIQUE (run_id, testname, item_path));")
- (sqlite3:execute db "CREATE INDEX IF NOT EXISTS tests_index ON tests (run_id, testname, item_path, uname);")
+ ;; deprecated -- (sqlite3:execute db "CREATE INDEX IF NOT EXISTS tests_index ON tests (run_id, testname, item_path, uname);")
+
+ (sqlite3:execute db "CREATE INDEX IF NOT EXISTS tests_run_id_index ON tests (run_id);") ;; new
+ (sqlite3:execute db "CREATE INDEX IF NOT EXISTS tests_testname_index ON tests (testname,item_path);") ;; new
+ (sqlite3:execute db "CREATE INDEX IF NOT EXISTS tests_state_status_index ON tests (state, status); ") ;; new
+
(sqlite3:execute db "CREATE TRIGGER IF NOT EXISTS update_tests_trigger AFTER UPDATE ON tests
FOR EACH ROW
BEGIN
UPDATE tests SET last_update=(strftime('%s','now'))
WHERE id=old.id;
@@ -1620,39 +1645,61 @@
(define (db:find-and-mark-incomplete dbstruct run-id ovr-deadtime)
(let* ((incompleted '())
(oldlaunched '())
(toplevels '())
- (deadtime-str (configf:lookup *configdat* "setup" "deadtime")) ;; FIXME suspect test run time & deadtime are not well matched; resulting in COMPLETED/DEAD status of an a-ok running test
- (deadtime (if (and deadtime-str
- (string->number deadtime-str))
- (string->number deadtime-str)
- 7200))) ;; two hours
+ (deadtime-trim (or ovr-deadtime (configf:lookup-number *configdat* "setup" "deadtime")))
+ (server-start-allowance 200)
+ (server-overloaded-budget 200)
+ (launch-monitor-off-time (or (configf:lookup-number *configdat* "setup" "test-stats-update-period") 30))
+ (launch-monitor-on-time-budget 30)
+ (launch-monitor-period (+ launch-monitor-off-time launch-monitor-on-time-budget server-overloaded-budget))
+ (remotehoststart-deadtime-default (+ server-start-allowance server-overloaded-budget 30))
+ (remotehoststart-deadtime (or deadtime-trim remotehoststart-deadtime-default))
+ (running-deadtime-default (+ server-start-allowance (* 2 launch-monitor-period)))
+ (running-deadtime (or deadtime-trim running-deadtime-default)) ;; two minutes (30 seconds between updates, this leaves 3x grace period)
+ )
(db:with-db
dbstruct #f #f
(lambda (db)
- (if (number? ovr-deadtime)(set! deadtime ovr-deadtime))
-
;; in RUNNING or REMOTEHOSTSTART for more than 10 minutes
;;
;; HOWEVER: this code in run:test seems to work fine
;; (> (- (current-seconds)(+ (db:test-get-event_time testdat)
;; (db:test-get-run_duration testdat)))
;; 600)
;; (db:delay-if-busy dbdat)
(sqlite3:for-each-row
- (lambda (test-id run-dir uname testname item-path)
+ (lambda (test-id run-dir uname testname item-path event-time run-duration)
+ (if (and (equal? uname "n/a")
+ (equal? item-path "")) ;; this is a toplevel test
+ ;; what to do with toplevel? call rollup?
+ (begin
+ (set! toplevels (cons (list test-id run-dir uname testname item-path run-id) toplevels))
+ (debug:print-info 0 *default-log-port* "Found old toplevel test in RUNNING state, test-id=" test-id))
+ (begin
+ (set! incompleted (cons (list test-id run-dir uname testname item-path run-id) incompleted))
+ (debug:print-info 0 *default-log-port* "Found old test in RUNNING state, test-id=" test-id" exceeded running-deadtime "running-deadtime" now="(current-seconds)" event-time="event-time" run-duration="run-duration))))
+ db
+ "SELECT id,rundir,uname,testname,item_path,event_time,run_duration FROM tests WHERE run_id=? AND (strftime('%s','now') - event_time) > (run_duration + ?) AND state IN ('RUNNING');"
+ run-id running-deadtime)
+
+
+ (sqlite3:for-each-row
+ (lambda (test-id run-dir uname testname item-path event-time run-duration)
(if (and (equal? uname "n/a")
(equal? item-path "")) ;; this is a toplevel test
;; what to do with toplevel? call rollup?
(begin
(set! toplevels (cons (list test-id run-dir uname testname item-path run-id) toplevels))
(debug:print-info 0 *default-log-port* "Found old toplevel test in RUNNING state, test-id=" test-id))
- (set! incompleted (cons (list test-id run-dir uname testname item-path run-id) incompleted))))
+ (begin
+ (debug:print-info 0 *default-log-port* "Found old test in REMOTEHOSTSTART state, test-id=" test-id" exceeded running-deadtime "running-deadtime" now="(current-seconds)" event-time="event-time" run-duration="run-duration)
+ (set! incompleted (cons (list test-id run-dir uname testname item-path run-id) incompleted)))))
db
- "SELECT id,rundir,uname,testname,item_path FROM tests WHERE run_id=? AND (strftime('%s','now') - event_time) > (run_duration + ?) AND state IN ('RUNNING','REMOTEHOSTSTART');"
- run-id deadtime)
+ "SELECT id,rundir,uname,testname,item_path,event_time,run_duration FROM tests WHERE run_id=? AND (strftime('%s','now') - event_time) > (run_duration + ?) AND state IN ('REMOTEHOSTSTART');"
+ run-id remotehoststart-deadtime)
;; in LAUNCHED for more than one day. Could be long due to job queues TODO/BUG: Need override for this in config
;;
;; (db:delay-if-busy dbdat)
(sqlite3:for-each-row
@@ -1659,11 +1706,13 @@
(lambda (test-id run-dir uname testname item-path)
(if (and (equal? uname "n/a")
(equal? item-path "")) ;; this is a toplevel test
;; what to do with toplevel? call rollup?
(set! toplevels (cons (list test-id run-dir uname testname item-path run-id) toplevels))
- (set! oldlaunched (cons (list test-id run-dir uname testname item-path run-id) oldlaunched))))
+ (begin
+ (debug:print-info 0 *default-log-port* "Found old test in LAUNCHED state, test-id=" test-id" 1 day since event_time marked")
+ (set! oldlaunched (cons (list test-id run-dir uname testname item-path run-id) oldlaunched)))))
db
"SELECT id,rundir,uname,testname,item_path FROM tests WHERE run_id=? AND (strftime('%s','now') - event_time) > 86400 AND state IN ('LAUNCHED');"
run-id)
(debug:print-info 18 *default-log-port* "Found " (length oldlaunched) " old LAUNCHED items, " (length toplevels) " old LAUNCHED toplevel tests and " (length incompleted) " tests marked RUNNING but apparently dead.")
@@ -1680,15 +1729,15 @@
;; incompleted))
(min-incompleted-ids (map car incompleted)) ;; do 'em all
(all-ids (append min-incompleted-ids (map car oldlaunched))))
(if (> (length all-ids) 0)
(begin
- (debug:print 0 *default-log-port* "WARNING: Marking test(s); " (string-intersperse (map conc all-ids) ", ") " as INCOMPLETE")
+ (debug:print 0 *default-log-port* "WARNING: Marking test(s); " (string-intersperse (map conc all-ids) ", ") " as DEAD")
(for-each
(lambda (test-id)
- (db:test-set-state-status dbstruct run-id test-id "COMPLETED" "DEAD" "Test failed to complete")) ;; fix for one aspect of Randy's ticket 1405717332 ;; TODO - fix problem where test goes to COMPLETED/DEAD while in progress, only later to go to COMPLETED/PASS. ref ticket 220546828
-
+ (db:set-state-status-and-roll-up-items dbstruct run-id test-id 'foo "COMPLETED" "DEAD" "Test stopped responding while in RUNNING or REMOTEHOSTSTART; presumed dead."))
+ ;;(db:test-set-state-status dbstruct run-id test-id "COMPLETED" "DEAD" "Test stopped responding while in RUNNING or REMOTEHOSTSTART; presumed dead.")) ;; fix for one aspect of Randy's ticket 1405717332 ;; TODO - fix problem where test goes to COMPLETED/DEAD while in progress, only later to go to COMPLETED/PASS. ref ticket 220546828
all-ids))))))))
;; ALL REPLACED BY THE BLOCK ABOVE
;;
;; (sqlite3:execute
@@ -2515,11 +2564,11 @@
(define (db:get-run-info dbstruct run-id)
;;(if (hash-table-ref/default *run-info-cache* run-id #f)
;; (hash-table-ref *run-info-cache* run-id)
(let* ((res (vector #f #f #f #f))
(keys (db:get-keys dbstruct))
- (remfields (list "id" "runname" "state" "status" "owner" "event_time" "comment" "fail_count" "pass_count" "contour")) ;; "area_id"))
+ (remfields (list "id" "runname" "state" "status" "owner" "event_time" "comment" "fail_count" "pass_count" "contour" "last_update")) ;; "area_id"))
(header (append keys remfields))
(keystr (conc (keys->keystr keys) ","
(string-intersperse remfields ","))))
(debug:print-info 11 *default-log-port* "db:get-run-info run-id: " run-id " header: " header " keystr: " keystr)
@@ -3055,11 +3104,11 @@
#f
test-id))))
(define db:test-record-fields '("id" "run_id" "testname" "state" "status" "event_time"
"host" "cpuload" "diskfree" "uname" "rundir" "item_path"
- "run_duration" "final_logf" "comment" "shortdir" "attemptnum" "archived"))
+ "run_duration" "final_logf" "comment" "shortdir" "attemptnum" "archived" "last_update"))
;; fields *must* be a non-empty list
;;
(define (db:field->number fieldname fields)
(if (null? fields)
@@ -3160,13 +3209,13 @@
#f ;; run-id
#f
(lambda (db)
(let ((res #f))
(sqlite3:for-each-row ;; attemptnum added to hold pid of top process (not Megatest) controlling a test
- (lambda (id run-id testname state status event-time host cpuload diskfree uname rundir-id item-path run_duration final-logf-id comment short-dir-id attemptnum archived)
+ (lambda (id run-id testname state status event-time host cpuload diskfree uname rundir-id item-path run_duration final-logf-id comment short-dir-id attemptnum archived last-update)
;; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
- (set! res (vector id run-id testname state status event-time host cpuload diskfree uname rundir-id item-path run_duration final-logf-id comment short-dir-id attemptnum archived)))
+ (set! res (vector id run-id testname state status event-time host cpuload diskfree uname rundir-id item-path run_duration final-logf-id comment short-dir-id attemptnum archived last-update)))
db
(conc "SELECT " db:test-record-qry-selector " FROM tests WHERE id=?;")
test-id)
res))))
@@ -3287,16 +3336,16 @@
(db:with-db
dbstruct
#f
#f
(lambda (db)
- (let* ((res (vector #f #f #f #f #f #f #f #f)))
+ (let* ((res (vector #f #f #f #f #f #f #f #f #f)))
(sqlite3:for-each-row
- (lambda (id test-id stepname state status event-time logfile comment)
- (set! res (vector id test-id stepname state status event-time (if (string? logfile) logfile "") comment)))
+ (lambda (id test-id stepname state status event-time logfile comment last-update)
+ (set! res (vector id test-id stepname state status event-time (if (string? logfile) logfile "") comment last-update)))
db
- "SELECT id,test_id,stepname,state,status,event_time,logfile,comment FROM test_steps WHERE id=? ORDER BY id ASC;" ;; event_time DESC,id ASC;
+ "SELECT id,test_id,stepname,state,status,event_time,logfile,comment,last_update FROM test_steps WHERE id=? ORDER BY id ASC;" ;; event_time DESC,id ASC;
test-step-id)
res))))
(define (db:get-steps-data dbstruct run-id test-id)
(db:with-db
@@ -3321,16 +3370,16 @@
(db:with-db
dbstruct
#f
#f
(lambda (db)
- (let* ((res (vector #f #f #f #f #f #f #f #f #f #f #f)))
+ (let* ((res (vector #f #f #f #f #f #f #f #f #f #f #f #f)))
(sqlite3:for-each-row
- (lambda (id test-id category variable value expected tol units comment status type )
- (set! res (vector id test-id category variable value expected tol units comment status type)))
+ (lambda (id test-id category variable value expected tol units comment status type last-update)
+ (set! res (vector id test-id category variable value expected tol units comment status type last-update)))
db
- "SELECT id,test_id, category, variable, value, expected, tol, units, comment, status, type FROM test_data WHERE id=? ORDER BY id ASC;" ;; event_time DESC,id ASC;
+ "SELECT id,test_id, category, variable, value, expected, tol, units, comment, status, type, last_update FROM test_data WHERE id=? ORDER BY id ASC;" ;; event_time DESC,id ASC;
test-data-id)
res))))
;; WARNING: Do NOT call this for the parent test on an iterated test
@@ -3511,11 +3560,11 @@
(set! res (cons (vector id test_id category variable value expected tol units comment status type) res)))
db
"SELECT id,test_id,category,variable,value,expected,tol,units,comment,status,type FROM test_data WHERE test_id=? AND category LIKE ? ORDER BY category,variable;" test-id categorypatt)
(reverse res)))))
-;; This routine moved from tdb.scm, tdb:read-test-data
+;; This routine moved from tdb.scm, :read-test-data
;;
(define (db:read-test-data* dbstruct run-id test-id categorypatt varpatt)
(let* ((res '()))
(db:with-db
dbstruct #f #f
@@ -3658,11 +3707,11 @@
(item-path (db:test-get-item-path testdat))
(tl-testdat (db:get-test-info dbstruct run-id test-name ""))
(tl-test-id (if tl-testdat
(db:test-get-id tl-testdat)
#f)))
- (if (member state '("LAUNCHED" "REMOTEHOSTSTART"))
+ (if (member state '("LAUNCHED" "REMOTEHOSTSTART"))
(db:general-call dbstruct 'set-test-start-time (list test-id)))
(mutex-lock! *db-transaction-mutex*)
(db:with-db
dbstruct #f #f
(lambda (db)
@@ -4321,10 +4370,14 @@
;;
;; Note: mode 'normal means that tests must be COMPLETED and ok (i.e. PASS, WARN, CHECK, SKIP or WAIVED)
;; mode 'toplevel means that tests must be COMPLETED only
;; mode 'itemmatch or 'itemwait means that tests items must be COMPLETED and (PASS|WARN|WAIVED|CHECK) [[ NB// NOT IMPLEMENTED YET ]]
;; mode 'exclusive means this test/item cannot run if the same test/item is LAUNCHED,REMOTEHOSTSTART or RUNNING
+;;
+;; IDEA for consideration:
+;; 1. collect all tests "upstream"
+;; 2. any NOT completed and good? if yes => return those as prereqs not met, if no => return null list
;;
;; (define (db:get-prereqs-not-met dbstruct run-id waitons ref-item-path mode)
(define (db:get-prereqs-not-met dbstruct run-id waitons ref-test-name ref-item-path mode itemmaps) ;; #!key (mode '(normal))(itemmap #f))
;; BBnote - rollup of an itemized test's overall state/status done in db:set-state-status-and-roll-up-items
(append
@@ -4364,11 +4417,11 @@
;; if waiton toplevel is not in both completed and ok status, add as unmet prerequisite
(if (or (not waitons)
(null? waitons))
'()
- (let* ((ref-test-itemized-mode (not (null? (lset-intersection eq? mode '(itemmatch itemwait)))))
+ (let* ((ref-test-itemized-mode (not (null? (lset-intersection eq? mode '(itemmatch itemwait))))) ;; how is this different from using member?
(ref-test-toplevel-mode (not (null? (lset-intersection eq? mode '(toplevel)))))
(ref-test-is-toplevel (equal? ref-item-path ""))
(ref-test-is-item (not ref-test-is-toplevel))
(unmet-pre-reqs '())
(result '())
@@ -4391,18 +4444,22 @@
(for-each ; test expanded from waiton
(lambda (waiton-test)
(let* ((waiton-state (db:test-get-state waiton-test))
(waiton-status (db:test-get-status waiton-test))
(waiton-item-path (db:test-get-item-path waiton-test)) ;; BB- this is the upstream itempath
+ (waiton-test-name (db:test-get-testname waiton-test))
(waiton-is-toplevel (equal? waiton-item-path ""))
(waiton-is-item (not waiton-is-toplevel))
(waiton-is-completed (member waiton-state *common:ended-states*))
(waiton-is-running (member waiton-state *common:running-states*))
(waiton-is-killed (member waiton-state *common:badly-ended-states*))
- (waiton-is-ok (member waiton-status *common:well-ended-states*))
- ;; testname-b path-a path-b
- (same-itempath (db:compare-itempaths ref-test-name waiton-item-path ref-item-path itemmaps))) ;; (equal? ref-item-path waiton-item-path)))
+ (waiton-is-ok (member waiton-status *common:well-ended-states*))
+ ;; testname-b path-a path-b
+ (same-itempath (db:compare-itempaths ref-test-name waiton-item-path ref-item-path itemmaps)) ;; (equal? ref-item-path waiton-item-path)))
+ (real-ref-test-name (car (string-split ref-test-name "/"))) ;; I THINK ref-test-name SHOULD NEVER HAVE THE ITEM_PATH!
+ (test-and-ref-are-same (equal? real-ref-test-name waiton-test-name)))
+ (debug:print 4 *default-log-port* "waiton-test-name " waiton-test-name " ref-test-name: " ref-test-name " test-and-ref-are-same: " test-and-ref-are-same)
(set! ever-seen #t)
;;(BB> "***consider waiton "waiton-test"/"waiton-item-path"***")
(cond
;; case 0 - toplevel of an itemized test, at least one item in prereq has completed
((and waiton-is-item ref-test-is-toplevel ref-test-itemized-mode waiton-is-completed)
@@ -4435,14 +4492,15 @@
(member 'toplevel mode)) ;; toplevel does not block on FAIL
(and waiton-is-ok (member 'itemmatch mode) ;; itemmatch blocks on not ok ;; TODO: THIS IS PROBABLY A BUG. ITEMMATCH AND ITEMWAIT ARE SYNONYMS!! WHAT HAPPENED OT ITEMWAIT???
))
;;(BB> "cond4")
(set! item-waiton-met #t))
-
((and waiton-is-completed waiton-is-ok same-itempath)
;;(BB> "cond5")
(set! item-waiton-met #t))
+ ((and waiton-is-completed waiton-is-ok test-and-ref-are-same) ;; probably from [waitons] table
+ (set! item-waiton-met #t))
(else
#t
;;(BB> "condelse")
))))
waiton-tests)
@@ -4468,10 +4526,32 @@
;; (if (not ever-seen)(set! result (cons waitontest-name result)))))
((not ever-seen)
(set! result (append (if (null? waiton-tests)(list waitontest-name) waiton-tests) result))))))
waitons)
(delete-duplicates result)))))
+;;======================================================================
+;; To sync individual run
+;;======================================================================
+(define (db:get-run-record-ids dbstruct target run keynames test-patt)
+(let ((backcons (lambda (lst item)(cons item lst))))
+ (db:with-db
+ dbstruct #f #f
+ (lambda (db)
+ (let* ((keystr (string-intersperse
+ (map (lambda (key val)
+ (conc key " like '" val "'"))
+ keynames
+ (string-split target "/"))
+ " AND "))
+ (run-qry (conc "SELECT id FROM runs WHERE " keystr " and runname='" run"'"))
+ (test-qry (conc "SELECT id FROM tests WHERE run_id in (" run-qry ") and testname like '" test-patt "'")))
+ ;(print run-qry)
+ `((runs . ,(fold-row backcons '() db run-qry))
+ (tests . ,(fold-row backcons '() db test-qry))
+ (test_steps . ,(fold-row backcons '() db (conc "SELECT id FROM test_steps WHERE test_id in (" test-qry ")")))
+ (test_data . ,(fold-row backcons '() db (conc "SELECT id FROM test_data WHERE test_id in (" test-qry ")" )))
+ ))))))
;;======================================================================
;; Just for sync, procedures to make sync easy
;;======================================================================
@@ -4482,16 +4562,16 @@
;; no transaction, allow the db to be accessed between the big queries
(let ((backcons (lambda (lst item)(cons item lst))))
(db:with-db
dbstruct #f #f
(lambda (db)
- `((runs . ,(fold-row backcons '() db "SELECT id FROM runs WHERE last_update>?" since-time))
- (tests . ,(fold-row backcons '() db "SELECT id FROM tests WHERE last_update>?" since-time))
- (test_steps . ,(fold-row backcons '() db "SELECT id FROM test_steps WHERE last_update>?" since-time))
- (test_data . ,(fold-row backcons '() db "SELECT id FROM test_data WHERE last_update>?" since-time))
+ `((runs . ,(fold-row backcons '() db "SELECT id FROM runs WHERE last_update>=?" since-time))
+ (tests . ,(fold-row backcons '() db "SELECT id FROM tests WHERE last_update>=?" since-time))
+ (test_steps . ,(fold-row backcons '() db "SELECT id FROM test_steps WHERE last_update>=?" since-time))
+ (test_data . ,(fold-row backcons '() db "SELECT id FROM test_data WHERE last_update>=?" since-time))
;; (test_meta . ,(fold-row backcons '() db "SELECT id FROM test_meta WHERE last_update>?" since-time))
- (run_stats . ,(fold-row backcons '() db "SELECT id FROM run_stats WHERE last_update>?" since-time))
+ (run_stats . ,(fold-row backcons '() db "SELECT id FROM run_stats WHERE last_update>=?" since-time))
)))))
;;======================================================================
;; Extract ods file from the db
;;======================================================================
Index: db_records.scm
==================================================================
--- db_records.scm
+++ db_records.scm
@@ -102,10 +102,11 @@
(define-inline (db:test-get-run_duration vec) (vector-ref vec 12))
(define-inline (db:test-get-final_logf vec) (vector-ref vec 13))
(define-inline (db:test-get-comment vec) (vector-ref vec 14))
(define-inline (db:test-get-process_id vec) (vector-ref vec 16))
(define-inline (db:test-get-archived vec) (vector-ref vec 17))
+(define-inline (db:test-get-last_update vec) (vector-ref vec 18))
;; (define-inline (db:test-get-pass_count vec) (vector-ref vec 15))
;; (define-inline (db:test-get-fail_count vec) (vector-ref vec 16))
(define-inline (db:test-get-fullname vec)
(conc (db:test-get-testname vec) "/" (db:test-get-item-path vec)))
@@ -186,10 +187,11 @@
(define-inline (db:test-data-get-tol vec) (vector-ref vec 6))
(define-inline (db:test-data-get-units vec) (vector-ref vec 7))
(define-inline (db:test-data-get-comment vec) (vector-ref vec 8))
(define-inline (db:test-data-get-status vec) (vector-ref vec 9))
(define-inline (db:test-data-get-type vec) (vector-ref vec 10))
+(define-inline (db:test-data-get-last_update vec) (vector-ref vec 11))
(define-inline (db:test-data-set-id! vec val)(vector-set! vec 0 val))
(define-inline (db:test-data-set-test_id! vec val)(vector-set! vec 1 val))
(define-inline (db:test-data-set-category! vec val)(vector-set! vec 2 val))
(define-inline (db:test-data-set-variable! vec val)(vector-set! vec 3 val))
@@ -204,27 +206,28 @@
;;======================================================================
;; S T E P S
;;======================================================================
;; Run steps
;; make-vector-record "Run steps" db step id test_id stepname step_complete step_pass event_time
-(define (make-db:step)(make-vector 7))
+(define (make-db:step)(make-vector 9))
(define-inline (tdb:step-get-id vec) (vector-ref vec 0))
(define-inline (tdb:step-get-test_id vec) (vector-ref vec 1))
(define-inline (tdb:step-get-stepname vec) (vector-ref vec 2))
(define-inline (tdb:step-get-state vec) (vector-ref vec 3))
(define-inline (tdb:step-get-status vec) (vector-ref vec 4))
(define-inline (tdb:step-get-event_time vec) (vector-ref vec 5))
(define-inline (tdb:step-get-logfile vec) (vector-ref vec 6))
(define-inline (tdb:step-get-comment vec) (vector-ref vec 7))
+(define-inline (tdb:step-get-last_update vec) (vector-ref vec 8))
(define-inline (tdb:step-set-id! vec val)(vector-set! vec 0 val))
(define-inline (tdb:step-set-test_id! vec val)(vector-set! vec 1 val))
(define-inline (tdb:step-set-stepname! vec val)(vector-set! vec 2 val))
(define-inline (tdb:step-set-state! vec val)(vector-set! vec 3 val))
(define-inline (tdb:step-set-status! vec val)(vector-set! vec 4 val))
(define-inline (tdb:step-set-event_time! vec val)(vector-set! vec 5 val))
(define-inline (tdb:step-set-logfile! vec val)(vector-set! vec 6 val))
-(define-inline (tdb:step-set-comment! vec vak)(vector-set! vec 7 val))
+(define-inline (tdb:step-set-comment! vec val)(vector-set! vec 7 val))
;; The steps table
(define (make-db:steps-table)(make-vector 5))
(define-inline (tdb:steps-table-get-stepname vec) (vector-ref vec 0))
Index: dcommon.scm
==================================================================
--- dcommon.scm
+++ dcommon.scm
@@ -946,24 +946,28 @@
(lambda (x y)
(list (+ x 0) ;; xtorig)
(+ y 0))) ;; ytorig)))
#f #f)) ;; process polyline
edges))))
- (llx (if no-dot
+ (cx (if no-dot ;; this is the centerpoint!
curr-x
(string->number (list-ref nodedat 2))))
- (lly (if no-dot
+ (cy (if no-dot
curr-y
(string->number (list-ref nodedat 3))))
(boxw (if no-dot
boxw
(string->number (list-ref nodedat 4))))
(boxh (if no-dot
boxh
(string->number (list-ref nodedat 5))))
- (urx (+ llx boxw))
- (ury (+ lly boxh)))
+ (boxw/2 (/ boxw 2))
+ (boxh/2 (/ boxh 2))
+ (urx (+ cx boxw/2))
+ (ury (+ cy boxh/2))
+ (llx (- cx boxw/2))
+ (lly (- cy boxh/2)))
;; if we are in no-dot mode then increment curr-x and curr-y as needed
(if no-dot
(begin
(cond
@@ -1150,28 +1154,29 @@
;; (apply iup:hbox
;; (let* ((dat (dashboard:update-target-selector tabdat action-proc: update-keyvals))
;; (key-lb (car dat))
;; (combos (cadr dat)))
;; combos)))
- (iup:hbox
- ;; Text box for STATES
- (iup:frame
- #:title "States"
- (dashboard:text-list-toggle-box
- ;; Move these definitions to common and find the other useages and replace!
- (map cadr *common:std-states*) ;; '("COMPLETED" "RUNNING" "STUCK" "INCOMPLETE" "LAUNCHED" "REMOTEHOSTSTART" "KILLED")
- (lambda (all)
- (dboard:tabdat-states-set! tabdat all)
- (dashboard:update-run-command tabdat))))
- ;; Text box for STATES
- (iup:frame
- #:title "Statuses"
- (dashboard:text-list-toggle-box
- (map cadr *common:std-statuses*) ;; '("PASS" "FAIL" "n/a" "CHECK" "WAIVED" "SKIP" "DELETED" "STUCK/DEAD")
- (lambda (all)
- (dboard:tabdat-statuses-set! tabdat all)
- (dashboard:update-run-command tabdat)))))))
+ ;; (iup:hbox
+ ;; ;; Text box for STATES
+ ;; (iup:frame
+ ;; #:title "States"
+ ;; (dashboard:text-list-toggle-box
+ ;; ;; Move these definitions to common and find the other useages and replace!
+ ;; (map cadr *common:std-states*) ;; '("COMPLETED" "RUNNING" "STUCK" "INCOMPLETE" "LAUNCHED" "REMOTEHOSTSTART" "KILLED")
+ ;; (lambda (all)
+ ;; (dboard:tabdat-states-set! tabdat all)
+ ;; (dashboard:update-run-command tabdat))))
+ ;; ;; Text box for STATES
+ ;; (iup:frame
+ ;; #:title "Statuses"
+ ;; (dashboard:text-list-toggle-box
+ ;; (map cadr *common:std-statuses*) ;; '("PASS" "FAIL" "n/a" "CHECK" "WAIVED" "SKIP" "DELETED" "STUCK/DEAD")
+ ;; (lambda (all)
+ ;; (dboard:tabdat-statuses-set! tabdat all)
+ ;; (dashboard:update-run-command tabdat)))))
+ ))
(define (dcommon:command-tests-tasks-canvas tabdat test-records sorted-testnames tests-draw-state)
(iup:frame
#:title "Tests and Tasks"
(let* ((updater #f)
@@ -1256,26 +1261,39 @@
;;======================================================================
;; S T E P S
;;======================================================================
(define (dcommon:populate-steps teststeps steps-matrix)
- (let ((max-row 0)
- (max-col 7))
+ (let ((max-row 0)
+ (max-col 9)
+ (white "255 255 255")
+ (running-color (car (gutils:get-color-for-state-status "RUNNING" "STARTED")))
+ (failcolor (car (gutils:get-color-for-state-status "COMPLETED" "FAIL"))))
(if (null? teststeps)
(iup:attribute-set! steps-matrix "CLEARVALUE" "CONTENTS")
(let loop ((hed (car teststeps))
(tal (cdr teststeps))
(rownum 1)
(colnum 1))
(if (> rownum max-row)(set! max-row rownum))
- (let ((val (vector-ref hed (- colnum 1)))
- (mtrx-rc (conc rownum ":" colnum)))
+ (let* ((status (vector-ref hed 3))
+ (val (vector-ref hed (- colnum 1)))
+ (bgcolor (cond
+ ((member (conc status) '("" "-" "#"))
+ running-color)
+ ((member (conc status) '("0" 0))
+ white)
+ (else failcolor)))
+ (mtrx-rc (conc rownum ":" colnum)))
+ ;;(print "BB> status=>"status"< bgcolor="bgcolor)
(iup:attribute-set! steps-matrix mtrx-rc (if val (conc val) ""))
+ (if (< colnum 5)
+ (iup:attribute-set! steps-matrix (conc "BGCOLOR" mtrx-rc) bgcolor))
(if (< colnum max-col)
(loop hed tal rownum (+ colnum 1))
(if (not (null? tal))
- (loop (car tal)(cdr tal)(+ rownum 1) 1))))))
+ (loop (car tal) (cdr tal) (+ rownum 1) 1))))))
(if (> max-row 0)
(begin
;; we are going to speculatively clear rows until we find a row that is already cleared
(let loop ((rownum (+ max-row 1))
(colnum 0)
ADDED docs/manual/devnotes.txt
Index: docs/manual/devnotes.txt
==================================================================
--- /dev/null
+++ docs/manual/devnotes.txt
@@ -0,0 +1,37 @@
+Developer Notes
+---------------
+
+Collected here are some topics that may interest the megatest developer.
+
+telemetry
+~~~~~~~~~
+
+A new feature introduced in v1.6525 allows a centralized debug messaging system. Debugging client-server issues
+is greatly aided by a centralized, time coherent log of events across test execution, server, and runner. This
+is provided by the telemetry feature
+
+
+source code call example
+
+
+[source,ini]
+ [telemetry]
+ host
+ port
+ want-events
+
+
+Usage:
+1. Add telemetry section to megatest.config
+2. Start telemetry daemon telemetry-daemon -a start -l /tmp/my-telemetry.log
+3. Run megatest
+4. examine / parse telemetry log
Index: docs/manual/megatest_manual.html
==================================================================
--- docs/manual/megatest_manual.html
+++ docs/manual/megatest_manual.html
@@ -900,69 +900,10 @@
sqlite3 database. Megatest has been used with the Intel Netbatch and
lsf (also known as openlava) batch systems and it should be
straightforward to use it with other similar systems.
-
-
-
Overview
-
-
-
Stand-alone Megatest Area
-
A single, stand-alone, Megatest based testsuite or "area" is
-sufficient for most validation, automation and build problems.
-
-
-

-
-
-
Megatest is designed as a distributed or decoupled system. This means
-you can run the areas stand-alone with no additional
-infrastructure. I.e. there are no databases, web servers or other
-centralized resources needed. However as your needs grow you can
-integrate multiple areas into a bigger system.
-
-
Component Descriptions
-
--
-
-Multi-area dashboard and xterm. A gui (the dashboard) is usually the
- best option for controlling and launching runs but all operations
- can also be done from the commandline. Note: The not yet released
- multi-area dashboard replaces the old dashboard for browsing and
- controlling runs but for managing a single area the old dashboard
- works very well.
-
-
--
-
-Area/testsuite. This is your testsuite or automation definition and
- consists of the information in megatest.config, runconfigs.config
- and your testconfigs along with any custom scripting that can’t be
- done with the native Megatest features.
-
-
--
-
-If your testsuite or build automation is too large to run on a
- single instance you can distribute your jobs into a compute server
- pool. The only current requirements are password-less ssh access and
- a network filesystem.
-
-
-
-
-
-
-
Full System Architecture
-
-
-

-
-
-
-