Megatest

Check-in [ce4213a580]
Login
Overview
Comment:Redraw of runs, refactoring
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | v1.61
Files: files | file ages | folders
SHA1: ce4213a5807706f61723030ad2b2436862ef1b4d
User & Date: matt on 2016-08-16 05:23:36
Other Links: branch diff | manifest | tags
Context
2016-08-16
08:19
Changed init of runs view to not call update-rundat check-in: 1489145939 user: mrwellan tags: v1.61
05:23
Redraw of runs, refactoring check-in: ce4213a580 user: matt tags: v1.61
2016-08-15
00:07
gui tweak check-in: a53c90a4b5 user: matt tags: v1.61
Changes

Modified dashboard.scm from [c152016b4b] to [8b099a84b6].

181
182
183
184
185
186
187

188
189
190
191
192
193
194
  ((run-keys          (make-hash-table)) : hash-table)
  (runs-matrix        #f)                               ;; used in newdashboard
  ((start-run-offset   0)                : number)      ;; left-right slider value
  ((start-test-offset  0)                : number)      ;; up-down slider value
  ((runs-btn-height    (or (configf:lookup *configdat* "dashboard" "btn-height") "x12")) : string) 
  ((runs-btn-fontsz    (or (configf:lookup *configdat* "dashboard" "btn-fontsz") "8")) : string)
  ((runs-cell-width    (or (configf:lookup *configdat* "dashboard" "cell-width") "50")) : string)

  
  ;; Canvas and drawing data
  (cnv                #f)
  (cnv-obj            #f)
  (drawing            #f)
  ((run-start-row     0)                 : number)
  ((max-row           0)                 : number)







>







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  ((run-keys          (make-hash-table)) : hash-table)
  (runs-matrix        #f)                               ;; used in newdashboard
  ((start-run-offset   0)                : number)      ;; left-right slider value
  ((start-test-offset  0)                : number)      ;; up-down slider value
  ((runs-btn-height    (or (configf:lookup *configdat* "dashboard" "btn-height") "x12")) : string) 
  ((runs-btn-fontsz    (or (configf:lookup *configdat* "dashboard" "btn-fontsz") "8")) : string)
  ((runs-cell-width    (or (configf:lookup *configdat* "dashboard" "cell-width") "50")) : string)
  ((all-test-names     '())              : list)
  
  ;; Canvas and drawing data
  (cnv                #f)
  (cnv-obj            #f)
  (drawing            #f)
  ((run-start-row     0)                 : number)
  ((max-row           0)                 : number)
315
316
317
318
319
320
321


322
323
324
325
326
327
328
329
330
331
332
   data-changed: #t
   )) 

(define (dboard:rundat-copy-tests-to-by-name rundat)
  (let ((src-ht (dboard:rundat-tests rundat))
	(trg-ht (dboard:rundat-tests-by-name rundat)))
    (if (and (hash-table? src-ht)(hash-table? trg-ht))


	(for-each
	 (lambda (testdat)
	   (hash-table-set! trg-ht (test:test-get-fullname testdat) testdat))
	 (hash-table-values src-ht))
	(debug:print 0 *default-log-port* "WARNING: src-ht " src-ht " trg-ht " trg-ht))))
  
(defstruct dboard:testdat
  id       ;; testid
  state    ;; test state
  status   ;; test status
  )







>
>
|
|
|
|







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
   data-changed: #t
   )) 

(define (dboard:rundat-copy-tests-to-by-name rundat)
  (let ((src-ht (dboard:rundat-tests rundat))
	(trg-ht (dboard:rundat-tests-by-name rundat)))
    (if (and (hash-table? src-ht)(hash-table? trg-ht))
	(begin
	  (hash-table-clear! trg-ht)
	  (for-each
	   (lambda (testdat)
	     (hash-table-set! trg-ht (test:test-get-fullname testdat) testdat))
	   (hash-table-values src-ht)))
	(debug:print 0 *default-log-port* "WARNING: src-ht " src-ht " trg-ht " trg-ht))))
  
(defstruct dboard:testdat
  id       ;; testid
  state    ;; test state
  status   ;; test status
  )
493
494
495
496
497
498
499




500
501
502
503
504
505
506
507
508
509
510
511

512
513
514
515
516
517
518
					     sort-order                           ;; sort-order
					     #f ;; 'shortlist                           ;; qrytype
					     (if (dboard:tabdat-filters-changed tabdat) 
						 0
						 last-update) ;; last-update
					     *dashboard-mode*)) ;; use dashboard mode
	 (use-new    (dboard:tabdat-hide-not-hide tabdat))




	 (tests-ht   (dboard:rundat-tests run-dat))
	 (start-time (current-seconds)))
    (for-each 
     (lambda (tdat)
       (let ((test-id (db:test-get-id tdat))
	     (state   (db:test-get-state tdat)))
	 (dboard:rundat-data-changed-set! run-dat #t)
	 (if (equal? state "DELETED")
	     (hash-table-delete! tests-ht test-id)
	     (hash-table-set! tests-ht test-id tdat))))
     tmptests)
    (dboard:rundat-last-update-set! run-dat (- (current-seconds) 10)) ;; go back two seconds in time to ensure all changes are captured.

    tests-ht))

;; tmptests   - new tests data
;; prev-tests - old tests data
;;
;; (define (dashboard:merge-changed-tests tabdat tests tmptests) ;;  use-new prev-tests) 
;;   (let* ((newdat     (filter







>
>
>
>
|











>







496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
					     sort-order                           ;; sort-order
					     #f ;; 'shortlist                           ;; qrytype
					     (if (dboard:tabdat-filters-changed tabdat) 
						 0
						 last-update) ;; last-update
					     *dashboard-mode*)) ;; use dashboard mode
	 (use-new    (dboard:tabdat-hide-not-hide tabdat))
	 (tests-ht   (if (dboard:tabdat-filters-changed tabdat)
			 (let ((ht (make-hash-table)))
			   (dboard:rundat-tests-set! run-dat ht)
			   ht)
			 (dboard:rundat-tests run-dat)))
	 (start-time (current-seconds)))
    (for-each 
     (lambda (tdat)
       (let ((test-id (db:test-get-id tdat))
	     (state   (db:test-get-state tdat)))
	 (dboard:rundat-data-changed-set! run-dat #t)
	 (if (equal? state "DELETED")
	     (hash-table-delete! tests-ht test-id)
	     (hash-table-set! tests-ht test-id tdat))))
     tmptests)
    (dboard:rundat-last-update-set! run-dat (- (current-seconds) 10)) ;; go back two seconds in time to ensure all changes are captured.
    (debug:print-info 0 *default-log-port* "tests-ht: " (hash-table-keys tests-ht))
    tests-ht))

;; tmptests   - new tests data
;; prev-tests - old tests data
;;
;; (define (dashboard:merge-changed-tests tabdat tests tmptests) ;;  use-new prev-tests) 
;;   (let* ((newdat     (filter
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
	 (vlst2        (bubble-up tabdat vlst priority: bubble-type)))
    (map (lambda (x)
	   (if (equal? (vector-ref x 1) "")
	       (vector-ref x 0)
	       (conc (vector-ref x 0) "(" (vector-ref x 1) ")")))
	 vlst2)))

(define (update-labels uidat)
  (let* ((rown    0)
	 (keycol  (dboard:uidat-get-keycol uidat))
	 (lftcol  (dboard:uidat-get-lftcol uidat))
	 (numcols (vector-length lftcol))
	 (maxn    (- numcols 1))
	 (allvals (make-vector numcols "")))
    (for-each (lambda (name)
		(if (<= rown maxn)
		    (vector-set! allvals rown name)) ;)
		(set! rown (+ 1 rown)))
	      *alltestnamelst*)
    (let loop ((i 0))
      (let* ((lbl    (vector-ref lftcol i))
	     (keyval (vector-ref keycol i))
	     (oldval (iup:attribute lbl "TITLE"))
	     (newval (vector-ref allvals i)))
	(if (not (equal? oldval newval))
	    (let ((munged-val (let ((parts (string-split newval "(")))







|










|







640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
	 (vlst2        (bubble-up tabdat vlst priority: bubble-type)))
    (map (lambda (x)
	   (if (equal? (vector-ref x 1) "")
	       (vector-ref x 0)
	       (conc (vector-ref x 0) "(" (vector-ref x 1) ")")))
	 vlst2)))

(define (update-labels uidat alltestnames)
  (let* ((rown    0)
	 (keycol  (dboard:uidat-get-keycol uidat))
	 (lftcol  (dboard:uidat-get-lftcol uidat))
	 (numcols (vector-length lftcol))
	 (maxn    (- numcols 1))
	 (allvals (make-vector numcols "")))
    (for-each (lambda (name)
		(if (<= rown maxn)
		    (vector-set! allvals rown name)) ;)
		(set! rown (+ 1 rown)))
	      alltestnames)
    (let loop ((i 0))
      (let* ((lbl    (vector-ref lftcol i))
	     (keyval (vector-ref keycol i))
	     (oldval (iup:attribute lbl "TITLE"))
	     (newval (vector-ref allvals i)))
	(if (not (equal? oldval newval))
	    (let ((munged-val (let ((parts (string-split newval "(")))
727
728
729
730
731
732
733
734

735
736

737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753








754



755
756

757
758
759
760
761
762

763
764
765
766
767
768
769
770
771
772
773
774
775
776
777

778
779
780
781
782
783
784
785
786
787

788
789
790
791
792
793
794
(define (update-buttons tabdat uidat numruns numtests)
  (let* ((runs        (if (> (length (dboard:tabdat-allruns tabdat)) numruns)
			  (take-right (dboard:tabdat-allruns tabdat) numruns)
			  (pad-list (dboard:tabdat-allruns tabdat) numruns)))
	 (lftcol      (dboard:uidat-get-lftcol uidat))
	 (tableheader (dboard:uidat-get-header uidat))
	 (table       (dboard:uidat-get-runsvec uidat))
	 (coln        0))

    (set! *alltestnamelst* '())
    ;; create a concise list of test names

    (for-each
     (lambda (rundat)
       (if rundat
	   (let* ((testdats  (dboard:rundat-tests rundat))
		  (testnames (map test:test-get-fullname (hash-table-values testdats)))
		  (alltests-by-name (make-hash-table)))
	     (dboard:rundat-copy-tests-to-by-name rundat)
	     ;; for the normalized list of testnames (union of all runs)
	     (if (not (and (dboard:tabdat-hide-empty-runs tabdat)
			   (null? testnames)))
		 (for-each (lambda (testname)
			     (if (not (member testname *alltestnamelst*))
				 (begin
				   (set! *alltestnamelst* (append *alltestnamelst* (list testname))))))
			   testnames)))))
     runs)









    ;; need alltestnames to enable lining up all tests from all runs



    (set! *alltestnamelst* (collapse-rows tabdat *alltestnamelst*)) ;;; argh. please clean up this sillyness
    (set! *alltestnamelst* (let ((xl (if (> (length *alltestnamelst*) (dboard:tabdat-start-test-offset tabdat))

					 (drop *alltestnamelst* (dboard:tabdat-start-test-offset tabdat))
					 '())))
			     (append xl (make-list (- (dboard:tabdat-num-tests tabdat) (length xl)) ""))))
    (update-labels uidat)
    (for-each
     (lambda (rundat)

       (if (or (not rundat) ;; handle padded runs
	       (not (dboard:rundat-run rundat)))
	   ;;           ;; id run-id testname state status event-time host cpuload diskfree uname rundir item-path run-duration
	   (set! rundat (dboard:rundat-make-init
			 key-vals: (map (lambda (x) "")(dboard:tabdat-keys tabdat)))))
       (let* ((run              (dboard:rundat-run rundat))
	      (testsdat-by-name (dboard:rundat-tests-by-name rundat))
	      (key-val-dat      (dboard:rundat-key-vals rundat))
	      (run-id           (db:get-value-by-header run (dboard:tabdat-header tabdat) "id"))
	      (key-vals         (append key-val-dat
					(list (let ((x (db:get-value-by-header run (dboard:tabdat-header tabdat) "runname")))
						(if x x "")))))
	      (run-key          (string-intersperse key-vals "\n")))
	 
	 ;; fill in the run header key values

	 (let ((rown      0)
	       (headercol (vector-ref tableheader coln)))
	   (for-each (lambda (kval)
		       (let* ((labl      (vector-ref headercol rown)))
			 (if (not (equal? kval (iup:attribute labl "TITLE")))
			     (iup:attribute-set! (vector-ref headercol rown) "TITLE" kval))
			 (set! rown (+ rown 1))))
		     key-vals))
	 
	 ;; For this run now fill in the buttons for each test

	 (let ((rown 0)
	       (columndat  (vector-ref table coln)))
	   (for-each
	    (lambda (testname)
	      (let ((buttondat  (hash-table-ref/default (dboard:tabdat-buttondat tabdat) (mkstr coln rown) #f)))
		(if (and buttondat
			 (hash-table? testsdat-by-name))







|
>
|

>




|
<





|
<
<



>
>
>
>
>
>
>
>
|
>
>
>
|
|
>
|
|
|
|


>


<












>










>







735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751

752
753
754
755
756
757


758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784

785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
(define (update-buttons tabdat uidat numruns numtests)
  (let* ((runs        (if (> (length (dboard:tabdat-allruns tabdat)) numruns)
			  (take-right (dboard:tabdat-allruns tabdat) numruns)
			  (pad-list (dboard:tabdat-allruns tabdat) numruns)))
	 (lftcol      (dboard:uidat-get-lftcol uidat))
	 (tableheader (dboard:uidat-get-header uidat))
	 (table       (dboard:uidat-get-runsvec uidat))
	 (coln        0)
	 (all-test-names (make-hash-table)))

    ;; create a concise list of test names
    ;;
    (for-each
     (lambda (rundat)
       (if rundat
	   (let* ((testdats  (dboard:rundat-tests rundat))
		  (testnames (map test:test-get-fullname (hash-table-values testdats))))

	     (dboard:rundat-copy-tests-to-by-name rundat)
	     ;; for the normalized list of testnames (union of all runs)
	     (if (not (and (dboard:tabdat-hide-empty-runs tabdat)
			   (null? testnames)))
		 (for-each (lambda (testname)
			     (hash-table-set! all-test-names testname #t))


			   testnames)))))
     runs)

    ;; create the minimize list of testnames to be displayed. Sorting
    ;; happens here *before* trimming
    ;;
    (dboard:tabdat-all-test-names-set!
     tabdat
     (collapse-rows
      tabdat
      (sort (hash-table-keys all-test-names) string>?))) ;; FIXME: Sorting needs to happen here

    ;; Trim the names list to fit the matrix of buttons
    ;;
    (dboard:tabdat-all-test-names-set!
     tabdat
     (let ((xl (if (> (length (dboard:tabdat-all-test-names tabdat)) (dboard:tabdat-start-test-offset tabdat))
		   (drop (dboard:tabdat-all-test-names tabdat)
			 (dboard:tabdat-start-test-offset tabdat))
		   '())))
       (append xl (make-list (- (dboard:tabdat-num-tests tabdat) (length xl)) ""))))
    (update-labels uidat (dboard:tabdat-all-test-names tabdat))
    (for-each
     (lambda (rundat)
       ;; if rundat is junk clobber it with a decent placeholder
       (if (or (not rundat) ;; handle padded runs
	       (not (dboard:rundat-run rundat)))

	   (set! rundat (dboard:rundat-make-init
			 key-vals: (map (lambda (x) "")(dboard:tabdat-keys tabdat)))))
       (let* ((run              (dboard:rundat-run rundat))
	      (testsdat-by-name (dboard:rundat-tests-by-name rundat))
	      (key-val-dat      (dboard:rundat-key-vals rundat))
	      (run-id           (db:get-value-by-header run (dboard:tabdat-header tabdat) "id"))
	      (key-vals         (append key-val-dat
					(list (let ((x (db:get-value-by-header run (dboard:tabdat-header tabdat) "runname")))
						(if x x "")))))
	      (run-key          (string-intersperse key-vals "\n")))
	 
	 ;; fill in the run header key values
	 ;;
	 (let ((rown      0)
	       (headercol (vector-ref tableheader coln)))
	   (for-each (lambda (kval)
		       (let* ((labl      (vector-ref headercol rown)))
			 (if (not (equal? kval (iup:attribute labl "TITLE")))
			     (iup:attribute-set! (vector-ref headercol rown) "TITLE" kval))
			 (set! rown (+ rown 1))))
		     key-vals))
	 
	 ;; For this run now fill in the buttons for each test
	 ;;
	 (let ((rown 0)
	       (columndat  (vector-ref table coln)))
	   (for-each
	    (lambda (testname)
	      (let ((buttondat  (hash-table-ref/default (dboard:tabdat-buttondat tabdat) (mkstr coln rown) #f)))
		(if (and buttondat
			 (hash-table? testsdat-by-name))
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
			  (iup:attribute-set! button "TITLE"   buttontxt))
		      (vector-set! buttondat 0 run-id)
		      (vector-set! buttondat 1 color)
		      (vector-set! buttondat 2 buttontxt)
		      (vector-set! buttondat 3 testdat)
		      (vector-set! buttondat 4 run-key)))
		(set! rown (+ rown 1))))
	    *alltestnamelst*))
	 (set! coln (+ coln 1))))
     runs)))

(define (mkstr . x)
  (string-intersperse (map conc x) ","))

(define (set-bg-on-filter commondat tabdat)







|







845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
			  (iup:attribute-set! button "TITLE"   buttontxt))
		      (vector-set! buttondat 0 run-id)
		      (vector-set! buttondat 1 color)
		      (vector-set! buttondat 2 buttontxt)
		      (vector-set! buttondat 3 testdat)
		      (vector-set! buttondat 4 run-key)))
		(set! rown (+ rown 1))))
	    (dboard:tabdat-all-test-names tabdat)))
	 (set! coln (+ coln 1))))
     runs)))

(define (mkstr . x)
  (string-intersperse (map conc x) ","))

(define (set-bg-on-filter commondat tabdat)
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
      (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 *alltestnamelst*))))
											 (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" 







|







1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
      (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" 

Modified docs/megatest-about.svg from [5cfe75c45c] to [5c520fd160].

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="744.09448819"
   height="1052.3622047"
   id="svg2"
   version="1.1"
   inkscape:version="0.48.3.1 r9886"
   sodipodi:docname="megatest-about.svg">
  <defs
     id="defs4">
    <linearGradient
       inkscape:collect="always"
       id="linearGradient4210">
      <stop







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="744.09448819"
   height="1052.3622047"
   id="svg2"
   version="1.1"
   inkscape:version="0.91 r13725"
   sodipodi:docname="megatest-about.svg">
  <defs
     id="defs4">
    <linearGradient
       inkscape:collect="always"
       id="linearGradient4210">
      <stop
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
     inkscape:cx="263.11623"
     inkscape:cy="534.40312"
     inkscape:document-units="px"
     inkscape:current-layer="layer1"
     showgrid="false"
     inkscape:window-width="1527"
     inkscape:window-height="1016"
     inkscape:window-x="215"
     inkscape:window-y="35"
     inkscape:window-maximized="0" />
  <metadata
     id="metadata7">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1">







|
|









|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
     inkscape:cx="263.11623"
     inkscape:cy="534.40312"
     inkscape:document-units="px"
     inkscape:current-layer="layer1"
     showgrid="false"
     inkscape:window-width="1527"
     inkscape:window-height="1016"
     inkscape:window-x="2114"
     inkscape:window-y="55"
     inkscape:window-maximized="0" />
  <metadata
     id="metadata7">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title />
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1">
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
         id="flowRegion2987"><rect
           id="rect2989"
           width="628.57141"
           height="104.28571"
           x="55.714287"
           y="40.933609"
           style="font-size:72px" /></flowRegion><flowPara
         id="flowPara2991"></flowPara></flowRoot>    <text
       xml:space="preserve"
       style="font-size:22px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
       x="187.14285"
       y="58.076473"
       id="text2993"
       sodipodi:linespacing="125%"><tspan
         sodipodi:role="line"







|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
         id="flowRegion2987"><rect
           id="rect2989"
           width="628.57141"
           height="104.28571"
           x="55.714287"
           y="40.933609"
           style="font-size:72px" /></flowRegion><flowPara
         id="flowPara2991" /></flowRoot>    <text
       xml:space="preserve"
       style="font-size:22px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
       x="187.14285"
       y="58.076473"
       id="text2993"
       sodipodi:linespacing="125%"><tspan
         sodipodi:role="line"
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
         id="tspan2999"
         x="195.71429"
         y="100.93362">Simple - but not TOO simple!</tspan></text>
    <image
       y="7.3621907"
       x="4.3571429"
       id="image3139"
       xlink:href="data:image/png;base64,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
FM/1Piolgf8Do6DT7EsG7IgAAAAASUVORK5CYII=
"
       height="70"
       width="137" />
    <text
       xml:space="preserve"
       style="font-size:28px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
       x="78.571426"
       y="139.50505"







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







115
116
117
118
119
120
121
122






























































































































































123
124
125
126
127
128
129
         id="tspan2999"
         x="195.71429"
         y="100.93362">Simple - but not TOO simple!</tspan></text>
    <image
       y="7.3621907"
       x="4.3571429"
       id="image3139"
       xlink:href="data:image/png;base64,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 FM/1Piolgf8Do6DT7EsG7IgAAAAASUVORK5CYII= "






























































































































































       height="70"
       width="137" />
    <text
       xml:space="preserve"
       style="font-size:28px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
       x="78.571426"
       y="139.50505"
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408






409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
       id="rect3402"
       width="0"
       height="0"
       x="687.14282"
       y="729.50494" />
    <text
       xml:space="preserve"
       style="font-size:28px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
       x="81.428574"
       y="390.93362"
       id="text4402"
       sodipodi:linespacing="125%"><tspan
         sodipodi:role="line"
         id="tspan4404"
         x="81.428574"
         y="390.93362">Write one task or test and iterate</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="425.93362"
         id="tspan4406">Distribute tasks over one or many hosts</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="460.93362"
         id="tspan4408">Organize runs by any variables you wish</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="495.93362"
         id="tspan4410"> - release</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="530.93359"
         id="tspan4412"> - architecture</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="565.93359"
         id="tspan4414"> - unit or partition</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="600.93359"
         id="tspan4416">Tasks or tests may depend on others</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="635.93359"
         id="tspan4418">Each task or test runs in clean area</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="670.93359"
         id="tspan4420">Add disk space or partitions as needed</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="705.93359"
         id="tspan4422">Rigorous results; error, pass, warn etc.</tspan><tspan






         sodipodi:role="line"
         x="81.428574"
         y="740.93359"
         id="tspan4424">Crontab friendly runs (skip if running)</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="775.93359"
         id="tspan4426">Easy debugging</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="810.93359"
         id="tspan4428"> - easy to recreate environment for task</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="845.93359"
         id="tspan4430"> - annotated HTML logs help find issues</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="880.93353"
         id="tspan4432">Simplify scripts</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="915.93353"
         id="tspan4434"> - eliminate for-each or while loops</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="950.93353"
         id="tspan4436"> - parallel running handled by tool</tspan></text>
    <rect
       style="opacity:0.7837838;fill:#e81c1c;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
       id="rect4444"
       width="95.714287"
       height="38.57143"
       x="17.142857"







|















|







|



















|
>
>
>
>
>
>


















|



|



|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
       id="rect3402"
       width="0"
       height="0"
       x="687.14282"
       y="729.50494" />
    <text
       xml:space="preserve"
       style="font-style:normal;font-weight:normal;font-size:28px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
       x="81.428574"
       y="390.93362"
       id="text4402"
       sodipodi:linespacing="125%"><tspan
         sodipodi:role="line"
         id="tspan4404"
         x="81.428574"
         y="390.93362">Write one task or test and iterate</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="425.93362"
         id="tspan4406">Distribute tasks over one or many hosts</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="460.93362"
         id="tspan4408">Organize runs by any variables, e.g:</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="495.93362"
         id="tspan4410"> - release</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="530.93359"
         id="tspan4412"> - git or fossil node hash</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="565.93359"
         id="tspan4414"> - unit or partition</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="600.93359"
         id="tspan4416">Tasks or tests may depend on others</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="635.93359"
         id="tspan4418">Each task or test runs in clean area</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="670.93359"
         id="tspan4420">Add disk space or partitions as needed</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="705.93359"
         id="tspan4422">Rigorous results; <tspan
   style="fill:#ff0000"
   id="tspan3387">error</tspan>, <tspan
   style="fill:#008000"
   id="tspan3389">pass</tspan>, <tspan
   style="fill:#ff7f2a"
   id="tspan3391">warn</tspan> etc.</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="740.93359"
         id="tspan4424">Crontab friendly runs (skip if running)</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="775.93359"
         id="tspan4426">Easy debugging</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="810.93359"
         id="tspan4428"> - easy to recreate environment for task</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="845.93359"
         id="tspan4430"> - annotated HTML logs help find issues</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="880.93359"
         id="tspan4432">Simplify scripts</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="915.93359"
         id="tspan4434"> - eliminate for-each or while loops</tspan><tspan
         sodipodi:role="line"
         x="81.428574"
         y="950.93359"
         id="tspan4436"> - parallel running handled by tool</tspan></text>
    <rect
       style="opacity:0.7837838;fill:#e81c1c;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
       id="rect4444"
       width="95.714287"
       height="38.57143"
       x="17.142857"