Index: Makefile
==================================================================
--- Makefile
+++ Makefile
@@ -15,28 +15,29 @@
# You should have received a copy of the GNU General Public License
# along with Megatest. If not, see .
# make install CSCOPTS='-accumulate-profile -profile-name $(PWD)/profile-ww$(shell date +%V.%u)'
# rm .o ; make install CSCOPTS='-profile' ; ... ; chicken-profile | less
+
+all : $(PREFIX)/bin/.$(ARCHSTR) mtest dboard mtut tcmt unitdeps.pdf
+
SHELL=/bin/bash
PREFIX=$(PWD)
CSCOPTS=
INSTALL=install
SRCFILES = common.scm items.scm launch.scm ods.scm runconfig.scm \
server.scm configf.scm db.scm keys.scm margs.scm \
process.scm runs.scm tasks.scm tests.scm genexample.scm \
tdb.scm mt.scm \
ezsteps.scm rmt.scm api.scm \
- subrun.scm portlogger.scm archive.scm env.scm \
+ subrun.scm archive.scm env.scm \
diff-report.scm cgisetup/models/pgdb.scm
# module source files
MSRCFILES = dbfile.scm debugprint.scm mtargs.scm commonmod.scm dbmod.scm \
tcp-transportmod.scm rmtmod.scm
-all : $(PREFIX)/bin/.$(ARCHSTR) mtest dboard mtut tcmt
-
transport-mode.scm : transport-mode.scm.template
cp transport-mode.scm.template transport-mode.scm
dashboard-transport-mode.scm : dashboard-transport-mode.scm.template
cp dashboard-transport-mode.scm.template dashboard-transport-mode.scm
@@ -126,11 +127,10 @@
keys.o \
launch.o \
margs.o \
mt.o \
ods.o \
- portlogger.o \
process.o \
rmt.o \
runconfig.o \
runs.o \
server.o \
Index: api.scm
==================================================================
--- api.scm
+++ api.scm
@@ -91,11 +91,10 @@
read-test-data-varpatt
login
tasks-get-last
testmeta-get-record
have-incompletes?
- ;; synchash-get
get-changed-record-ids
get-run-record-ids
get-not-completed-cnt))
(define api:write-queries
@@ -402,11 +401,10 @@
((test-get-top-process-pid) (apply db:test-get-top-process-pid dbstruct params))
((test-get-paths-matching-keynames-target-new) (apply db:test-get-paths-matching-keynames-target-new dbstruct params))
((get-prereqs-not-met) (apply db:get-prereqs-not-met dbstruct params))
((get-count-tests-running-for-run-id) (apply db:get-count-tests-running-for-run-id dbstruct params))
((get-not-completed-cnt) (apply db:get-not-completed-cnt dbstruct params))
- ;; ((synchash-get) (apply synchash:server-get dbstruct params))
((get-raw-run-stats) (apply db:get-raw-run-stats dbstruct params))
((get-test-times) (apply db:get-test-times dbstruct params))
;; RUNS
((get-run-info) (apply db:get-run-info dbstruct params))
ADDED attic/mlaunch.scm
Index: attic/mlaunch.scm
==================================================================
--- /dev/null
+++ attic/mlaunch.scm
@@ -0,0 +1,35 @@
+;; Copyright 2006-2014, Matthew Welland.
+;;
+;; This file is part of Megatest.
+;;
+;; Megatest is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; Megatest is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Megatest. If not, see .
+
+;; strftime('%m/%d/%Y %H:%M:%S','now','localtime')
+
+;;======================================================================
+;; MLAUNCH
+;;
+;; take jobs from the given queue and keep launching them keeping
+;; the cpu load at the targeted level
+;;
+;;======================================================================
+
+(use sqlite3 srfi-1 posix regex regex-case srfi-69 format)
+
+(declare (unit mlaunch))
+(declare (uses db))
+(declare (uses common))
+(declare (uses commonmod))
+(import commonmod)
+
ADDED attic/portlogger-example.scm
Index: attic/portlogger-example.scm
==================================================================
--- /dev/null
+++ attic/portlogger-example.scm
@@ -0,0 +1,21 @@
+;; Copyright 2006-2017, Matthew Welland.
+;;
+;; This file is part of Megatest.
+;;
+;; Megatest is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; Megatest is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Megatest. If not, see .
+
+
+(declare (uses portlogger))
+
+(print (apply portlogger:main (cdr (argv))))
ADDED attic/portlogger.scm
Index: attic/portlogger.scm
==================================================================
--- /dev/null
+++ attic/portlogger.scm
@@ -0,0 +1,190 @@
+
+;; Copyright 2006-2014, Matthew Welland.
+;;
+;; This file is part of Megatest.
+;;
+;; Megatest is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; Megatest is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Megatest. If not, see .
+;;
+
+(require-extension (srfi 18) extras tcp s11n)
+
+(use sqlite3 srfi-1 posix srfi-69 hostinfo dot-locking z3)
+(import (prefix sqlite3 sqlite3:))
+
+(declare (unit portlogger))
+(declare (uses debugprint))
+(declare (uses db))
+
+(import debugprint)
+;; lsof -i
+
+(define (portlogger:open-db fname)
+ (let* ((avail (tasks:wait-on-journal fname 5 remove: #t)) ;; wait up to about 10 seconds for the journal to go away
+ (exists (common:file-exists? fname))
+ (db (if avail
+ (sqlite3:open-database fname)
+ (begin
+ (system (conc "rm -f " fname))
+ (sqlite3:open-database fname))))
+ (handler (sqlite3:make-busy-timeout 136000))
+ (canwrite (file-write-access? fname)))
+ ;; (db-init (lambda ()
+ ;; (sqlite3:execute
+ ;; db
+ ;; "CREATE TABLE IF NOT EXISTS ports (
+ ;; port INTEGER PRIMARY KEY,
+ ;; state TEXT DEFAULT 'not-used',
+ ;; fail_count INTEGER DEFAULT 0,
+ ;; update_time TIMESTAMP DEFAULT (strftime('%s','now')) );"))))
+ (sqlite3:set-busy-handler! db handler)
+ (db:set-sync db) ;; (sqlite3:execute db "PRAGMA synchronous = 0;")
+ ;; (if (not exists) ;; needed with IF NOT EXISTS?
+ (sqlite3:execute
+ db
+ "CREATE TABLE IF NOT EXISTS ports (
+ port INTEGER PRIMARY KEY,
+ state TEXT DEFAULT 'not-used',
+ fail_count INTEGER DEFAULT 0,
+ update_time TIMESTAMP DEFAULT (strftime('%s','now')) );")
+ db))
+
+(define (portlogger:open-run-close proc . params)
+ (let* ((fname (conc "/tmp/." (current-user-name) "-portlogger.db"))
+ (avail (tasks:wait-on-journal fname 10))) ;; wait up to about 10 seconds for the journal to go away
+ (handle-exceptions
+ exn
+ (begin
+ ;; (release-dot-lock fname)
+ (debug:print-error 0 *default-log-port* "portlogger:open-run-close failed. " proc " " params)
+ (debug:print 0 *default-log-port* " message: " ((condition-property-accessor 'exn 'message) exn))
+ ;; (debug:print 5 *default-log-port* "exn=" (condition->list exn))
+ (if (common:file-exists? fname)(delete-file fname)) ;; brutally get rid of it
+ (print-call-chain (current-error-port)))
+ (let* (;; (lock (obtain-dot-lock fname 2 9 10))
+ (db (portlogger:open-db fname))
+ (res (apply proc db params)))
+ (sqlite3:finalize! db)
+ ;; (release-dot-lock fname)
+ res))))
+
+;; (fold-row PROC INIT DATABASE SQL . PARAMETERS)
+(define (portlogger:take-port db portnum)
+ (let* ((qry1 (sqlite3:prepare db "INSERT INTO ports (port,state) VALUES (?,?);"))
+ (qry2 (sqlite3:prepare db "UPDATE ports SET state=?,update_time=strftime('%s','now') WHERE port=?;"))
+ (qry3 (sqlite3:prepare db "SELECT state FROM ports WHERE port=?;"))
+ (res (sqlite3:with-transaction
+ db
+ (lambda ()
+ ;; (fold-row (lambda (var curr) (or var curr)) #f db "SELECT var FROM foo WHERE id=100;")
+ (let* ((curr #f)
+ (res #f))
+ (set! curr (sqlite3:fold-row
+ (lambda (var curr)
+ (or curr var curr))
+ "not-tried"
+ qry3
+ portnum))
+ ;; (print "curr=" curr)
+ (set! res (case (string->symbol curr)
+ ((released) (sqlite3:execute qry2 "taken" portnum) 'taken)
+ ((not-tried) (sqlite3:execute qry1 portnum "taken") 'taken)
+ ((taken) 'already-taken)
+ ((failed) 'failed)
+ (else 'error)))
+ ;; (print "res=" res)
+ res)))))
+ (sqlite3:finalize! qry1)
+ (sqlite3:finalize! qry2)
+ (sqlite3:finalize! qry3)
+ res))
+
+(define (portlogger:get-prev-used-port db)
+ (handle-exceptions
+ exn
+ (begin
+ (debug:print 0 *default-log-port* "EXCEPTION: portlogger database probably overloaded or unreadable. If you see this message again remove /tmp/.$USER-portlogger.db")
+ (debug:print 0 *default-log-port* " message: " ((condition-property-accessor 'exn 'message) exn))
+ (debug:print 5 *default-log-port* "exn=" (condition->list exn))
+ (print-call-chain (current-error-port))
+ (debug:print 0 *default-log-port* "Continuing anyway.")
+ #f)
+ (sqlite3:fold-row
+ (lambda (var curr)
+ (or curr var curr))
+ #f
+ db
+ "SELECT (port) FROM ports WHERE state='released' LIMIT 1;")))
+
+(define (portlogger:find-port db)
+ (let* ((lowport (let ((val (configf:lookup *configdat* "server" "lowport")))
+ (if (and val
+ (string->number val))
+ (string->number val)
+ 32768)))
+ (portnum (or (portlogger:get-prev-used-port db)
+ (+ lowport ;; top of registered ports is 49152 but lets use ports in the registered range
+ (random (- 64000 lowport))))))
+ (handle-exceptions
+ exn
+ (begin
+ (debug:print 0 *default-log-port* "EXCEPTION: portlogger database probably overloaded or unreadable. If you see this message again remove /tmp/.$USER-portlogger.db")
+ (debug:print 0 *default-log-port* " message: " ((condition-property-accessor 'exn 'message) exn))
+ (debug:print 5 *default-log-port* "exn=" (condition->list exn))
+ (print-call-chain (current-error-port))
+ (debug:print 0 *default-log-port* "Continuing anyway."))
+ (portlogger:take-port db portnum))
+ portnum))
+
+;; set port to "released", "failed" etc.
+;;
+(define (portlogger:set-port db portnum value)
+ (sqlite3:execute db "UPDATE ports SET state=?,update_time=strftime('%s','now') WHERE port=?;" value portnum))
+
+;; set port to failed (attempted to take but got error)
+;;
+(define (portlogger:set-failed db portnum)
+ (sqlite3:execute db "UPDATE ports SET state='failed',fail_count=fail_count+1,update_time=strftime('%s','now') WHERE port=?;" portnum))
+
+;;======================================================================
+;; MAIN
+;;======================================================================
+
+(define (portlogger:main . args)
+ (let* ((dbfname (conc "/tmp/." (current-user-name) "-portlogger.db"))
+ (db (portlogger:open-db dbfname))
+ (numargs (length args))
+ (result
+ (handle-exceptions
+ exn
+ (begin
+ (debug:print 0 *default-log-port* "EXCEPTION: portlogger database at " dbfname " probably overloaded or unreadable. Try removing it.")
+ (debug:print 0 *default-log-port* " message: " ((condition-property-accessor 'exn 'message) exn))
+ (debug:print 5 *default-log-port* "exn=" (condition->list exn))
+ (debug:print 0 *default-log-port* " status: " ((condition-property-accessor 'sqlite3 'status) exn))
+ (print-call-chain (current-error-port))
+ #f)
+ (case (string->symbol (car args)) ;; commands with two or more params
+ ((take)(portlogger:take-port db (string->number (cadr args))))
+ ((find)(portlogger:find-port db))
+ ((set) (let ((port (cadr args))
+ (state (caddr args)))
+ (portlogger:set-port db
+ (if (number? port) port (string->number port))
+ state)
+ state))
+ ((failed)(portlogger:set-failed db (string->number (cadr args))) 'failed)))))
+ (sqlite3:finalize! db)
+ result))
+
+;; (print (apply portlogger:main (cdr (argv))))
ADDED attic/synchash.scm
Index: attic/synchash.scm
==================================================================
--- /dev/null
+++ attic/synchash.scm
@@ -0,0 +1,137 @@
+;;======================================================================
+;; Copyright 2006-2012, Matthew Welland.
+;;
+;; This file is part of Megatest.
+;;
+;; Megatest is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; Megatest is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Megatest. If not, see .
+;;
+;;======================================================================
+
+;;======================================================================
+;; A hash of hashes that can be kept in sync by sending minial deltas
+;;======================================================================
+
+(use format)
+(use srfi-1 srfi-69 sqlite3)
+(import (prefix sqlite3 sqlite3:))
+
+(declare (unit synchash))
+(declare (uses db))
+(declare (uses server))
+(declare (uses rmtmod))
+
+(include "db_records.scm")
+
+(import rmtmod)
+
+(define (synchash:make)
+ (make-hash-table))
+
+;; given an alist of objects '((id obj) ...)
+;; 1. remove unchanged objects from the list
+;; 2. create a list of removed objects by id
+;; 3. remove removed objects from synchash
+;; 4. replace or add new or changed objects to synchash
+;;
+(define (synchash:get-delta indat synchash)
+ (let ((deleted '())
+ (changed '())
+ (found '())
+ (orig-keys (hash-table-keys synchash)))
+ (for-each
+ (lambda (item)
+ (let* ((id (car item))
+ (dat (cadr item))
+ (ref (hash-table-ref/default synchash id #f)))
+ (if (not (equal? dat ref)) ;; item changed or new
+ (begin
+ (set! changed (cons item changed))
+ (hash-table-set! synchash id dat)))
+ (set! found (cons id found))))
+ indat)
+ (for-each
+ (lambda (id)
+ (if (not (member id found))
+ (begin
+ (set! deleted (cons id deleted))
+ (hash-table-delete! synchash id))))
+ orig-keys)
+ (list changed deleted)
+ ;; (list indat '()) ;; just for debugging
+ ))
+
+;; keynum => the field to use as the unique key (usually 0 but can be other field)
+;;
+(define (synchash:client-get proc synckey keynum synchash run-id . params)
+ (let* ((data (rmt:synchash-get run-id proc synckey keynum params))
+ (newdat (car data))
+ (removs (cadr data))
+ (myhash (hash-table-ref/default synchash synckey #f)))
+ (if (not myhash)
+ (begin
+ (set! myhash (make-hash-table))
+ (hash-table-set! synchash synckey myhash)))
+ (for-each
+ (lambda (item)
+ (let ((id (car item))
+ (dat (cadr item)))
+ ;; (debug:print-info 2 *default-log-port* "Processing item: " item)
+ (hash-table-set! myhash id dat)))
+ newdat)
+ (for-each
+ (lambda (id)
+ (hash-table-delete! myhash id))
+ removs)
+ ;; WHICH ONE!?
+ ;; data)) ;; return the changed and deleted list
+ (list newdat removs))) ;; synchash))
+
+(define *synchashes* (make-hash-table))
+
+(define (synchash:server-get dbstruct run-id proc synckey keynum params)
+ ;; (debug:print-info 2 *default-log-port* "synckey: " synckey ", keynum: " keynum ", params: " params)
+ (let* ((dbdat (db:get-db dbstruct run-id))
+ (db (db:dbdat-get-db dbdat))
+ (synchash (hash-table-ref/default *synchashes* synckey #f))
+ (newdat (apply (case proc
+ ((db:get-runs) db:get-runs)
+ ((db:get-tests-for-run-mindata) db:get-tests-for-run-mindata)
+ ((db:get-test-info-by-ids) db:get-test-info-by-ids)
+ (else
+ (print "ERROR: sync for hash " proc " not setup! Edits needed in synchash.scm")
+ print))
+ db params))
+ (postdat #f)
+ (make-indexed (lambda (x)
+ (list (vector-ref x keynum) x))))
+ ;; Now process newdat based on the query type
+ (set! postdat (case proc
+ ((db:get-runs)
+ ;; (debug:print-info 2 *default-log-port* "Get runs call")
+ (let ((header (vector-ref newdat 0))
+ (data (vector-ref newdat 1)))
+ ;; (debug:print-info 2 *default-log-port* "header: " header ", data: " data)
+ (cons (list "header" header) ;; add the header keyed by the word "header"
+ (map make-indexed data)))) ;; add each element keyed by the keynum'th val
+ (else
+ ;; (debug:print-info 2 *default-log-port* "Non-get runs call")
+ (map make-indexed newdat))))
+ ;; (debug:print-info 2 *default-log-port* "postdat: " postdat)
+ ;; (if (not indb)(sqlite3:finalize! db))
+ (if (not synchash)
+ (begin
+ (set! synchash (make-hash-table))
+ (hash-table-set! *synchashes* synckey synchash)))
+ (synchash:get-delta postdat synchash)))
+
Index: dcommon.scm
==================================================================
--- dcommon.scm
+++ dcommon.scm
@@ -33,11 +33,10 @@
(use regex typed-records matchable)
(import commonmod
rmtmod
debugprint)
-;; (declare (uses synchash))
(include "megatest-version.scm")
(include "common_records.scm")
(include "db_records.scm")
(include "key_records.scm")
DELETED mlaunch.scm
Index: mlaunch.scm
==================================================================
--- mlaunch.scm
+++ /dev/null
@@ -1,35 +0,0 @@
-;; Copyright 2006-2014, Matthew Welland.
-;;
-;; This file is part of Megatest.
-;;
-;; Megatest is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; Megatest is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with Megatest. If not, see .
-
-;; strftime('%m/%d/%Y %H:%M:%S','now','localtime')
-
-;;======================================================================
-;; MLAUNCH
-;;
-;; take jobs from the given queue and keep launching them keeping
-;; the cpu load at the targeted level
-;;
-;;======================================================================
-
-(use sqlite3 srfi-1 posix regex regex-case srfi-69 format)
-
-(declare (unit mlaunch))
-(declare (uses db))
-(declare (uses common))
-(declare (uses commonmod))
-(import commonmod)
-
Index: newdashboard.scm
==================================================================
--- newdashboard.scm
+++ newdashboard.scm
@@ -40,11 +40,10 @@
;; (declare (uses launch))
;; (declare (uses gutils))
;; (declare (uses db))
;; (declare (uses server))
-;; (declare (uses synchash))
(declare (uses dcommon))
;; (declare (uses tree))
;;
;; (include "common_records.scm")
;; (include "db_records.scm")
DELETED portlogger-example.scm
Index: portlogger-example.scm
==================================================================
--- portlogger-example.scm
+++ /dev/null
@@ -1,21 +0,0 @@
-;; Copyright 2006-2017, Matthew Welland.
-;;
-;; This file is part of Megatest.
-;;
-;; Megatest is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; Megatest is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with Megatest. If not, see .
-
-
-(declare (uses portlogger))
-
-(print (apply portlogger:main (cdr (argv))))
DELETED portlogger.scm
Index: portlogger.scm
==================================================================
--- portlogger.scm
+++ /dev/null
@@ -1,190 +0,0 @@
-
-;; Copyright 2006-2014, Matthew Welland.
-;;
-;; This file is part of Megatest.
-;;
-;; Megatest is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; Megatest is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with Megatest. If not, see .
-;;
-
-(require-extension (srfi 18) extras tcp s11n)
-
-(use sqlite3 srfi-1 posix srfi-69 hostinfo dot-locking z3)
-(import (prefix sqlite3 sqlite3:))
-
-(declare (unit portlogger))
-(declare (uses debugprint))
-(declare (uses db))
-
-(import debugprint)
-;; lsof -i
-
-(define (portlogger:open-db fname)
- (let* ((avail (tasks:wait-on-journal fname 5 remove: #t)) ;; wait up to about 10 seconds for the journal to go away
- (exists (common:file-exists? fname))
- (db (if avail
- (sqlite3:open-database fname)
- (begin
- (system (conc "rm -f " fname))
- (sqlite3:open-database fname))))
- (handler (sqlite3:make-busy-timeout 136000))
- (canwrite (file-write-access? fname)))
- ;; (db-init (lambda ()
- ;; (sqlite3:execute
- ;; db
- ;; "CREATE TABLE IF NOT EXISTS ports (
- ;; port INTEGER PRIMARY KEY,
- ;; state TEXT DEFAULT 'not-used',
- ;; fail_count INTEGER DEFAULT 0,
- ;; update_time TIMESTAMP DEFAULT (strftime('%s','now')) );"))))
- (sqlite3:set-busy-handler! db handler)
- (db:set-sync db) ;; (sqlite3:execute db "PRAGMA synchronous = 0;")
- ;; (if (not exists) ;; needed with IF NOT EXISTS?
- (sqlite3:execute
- db
- "CREATE TABLE IF NOT EXISTS ports (
- port INTEGER PRIMARY KEY,
- state TEXT DEFAULT 'not-used',
- fail_count INTEGER DEFAULT 0,
- update_time TIMESTAMP DEFAULT (strftime('%s','now')) );")
- db))
-
-(define (portlogger:open-run-close proc . params)
- (let* ((fname (conc "/tmp/." (current-user-name) "-portlogger.db"))
- (avail (tasks:wait-on-journal fname 10))) ;; wait up to about 10 seconds for the journal to go away
- (handle-exceptions
- exn
- (begin
- ;; (release-dot-lock fname)
- (debug:print-error 0 *default-log-port* "portlogger:open-run-close failed. " proc " " params)
- (debug:print 0 *default-log-port* " message: " ((condition-property-accessor 'exn 'message) exn))
- ;; (debug:print 5 *default-log-port* "exn=" (condition->list exn))
- (if (common:file-exists? fname)(delete-file fname)) ;; brutally get rid of it
- (print-call-chain (current-error-port)))
- (let* (;; (lock (obtain-dot-lock fname 2 9 10))
- (db (portlogger:open-db fname))
- (res (apply proc db params)))
- (sqlite3:finalize! db)
- ;; (release-dot-lock fname)
- res))))
-
-;; (fold-row PROC INIT DATABASE SQL . PARAMETERS)
-(define (portlogger:take-port db portnum)
- (let* ((qry1 (sqlite3:prepare db "INSERT INTO ports (port,state) VALUES (?,?);"))
- (qry2 (sqlite3:prepare db "UPDATE ports SET state=?,update_time=strftime('%s','now') WHERE port=?;"))
- (qry3 (sqlite3:prepare db "SELECT state FROM ports WHERE port=?;"))
- (res (sqlite3:with-transaction
- db
- (lambda ()
- ;; (fold-row (lambda (var curr) (or var curr)) #f db "SELECT var FROM foo WHERE id=100;")
- (let* ((curr #f)
- (res #f))
- (set! curr (sqlite3:fold-row
- (lambda (var curr)
- (or curr var curr))
- "not-tried"
- qry3
- portnum))
- ;; (print "curr=" curr)
- (set! res (case (string->symbol curr)
- ((released) (sqlite3:execute qry2 "taken" portnum) 'taken)
- ((not-tried) (sqlite3:execute qry1 portnum "taken") 'taken)
- ((taken) 'already-taken)
- ((failed) 'failed)
- (else 'error)))
- ;; (print "res=" res)
- res)))))
- (sqlite3:finalize! qry1)
- (sqlite3:finalize! qry2)
- (sqlite3:finalize! qry3)
- res))
-
-(define (portlogger:get-prev-used-port db)
- (handle-exceptions
- exn
- (begin
- (debug:print 0 *default-log-port* "EXCEPTION: portlogger database probably overloaded or unreadable. If you see this message again remove /tmp/.$USER-portlogger.db")
- (debug:print 0 *default-log-port* " message: " ((condition-property-accessor 'exn 'message) exn))
- (debug:print 5 *default-log-port* "exn=" (condition->list exn))
- (print-call-chain (current-error-port))
- (debug:print 0 *default-log-port* "Continuing anyway.")
- #f)
- (sqlite3:fold-row
- (lambda (var curr)
- (or curr var curr))
- #f
- db
- "SELECT (port) FROM ports WHERE state='released' LIMIT 1;")))
-
-(define (portlogger:find-port db)
- (let* ((lowport (let ((val (configf:lookup *configdat* "server" "lowport")))
- (if (and val
- (string->number val))
- (string->number val)
- 32768)))
- (portnum (or (portlogger:get-prev-used-port db)
- (+ lowport ;; top of registered ports is 49152 but lets use ports in the registered range
- (random (- 64000 lowport))))))
- (handle-exceptions
- exn
- (begin
- (debug:print 0 *default-log-port* "EXCEPTION: portlogger database probably overloaded or unreadable. If you see this message again remove /tmp/.$USER-portlogger.db")
- (debug:print 0 *default-log-port* " message: " ((condition-property-accessor 'exn 'message) exn))
- (debug:print 5 *default-log-port* "exn=" (condition->list exn))
- (print-call-chain (current-error-port))
- (debug:print 0 *default-log-port* "Continuing anyway."))
- (portlogger:take-port db portnum))
- portnum))
-
-;; set port to "released", "failed" etc.
-;;
-(define (portlogger:set-port db portnum value)
- (sqlite3:execute db "UPDATE ports SET state=?,update_time=strftime('%s','now') WHERE port=?;" value portnum))
-
-;; set port to failed (attempted to take but got error)
-;;
-(define (portlogger:set-failed db portnum)
- (sqlite3:execute db "UPDATE ports SET state='failed',fail_count=fail_count+1,update_time=strftime('%s','now') WHERE port=?;" portnum))
-
-;;======================================================================
-;; MAIN
-;;======================================================================
-
-(define (portlogger:main . args)
- (let* ((dbfname (conc "/tmp/." (current-user-name) "-portlogger.db"))
- (db (portlogger:open-db dbfname))
- (numargs (length args))
- (result
- (handle-exceptions
- exn
- (begin
- (debug:print 0 *default-log-port* "EXCEPTION: portlogger database at " dbfname " probably overloaded or unreadable. Try removing it.")
- (debug:print 0 *default-log-port* " message: " ((condition-property-accessor 'exn 'message) exn))
- (debug:print 5 *default-log-port* "exn=" (condition->list exn))
- (debug:print 0 *default-log-port* " status: " ((condition-property-accessor 'sqlite3 'status) exn))
- (print-call-chain (current-error-port))
- #f)
- (case (string->symbol (car args)) ;; commands with two or more params
- ((take)(portlogger:take-port db (string->number (cadr args))))
- ((find)(portlogger:find-port db))
- ((set) (let ((port (cadr args))
- (state (caddr args)))
- (portlogger:set-port db
- (if (number? port) port (string->number port))
- state)
- state))
- ((failed)(portlogger:set-failed db (string->number (cadr args))) 'failed)))))
- (sqlite3:finalize! db)
- result))
-
-;; (print (apply portlogger:main (cdr (argv))))
DELETED synchash.scm
Index: synchash.scm
==================================================================
--- synchash.scm
+++ /dev/null
@@ -1,137 +0,0 @@
-;;======================================================================
-;; Copyright 2006-2012, Matthew Welland.
-;;
-;; This file is part of Megatest.
-;;
-;; Megatest is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; Megatest is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with Megatest. If not, see .
-;;
-;;======================================================================
-
-;;======================================================================
-;; A hash of hashes that can be kept in sync by sending minial deltas
-;;======================================================================
-
-(use format)
-(use srfi-1 srfi-69 sqlite3)
-(import (prefix sqlite3 sqlite3:))
-
-(declare (unit synchash))
-(declare (uses db))
-(declare (uses server))
-(declare (uses rmtmod))
-
-(include "db_records.scm")
-
-(import rmtmod)
-
-(define (synchash:make)
- (make-hash-table))
-
-;; given an alist of objects '((id obj) ...)
-;; 1. remove unchanged objects from the list
-;; 2. create a list of removed objects by id
-;; 3. remove removed objects from synchash
-;; 4. replace or add new or changed objects to synchash
-;;
-(define (synchash:get-delta indat synchash)
- (let ((deleted '())
- (changed '())
- (found '())
- (orig-keys (hash-table-keys synchash)))
- (for-each
- (lambda (item)
- (let* ((id (car item))
- (dat (cadr item))
- (ref (hash-table-ref/default synchash id #f)))
- (if (not (equal? dat ref)) ;; item changed or new
- (begin
- (set! changed (cons item changed))
- (hash-table-set! synchash id dat)))
- (set! found (cons id found))))
- indat)
- (for-each
- (lambda (id)
- (if (not (member id found))
- (begin
- (set! deleted (cons id deleted))
- (hash-table-delete! synchash id))))
- orig-keys)
- (list changed deleted)
- ;; (list indat '()) ;; just for debugging
- ))
-
-;; keynum => the field to use as the unique key (usually 0 but can be other field)
-;;
-(define (synchash:client-get proc synckey keynum synchash run-id . params)
- (let* ((data (rmt:synchash-get run-id proc synckey keynum params))
- (newdat (car data))
- (removs (cadr data))
- (myhash (hash-table-ref/default synchash synckey #f)))
- (if (not myhash)
- (begin
- (set! myhash (make-hash-table))
- (hash-table-set! synchash synckey myhash)))
- (for-each
- (lambda (item)
- (let ((id (car item))
- (dat (cadr item)))
- ;; (debug:print-info 2 *default-log-port* "Processing item: " item)
- (hash-table-set! myhash id dat)))
- newdat)
- (for-each
- (lambda (id)
- (hash-table-delete! myhash id))
- removs)
- ;; WHICH ONE!?
- ;; data)) ;; return the changed and deleted list
- (list newdat removs))) ;; synchash))
-
-(define *synchashes* (make-hash-table))
-
-(define (synchash:server-get dbstruct run-id proc synckey keynum params)
- ;; (debug:print-info 2 *default-log-port* "synckey: " synckey ", keynum: " keynum ", params: " params)
- (let* ((dbdat (db:get-db dbstruct run-id))
- (db (db:dbdat-get-db dbdat))
- (synchash (hash-table-ref/default *synchashes* synckey #f))
- (newdat (apply (case proc
- ((db:get-runs) db:get-runs)
- ((db:get-tests-for-run-mindata) db:get-tests-for-run-mindata)
- ((db:get-test-info-by-ids) db:get-test-info-by-ids)
- (else
- (print "ERROR: sync for hash " proc " not setup! Edits needed in synchash.scm")
- print))
- db params))
- (postdat #f)
- (make-indexed (lambda (x)
- (list (vector-ref x keynum) x))))
- ;; Now process newdat based on the query type
- (set! postdat (case proc
- ((db:get-runs)
- ;; (debug:print-info 2 *default-log-port* "Get runs call")
- (let ((header (vector-ref newdat 0))
- (data (vector-ref newdat 1)))
- ;; (debug:print-info 2 *default-log-port* "header: " header ", data: " data)
- (cons (list "header" header) ;; add the header keyed by the word "header"
- (map make-indexed data)))) ;; add each element keyed by the keynum'th val
- (else
- ;; (debug:print-info 2 *default-log-port* "Non-get runs call")
- (map make-indexed newdat))))
- ;; (debug:print-info 2 *default-log-port* "postdat: " postdat)
- ;; (if (not indb)(sqlite3:finalize! db))
- (if (not synchash)
- (begin
- (set! synchash (make-hash-table))
- (hash-table-set! *synchashes* synckey synchash)))
- (synchash:get-delta postdat synchash)))
-
Index: tree.scm
==================================================================
--- tree.scm
+++ tree.scm
@@ -20,15 +20,13 @@
(declare (unit tree))
(declare (uses mtargs))
(declare (uses debugprint))
(declare (uses launch))
-;; (declare (uses megatest-version))
(declare (uses gutils))
(declare (uses db))
(declare (uses server))
-;; (declare (uses synchash))
(declare (uses dcommon))
(use format)
(require-library iup)
(import (prefix iup iup:))