︙ | | |
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
+
+
+
|
*tests-sort-reverse*)
(define (get-curr-sort)
(vector-ref *tests-sort-options* *tests-sort-reverse*))
(define *tests-sort-reverse* 3)
(define *hide-empty-runs* #f)
(define *hide-not-hide* #t) ;; toggle for hide/not hide
(define *hide-not-hide-button* #f)
(define *hide-not-hide-tabs* #f)
(define *current-tab-number* 0)
(define *updaters* (make-hash-table))
(debug:setup)
(define uidat #f)
|
︙ | | |
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
-
+
+
+
+
|
'testname
'itempath)))
;;
;; trim runs to only those that are changing often here
;;
(for-each (lambda (run)
(let* ((run-id (db:get-value-by-header run header "id"))
(tests (mt:get-tests-for-run run-id testnamepatt states statuses sort-by: sort-by sort-order: sort-order))
(tests (mt:get-tests-for-run run-id testnamepatt states statuses
not-in: *hide-not-hide*
sort-by: sort-by
sort-order: sort-order))
;; NOTE: bubble-up also sets the global *all-item-test-names*
;; (tests (bubble-up tmptests priority: bubble-type))
(key-vals (cdb:remote-run db:get-key-vals #f run-id)))
;; Not sure this is needed?
(set! referenced-run-ids (cons run-id referenced-run-ids))
(if (> (length tests) maxtests)
(set! maxtests (length tests)))
|
︙ | | |
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
|
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
|
(set! rown (+ rown 1))))
*alltestnamelst*))
(set! coln (+ coln 1))))
runs)))
(define (mkstr . x)
(string-intersperse (map conc x) ","))
(define (set-bg-on-filter)
(let ((search-changed (not (null? (filter (lambda (key)
(not (equal? (hash-table-ref *searchpatts* key) "%")))
(hash-table-keys *searchpatts*)))))
(state-changed (not (null? (hash-table-keys *state-ignore-hash*))))
(status-changed (not (null? (hash-table-keys *status-ignore-hash*)))))
(iup:attribute-set! *hide-not-hide-tabs* "BGCOLOR"
(if (or search-changed
state-changed
status-changed)
"190 180 190"
"190 190 190"
))))
(define (update-search x val)
;; (print "Setting search for " x " to " val)
(hash-table-set! *searchpatts* x val))
(hash-table-set! *searchpatts* x val)
(set-bg-on-filter))
(define (mark-for-update)
(set! *last-db-update-time* 0)
(set! *delayed-update* 1))
;;======================================================================
;; R U N C O N T R O L
|
︙ | | |
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
|
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
|
-
+
-
+
|
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!
'("COMPLETED" "RUNNING" "STUCK" "INCOMPLETE" "LAUNCHED" "REMOTEHOSTSTART" "KILLED")
*common:std-states* ;; '("COMPLETED" "RUNNING" "STUCK" "INCOMPLETE" "LAUNCHED" "REMOTEHOSTSTART" "KILLED")
(lambda (all)
(dboard:data-set-states! *data* all)
(dashboard:update-run-command))))
;; Text box for STATES
(iup:frame
#:title "Statuses"
(dashboard:text-list-toggle-box
'("PASS" "FAIL" "n/a" "CHECK" "WAIVED" "SKIP" "DELETED" "STUCK/DEAD")
*common:std-statuses* ;; '("PASS" "FAIL" "n/a" "CHECK" "WAIVED" "SKIP" "DELETED" "STUCK/DEAD")
(lambda (all)
(dboard:data-set-statuses! *data* all)
(dashboard:update-run-command))))))))
(iup:frame
#:title "Tests and Tasks"
(let* ((updater #f)
|
︙ | | |
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
|
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
|
-
+
+
+
+
+
|
))))
(run-matrix (iup:matrix
#:expand "YES"))
(updater (lambda ()
(let* ((runs-dat (mt:get-runs-by-patt *keys* "%" #f))
(runs-header (vector-ref runs-dat 0)) ;; 0 is header, 1 is list of records
(run-id (dboard:data-get-curr-run-id *data*))
(tests-dat (let ((tdat (mt:get-tests-for-run run-id "%" '() '()
(tests-dat (let ((tdat (mt:get-tests-for-run run-id
(hash-table-ref/default *searchpatts* "test-name" "%/%")
(hash-table-keys *state-ignore-hash*) ;; '()
(hash-table-keys *status-ignore-hash*) ;; '()
not-in: *hide-not-hide*
qryvals: "id,testname,item_path,state,status"))) ;; get 'em all
(sort tdat (lambda (a b)
(let* ((aval (vector-ref a 2))
(bval (vector-ref b 2))
(anum (string->number aval))
(bnum (string->number bval)))
(if (and anum bnum)
|
︙ | | |
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
|
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
|
-
-
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
-
-
+
+
+
-
-
+
+
+
+
|
(iup:hbox
(iup:button "Sort -t" #:action (lambda (obj)
(next-sort-option)
(iup:attribute-set! obj "TITLE" (vector-ref (vector-ref *tests-sort-options* *tests-sort-reverse*) 0))
(mark-for-update)))
(iup:button "HideEmpty" #:action (lambda (obj)
(set! *hide-empty-runs* (not *hide-empty-runs*))
(iup:attribute-set! obj "TITLE" (if *hide-empty-runs* "+Hide" "-Hide"))
(mark-for-update))))
(iup:attribute-set! obj "TITLE" (if *hide-empty-runs* "+HideE" "-HideE"))
(mark-for-update)))
(let ((hideit (iup:button "HideTests" #:action (lambda (obj)
(set! *hide-not-hide* (not *hide-not-hide*))
(iup:attribute-set! obj "TITLE" (if *hide-not-hide* "HideTests" "NotHide"))
(mark-for-update)))))
(set! *hide-not-hide-button* hideit)
hideit))
(iup:hbox
(iup:button "Quit" #:action (lambda (obj)(if *db* (sqlite3:finalize! *db*))(exit)))
(iup:button "Refresh" #:action (lambda (obj)
(mark-for-update)))
(iup:button "Collapse" #:action (lambda (obj)
(let ((myname (iup:attribute obj "TITLE")))
(if (equal? myname "Collapse")
(begin
(for-each (lambda (tname)
(hash-table-set! *collapsed* tname #t))
*all-item-test-names*)
(iup:attribute-set! obj "TITLE" "Expand"))
(begin
(for-each (lambda (tname)
(hash-table-delete! *collapsed* tname))
(hash-table-keys *collapsed*))
(iup:attribute-set! obj "TITLE" "Collapse"))))
(mark-for-update))))))
(iup:frame
#:title "hide"
#:title "state/status filter"
(iup:vbox
(apply
iup:hbox
(map (lambda (status)
(iup:toggle status #:action (lambda (obj val)
(mark-for-update)
(if (eq? val 1)
(hash-table-set! *status-ignore-hash* status #t)
(hash-table-delete! *status-ignore-hash* status)))))
'("PASS" "FAIL" "WARN" "CHECK" "WAIVED" "STUCK/DEAD" "n/a" "SKIP")))
(hash-table-delete! *status-ignore-hash* status))
(set-bg-on-filter))))
*common:std-statuses*)) ;; '("PASS" "FAIL" "WARN" "CHECK" "WAIVED" "STUCK/DEAD" "n/a" "SKIP")))
(apply
iup:hbox
(map (lambda (state)
(iup:toggle state #:action (lambda (obj val)
(mark-for-update)
(if (eq? val 1)
(hash-table-set! *state-ignore-hash* state #t)
(hash-table-delete! *state-ignore-hash* state)))))
'("RUNNING" "COMPLETED" "INCOMPLETE" "LAUNCHED" "NOT_STARTED" "KILLED" "DELETED")))
(hash-table-delete! *state-ignore-hash* state))
(set-bg-on-filter))))
*common:std-states*)) ;; '("RUNNING" "COMPLETED" "INCOMPLETE" "LAUNCHED" "NOT_STARTED" "KILLED" "DELETED")))
(iup:valuator #:valuechanged_cb (lambda (obj)
(let ((val (inexact->exact (round (/ (string->number (iup:attribute obj "VALUE")) 10))))
(oldmax (string->number (iup:attribute obj "MAX")))
(maxruns *tot-run-count*))
(set! *start-run-offset* val)
(mark-for-update)
(debug:print 6 "*start-run-offset* " *start-run-offset* " maxruns: " maxruns ", val: " val " oldmax: " oldmax)
(iup:attribute-set! obj "MAX" (* maxruns 10))))
#:expand "YES"
#:max (* 10 (length *allruns*)))))
#:expand "HORIZONTAL"
#:max (* 10 (length *allruns*))
#:min 0
#:step 0.01)))
;(iup:button "inc rows" #:action (lambda (obj)(set! *num-tests* (+ *num-tests* 1))))
;(iup:button "dec rows" #:action (lambda (obj)(set! *num-tests* (if (> *num-tests* 0)(- *num-tests* 1) 0))))
)
)
;; create the left most column for the run key names and the test names
(set! lftlst (list (iup:hbox
|
︙ | | |
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
|
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
|
-
+
+
+
|
(set! *please-update-buttons* #t)
(set! *start-test-offset* (inexact->exact (round (/ val 10))))
(debug:print 6 "*start-test-offset* " *start-test-offset* " val: " val " newmax: " newmax " oldmax: " oldmax)
(if (< val 10)
(iup:attribute-set! obj "MAX" newmax))
))
#:expand "VERTICAL"
#:orientation "VERTICAL")
#:orientation "VERTICAL"
#:min 0
#:step 0.01)
(apply iup:vbox (reverse res)))))))
(else
(let ((labl (iup:button ""
#:flat "YES"
#:alignment "ALEFT"
; #:image img1
; #:impress img2
|
︙ | | |
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
|
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
|
+
+
|
(dashboard:run-controls)
)))
;; (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" "Run Summary")
(iup:attribute-set! tabs "TABTITLE3" "Run Control")
(iup:attribute-set! tabs "BGCOLOR" "190 190 190")
(set! *hide-not-hide-tabs* tabs)
tabs)))
(vector keycol lftcol header runsvec)))
(if (or (args:get-arg "-rows")
(get-environment-variable "DASHBOARDROWS" ))
(begin
(set! *num-tests* (string->number (or (args:get-arg "-rows")
|
︙ | | |
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
|
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
|
-
+
|
(mutex-lock! *update-mutex*)
(set! update-is-running *update-is-running*)
(if (not update-is-running)
(set! *update-is-running* #t))
(mutex-unlock! *update-mutex*)
(if (not update-is-running)
(begin
(dashboard:run-update x)
(dashboard:run-update x)
(mutex-lock! *update-mutex*)
(set! *update-is-running* #f)
(mutex-unlock! *update-mutex*))))
1))))
(iup:main-loop)
|
︙ | | |
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
-
+
|
(dbexists (file-exists? dbpath))
(handler (make-busy-timeout (if (args:get-arg "-override-timeout")
(string->number (args:get-arg "-override-timeout"))
136000))))
(handle-exceptions
exn
(begin
(debug:print 0 "ERROR: problem accessing test db " work-area ", you probably should clean and re-run this test"
(debug:print 2 "ERROR: problem accessing test db " work-area ", you probably should clean and re-run this test"
((condition-property-accessor 'exn 'message) exn))
(set! db (sqlite3:open-database ":memory:"))) ;; open an in-memory db to allow readonly access
(set! db (sqlite3:open-database dbpath)))
(sqlite3:set-busy-handler! db handler)
(if (not dbexists)
(begin
(sqlite3:execute db "PRAGMA synchronous = FULL;")
|
︙ | | |
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
|
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
|
-
+
|
(sqlite3:prepare db stmt))
(list
;; delete all tests that belong to runs that are 'deleted'
"DELETE FROM tests WHERE run_id in (SELECT id FROM runs WHERE state='deleted');"
;; delete all tests that are 'DELETED'
"DELETE FROM tests WHERE state='DELETED';"
;; delete all tests that have no run
"DELETE FROM tests WHERE run_id NOT IN (SELECT DISTINCT run_id FROM runs);"
"DELETE FROM tests WHERE run_id NOT IN (SELECT DISTINCT id FROM runs);"
;; delete all runs that are state='deleted'
"DELETE FROM runs WHERE state='deleted';"
;; delete empty runs
"DELETE FROM runs WHERE id NOT IN (SELECT DISTINCT r.id FROM runs AS r INNER JOIN tests AS t ON t.run_id=r.id);"
))))
(sqlite3:with-transaction
db
|
︙ | | |
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
|
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
|
-
+
|
(lambda (id)
(set! res id))
db
(let ((qry (conc "SELECT id FROM runs WHERE (runname=? " andstr key=?str ");")))
;(debug:print 4 "qry: " qry)
qry)
qryvals)
(sqlite3:execute db "UPDATE runs SET state=?,status=?,event_time=strftime('%s','now') WHERE id=?;" state status res)
(sqlite3:execute db "UPDATE runs SET state=?,status=?,event_time=strftime('%s','now') WHERE id=? AND state='deleted';" state status res)
res)
(begin
(debug:print 0 "ERROR: Called without all necessary keys")
#f))))
;; replace header and keystr with a call to runs:get-std-run-fields
|
︙ | | |
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
|
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
|
-
-
+
+
|
(sqlite3:execute db "UPDATE runs SET comment=? WHERE id=?;" comment run-id)
(debug:print-info 11 "db:set-comment-for-run END run-id: " run-id " comment: " comment))
;; does not (obviously!) removed dependent data. But why not!!?
(define (db:delete-run db run-id)
(common:clear-caches) ;; don't trust caches after doing any deletion
;; First set any related tests to DELETED
(let ((stmt1 (sqlite3:prepare db "UPDATE tests SET state='DELETED' WHERE run_id=?;"))
(stmt2 (sqlite3:prepare db "UPDATE runs SET state='deleted' WHERE id=?;")))
(let ((stmt1 (sqlite3:prepare db "UPDATE tests SET state='DELETED',comment='' WHERE run_id=?;"))
(stmt2 (sqlite3:prepare db "UPDATE runs SET state='deleted',comment='' WHERE id=?;")))
(sqlite3:with-transaction
db (lambda ()
(sqlite3:execute stmt1 run-id)
(sqlite3:execute stmt2 run-id)))
(sqlite3:finalize! stmt1)
(sqlite3:finalize! stmt2)))
;; (sqlite3:execute db "DELETE FROM runs WHERE id=?;" run-id))
|
︙ | | |
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
|
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
|
-
+
|
;; (sqlite3:execute db "DELETE FROM tests WHERE id=?;" test-id))
(if db
(begin
(sqlite3:execute db "DELETE FROM test_steps WHERE test_id=?;" test-id)
(sqlite3:execute db "DELETE FROM test_data WHERE test_id=?;" test-id)
(if force
(sqlite3:execute db "DELETE FROM tests WHERE id=?;" test-id)
(sqlite3:execute db "UPDATE tests SET state='DELETED',status='n/a' WHERE id=?;" test-id)))))
(sqlite3:execute db "UPDATE tests SET state='DELETED',status='n/a',comment='' WHERE id=?;" test-id)))))
(define (db:delete-tests-for-run db run-id)
(common:clear-caches)
(sqlite3:execute db "DELETE FROM tests WHERE run_id=?;" run-id))
(define (db:delete-old-deleted-test-records db)
(common:clear-caches)
|
︙ | | |
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
|
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
|
-
+
|
0 ;;
(let ((res 0))
(sqlite3:for-each-row
(lambda (count)
(set! res count))
db
"SELECT count(id) FROM tests WHERE state = 'RUNNING' OR state = 'LAUNCHED' OR state = 'REMOTEHOSTSTART'
AND testname in (SELECT testname FROM test_meta WHERE jobgroup=?;"
AND testname in (SELECT testname FROM test_meta WHERE jobgroup=?);"
jobgroup)
res)))
;; done with run when:
;; 0 tests in LAUNCHED, NOT_STARTED, REMOTEHOSTSTART, RUNNING
(define (db:estimated-tests-remaining db run-id)
(let ((res 0))
|
︙ | | |
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
|
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
|
-
+
|
WHERE run_id=? AND testname=? AND item_path='';")
'(top-test-set-running "UPDATE tests SET state='RUNNING' WHERE run_id=? AND testname=? AND item_path='';")
'(top-test-set-per-pf-counts "UPDATE tests
SET state=CASE
WHEN (SELECT count(id) FROM tests
WHERE run_id=? AND testname=?
AND item_path != ''
AND state in ('RUNNING','NOT_STARTED')) > 0 THEN 'RUNNING'
AND state in ('RUNNING','NOT_STARTED','LAUNCHED','REMOTEHOSTSTART')) > 0 THEN 'RUNNING'
ELSE 'COMPLETED' END,
status=CASE
WHEN fail_count > 0 THEN 'FAIL'
WHEN pass_count > 0 AND fail_count=0 THEN 'PASS'
WHEN (SELECT count(id) FROM tests
WHERE run_id=? AND testname=?
AND item_path != ''
|
︙ | | |
︙ | | |
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
|
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
|
+
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
-
+
|
;; environment overrides are done *before* the remaining critical envars.
(alist->env-vars env-ovrd)
(set-megatest-env-vars run-id)
(set-item-env-vars itemdat)
(save-environment-as-files "megatest")
;; open-run-close not needed for test-set-meta-info
(tests:set-full-meta-info #f test-id run-id 0 work-area)
(tests:test-set-status! test-id "REMOTEHOSTSTART" "n/a" (args:get-arg "-m") #f)
;; (tests:test-set-status! test-id "REMOTEHOSTSTART" "n/a" (args:get-arg "-m") #f)
(tests:test-force-state-status! test-id "REMOTEHOSTSTART" "n/a")
(thread-sleep! 0.3) ;; NFS slowness has caused grief here
(if (args:get-arg "-xterm")
(set! fullrunscript "xterm")
(if (and fullrunscript (not (file-execute-access? fullrunscript)))
(system (conc "chmod ug+x " fullrunscript))))
;; We are about to actually kick off the test
;; so this is a good place to remove the records for
;; any previous runs
;; (db:test-remove-steps db run-id testname itemdat)
(let* ((m (make-mutex))
(kill-job? #f)
(exit-info (vector #t #t #t))
(job-thread #f)
(keep-going #t)
(runit (lambda ()
;; (let-values
;; (((pid exit-status exit-code)
;; (run-n-wait fullrunscript)))
(tests:test-set-status! test-id "RUNNING" "n/a" #f #f)
;; (tests:test-set-status! test-id "RUNNING" "n/a" #f #f)
;; Since we should have a clean slate at this time there is no need to do
;; any of the other stuff that tests:test-set-status! does. Let's just
;; force RUNNING/n/a
(thread-sleep! 0.3)
(tests:test-force-state-status! test-id "RUNNING" "n/a")
(thread-sleep! 0.3) ;; NFS slowness has caused grief here
;; if there is a runscript do it first
(if fullrunscript
(let ((pid (process-run fullrunscript)))
(let loop ((i 0))
(let-values
(((pid-val exit-status exit-code) (process-wait pid #t)))
(mutex-lock! m)
(vector-set! exit-info 0 pid)
(vector-set! exit-info 1 exit-status)
(vector-set! exit-info 2 exit-code)
(set! rollup-status exit-code)
(mutex-unlock! m)
(if (eq? pid-val 0)
(begin
(thread-sleep! 1)
(thread-sleep! 2)
(loop (+ i 1)))
)))))
;; then, if runscript ran ok (or did not get called)
;; do all the ezsteps (if any)
(if ezsteps
(let* ((testconfig (read-config (conc work-area "/testconfig") #f #t environ-patt: "pre-launch-env-vars")) ;; FIXME??? is allow-system ok here?
(ezstepslst (hash-table-ref/default testconfig "ezsteps" '())))
|
︙ | | |
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
-
+
|
(mutex-lock! m)
(vector-set! exit-info 0 pid)
(vector-set! exit-info 1 exit-status)
(vector-set! exit-info 2 exit-code)
(mutex-unlock! m)
(if (eq? pid-val 0)
(begin
(thread-sleep! 1)
(thread-sleep! 2)
(processloop (+ i 1))))
))
(let ((exinfo (vector-ref exit-info 2))
(logfna (if logpro-used (conc stepname ".html") "")))
;; testing if procedures called in a remote call cause problems (ans: no or so I suspect)
(db:teststep-set-status! #f test-id stepname "end" exinfo #f logfna work-area: work-area))
(if logpro-used
|
︙ | | |
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
|
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
|
-
+
+
-
-
-
+
+
+
-
+
|
(sqlite3:finalize! tdb)
(exit 1))))
(set! kill-tries (+ 1 kill-tries))
(mutex-unlock! m)))
;; (sqlite3:finalize! db)
(if keep-going
(begin
(thread-sleep! (+ 10 (random 10))) ;; add some jitter to the call home time to spread out the db accesses
(thread-sleep! 3) ;; (+ 3 (random 6))) ;; add some jitter to the call home time to spread out the db accesses
(if keep-going
(loop (calc-minutes)))))))))) ;; NOTE: Checking twice for keep-going is intentional
(th1 (make-thread monitorjob "monitor job"))
(th2 (make-thread runit "run job")))
(set! job-thread th2)
(thread-start! th1)
(thread-start! th2)
(thread-join! th2)
(set! keep-going #f)
(thread-join! th1)
(thread-sleep! 1)
(thread-terminate! th1) ;; Not sure if this is a good idea
(thread-sleep! 0.1) ;; give thread th1 a chance to be done TODO: Verify this is needed. At 0.1 I was getting fail to stop, increased to total of 1.1 sec.
;; (thread-sleep! 1)
;; (thread-terminate! th1) ;; Not sure if this is a good idea
(thread-sleep! 1) ;; give thread th1 a chance to be done TODO: Verify this is needed. At 0.1 I was getting fail to stop, increased to total of 1.1 sec.
(mutex-lock! m)
(let* ((item-path (item-list->path itemdat))
(testinfo (cdb:get-test-info-by-id *runremote* test-id))) ;; )) ;; run-id test-name item-path)))
;; Am I completed?
(if (equal? (db:test-get-state testinfo) "RUNNING") ;; (not (equal? (db:test-get-state testinfo) "COMPLETED"))
(if (member (db:test-get-state testinfo) '("REMOTEHOSTSTART" "RUNNING")) ;; NOTE: It should *not* be REMOTEHOSTSTART but for reasons I don't yet understand it sometimes gets stuck in that state ;; (not (equal? (db:test-get-state testinfo) "COMPLETED"))
(let ((new-state (if kill-job? "KILLED" "COMPLETED") ;; (if (eq? (vector-ref exit-info 2) 0) ;; exited with "good" status
;; "COMPLETED"
;; (db:test-get-state testinfo))) ;; else preseve the state as set within the test
)
(new-status (cond
((not (vector-ref exit-info 1)) "FAIL") ;; job failed to run
((eq? rollup-status 0)
|
︙ | | |
︙ | | |
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
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
|
;;
;; NOTE: We run this server-side!! Do not use this global except in the runs:can-run-more-tests routine
;;
(define *last-num-running-tests* 0)
(define *runs:can-run-more-tests-count* 0)
(define (runs:shrink-can-run-more-tests-count) ;; the db is a dummy var so we can use cdb:remote-run
(set! *runs:can-run-more-tests-count* 0)) ;; (/ *runs:can-run-more-tests-count* 2)))
;; Temporary globals. Move these into the logic or into common
;;
(define *seen-cant-run-tests* (make-hash-table)) ;; use to track tests that we suspect cannot be run
(define (runs:inc-cant-run-tests testname)
(hash-table-set! *seen-cant-run-tests* testname
(+ (hash-table-ref/default *seen-cant-run-tests* testname 0) 1)))
(define (runs:can-keep-running? testname n)
(< (hash-table-ref/default *seen-cant-run-tests* testname 0) n))
(define *runs:denoise* (make-hash-table)) ;; key => last-time-ran
(define (runs:lownoise key waitval)
(let ((lasttime (hash-table-ref/default *runs:denoise* key 0))
(currtime (current-seconds)))
(if (> (- currtime lasttime) waitval)
(begin
(hash-table-set! *runs:denoise* key currtime)
#t)
#f)))
(define (runs:can-run-more-tests jobgroup max-concurrent-jobs)
(thread-sleep! (cond
((> *runs:can-run-more-tests-count* 20) 2);; obviously haven't had any work to do for a while
(else 0)))
(let* ((num-running (cdb:remote-run db:get-count-tests-running #f))
(num-running-in-jobgroup (cdb:remote-run db:get-count-tests-running-in-jobgroup #f jobgroup))
(job-group-limit (config-lookup *configdat* "jobgroups" jobgroup)))
(if (> (+ num-running num-running-in-jobgroup) 0)
(set! *runs:can-run-more-tests-count* (+ *runs:can-run-more-tests-count* 1)))
(if (not (eq? *last-num-running-tests* num-running))
(begin
(debug:print 2 "max-concurrent-jobs: " max-concurrent-jobs ", num-running: " num-running)
(set! *last-num-running-tests* num-running)))
(if (not (eq? 0 *globalexitstatus*))
(list #f num-running num-running-in-jobgroup max-concurrent-jobs job-group-limit)
(let ((can-not-run-more (cond
;; if max-concurrent-jobs is set and the number running is greater
;; than it than cannot run more jobs
((and max-concurrent-jobs (>= num-running max-concurrent-jobs))
(if (runs:lownoise "mcj msg" 60)
(debug:print 0 "WARNING: Max running jobs exceeded, current number running: " num-running
", max_concurrent_jobs: " max-concurrent-jobs)
(debug:print 0 "WARNING: Max running jobs exceeded, current number running: " num-running
", max_concurrent_jobs: " max-concurrent-jobs))
#t)
;; if job-group-limit is set and number of jobs in the group is greater
;; than the limit then cannot run more jobs of this kind
((and job-group-limit
(>= num-running-in-jobgroup job-group-limit))
(debug:print 1 "WARNING: number of jobs " num-running-in-jobgroup
" in " jobgroup " exceeded, will not run " (tests:testqueue-get-testname test-record))
|
︙ | | |
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
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
|
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
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
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
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
|
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
|
(define (runs:queue-next-reg tal reg n regfull)
(if regfull
(cdr reg)
(if (null? tal) ;; if tal is null and reg not full then '() as reg contents moved to tal
'()
reg)))
(define runs:nothing-left-in-queue-count 0)
(define (runs:expand-items hed tal reg reruns regfull newtal jobgroup max-concurrent-jobs run-id waitons item-path testmode test-record can-run-more items runname tconfig reglen)
(define (runs:expand-items hed tal reg reruns regfull newtal jobgroup max-concurrent-jobs run-id waitons item-path testmode test-record can-run-more items runname tconfig reglen test-registry)
(let* ((loop-list (list hed tal reg reruns))
(prereqs-not-met (mt:get-prereqs-not-met run-id waitons item-path mode: testmode))
(fails (runs:calc-fails prereqs-not-met))
(non-completed (runs:calc-not-completed prereqs-not-met)))
(debug:print-info 4 "START OF INNER COND #2 "
"\n can-run-more: " can-run-more
"\n testname: " hed
"\n prereqs-not-met: " (runs:pretty-string prereqs-not-met)
"\n non-completed: " (runs:pretty-string non-completed)
"\n fails: " (runs:pretty-string fails)
"\n testmode: " testmode
"\n (eq? testmode 'toplevel): " (eq? testmode 'toplevel)
"\n (null? non-completed): " (null? non-completed)
"\n reruns: " reruns
"\n items: " items
"\n can-run-more: " can-run-more)
(cond
;; all prereqs met, fire off the test
;; or, if it is a 'toplevel test and all prereqs not met are COMPLETED then launch
((member (hash-table-ref/default test-registry (runs:make-full-test-name hed item-path) 'n/a)
'(DONOTRUN removed)) ;; *common:cant-run-states-sym*) ;; '(COMPLETED KILLED WAIVED UNKNOWN INCOMPLETE)) ;; try to catch repeat processing of COMPLETED tests here
(debug:print-info 1 "Test " hed " set to \"" (hash-table-ref test-registry (runs:make-full-test-name hed item-path)) "\". Removing it from the queue")
(if (or (not (null? tal))
(not (null? reg)))
(list (runs:queue-next-hed tal reg reglen regfull)
(runs:queue-next-tal tal reg reglen regfull)
(runs:queue-next-reg tal reg reglen regfull)
reruns)
(begin
(debug:print-info 0 "Nothing left in the queue!")
;; If get here twice then we know we've tried to expand all items
;; since there must be a logic issue with the handling of loops in the
;; items expand phase we will brute force an exit here.
(if (> runs:nothing-left-in-queue-count 2)
(begin
(debug:print 0 "WARNING: this condition is triggered when there were no items to expand and nothing to run. Please check your run for completeness")
(exit 0))
(set! runs:nothing-left-in-queue-count (+ runs:nothing-left-in-queue-count 1)))
#f)))
;;
((or (null? prereqs-not-met)
(and (eq? testmode 'toplevel)
(null? non-completed)))
(debug:print-info 4 "runs:expand-items: (or (null? prereqs-not-met) (and (eq? testmode 'toplevel)(null? non-completed)))")
(let ((test-name (tests:testqueue-get-testname test-record)))
(setenv "MT_TEST_NAME" test-name) ;;
(setenv "MT_RUNNAME" runname)
(set-megatest-env-vars run-id inrunname: runname) ;; these may be needed by the launching process
(let ((items-list (items:get-items-from-config tconfig)))
(if (list? items-list)
(begin
(tests:testqueue-set-items! test-record items-list)
(list hed tal reg reruns))
(begin
(debug:print 0 "ERROR: The proc from reading the setup did not yield a list - please report this")
(exit 1))))))
((null? fails)
(debug:print-info 4 "fails is null, moving on in the queue but keeping " hed " for now")
;; num-retries code was here
;; we use this opportunity to move contents of reg to tal
(list (car newtal)(append (cdr newtal) reg) '() reruns)) ;; an issue with prereqs not yet met?
((and (null? fails)
(not (null? non-completed)))
(let* ((allinqueue (map (lambda (x)(if (string? x) x (db:test-get-testname x)))
(append newtal reruns)))
;; prereqstrs is a list of test names as strings that are prereqs for hed
(prereqstrs (delete-duplicates (map (lambda (x)(if (string? x) x (db:test-get-testname x)))
prereqs-not-met)))
;; a prereq that is not found in allinqueue will be put in the notinqueue list
;;
;; (notinqueue (filter (lambda (x)
;; (not (member x allinqueue)))
;; prereqstrs))
(give-up #f))
;; We can get here when a prereq has not been run due to *it* having a prereq that failed.
;; We need to use this to dequeue this item as CANNOTRUN
(for-each (lambda (prereq)
(if (eq? (hash-table-ref/default test-registry prereq 'justfine) 'CANNOTRUN)
(set! give-up #t)))
prereqstrs)
(if (and give-up
(not (and (null? tal)(null? reg))))
(begin
(debug:print 1 "WARNING: test " hed " has no discarded prerequisites, removing it from the queue")
(list (runs:queue-next-hed tal reg reglen regfull)
(runs:queue-next-tal tal reg reglen regfull)
(runs:queue-next-reg tal reg reglen regfull)
reruns))
(list (car newtal)(append (cdr newtal) reg) '() reruns))))
;; (debug:print-info 1 "allinqueue: " allinqueue)
;; (debug:print-info 1 "prereqstrs: " prereqstrs)
;; (debug:print-info 1 "notinqueue: " notinqueue)
;; (debug:print-info 1 "tal: " tal)
;; (debug:print-info 1 "newtal: " newtal)
;; (debug:print-info 1 "reg: " reg)
;; == == ;; num-retries code was here
;; == == ;; we use this opportunity to move contents of reg to tal
;; == == ;; but also lets check that the prerequisites are all in the newtal or reruns lists
;; == ==
;; == == (let* ((allinqueue (map (lambda (x)(if (string? x) x (db:test-get-testname x)))
;; == == (append newtal reruns)))
;; == == ;; prereqstrs is a list of test names as strings that are prereqs for hed
;; == == (prereqstrs (map (lambda (x)(if (string? x) x (db:test-get-testname x)))
;; == == prereqs-not-met))
;; == == ;; a prereq that is not found in allinqueue will be put in the notinqueue list
;; == == ;;
;; == == (notinqueue (filter (lambda (x)
;; == == (not (member x allinqueue)))
;; == == prereqstrs)))
;; == == (if (not (null? notinqueue))
;; == == (if (runs:can-keep-running? hed 5) ;; try five times
;; == == (begin
;; == == (debug:print-info 4 "increment cant-run-tests for " hed)
;; == == (runs:inc-cant-run-tests hed)
;; == == (list (car newtal)(append (cdr newtal) reg) '() reruns))
;; == == (begin
;; == ==
;; == == (if (runs:lownoise (conc "no fails prereq, null notinqueue " hed) 30)
;; == == (begin
;; == == (debug:print 1 "WARNING: test " hed " has no failed prerequisites but does have prerequistes that are NOT in the queue: " (string-intersperse notinqueue ", "))
;; == == (debug:print-info 4 "allinqueue: " allinqueue)
;; == == (debug:print-info 4 "prereqstrs: " prereqstrs)
;; == == (debug:print-info 4 "notinqueue: " notinqueue)))
;; == == (if (and (null? tal)(null? reg))
;; == == (list (car newtal)(append (cdr newtal) reg) '() reruns)
;; == == (list (runs:queue-next-hed tal reg reglen regfull)
;; == == (runs:queue-next-tal tal reg reglen regfull)
;; == == (runs:queue-next-reg tal reg reglen regfull)
;; == == reruns))))
;; == == ;; have prereqs in queue, keep going.
;; == == (begin
;; == == (if (runs:lownoise (conc "no fails prereq " hed) 30)
;; == == (debug:print-info 1 "no fails in prerequisites for " hed ", waiting on tests; "
;; == == (string-intersperse (map (lambda (x)
;; == == (if (string? x)
;; == == x
;; == == (runs:make-full-test-name (db:test-get-testname x)
;; == == (db:test-get-item-path x))))
;; == == non-completed) ", ")
;; == == ". Delaying launch of " hed "."))
;; == == (list (car newtal)(append (cdr newtal) reg) '() reruns))))) ;; an issue with prereqs not yet met?
((and (null? fails)
(null? non-completed))
(if (runs:can-keep-running? hed 5)
(begin
(runs:inc-cant-run-tests hed)
(debug:print-info 1 "no fails in prerequisites for " hed " but also none running, keeping " hed " for now. Try count: " (hash-table-ref/default *seen-cant-run-tests* hed 0))
;; num-retries code was here
;; we use this opportunity to move contents of reg to tal
(list (car newtal)(append (cdr newtal) reg) '() reruns)) ;; an issue with prereqs not yet met?
(begin
(debug:print-info 1 "no fails in prerequisites for " hed " but nothing seen running in a while, dropping test " hed " from the run queue")
(list (runs:queue-next-hed tal reg reglen regfull)
(runs:queue-next-tal tal reg reglen regfull)
(runs:queue-next-reg tal reg reglen regfull)
reruns))))
((and (not (null? fails))(eq? testmode 'normal))
(debug:print-info 1 "test " hed " (mode=" testmode ") has failed prerequisite(s); "
(string-intersperse (map (lambda (t)(conc (db:test-get-testname t) ":" (db:test-get-state t)"/"(db:test-get-status t))) fails) ", ")
", removing it from to-do list")
(if (or (not (null? reg))(not (null? tal)))
(begin
(hash-table-set! test-registry hed 'CANNOTRUN)
(list (runs:queue-next-hed tal reg reglen regfull)
(runs:queue-next-tal tal reg reglen regfull)
(runs:queue-next-reg tal reg reglen regfull)
(cons hed reruns))
(list (runs:queue-next-hed tal reg reglen regfull)
(runs:queue-next-tal tal reg reglen regfull)
(runs:queue-next-reg tal reg reglen regfull)
(cons hed reruns)))
#f)) ;; #f flags do not loop
((and (not (null? fails))(eq? testmode 'toplevel))
(if (or (not (null? reg))(not (null? tal)))
(list (car newtal)(append (cdr newtal) reg) '() reruns)
#f))
(else
(debug:print 4 "ERROR: No handler for this condition.")
(list (car newtal)(cdr newtal) reg reruns)))))
(debug:print 1 "WARNING: FAILS or incomplete tests are preventing completion of this run. Dropping test " hed " from the run queue")
(list (runs:queue-next-hed tal reg reglen regfull)
(runs:queue-next-tal tal reg reglen regfull)
(runs:queue-next-reg tal reg reglen regfull)
reruns))))) ;; (list (car newtal)(cdr newtal) reg reruns)))))
(define (runs:mixed-list-testname-and-testrec->list-of-strings inlst)
(map (lambda (t)
(cond
((vector? t)
(conc (db:test-get-state t) "/" (db:test-get-status t)))
((string? t)
t)
(else
(conc t))))
inlst))
(define (runs:process-expanded-tests hed tal reg reruns reglen regfull test-record runname test-name item-path jobgroup max-concurrent-jobs run-id waitons item-path testmode test-patts required-tests test-registry registry-mutex flags keyvals run-info newtal all-tests-registry)
(let* ((run-limits-info (runs:can-run-more-tests jobgroup max-concurrent-jobs)) ;; look at the test jobgroup and tot jobs running
(have-resources (car run-limits-info))
(num-running (list-ref run-limits-info 1))
(num-running-in-jobgroup (list-ref run-limits-info 2))
(num-running-in-jobgroup (list-ref run-limits-info 2))
(max-concurrent-jobs (list-ref run-limits-info 3))
(job-group-limit (list-ref run-limits-info 4))
(prereqs-not-met (mt:get-prereqs-not-met run-id waitons item-path mode: testmode))
(fails (runs:calc-fails prereqs-not-met))
(non-completed (runs:calc-not-completed prereqs-not-met))
(loop-list (list hed tal reg reruns)))
(debug:print-info 4 "have-resources: " have-resources " prereqs-not-met: ("
(string-intersperse
(map (lambda (t)
(if (vector? t)
(conc (db:test-get-state t) "/" (db:test-get-status t))
(conc " WARNING: t is not a vector=" t )))
prereqs-not-met) ", ") ") fails: " fails)
(if (not (null? prereqs-not-met))
(debug:print-info 1 "waiting on tests; " (string-intersperse (runs:mixed-list-testname-and-testrec->list-of-strings prereqs-not-met) ", ")))
;; Don't know at this time if the test have been launched at some time in the past
;; i.e. is this a re-launch?
(debug:print-info 4 "run-limits-info = " run-limits-info)
(cond
;; Check item path against item-patts,
|
︙ | | |
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
|
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
|
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
|
reruns)
#f))
;; Register tests
;;
((not (hash-table-ref/default test-registry (runs:make-full-test-name test-name item-path) #f))
(debug:print-info 4 "Pre-registering test " test-name "/" item-path " to create placeholder" )
(if (eq? *transport-type* 'fs) ;; no point in parallel registration if use fs
(begin
(cdb:tests-register-test *runremote* run-id test-name item-path)
(hash-table-set! test-registry (runs:make-full-test-name test-name item-path) 'done))
(let ((th (make-thread (lambda ()
(mutex-lock! registry-mutex)
(hash-table-set! test-registry (runs:make-full-test-name test-name item-path) 'start)
(mutex-unlock! registry-mutex)
;; If haven't done it before register a top level test if this is an itemized test
(if (not (eq? (hash-table-ref/default test-registry (runs:make-full-test-name test-name "") #f) 'done))
(cdb:tests-register-test *runremote* run-id test-name ""))
(cdb:tests-register-test *runremote* run-id test-name item-path)
(mutex-lock! registry-mutex)
(hash-table-set! test-registry (runs:make-full-test-name test-name item-path) 'done)
(mutex-unlock! registry-mutex))
(conc test-name "/" item-path))))
(thread-start! th))
(let ((th (make-thread (lambda ()
(mutex-lock! registry-mutex)
(hash-table-set! test-registry (runs:make-full-test-name test-name item-path) 'start)
(mutex-unlock! registry-mutex)
;; If haven't done it before register a top level test if this is an itemized test
(if (not (eq? (hash-table-ref/default test-registry (runs:make-full-test-name test-name "") #f) 'done))
(cdb:tests-register-test *runremote* run-id test-name ""))
(cdb:tests-register-test *runremote* run-id test-name item-path)
(mutex-lock! registry-mutex)
(hash-table-set! test-registry (runs:make-full-test-name test-name item-path) 'done)
(mutex-unlock! registry-mutex))
(conc test-name "/" item-path))))
(thread-start! th)))
(runs:shrink-can-run-more-tests-count) ;; DELAY TWEAKER (still needed?)
(if (and (null? tal)(null? reg))
(list hed tal (append reg (list hed)) reruns)
(list (runs:queue-next-hed tal reg reglen regfull)
(runs:queue-next-tal tal reg reglen regfull)
;; NB// Here we are building reg as we register tests
;; if regfull we must pop the front item off reg
|
︙ | | |
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
|
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
|
+
-
+
|
", "))
(thread-sleep! 0.1)
(list hed tal reg reruns))
;; If no resources are available just kill time and loop again
;;
((not have-resources) ;; simply try again after waiting a second
(if (runs:lownoise "no resources" 60)
(debug:print-info 1 "no resources to run new tests, waiting ...")
(debug:print-info 1 "no resources to run new tests, waiting ..."))
;; Have gone back and forth on this but db starvation is an issue.
;; wait one second before looking again to run jobs.
(thread-sleep! 1)
;; could have done hed tal here but doing car/cdr of newtal to rotate tests
(list (car newtal)(cdr newtal) reg reruns))
;; This is the final stage, everything is in place so launch the test
|
︙ | | |
513
514
515
516
517
518
519
520
521
522
523
524
525
526
|
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
|
+
+
+
+
|
;; must be we have unmet prerequisites
;;
(else
(debug:print 4 "FAILS: " fails)
;; If one or more of the prereqs-not-met are FAIL then we can issue
;; a message and drop hed from the items to be processed.
(if (not (null? prereqs-not-met))
(debug:print-info 1 "waiting on tests; " (string-intersperse prereqs-not-met ", ")))
(if (null? fails)
(begin
;; couldn't run, take a breather
(debug:print-info 0 "Waiting for more work to do...")
(thread-sleep! 1)
(list (car newtal)(cdr newtal) reg reruns))
;; the waiton is FAIL so no point in trying to run hed ever again
|
︙ | | |
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
|
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
|
+
-
+
+
+
+
+
+
+
+
+
-
+
-
+
+
-
+
|
;; Initialize the test-registery hash with tests that already have a record
;; convert state to symbol and use that as the hash value
(for-each (lambda (trec)
(let ((id (db:test-get-id trec))
(tn (db:test-get-testname trec))
(ip (db:test-get-item-path trec))
(st (db:test-get-state trec)))
(if (not (equal? st "DELETED"))
(hash-table-set! test-registry (runs:make-full-test-name tn ip) (string->symbol st))))
(hash-table-set! test-registry (runs:make-full-test-name tn ip) (string->symbol st)))))
tests-info)
(set! max-retries (if (and max-retries (string->number max-retries))(string->number max-retries) 100))
(let loop ((hed (car sorted-test-names))
(tal (cdr sorted-test-names))
(reg '()) ;; registered, put these at the head of tal
(reruns '()))
(if (not (null? reruns))(debug:print-info 4 "reruns=" reruns))
;; (print "Top of loop, hed=" hed ", tal=" tal " ,reruns=" reruns)
(let* ((test-record (hash-table-ref test-records hed))
(test-name (tests:testqueue-get-testname test-record))
(tconfig (tests:testqueue-get-testconfig test-record))
(jobgroup (config-lookup tconfig "requirements" "jobgroup"))
(testmode (let ((m (config-lookup tconfig "requirements" "mode")))
(if m (string->symbol m) 'normal)))
(waitons (tests:testqueue-get-waitons test-record))
(priority (tests:testqueue-get-priority test-record))
(itemdat (tests:testqueue-get-itemdat test-record)) ;; itemdat can be a string, list or #f
(items (tests:testqueue-get-items test-record))
(item-path (item-list->path itemdat))
(tfullname (runs:make-full-test-name test-name item-path))
(newtal (append tal (list hed)))
(regfull (>= (length reg) reglen)))
;; Ensure all top level tests get registered. This way they show up as "NOT_STARTED" on the dashboard
;; and it is clear they *should* have run but did not.
(if (not (hash-table-ref/default test-registry (runs:make-full-test-name test-name "") #f))
(begin
(cdb:tests-register-test *runremote* run-id test-name "")
(hash-table-set! test-registry (runs:make-full-test-name test-name "") 'done)))
;; Fast skip of tests that are already "COMPLETED"
;; Fast skip of tests that are already "COMPLETED" - NO! Cannot do that as the items may not have been expanded yet :(
;;
(if (equal? (hash-table-ref/default test-registry tfullname #f) 'COMPLETED)
(if (member (hash-table-ref/default test-registry tfullname #f)
'(DONOTRUN removed)) ;; *common:cant-run-states-sym*) ;; '(COMPLETED KILLED WAIVED UNKNOWN INCOMPLETE))
(begin
(debug:print-info 0 "Skipping COMPLETED test " tfullname)
(debug:print-info 0 "Skipping test " tfullname " as it has been marked do not run due to being completed or not runnable")
(if (or (not (null? tal))(not (null? reg)))
(loop (runs:queue-next-hed tal reg reglen regfull)
(runs:queue-next-tal tal reg reglen regfull)
(runs:queue-next-reg tal reg reglen regfull)
reruns))))
;; (loop (car tal)(cdr tal) reg reruns))))
|
︙ | | |
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
|
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
|
-
+
|
;; if items is a proc then need to run items:get-items-from-config, get the list and loop
;; - but only do that if resources exist to kick off the job
;; EXPAND ITEMS
((or (procedure? items)(eq? items 'have-procedure))
(let ((can-run-more (runs:can-run-more-tests jobgroup max-concurrent-jobs)))
(if (and (list? can-run-more)
(car can-run-more))
(let ((loop-list (runs:expand-items hed tal reg reruns regfull newtal jobgroup max-concurrent-jobs run-id waitons item-path testmode test-record can-run-more items runname tconfig reglen)))
(let ((loop-list (runs:expand-items hed tal reg reruns regfull newtal jobgroup max-concurrent-jobs run-id waitons item-path testmode test-record can-run-more items runname tconfig reglen test-registry)))
(if loop-list
(apply loop loop-list)))
;; if can't run more just loop with next possible test
(loop (car newtal)(cdr newtal) reg reruns))))
;; this case should not happen, added to help catch any bugs
((and (list? items) itemdat)
|
︙ | | |
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
|
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
|
-
+
-
+
|
(force (set! runflag #t))
;; NOT_STARTED, run no matter what
((member (test:get-state testdat) '("DELETED" "NOT_STARTED"))(set! runflag #t))
;; not -rerun and PASS, WARN or CHECK, do no run
((and (or (not rerun)
keepgoing)
;; Require to force re-run for COMPLETED or *anything* + PASS,WARN or CHECK
(or (member (test:get-status testdat) '("PASS" "WARN" "CHECK" "SKIP"))
(or (member (test:get-status testdat) '("PASS" "WARN" "CHECK" "SKIP" "WAIVED"))
(member (test:get-state testdat) '("COMPLETED"))))
(debug:print-info 2 "running test " test-name "/" item-path " suppressed as it is " (test:get-state testdat) " and " (test:get-status testdat))
(hash-table-set! test-registry full-test-name 'COMPLETED)
(hash-table-set! test-registry full-test-name 'DONOTRUN) ;; COMPLETED)
(set! runflag #f))
;; -rerun and status is one of the specifed, run it
((and rerun
(let* ((rerunlst (string-split rerun ","))
(must-rerun (member (test:get-status testdat) rerunlst)))
(debug:print-info 3 "-rerun list: " rerun ", test-status: " (test:get-status testdat)", must-rerun: " must-rerun)
must-rerun))
|
︙ | | |
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
|
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
|
-
+
+
+
-
+
+
+
+
+
+
|
(debug:print-info 1 "SKIPPING Test " full-test-name " due to " skip-test))
(if (not (launch-test test-id run-id run-info keyvals runname test-conf test-name test-path itemdat flags))
(begin
(print "ERROR: Failed to launch the test. Exiting as soon as possible")
(set! *globalexitstatus* 1) ;;
(process-signal (current-process-id) signal/kill))))))))
((KILLED)
(debug:print 1 "NOTE: " full-test-name " is already running or was explictly killed, use -force to launch it."))
(debug:print 1 "NOTE: " full-test-name " is already running or was explictly killed, use -force to launch it.")
(hash-table-set! test-registry (runs:make-full-test-name test-name test-path) 'DONOTRUN)) ;; KILLED))
((LAUNCHED REMOTEHOSTSTART RUNNING)
(if (> (- (current-seconds)(+ (db:test-get-event_time testdat)
(db:test-get-run_duration testdat)))
600) ;; i.e. no update for more than 600 seconds
(begin
(debug:print 0 "WARNING: Test " test-name " appears to be dead. Forcing it to state INCOMPLETE and status STUCK/DEAD")
(tests:test-set-status! test-id "INCOMPLETE" "STUCK/DEAD" "Test is stuck or dead" #f))
(debug:print 2 "NOTE: " test-name " is already running")))
(else
(else (debug:print 0 "ERROR: Failed to launch test " full-test-name ". Unrecognised state " (test:get-state testdat)))))))
(debug:print 0 "ERROR: Failed to launch test " full-test-name ". Unrecognised state " (test:get-state testdat))
(case (string->symbol (test:get-state testdat))
((COMPLETED INCOMPLETE)
(hash-table-set! test-registry (runs:make-full-test-name test-name test-path) 'DONOTRUN))
(else
(hash-table-set! test-registry (runs:make-full-test-name test-name test-path) 'DONOTRUN))))))))
;;======================================================================
;; END OF NEW STUFF
;;======================================================================
(define (get-dir-up-n dir . params)
(let ((dparts (string-split dir "/"))
|
︙ | | |
︙ | | |
276
277
278
279
280
281
282
283
284
285
286
287
288
289
|
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
+
+
+
|
(if (null? tal)
#t
(loop (car tal)(cdr tal)))
#f))))))
(pop-directory)
result)))))
(define (tests:test-force-state-status! test-id state status)
(cdb:test-set-status-state *runremote* test-id status state #f)
(mt:process-triggers test-id state status))
;; Do not rpc this one, do the underlying calls!!!
(define (tests:test-set-status! test-id state status comment dat #!key (work-area #f))
(debug:print-info 4 "tests:test-set-status! test-id=" test-id ", state=" state ", status=" status ", dat=" dat)
(let* ((db #f)
(real-status status)
(otherdat (if dat dat (make-hash-table)))
|
︙ | | |
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
|
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
|
+
-
+
|
;; 2. logf is same as outputfilename
(let* ((outputfilename (conc "megatest-rollup-" test-name ".html"))
(orig-dir (current-directory))
(logf-info (cdb:remote-run db:test-get-logfile-info #f run-id test-name))
(logf (if logf-info (cadr logf-info) #f))
(path (if logf-info (car logf-info) #f)))
;; This query finds the path and changes the directory to it for the test
(if (and (string? path)
(if (directory? path)
(directory? path)) ;; can get #f here under some wierd conditions. why, unknown ...
(begin
(debug:print 4 "Found path: " path)
(change-directory path))
;; (set! outputfilename (conc path "/" outputfilename)))
(print "No such path: " path))
(debug:print 4 "summarize-items with logf " logf ", outputfilename " outputfilename " and force " force)
(if (or (equal? logf "logs/final.log")
|
︙ | | |
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
|
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
|
-
-
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
|
(waitons (tests:testqueue-get-waitons test-record))
(keep-test #t)
(test-id (cdb:remote-run db:get-test-id #f run-id test-name item-path))
(tdat (cdb:get-test-info-by-id *runremote* test-id)))
(if tdat
(begin
;; Look at the test state and status
(if (or (member (db:test-get-status tdat)
'("PASS" "WARN" "WAIVED" "CHECK" "SKIP"))
(if (or (and (member (db:test-get-status tdat)
'("PASS" "WARN" "WAIVED" "CHECK" "SKIP"))
(equal? (db:test-get-state tdat) "COMPLETED"))
(member (db:test-get-state tdat)
'("INCOMPLETE" "KILLED")))
'("INCOMPLETE" "KILLED")))
(set! keep-test #f))
;; examine waitons for any fails. If it is FAIL or INCOMPLETE then eliminate this test
;; from the runnable list
(if keep-test
(for-each (lambda (waiton)
;; for now we are waiting only on the parent test
(let* ((parent-test-id (cdb:remote-run db:get-test-id #f run-id waiton ""))
(wtdat (cdb:get-test-info-by-id *runremote* test-id)))
(if (or (member (db:test-get-status wtdat)
'("FAIL" "KILLED"))
(member (db:test-get-state wtdat)
'("INCOMPETE")))
(wtdat (cdb:get-test-info-by-id *runremote* test-id)))
(if (or (and (equal? (db:test-get-state wtdat) "COMPLETED")
(member (db:test-get-status wtdat) '("FAIL")))
(member (db:test-get-status wtdat) '("KILLED"))
(member (db:test-get-state wtdat) '("INCOMPETE")))
;; (if (or (member (db:test-get-status wtdat)
;; '("FAIL" "KILLED"))
;; (member (db:test-get-state wtdat)
;; '("INCOMPETE")))
(set! keep-test #f)))) ;; no point in running this one again
waitons))))
(if keep-test (set! runnables (cons testkeyname runnables)))))
testkeynames)
runnables))
;;======================================================================
|
︙ | | |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
-
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
-
+
-
-
-
+
|
(http://www.gnumeric.org/v10.dtd:Sheet
(@ (Visibility "GNM_SHEET_VISIBILITY_VISIBLE")
(OutlineSymbolsRight "1")
(OutlineSymbolsBelow "1")
(HideZero "0")
(HideRowHeader "0")
(HideGrid "0")
(HideColHeader "0")
(GridColor "0:0:0")
(DisplayOutlines "1")
(DisplayFormulas "0"))
(http://www.gnumeric.org/v10.dtd:MaxCol "8")
(http://www.gnumeric.org/v10.dtd:MaxRow "18")
(http://www.gnumeric.org/v10.dtd:MaxRow "19")
(http://www.gnumeric.org/v10.dtd:Zoom "1")
(http://www.gnumeric.org/v10.dtd:Names
(http://www.gnumeric.org/v10.dtd:Name
(http://www.gnumeric.org/v10.dtd:name "Print_Area")
(http://www.gnumeric.org/v10.dtd:value "#REF!")
(http://www.gnumeric.org/v10.dtd:name "Sheet_Title")
(http://www.gnumeric.org/v10.dtd:value "\"First_Sheet\"")
(http://www.gnumeric.org/v10.dtd:position "A1"))
(http://www.gnumeric.org/v10.dtd:Name
(http://www.gnumeric.org/v10.dtd:name "Sheet_Title")
(http://www.gnumeric.org/v10.dtd:value "\"First_Sheet\"")
(http://www.gnumeric.org/v10.dtd:name "Print_Area")
(http://www.gnumeric.org/v10.dtd:value "#REF!")
(http://www.gnumeric.org/v10.dtd:position "A1")))
(http://www.gnumeric.org/v10.dtd:PrintInformation
(http://www.gnumeric.org/v10.dtd:Margins
(http://www.gnumeric.org/v10.dtd:top
(@ (PrefUnit "mm") (Points "93.26")))
(http://www.gnumeric.org/v10.dtd:bottom
(@ (PrefUnit "mm") (Points "93.26")))
(http://www.gnumeric.org/v10.dtd:left (@ (PrefUnit "mm") (Points "72")))
(http://www.gnumeric.org/v10.dtd:right (@ (PrefUnit "mm") (Points "72")))
(http://www.gnumeric.org/v10.dtd:left (@ (PrefUnit "Pt") (Points "72")))
(http://www.gnumeric.org/v10.dtd:right (@ (PrefUnit "Pt") (Points "72")))
(http://www.gnumeric.org/v10.dtd:header
(@ (PrefUnit "mm") (Points "72")))
(@ (PrefUnit "Pt") (Points "72")))
(http://www.gnumeric.org/v10.dtd:footer
(@ (PrefUnit "mm") (Points "72"))))
(@ (PrefUnit "Pt") (Points "72"))))
(http://www.gnumeric.org/v10.dtd:Scale
(@ (type "percentage") (percentage "100")))
(http://www.gnumeric.org/v10.dtd:vcenter (@ (value "0")))
(http://www.gnumeric.org/v10.dtd:hcenter (@ (value "0")))
(http://www.gnumeric.org/v10.dtd:grid (@ (value "0")))
(http://www.gnumeric.org/v10.dtd:even_if_only_styles (@ (value "0")))
(http://www.gnumeric.org/v10.dtd:monochrome (@ (value "0")))
(http://www.gnumeric.org/v10.dtd:draft (@ (value "0")))
(http://www.gnumeric.org/v10.dtd:titles (@ (value "0")))
(http://www.gnumeric.org/v10.dtd:do_not_print (@ (value "0")))
(http://www.gnumeric.org/v10.dtd:print_range (@ (value "0")))
(http://www.gnumeric.org/v10.dtd:order "d_then_r")
(http://www.gnumeric.org/v10.dtd:orientation "portrait")
(http://www.gnumeric.org/v10.dtd:Header
(@ (Right "") (Middle "&[tab]") (Left "")))
(http://www.gnumeric.org/v10.dtd:Footer
(@ (Right "") (Middle "&[page]") (Left "")))
(http://www.gnumeric.org/v10.dtd:paper "na_letter")
(http://www.gnumeric.org/v10.dtd:paper "na_letter"))
(http://www.gnumeric.org/v10.dtd:comments "in_place")
(http://www.gnumeric.org/v10.dtd:errors "as_displayed"))
(http://www.gnumeric.org/v10.dtd:Styles
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "0") (startCol "0") (endRow "0") (endCol "1"))
(@ (startRow "4096") (startCol "0") (endRow "65535") (endCol "63"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
|
︙ | | |
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
-
-
+
+
-
-
+
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
+
-
-
-
-
-
-
-
+
+
-
+
|
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")))
(http://www.gnumeric.org/v10.dtd:StyleRegion
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(@ (startRow "1") (startCol "0") (endRow "17") (endCol "1"))
(http://www.gnumeric.org/v10.dtd:Style
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
(Locked "1")
(Indent "0")
(Hidden "0")
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(HAlign "1")
(Format "hh\":\"mm\":\"ss AM/PM")
(Fore "0:0:0")
(Back "FFFF:FFFF:FFFF"))
(http://www.gnumeric.org/v10.dtd:Font
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "18") (startCol "0") (endRow "31") (endCol "2"))
(@ (startRow "0") (startCol "4") (endRow "255") (endCol "15"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
|
︙ | | |
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
-
+
+
+
+
+
+
+
+
-
+
|
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")))
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "32") (startCol "0") (endRow "255") (endCol "7"))
(@ (startRow "32") (startCol "0") (endRow "255") (endCol "3"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
|
︙ | | |
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
|
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
-
-
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
+
-
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
|
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")))
(http://www.gnumeric.org/v10.dtd:StyleRegion
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(@ (startRow "256") (startCol "0") (endRow "65535") (endCol "63"))
(http://www.gnumeric.org/v10.dtd:Style
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
(Locked "1")
(Indent "0")
(Hidden "0")
(HAlign "1")
(Format "General")
(Fore "0:0:0")
(Back "FFFF:FFFF:FFFF"))
(http://www.gnumeric.org/v10.dtd:Font
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
"Sans")))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(@ (startRow "0") (startCol "2") (endRow "1") (endCol "2"))
(http://www.gnumeric.org/v10.dtd:Style
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
(Locked "1")
(Indent "0")
(Hidden "0")
(HAlign "1")
(Format "General")
(Fore "0:0:0")
(Back "FFFF:FFFF:FFFF"))
(http://www.gnumeric.org/v10.dtd:Font
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "2") (startCol "2") (endRow "17") (endCol "2"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
|
︙ | | |
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
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
|
-
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")))
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "0") (startCol "3") (endRow "31") (endCol "7"))
(@ (startRow "0") (startCol "3") (endRow "31") (endCol "3"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
(Locked "1")
(Indent "0")
(Hidden "0")
(HAlign "1")
(Format "General")
(Fore "0:0:0")
(Back "FFFF:FFFF:FFFF"))
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "1") (startCol "0") (endRow "17") (endCol "1"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
(Locked "1")
(Indent "0")
(Hidden "0")
(HAlign "1")
(Format "hh\":\"mm\":\"ss AM/PM")
(Fore "0:0:0")
(Back "FFFF:FFFF:FFFF"))
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "18") (startCol "0") (endRow "31") (endCol "2"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
(Locked "1")
(Indent "0")
(Hidden "0")
(HAlign "1")
(Format "General")
(Fore "0:0:0")
(Back "FFFF:FFFF:FFFF"))
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "0") (startCol "16") (endRow "4095") (endCol "63"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
|
︙ | | |
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
-
+
+
+
+
+
+
+
+
-
+
|
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")))
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "0") (startCol "8") (endRow "255") (endCol "63"))
(@ (startRow "0") (startCol "2") (endRow "1") (endCol "2"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
|
︙ | | |
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
|
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
|
-
+
+
+
+
+
+
+
+
|
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")))
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "0") (startCol "64") (endRow "65535") (endCol "255"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
|
︙ | | |
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
|
347
348
349
350
351
352
353
354
355
356
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
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
|
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
+
-
+
-
+
+
-
-
+
+
+
+
+
-
+
+
-
+
-
+
+
|
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans"))))
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "256") (startCol "0") (endRow "4095") (endCol "15"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
(Locked "1")
(Indent "0")
(Hidden "0")
(HAlign "1")
(Format "General")
(Fore "0:0:0")
(Back "FFFF:FFFF:FFFF"))
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0"))))))
(http://www.gnumeric.org/v10.dtd:StyleRegion
(@ (startRow "0") (startCol "0") (endRow "0") (endCol "1"))
(http://www.gnumeric.org/v10.dtd:Style
(@ (WrapText "0")
(VAlign "2")
(ShrinkToFit "0")
(Shade "0")
(Rotation "0")
(PatternColor "0:0:0")
(Locked "1")
(Indent "0")
(Hidden "0")
(HAlign "1")
(Format "General")
(Fore "0:0:0")
(Back "FFFF:FFFF:FFFF"))
(http://www.gnumeric.org/v10.dtd:Font
(@ (Unit "10")
(Underline "0")
(StrikeThrough "0")
(Script "0")
(Italic "0")
(Bold "0"))
"Sans")
(http://www.gnumeric.org/v10.dtd:StyleBorder
(http://www.gnumeric.org/v10.dtd:Top (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Bottom (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Left (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Right (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Diagonal (@ (Style "0")))
(http://www.gnumeric.org/v10.dtd:Rev-Diagonal (@ (Style "0")))))))
(http://www.gnumeric.org/v10.dtd:Cols
(@ (DefaultSizePts "48"))
(http://www.gnumeric.org/v10.dtd:ColInfo (@ (Unit "48") (No "0")))
(http://www.gnumeric.org/v10.dtd:ColInfo
(@ (Unit "48") (No "0") (MarginB "2") (MarginA "2")))
(http://www.gnumeric.org/v10.dtd:ColInfo
(@ (Unit "99") (No "1") (HardSize "1")))
(@ (Unit "99") (No "1") (MarginB "2") (MarginA "2") (HardSize "1")))
(http://www.gnumeric.org/v10.dtd:ColInfo
(@ (Unit "64.01") (No "2") (Count "7"))))
(@ (Unit "64.01") (No "2") (MarginB "2") (MarginA "2") (Count "7"))))
(http://www.gnumeric.org/v10.dtd:Rows
(@ (DefaultSizePts "12.1"))
(http://www.gnumeric.org/v10.dtd:RowInfo (@ (Unit "12.64") (No "0")))
(http://www.gnumeric.org/v10.dtd:RowInfo
(@ (Unit "12.64") (No "0") (MarginB "0") (MarginA "0")))
(http://www.gnumeric.org/v10.dtd:RowInfo
(@ (Unit "13.5") (No "1") (Count "17")))
(http://www.gnumeric.org/v10.dtd:RowInfo (@ (Unit "12.1") (No "18"))))
(@ (Unit "13.5") (No "1") (MarginB "0") (MarginA "0") (Count "17")))
(http://www.gnumeric.org/v10.dtd:RowInfo
(@ (Unit "12.1") (No "18") (MarginB "0") (MarginA "0") (Count "2"))))
(http://www.gnumeric.org/v10.dtd:Selections
(@ (CursorRow "3") (CursorCol "1"))
(http://www.gnumeric.org/v10.dtd:Selection
(@ (startRow "3") (startCol "1") (endRow "3") (endCol "1"))))
(http://www.gnumeric.org/v10.dtd:SheetLayout
(@ (TopLeft "A2"))
(http://www.gnumeric.org/v10.dtd:FreezePanes
(@ (UnfrozenTopLeft "A2") (FrozenTopLeft "A1"))))
(http://www.gnumeric.org/v10.dtd:Solver
(@ (ShowIter "0")
(SensitivityR "0")
(@ (ProgramR "0")
(ProgramR "0")
(ProblemType "0")
(PerformR "0")
(NonNeg "1")
(ModelType "0")
(MaxTime "60")
(MaxIter "1000")
(LimitsR "0")
(Discr "0")
(AutoScale "0"))))
(AutoScale "0")
(AnswerR "0"))))
|