Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -31,11 +31,11 @@ cgisetup/models/pgdb.scm # module source files # ftail.scm rmtmod.scm commonmod.scm removed MSRCFILES = ducttape-lib.scm pkts.scm stml2.scm cookie.scm mutils.scm \ - mtargs.scm commonmod.scm dbmod.scm + mtargs.scm commonmod.scm dbmod.scm adjutant.scm GUISRCF = dashboard-context-menu.scm dashboard-tests.scm \ dashboard-guimonitor.scm gutils.scm dcommon.scm tree.scm \ vg.scm @@ -61,25 +61,16 @@ ifeq ($(MTESTHASH),) $(error MTESTHASH is broken!) endif -CSIPATH=$(shell which csi) -CKPATH=$(shell dirname $(shell dirname $(CSIPATH))) ARCHSTR=$(shell if [[ -e /usr/bin/sw_vers ]]; then /usr/bin/sw_vers -productVersion; else lsb_release -sr; fi) -# ARCHSTR=$(shell bash -c "echo \$$MACHTYPE") - -# if have csi on path use that, else use default -CHICKEN_PREFIX=$(or $(CKPATH),$(PREFIX)/$(ARCHSTR)) PNGFILES = $(shell cd docs/manual;ls *png) all : $(PREFIX)/bin/.$(ARCHSTR) mtest dboard mtut tcmt -whatever : - @echo "CHICKEN_PREFIX=$(CHICKEN_PREFIX)" - mtest: $(OFILES) readline-fix.scm megatest.o $(MOFILES) $(MOIMPFILES) csc $(CSCOPTS) $(OFILES) $(MOFILES) $(MOIMPFILES) megatest.o -o mtest showmtesthash: @echo $(MTESTHASH) @@ -122,11 +113,12 @@ runs.o \ server.o \ tasks.o \ tdb.o \ tests.o \ - subrun.o + subrun.o \ + ezsteps.o # mofiles/commonmod.o \ tcmt : $(TCMTOBJS) tcmt.scm csc $(CSCOPTS) $(TCMTOBJS) $(MOFILES) $(MOIMPFILES) tcmt.scm -o tcmt @@ -178,10 +170,11 @@ mofiles/stml2.o : mofiles/cookie.o # special include based modules mofiles/pkts.o : pkts/pkts.scm +mofiles/stml2.o : cookie.o # mofiles/mtargs.o : mtargs/mtargs.scm # mofiles/mtconfigf.o : mtconfigf/mtconfigf.scm # mofiles/ulex.o : ulex/ulex.scm mofiles/mutils.o : mutils/mutils.scm mofiles/cookie.o : stml2/cookie.scm Index: TODO ================================================================== --- TODO +++ TODO @@ -17,10 +17,61 @@ NOTE: This file gets copied occasionally into the wiki as "Roadmap". Do not make changes in the wiki, they will be lost! See the file "DONE" to see completed items. +FIXME +==== + +.dump +---------------- +WARNING: disk disk0 at path "/mfs/tmp/archive" is not a directory - ignoring it. + +Warning (#): in thread: unbound variable: block-id + + Call history: + + common.scm:693: hash-table-ref/default + common.scm:694: current-seconds + common.scm:697: hash-table-set! + common.scm:2232: debug:print + common_records.scm:140: debug:debug-mode + common_records.scm:141: with-output-to-port + common.scm:2245: directory? + common.scm:2246: common:low-noise-print + common.scm:692: g2022 + common.scm:692: g2022 + common.scm:692: string-intersperse + common.scm:693: hash-table-ref/default + common.scm:694: current-seconds + common.scm:2261: debug:print + common_records.scm:140: debug:debug-mode + archive.scm:125: debug:print <-- +INFO: (0) Estimating disk space usage for scriptinc/: 184 + +Error: uncaught exception: # + + Call history: + + common.scm:1299: ##sys#get-keyword + common.scm:1299: call-with-current-continuation + common.scm:1299: with-exception-handler + common.scm:1299: ##sys#call-with-values + common.scm:1304: thunk + common.scm:1310: file-exists? + common.scm:1299: k2554 + common.scm:1299: g2558 + runs.scm:2438: common:get-disk-space-used + common.scm:2128: conc + common.scm:2128: with-input-from-pipe + runs.scm:2438: debug:print-info + common_records.scm:235: debug:debug-mode + common_records.scm:236: port? + common_records.scm:236: with-output-to-port + runs.scm:2443: thread-join! <-- +Press any key to continue +---------------- TODO ==== WW15 ADDED adjutant.scm Index: adjutant.scm ================================================================== --- /dev/null +++ adjutant.scm @@ -0,0 +1,34 @@ +;;====================================================================== +;; Copyright 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 (unit adjutant)) + +(module adjutant + * + +(import scheme chicken data-structures extras files) +(import (prefix sqlite3 sqlite3:) posix typed-records srfi-18 srfi-69 + md5 message-digest + regex srfi-1) + +(define (adjutant-run) + (print "Running the adjutant!")) + +) Index: chicken.makefile ================================================================== --- chicken.makefile +++ chicken.makefile @@ -19,10 +19,19 @@ #====================================================================== # Chicken build #====================================================================== +# CHICKEN_BIN_DIR=$(shell dirname $(shell which csi)) +# if have csi on path use that, else use default +# CSIPATH=$(shell which csi) +# CKPATH=$(shell dirname $(shell dirname $(CSIPATH))) +sCHICKEN_PREFIX=$(or $(CKPATH),$(PREFIX)/bin/.$(ARCHSTR)) + +whatever : + @echo "CHICKEN_PREFIX=$(CHICKEN_PREFIX)" + tgz-$(USER)/postgresql-9.6.4.tar.gz : mkdir -p tgz-$(USER) wget -c https://ftp.postgresql.org/pub/source/v9.6.4/postgresql-9.6.4.tar.gz mv postgresql-9.6.4.tar.gz tgz-$(USER)/ @@ -101,19 +110,18 @@ ALL_CKBIN=chicken chicken-bind chicken-bug chicken-dump \ chicken-install chicken-profile chicken-sqlite3 chicken-status \ chicken-uninstall csc csi feathers nanocat sqlite3 vacuumdb logpro \ refdb -# CHICKEN_BIN_DIR=$(shell dirname $(shell which csi)) CKBIN_WRAPPERS=$(addprefix $(PREFIX)/bin/,$(ALL_CKBIN)) $(PREFIX)/bin/% : $(CHICKEN_PREFIX)/bin/% $(CHICKEN_PREFIX)/bin/csi $(EGGSTARG2) utils/mk_wrapper_tool $(PREFIX) $* $(PREFIX)/bin/$* chmod a+x $(PREFIX)/bin/$* $(PREFIX)/bin : - mkdir -p $(PREFIX)/bin + mkdir -p $(PREFIX)/bin $(CHICKEN_PREFIX)/bin chicken : $(PREFIX)/bin $(CHICKEN_PREFIX)/bin/csi binwrappers @echo "Fake target to build prefix chicken" binwrappers : $(CKBIN_WRAPPERS) @@ -143,7 +151,7 @@ $(CHICKEN_PREFIX)/bin/chicken-install $* > $*.done build-$(USER)/eggs-installed/%.done : $(CHICKEN_PREFIX)/bin/csi $(EGGS) $(CHICKEN_PREFIX)/bin/chicken-install $* > build-$(USER)/eggs-installed/$*.done - - +build-clean : + rm -rf build-$(USER) bin Index: common.scm ================================================================== --- common.scm +++ common.scm @@ -2190,12 +2190,13 @@ ;; check space in dbdir and in megatest dir ;; returns: ok/not dbspace required-space ;; (define (common:check-db-dir-space) (let* ((required (string->number + ;; default is 1GB (or actually a billion bytes) This is the number of 1 kB blocks. (or (configf:lookup *configdat* "setup" "dbdir-space-required") - "100000"))) + "1000000"))) (dbdir (common:get-db-tmp-area)) ;; (db:get-dbdir)) (tdbspace (common:check-space-in-dir dbdir required)) (mdbspace (common:check-space-in-dir *toppath* required))) (sort (list tdbspace mdbspace) (lambda (a b) (< (cadr a)(cadr b)))))) @@ -2214,13 +2215,16 @@ (exit 1))))) ;; paths is list of lists ((name path) ... ) ;; (define (common:get-disk-with-most-free-space disks minsize) - (let ((best #f) + (let* ((best #f) (bestsize 0) - (min-inodes (or (string->number (if (configf:lookup *configdat* "setup" "min_inodes") (configf:lookup *configdat* "setup" "min_inodes") "0")) 0))) + (default-min-inodes-string "1000000") + (default-min-inodes (string->number default-min-inodes-string)) + (min-inodes (or (string->number (if (configf:lookup *configdat* "setup" "min_inodes") (configf:lookup *configdat* "setup" "min_inodes") default-min-inodes-string)) default-min-inodes))) + (for-each (lambda (disk-num) (let* ((dirpath (cadr (assoc disk-num disks))) (freespc (cond ((not (directory? dirpath)) @@ -2252,10 +2256,11 @@ -1) (else (get-free-inodes dirpath)))) ;;(free-inodes (get-free-inodes dirpath)) ) + (debug:print 2 *default-log-port* "INFO: disk " disk-num " path " dirpath " free space " freespc " free inodes " free-inodes) (if (and (> freespc bestsize)(> free-inodes min-inodes )) (begin (set! best (cons disk-num dirpath)) (set! bestsize freespc))) ;;(print "Processing: " disk-num " bestsize: " bestsize " best: " best " freespc: " freespc " min-inodes: " min-inodes " free-inodes: " free-inodes) Index: configure ================================================================== --- configure +++ configure @@ -16,10 +16,17 @@ # # You should have received a copy of the GNU General Public License # along with Megatest. If not, see . # Configure the build + +if [[ "$1"x == "x" ]];then + PREFIX=$PWD +else + PREFIX=$1 +fi + #====================================================================== # Configure stuff needed for eggs #====================================================================== @@ -58,15 +65,37 @@ #====================================================================== # Do we need Chicken? #====================================================================== +if [[ -e /usr/bin/sw_vers ]]; then + ARCHSTR=$(/usr/bin/sw_vers -productVersion) +else + ARCHSTR=$(lsb_release -sr) +fi + +echo "CHICKEN_PREFIX=$PREFIX/.$ARCHSTR" >> makefile.inc +CHICKEN_PREFIX=$PREFIX/bin/.$ARCHSTR + if [[ ! $(type csi) ]];then echo "Chicken build needed." echo "BUILD_CHICKEN=yes" >> makefile.inc configure_dependencies echo "include chicken.makefile" >> makefile.inc +else + echo "CSIPATH=$(which csi)" >> makefile.inc + CSIPATH=$(which csi) + echo "CKPATH=$(dirname $(dirname $CSIPATH))" >> makefile.inc fi -echo "All done creating makefile.inc, feel free to edit it!" +# Make setup scripts +echo "#!/bin/bash" > setup.sh +echo "export PATH=$CHICKEN_PREFIX/bin:\$PATH" >> setup.sh +echo "export LD_LIBRARY_PATH=$CHICKEN_PREFIX/lib" >> setup.sh +echo 'exec "$@"' >> setup.sh +chmod a+x setup.sh + +echo "setenv PATH $CHICKEN_PREFIX/bin:\$PATH" > setup.csh +echo "setenv LD_LIBRARY_PATH $CHICKEN_PREFIX/lib" >> setup.csh - +echo "All done creating makefile.inc, feel free to edit it!" +echo "run \"setup.sh bash\" or source setup.csh to get PATH and LD_LIBRARY_PATH adjusted" Index: dashboard.scm ================================================================== --- dashboard.scm +++ dashboard.scm @@ -1484,11 +1484,11 @@ (hash-table-set! tests-draw-state 'first-time #t) ;; (hash-table-set! tests-draw-state 'scalef 1) (tests:get-full-data test-names test-records '() all-tests-registry) (set! sorted-testnames (tests:sort-by-priority-and-waiton test-records)) - ;; refer to (dboard:tabcodat-keys tabdat), (dboard:tabdat-dbkeys tabdat) for keys + ;; refer to (dboard:tabdat-keys tabdat), (dboard:tabdat-dbkeys tabdat) for keys (let* ((result (iup:vbox (dcommon:command-execution-control tabdat) (iup:split #:orientation "VERTICAL" ;; "HORIZONTAL" @@ -2765,65 +2765,83 @@ (cell-width (dboard:tabdat-runs-cell-width runs-dat))) ;; controls (along bottom) ;; (set! controls (dboard:make-controls commondat runs-dat)) ;; create the left most column for the run key names and the test names - (set! lftlst (list (iup:hbox - (iup:label) ;; (iup:valuator) - (apply iup:vbox - (map (lambda (x) - (let ((res (iup:hbox #:expand "HORIZONTAL" - (iup:label x #:size (conc 40 btn-height) #:fontsize btn-fontsz #:expand "NO") ;; "HORIZONTAL") - (iup:textbox #:size (conc 35 btn-height) #:fontsize btn-fontsz #:value "%" #:expand "NO" ;; "HORIZONTAL" - #:action (lambda (obj unk val) - ;; each field (field name is "x" var) live updates - ;; the search filter as it is typed - (dboard:tabdat-target-set! runs-dat #f) ;; ensure the fields text boxes are used and not the info from the tree - (mark-for-update runs-dat) - (update-search commondat runs-dat x val)))))) - (set! i (+ i 1)) - res)) - keynames))))) + (set! lftlst + (list (iup:hbox + (iup:label) ;; (iup:valuator) + (apply iup:vbox + (map (lambda (x) + (let ((res (iup:hbox + #:expand "HORIZONTAL" + (iup:label x + #:size (conc 40 btn-height) + #:fontsize btn-fontsz + #:expand "NO") ;; "HORIZONTAL") + (iup:textbox + #:size (conc 35 btn-height) + #:fontsize btn-fontsz + #:value "%" + #:expand "NO" ;; "HORIZONTAL" + #:action (lambda (obj unk val) + ;; each field + ;; (field name is "x" var) live updates + ;; the search filter as it is typed + (dboard:tabdat-target-set! runs-dat #f) + ;; ensure fields text boxes are used + ;; and not the info from the tree + (mark-for-update runs-dat) + (update-search commondat runs-dat x val)))))) + (set! i (+ i 1)) + res)) + keynames))))) (let loop ((testnum 0) (res '())) (cond ((>= testnum ntests) ;; now lftlst will be an hbox with the test keys and the test name labels (set! lftlst - (append lftlst - (list (iup:hbox - #:expand "HORIZONTAL" - (iup:valuator - #:valuechanged_cb (lambda (obj) - (let ((val (string->number (iup:attribute obj "VALUE"))) - (oldmax (string->number (iup:attribute obj "MAX"))) - (newmax (* 10 (length (dboard:tabdat-all-test-names runs-dat))))) - (dboard:commondat-please-update-set! commondat #t) - (dboard:tabdat-start-test-offset-set! runs-dat (inexact->exact (round (/ val 10)))) - (debug:print 6 *default-log-port* "(dboard:tabdat-start-test-offset runs-dat) " - (dboard:tabdat-start-test-offset runs-dat) " val: " val - " newmax: " newmax " oldmax: " oldmax) - (if (< val 10) - (iup:attribute-set! obj "MAX" newmax)) - )) - #:expand "VERTICAL" - #:orientation "VERTICAL" - #:min 0 - #:step 0.01) - (apply iup:vbox (reverse res))))))) + (append + lftlst + (list + (iup:hbox + #:expand "HORIZONTAL" + (iup:valuator + #:valuechanged_cb + (lambda (obj) + (let ((val (string->number (iup:attribute obj "VALUE"))) + (oldmax (string->number (iup:attribute obj "MAX"))) + (newmax (* 10 (length (dboard:tabdat-all-test-names runs-dat))))) + (dboard:commondat-please-update-set! commondat #t) + (dboard:tabdat-start-test-offset-set! runs-dat + (inexact->exact (round (/ val 10)))) + (debug:print 6 *default-log-port* + "(dboard:tabdat-start-test-offset runs-dat) " + (dboard:tabdat-start-test-offset runs-dat) " val: " val + " newmax: " newmax " oldmax: " oldmax) + (if (< val 10) + (iup:attribute-set! obj "MAX" newmax)) + )) + #:expand "VERTICAL" + #:orientation "VERTICAL" + #:min 0 + #:step 0.01) + (apply iup:vbox (reverse res))))))) (else - (let ((labl (iup:button "" ;; the testname labels - #:flat "YES" - #:alignment "ALEFT" + (let ((labl (iup:button + "" ;; the testname labels + #:flat "YES" + #:alignment "ALEFT" ; #:image img1 ; #:impress img2 - #:size (conc cell-width btn-height) - #:expand "HORIZONTAL" - #:fontsize btn-fontsz - #:action (lambda (obj) - (mark-for-update runs-dat) - (toggle-hide testnum (dboard:commondat-uidat commondat)))))) ;; (iup:attribute obj "TITLE")))) + #:size (conc cell-width btn-height) + #:expand "HORIZONTAL" + #:fontsize btn-fontsz + #:action (lambda (obj) + (mark-for-update runs-dat) + (toggle-hide testnum (dboard:commondat-uidat commondat)))))) (vector-set! lftcol testnum labl) (loop (+ testnum 1)(cons labl res)))))) ;; These are the headers for each row (let loop ((runnum 0) (keynum 0) @@ -2921,11 +2939,11 @@ (dashboard:runs-horizontal-slider runs-dat)))) controls )) (views-cfgdat (common:load-views-config)) (additional-tabnames '()) - (tab-start-num 6) ;; DON'T FORGET TO UPDATE THIS WHEN CHANGING THE STANDARD TABS BELOW + (tab-start-num 5) ;; DON'T FORGET TO UPDATE THIS WHEN CHANGING THE STANDARD TABS BELOW ;; (data (dboard:tabdat-init (make-d:data))) (additional-views ;; process views-dat (let ((tab-num tab-start-num) (result '())) (for-each @@ -2964,24 +2982,22 @@ (dboard:commondat-please-update-set! commondat #t) (dboard:tabdat-layout-update-ok-set! tabdat #t))) "tabchangepos")) (dashboard:summary commondat stats-dat tab-num: 0) runs-view - (make-runs-view commondat runs2-dat 2) - (dashboard:runs-summary commondat onerun-dat tab-num: 3) - ;; (dashboard:new-view db data new-view-dat tab-num: 3) - (dashboard:run-controls commondat runcontrols-dat tab-num: 4) - (dashboard:run-times commondat runtimes-dat tab-num: 5) - ;; (dashboard:runs-summary commondat onerun-dat tab-num: 4) + ;; (make-runs-view commondat runs2-dat 2) + (dashboard:runs-summary commondat onerun-dat tab-num: 2) + (dashboard:run-controls commondat runcontrols-dat tab-num: 3) + (dashboard:run-times commondat runtimes-dat tab-num: 4) additional-views))) ;; (set! (iup:callback tabs tabchange-cb:) (lambda (a b c)(print "SWITCHED TO TAB: " a " " b " " c))) (iup:attribute-set! tabs "TABTITLE0" "Summary") (iup:attribute-set! tabs "TABTITLE1" "Runs") - (iup:attribute-set! tabs "TABTITLE2" "Runs2") - (iup:attribute-set! tabs "TABTITLE3" "Run Summary") - (iup:attribute-set! tabs "TABTITLE4" "Run Control") - (iup:attribute-set! tabs "TABTITLE5" "Run Times") + ;; (iup:attribute-set! tabs "TABTITLE2" "Runs2") + (iup:attribute-set! tabs "TABTITLE2" "Run Summary") + (iup:attribute-set! tabs "TABTITLE3" "Run Control") + (iup:attribute-set! tabs "TABTITLE4" "Run Times") ;; (iup:attribute-set! tabs "TABTITLE3" "New View") ;; (iup:attribute-set! tabs "TABTITLE4" "Run Control") ;; set the tab names for user added tabs (for-each @@ -2993,14 +3009,14 @@ ;; make the iup tabs object available (for changing color for example) (dboard:commondat-hide-not-hide-tabs-set! commondat tabs) ;; now set up the tabdat lookup (dboard:common-set-tabdat! commondat 0 stats-dat) (dboard:common-set-tabdat! commondat 1 runs-dat) + ;;(dboard:common-set-tabdat! commondat 2 runs2-dat) (dboard:common-set-tabdat! commondat 2 onerun-dat) (dboard:common-set-tabdat! commondat 3 runcontrols-dat) - (dboard:common-set-tabdat! commondat 4 runs2-dat) - (dboard:common-set-tabdat! commondat 5 runtimes-dat) + (dboard:common-set-tabdat! commondat 4 runtimes-dat) (iup:vbox tabs ;; controls )))) Index: db.scm ================================================================== --- db.scm +++ db.scm @@ -1251,28 +1251,28 @@ id INTEGER PRIMARY KEY, archive_area_name TEXT, disk_path TEXT, last_df INTEGER DEFAULT -1, last_df_time TIMESTAMP DEFAULT (strftime('%s','now')), - creation_time TIMESTAMP DEFAULT (strftime('%','now')));") + creation_time TIMESTAMP DEFAULT (strftime('%s','now')));") ;; individual bup (or tar) data chunks (sqlite3:execute db "CREATE TABLE IF NOT EXISTS archive_blocks ( id INTEGER PRIMARY KEY, archive_disk_id INTEGER, disk_path TEXT, last_du INTEGER DEFAULT -1, last_du_time TIMESTAMP DEFAULT (strftime('%s','now')), - creation_time TIMESTAMP DEFAULT (strftime('%','now')));") + creation_time TIMESTAMP DEFAULT (strftime('%s','now')));") ;; tests allocated to what chunks. reusing a chunk for a test/item_path is very efficient ;; NB// the per run/test recording of where the archive is stored is done in the test ;; record. (sqlite3:execute db "CREATE TABLE IF NOT EXISTS archive_allocations ( id INTEGER PRIMARY KEY, archive_block_id INTEGER, testname TEXT, item_path TEXT, - creation_time TIMESTAMP DEFAULT (strftime('%','now')));") + creation_time TIMESTAMP DEFAULT (strftime('%s','now')));") ;; move this clean up call somewhere else (sqlite3:execute db "DELETE FROM tasks_queue WHERE state='done' AND creation_time < ?;" (- (current-seconds)(* 24 60 60))) ;; remove older than 24 hrs (sqlite3:execute db (conc "CREATE INDEX IF NOT EXISTS runs_index ON runs (runname" (if havekeys "," "") keystr ");")) ;; (sqlite3:execute db "CREATE VIEW runs_tests AS SELECT * FROM runs INNER JOIN tests ON runs.id=tests.run_id;") (sqlite3:execute db "CREATE TABLE IF NOT EXISTS extradat (id INTEGER PRIMARY KEY, run_id INTEGER, key TEXT, val TEXT);") Index: docs/manual/installation.txt ================================================================== --- docs/manual/installation.txt +++ docs/manual/installation.txt @@ -20,9 +20,32 @@ Dependencies ~~~~~~~~~~~~ Chicken scheme and a number of "eggs" are required for building -Megatest. See the script installall.sh in the utils directory of the -source distribution for an automated way to install everything -needed for building Megatest on Linux. +Megatest. In the v1.66 and beyond assistance to create the build +system is built into the Makefile. + +.Installation steps (overview) +------------------------------------- +./configure +make chicken +setup.sh make -j install +------------------------------------- + +Or install the needed build system manually: + +. Chicken scheme from http://call-cc.org +. IUP from http://webserver2.tecgraf.puc-rio.br/iup/ +. CD from http://webserver2.tecgraf.puc-rio.br/cd/ +. IM from https://webserver2.tecgraf.puc-rio.br/im/ +. ffcall from http://webserver2.tecgraf.puc-rio.br/iup/ +. Nanomsg from https://nanomsg.org/ (NOTE: Plan is to eliminate nanomsg dependency). +. Needed eggs (look at the eggs lists in the Makefile) + +Then follow these steps: +.Installation steps (self-built chicken scheme build system) +------------------------------------- +./configure +make -j install +------------------------------------- Index: docs/manual/megatest_manual.html ================================================================== --- docs/manual/megatest_manual.html +++ docs/manual/megatest_manual.html @@ -1,10 +1,10 @@ - + The Megatest Users Manual