Index: db.scm ================================================================== --- db.scm +++ db.scm @@ -3266,26 +3266,21 @@ ;;====================================================================== ;; M I S C M A N A G E M E N T I T E M S ;;====================================================================== ;; A routine to map itempaths using a itemmap -(define (db:compare-itempaths patha pathb itemmap) - (debug:print-info 6 "ITEMMAP is " itemmap) - (if itemmap - (let ((pathb-mapped (db:multi-pattern-apply pathb itemmap))) - (debug:print-info 6 "ITEMMAP is " itemmap ", path: " pathb ", mapped path: " pathb-mapped) - (equal? patha pathb-mapped)) - (equal? patha pathb))) - -;; (let* ((mapparts (string-split itemmap)) -;; (pattern (car mapparts)) -;; (replacement (if (> (length mapparts) 1) (cadr mapparts) ""))) -;; (if replacement -;; (equal? (string-substitute pattern replacement patha) -;; (string-substitute pattern replacement pathb)) -;; (equal? (string-substitute pattern "" patha) -;; (string-substitute pattern "" pathb)))) +;; patha and pathb must be strings or this will fail +;; +(define (db:compare-itempaths patha pathb itemmaps) + (debug:print-info 6 "ITEMMAPS: " itemmaps) + (let* ((testname-a (car (string-split patha "/"))) + (itemmap (tests:lookup-itemmap itemmaps testname-a))) + (if itemmap + (let ((pathb-mapped (db:multi-pattern-apply pathb itemmap))) + (debug:print-info 6 "ITEMMAP is " itemmap ", path: " pathb ", mapped path: " pathb-mapped) + (equal? patha pathb-mapped)) + (equal? patha pathb)))) ;; A routine to convert test/itempath using a itemmap ;; NOTE: to process only an itempath (i.e. no prepended testname) ;; just call db:multi-pattern-apply ;; @@ -3329,11 +3324,11 @@ ;; Note: mode 'normal means that tests must be COMPLETED and ok (i.e. PASS, WARN, CHECK, SKIP or WAIVED) ;; mode 'toplevel means that tests must be COMPLETED only ;; mode 'itemmatch or 'itemwait means that tests items must be COMPLETED and (PASS|WARN|WAIVED|CHECK) [[ NB// NOT IMPLEMENTED YET ]] ;; ;; (define (db:get-prereqs-not-met dbstruct run-id waitons ref-item-path mode) -(define (db:get-prereqs-not-met dbstruct run-id waitons ref-item-path mode itemmap) ;; #!key (mode '(normal))(itemmap #f)) +(define (db:get-prereqs-not-met dbstruct run-id waitons ref-item-path mode itemmaps) ;; #!key (mode '(normal))(itemmap #f)) (if (or (not waitons) (null? waitons)) '() (let* ((unmet-pre-reqs '()) (result '())) @@ -3354,11 +3349,11 @@ (item-path (db:test-get-item-path test)) (is-completed (equal? state "COMPLETED")) (is-running (equal? state "RUNNING")) (is-killed (equal? state "KILLED")) (is-ok (member status '("PASS" "WARN" "CHECK" "WAIVED" "SKIP"))) - (same-itempath (db:compare-itempaths item-path ref-item-path itemmap))) ;; (equal? ref-item-path item-path))) + (same-itempath (db:compare-itempaths item-path ref-item-path itemmaps))) ;; (equal? ref-item-path item-path))) (set! ever-seen #t) (cond ;; case 1, non-item (parent test) is ((and (equal? item-path "") ;; this is the parent test of the waiton being examined is-completed @@ -3368,11 +3363,11 @@ ((and (equal? item-path "") ;; this is the parent test is-killed (member 'toplevel mode)) (set! parent-waiton-met #t)) ;; For itemwait mode IFF the previous matching item is good the set parent-waiton-met - ((and (not (null? (lset-intersection eq? mode '(itemmatch itemwait)))) + ((and (not (null? (lset-intersection eq? mode '(itemmatch itemwait)))) ;; how is that different from (member mode '(itemmatch itemwait)) ????? ;; (not (equal? item-path "")) ;; this applies to both top level (to allow launching of next batch) and items same-itempath) (if (and is-completed is-ok) (set! item-waiton-met #t)) (if (and (equal? item-path "") Index: docs/manual/Makefile ================================================================== --- docs/manual/Makefile +++ docs/manual/Makefile @@ -11,11 +11,11 @@ # design_spec.html : $(SRCFILES) $(CSVFILES) # asciidoc -b html5 -a icons -a iconsdir=$(DISPATH)/images/icons -a toc2 design_spec.txt # -all : server.ps megatest_manual.html client.ps +all : server.ps megatest_manual.html client.ps complex-itemmap.png megatest_manual.html : megatest_manual.txt getting_started.txt writing_tests.txt reference.txt ../plan.txt howto.txt *png asciidoc -b html5 -a icons -a iconsdir=$(DISPATH)/images/icons -a toc2 megatest_manual.txt # dos2unix megatest_manual.html @@ -23,7 +23,11 @@ dot -Tps server.dot > server.ps client.ps : client.dot dot -Tps client.dot > client.ps +complex-itemmap.png : complex-itemmap.dot + dot -Tpng complex-itemmap.dot -o complex-itemmap.png + dot -Tpdf complex-itemmap.dot -o complex-itemmap.pdf + clean: rm -f megatest_manual.html Index: docs/manual/complex-itemmap.dot ================================================================== --- docs/manual/complex-itemmap.dot +++ docs/manual/complex-itemmap.dot @@ -1,35 +1,47 @@ digraph G { // put client after server so server_start node is visible // - subgraph cluster_2 { + subgraph cluster_1 { node [style=filled,shape=box]; - "test1" -> test2; - runremote_lookup_server -> login_attempt [label="have server"]; - runremote_lookup_server -> monitordb_lookup_server [label="no server"]; - - monitordb_lookup_server -> login_attempt [label="have server"]; - monitordb_lookup_server -> server_start_remote [label="no server"]; - - server_start_remote -> delay_2_sec; - delay_2_sec -> runremote_lookup_server; - - login_attempt -> "rmt:send-receive_start" [label="login sucessful"]; - "rmt:send-receive_start" -> "rmt:send-receive_start"; - - "rmt:send-receive_start" -> runremote_lookup_server [label=exception]; - login_attempt -> clear_runremote [label="login failed"]; - - "remove_running > 5s" -> runremote_lookup_server; - - subgraph cluster_3 { - node [style=filled]; - clear_runremote -> "remove_running > 5s"; - } - - label = "client:setup"; + subgraph cluster_3 { + node [style=filled]; + label = "Test B"; + "B/bb/2"; + "B/bb/1"; + } + subgraph cluster_2 { + node [style=filled]; + label = "Test A"; + "A/aa/2"; + "A/aa/1" [color=cyan]; + } + subgraph cluster_4 { + node [style=filled]; + label = "Test C"; + "C/1/aa" [color=cyan]; + "A/aa/1" -> "C/1/aa"; + "B/bb/1" -> "C/1/bb"; + "A/aa/2" -> "C/2/aa"; + "B/bb/2" -> "C/2/bb"; + } + subgraph cluster_5 { + node [style=filled]; + label = "Test D"; + "D/1/res" [color=cyan]; + "C/1/aa" -> "D/1/res"; + "C/2/aa" -> "D/2/res"; + } + subgraph cluster_6 { + node [style=filled]; + label = "Test E"; + "C/1/bb" -> "E/1/res"; + "C/2/bb" -> "E/2/res"; + } + + label = "Complex Itemmapping"; color=green; } } Index: docs/manual/itemmap.fig ================================================================== --- docs/manual/itemmap.fig +++ docs/manual/itemmap.fig @@ -88,10 +88,25 @@ 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 5625 5085 5625 5220 6120 5220 6120 4725 5985 4725 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 5760 5220 5760 5355 6255 5355 6255 4860 6120 4860 -6 +6 6840 2790 8910 3420 +4 0 0 50 -1 0 12 0.0000 4 180 1260 6840 2970 [requirements]\001 +4 0 0 50 -1 0 12 0.0000 4 135 990 6840 3165 waiton TstE\001 +4 0 0 50 -1 0 12 0.0000 4 180 2070 6840 3360 itemap foo/(\\d+) \\1/bar\001 +-6 +6 6840 6345 8910 6975 +4 0 0 50 -1 0 12 0.0000 4 180 1260 6840 6525 [requirements]\001 +4 0 0 50 -1 0 12 0.0000 4 135 990 6840 6720 waiton TstE\001 +4 0 0 50 -1 0 12 0.0000 4 180 2070 6840 6915 itemap baz/(\\d+) \\1/bar\001 +-6 +6 3600 6570 4860 7200 +4 0 0 50 -1 0 12 0.0000 4 180 810 3600 6750 [itemmap]\001 +4 0 0 50 -1 0 12 0.0000 4 150 1260 3600 6945 TstA .*/ foo/\001 +4 0 0 50 -1 0 12 0.0000 4 165 1080 3600 7140 TstB ab/ xy/\001 +-6 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5355 4455 4500 3600 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 @@ -104,26 +119,31 @@ 3510 2610 2790 1890 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 1530 675 3060 675 3060 5580 1530 5580 1530 675 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 3195 675 4815 675 4815 5580 3195 5580 3195 675 -2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 4950 675 6660 675 6660 5580 4950 5580 4950 675 -2 2 0 2 7 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 0 45 8550 45 8550 7245 0 7245 0 45 -2 1 0 2 23 7 50 -1 -1 0.000 0 0 -1 1 0 3 - 0 0 1.00 60.00 120.00 - 5040 6300 4050 5175 4050 3690 -2 1 0 2 23 7 50 -1 -1 0.000 0 0 -1 1 0 3 - 0 0 1.00 60.00 120.00 - 1080 5850 1080 2115 1755 1530 -4 0 0 50 -1 0 16 0.0000 4 135 360 1935 4725 TstB\001 -4 0 0 50 -1 0 16 0.0000 4 135 360 5445 1170 TstC\001 -4 0 0 50 -1 0 16 0.0000 4 135 360 5445 4770 TstD\001 -4 0 0 50 -1 0 16 0.0000 4 135 360 3600 2970 TstE\001 -4 0 0 50 -1 0 16 0.0000 4 135 360 1845 1170 TstA\001 -4 0 0 50 -1 0 16 0.0000 4 180 1260 900 6210 [requirements]\001 -4 0 0 50 -1 0 16 0.0000 4 135 990 900 6405 waiton TstE\001 -4 0 0 50 -1 0 16 0.0000 4 180 2070 900 6600 itemap foo/(\\d+) \\1/bar\001 -4 0 0 50 -1 0 16 0.0000 4 180 810 5220 6165 [itemmap]\001 -4 0 0 50 -1 0 16 0.0000 4 150 1260 5220 6360 TstC .*/ foo/\001 -4 0 0 50 -1 0 16 0.0000 4 165 1080 5220 6555 TstD ab/ xy/\001 +2 1 0 2 23 7 50 -1 -1 0.000 0 0 -1 1 0 3 + 0 0 1.00 60.00 120.00 + 4050 5850 4050 5175 4050 3690 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4950 675 6660 675 6660 5580 4950 5580 4950 675 +2 1 0 2 23 7 50 -1 -1 0.000 0 0 -1 1 0 3 + 0 0 1.00 60.00 120.00 + 7065 2700 7065 2160 6390 1575 +2 1 0 2 23 7 50 -1 -1 0.000 0 0 -1 1 0 3 + 0 0 1.00 60.00 120.00 + 7065 6255 7065 5715 6390 5130 +2 2 0 2 7 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 900 0 9000 0 9000 7425 900 7425 900 0 +4 0 0 50 -1 0 12 0.0000 4 135 360 1935 4725 TstB\001 +4 0 0 50 -1 0 12 0.0000 4 135 360 5445 1170 TstC\001 +4 0 0 50 -1 0 12 0.0000 4 135 360 5445 4770 TstD\001 +4 0 0 50 -1 0 12 0.0000 4 135 360 3600 2970 TstE\001 +4 0 0 50 -1 0 12 0.0000 4 135 360 1845 1170 TstA\001 +4 0 0 50 -1 0 12 0.0000 4 135 720 5085 450 runthird\001 +4 0 0 50 -1 0 12 0.0000 4 135 810 3330 405 runsecond\001 +4 0 0 50 -1 0 12 0.0000 4 135 720 1575 405 runfirst\001 +4 0 0 50 -1 0 12 0.0000 4 150 1260 6750 1005 2. TstE starts\001 +4 0 0 50 -1 0 12 0.0000 4 150 1800 6750 1215 3. TstC & TstD start\001 +4 0 0 50 -1 0 12 0.0000 4 150 1800 6750 810 1. TstA & TstB start\001 +4 0 0 50 -1 0 12 0.0000 4 180 1260 3600 6165 [requirements]\001 +4 0 0 50 -1 0 12 0.0000 4 135 1440 3600 6360 waiton TstA TstB\001 Index: docs/manual/itemmap.png ================================================================== --- docs/manual/itemmap.png +++ docs/manual/itemmap.png cannot compute difference between binary files Index: docs/manual/megatest_manual.html ================================================================== --- docs/manual/megatest_manual.html +++ docs/manual/megatest_manual.html @@ -1252,13 +1252,68 @@

Complex mappings

Complex mappings can be handled with the [itemmap] section

-itemmap.png +complex-itemmap.png +
+
+

Example:

+
    +
  1. +

    +Request to run D/1/res +

    +
  2. +
  3. +

    +Megatest calculates all posible items for Test C and filters down to: C/1/aa +

    +
  4. +
  5. +

    +Full list to be run is now: D/1/res, C/1/aa +

    +
  6. +
  7. +

    +Megatest calculates all posible items for Test A and filters down to: A/aa/1 +

    +
  8. +
  9. +

    +Full list to be run is now: D/1/res, C/1/aa, A/aa/1 +

    +
  10. +
+
+
Testconfig for Test C
+
+
[requirements]
+waiton A B
+
+[itemmap]
+A (\d+)/aa aa/\1
+B (\d+)/bb bb/\1
+
+
+
Testconfig for Test D
+
+
[requirements]
+waiton C
+itemmap (\d+)/res \1/aa
+
+
+
Testconfig for Test E
+
+
[requirements]
+waiton C
+itemmap (\d+)/res \1/bb
+
- +
+

Dynamic Flow Dependency Tree

Autogeneration waiton list for dynamic flow dependency trees
[requirements]
 # With a toplevel test you may wish to generate your list

Index: docs/manual/reference.txt
==================================================================
--- docs/manual/reference.txt
+++ docs/manual/reference.txt
@@ -168,13 +168,48 @@
 Complex mappings
 ^^^^^^^^^^^^^^^^
 
 Complex mappings can be handled with the [itemmap] section
 
-image::itemmap.png[]
+// image::itemmap.png[]
+image::complex-itemmap.png[]
+
+Example:
+
+. Request to run D/1/res
+. Megatest calculates all posible items for Test C and filters down to: C/1/aa
+. Full list to be run is now: D/1/res, C/1/aa
+. Megatest calculates all posible items for Test A and filters down to: A/aa/1
+. Full list to be run is now: D/1/res, C/1/aa, A/aa/1
+
+.Testconfig for Test C
+----------------------
+[requirements]
+waiton A B
+
+[itemmap]
+A (\d+)/aa aa/\1
+B (\d+)/bb bb/\1
+----------------------
+
+.Testconfig for Test D
+----------------------
+[requirements]
+waiton C
+itemmap (\d+)/res \1/aa
+----------------------
+
+.Testconfig for Test E
+----------------------
+[requirements]
+waiton C
+itemmap (\d+)/res \1/bb
+----------------------
 
-.Complex mapping from 
+Dynamic Flow Dependency Tree
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 .Autogeneration waiton list for dynamic flow dependency trees
 -------------------
 [requirements]
 # With a toplevel test you may wish to generate your list 
 # of tests to run dynamically

Index: megatest-version.scm
==================================================================
--- megatest-version.scm
+++ megatest-version.scm
@@ -1,7 +1,7 @@
 ;; Always use two or four digit decimal
 ;; 1.01, 1.02...1.10,1.11,1,1101 ... 1.99,2.00..
 
 (declare (unit megatest-version))
 
-(define megatest-version 1.6023)
+(define megatest-version 1.6024)
 

Index: mt.scm
==================================================================
--- mt.scm
+++ mt.scm
@@ -82,11 +82,11 @@
 		  full-list
 		  new-offset
 		  limit))
 	  full-list))))
 
-(define (mt:lazy-get-prereqs-not-met run-id waitons ref-item-path #!key (mode '(normal))(itemmap #f) )
+(define (mt:lazy-get-prereqs-not-met run-id waitons ref-item-path #!key (mode '(normal))(itemmaps #f) )
   (let* ((key    (list run-id waitons ref-item-path mode))
 	 (res    (hash-table-ref/default *pre-reqs-met-cache* key #f))
 	 (useres (let ((last-time (if (vector? res) (vector-ref res 0) #f)))
 		   (if last-time
 		       (< (current-seconds)(+ last-time 5))
@@ -93,12 +93,11 @@
 		       #f))))
     (if useres
 	(let ((result (vector-ref res 1)))
 	  (debug:print 4 "Using lazy value res: " result)
 	  result)
-	(let ((newres (rmt:get-prereqs-not-met run-id waitons ref-item-path mode: mode itemmap: itemmap)))
-;;	(let ((newres (db:get-prereqs-not-met run-id waitons ref-item-path mode: mode itemmap: itemmap)))
+	(let ((newres (rmt:get-prereqs-not-met run-id waitons ref-item-path mode: mode itemmaps: itemmaps)))
 	  (hash-table-set! *pre-reqs-met-cache* key (vector (current-seconds) newres))
 	  newres))))
 
 (define (mt:get-run-stats dbstruct run-id)
 ;;  Get run stats from local access, move this ... but where?

Index: rmt.scm
==================================================================
--- rmt.scm
+++ rmt.scm
@@ -504,12 +504,12 @@
 	   run-ids))))
 
 ;; (define (rmt:get-run-ids-matching keynames target res)
 ;;   (rmt:send-receive #f 'get-run-ids-matching (list keynames target res)))
 
-(define (rmt:get-prereqs-not-met run-id waitons ref-item-path #!key (mode '(normal))(itemmap #f))
-  (rmt:send-receive 'get-prereqs-not-met run-id (list run-id waitons ref-item-path mode itemmap)))
+(define (rmt:get-prereqs-not-met run-id waitons ref-item-path #!key (mode '(normal))(itemmaps #f))
+  (rmt:send-receive 'get-prereqs-not-met run-id (list run-id waitons ref-item-path mode itemmaps)))
 
 (define (rmt:get-count-tests-running-for-run-id run-id)
   (rmt:send-receive 'get-count-tests-running-for-run-id run-id (list run-id)))
 
 ;; Statistical queries

Index: runs.scm
==================================================================
--- runs.scm
+++ runs.scm
@@ -423,12 +423,12 @@
 		   (let* ((waiton-record   (hash-table-ref/default test-records waiton #f))
 			  (waiton-tconfig  (if waiton-record (vector-ref waiton-record 1) #f))
 			  (waiton-itemized (and waiton-tconfig
 						(or (hash-table-ref/default waiton-tconfig "items" #f)
 						    (hash-table-ref/default waiton-tconfig "itemstable" #f))))
-			  (itemmap         (configf:lookup config "requirements" "itemmap"))
-			  (new-test-patts  (tests:extend-test-patts test-patts hed waiton itemmap)))
+			  (itemmaps        (tests:get-itemmaps config));; (configf:lookup config "requirements" "itemmap"))
+			  (new-test-patts  (tests:extend-test-patts test-patts hed waiton itemmaps)))
 		     (debug:print-info 0 "Test " waiton " has " (if waiton-record "a" "no") " waiton-record and" (if waiton-itemized " " " no ") "items")
 		     ;; need to account for test-patt here, if I am test "a", selected with a test-patt of "hed/b%"
 		     ;; and we are waiting on "waiton" we need to add "waiton/,waiton/b%" to test-patt
 		     ;; is this satisfied by merely appending "/" to the waiton name added to the list?
 		     ;;
@@ -559,13 +559,13 @@
 	  '()
 	  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 test-registry test-records itemmap)
+(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 test-records itemmaps)
   (let* ((loop-list       (list hed tal reg reruns))
-	 (prereqs-not-met (rmt:get-prereqs-not-met run-id waitons item-path mode: testmode itemmap: itemmap))
+	 (prereqs-not-met (rmt:get-prereqs-not-met run-id waitons item-path mode: testmode itemmaps: itemmaps))
 	 ;; (prereqs-not-met (mt:lazy-get-prereqs-not-met run-id waitons item-path mode: testmode itemmap: itemmap))
 	 (fails           (runs:calc-fails prereqs-not-met))
 	 (prereq-fails    (runs:calc-prereq-fail prereqs-not-met))
 	 (non-completed   (runs:calc-not-completed prereqs-not-met))
 	 (runnables       (runs:calc-runnable prereqs-not-met)))
@@ -742,18 +742,18 @@
 	       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 itemmap)
+(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 itemmaps)
   (let* ((run-limits-info         (runs:can-run-more-tests run-id 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)) 
 	 (max-concurrent-jobs     (list-ref run-limits-info 3))
 	 (job-group-limit         (list-ref run-limits-info 4))
-	 (prereqs-not-met         (rmt:get-prereqs-not-met run-id waitons item-path mode: testmode itemmap: itemmap))
+	 (prereqs-not-met         (rmt:get-prereqs-not-met run-id waitons item-path mode: testmode itemmaps: itemmaps))
 	 ;; (prereqs-not-met         (mt:lazy-get-prereqs-not-met run-id waitons item-path mode: testmode itemmap: itemmap))
 	 (fails                   (runs:calc-fails prereqs-not-met))
 	 (non-completed           (filter (lambda (x)             ;; remove hed from not completed list, duh, of course it is not completed!
 					    (not (equal? x hed)))
 					  (runs:calc-not-completed prereqs-not-met)))
@@ -1058,11 +1058,11 @@
 	     (test-name   (tests:testqueue-get-testname test-record))
 	     (tconfig     (tests:testqueue-get-testconfig test-record))
 	     (jobgroup    (config-lookup tconfig "test_meta" "jobgroup"))
 	     (testmode    (let ((m (config-lookup tconfig "requirements" "mode")))
 			    (if m (map string->symbol (string-split m)) '(normal))))
-	     (itemmap     (configf:lookup tconfig "requirements" "itemmap"))
+	     (itemmaps    (tests:get-itemmaps tconfig)) ;;  (configf:lookup tconfig "requirements" "itemmap"))
 	     (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))
@@ -1150,11 +1150,11 @@
 	 ((not items)
 	  (debug:print-info 4 "OUTER COND: (not items)")
 	  (if (and (not (tests:match test-patts (tests:testqueue-get-testname test-record) item-path required: required-tests))
 		   (not (null? tal)))
 	      (loop (car tal)(cdr tal) reg reruns))
-	  (let ((loop-list (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 itemmap)))
+	  (let ((loop-list (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 itemmaps)))
 	    (if loop-list (apply loop loop-list))))
 
 	 ;; items processed into a list but not came in as a list been processed
 	 ;;
 	 ((and (list? items)     ;; thus we know our items are already calculated
@@ -1205,11 +1205,11 @@
 	 ;; EXPAND ITEMS
 	 ((or (procedure? items)(eq? items 'have-procedure))
 	  (let ((can-run-more    (runs:can-run-more-tests run-id 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 test-registry test-records itemmap)))
+		(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 test-records itemmaps)))
 		  (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))))
 	    

Index: tests.scm
==================================================================
--- tests.scm
+++ tests.scm
@@ -72,10 +72,38 @@
   (delete-duplicates
    (filter (lambda (testname)
 	     (tests:match test-patts testname #f))
 	   test-names)))
 
+;; itemmap is a list of testname patterns to maps
+;;     test1 .*/bar/(\d+) foo/\1
+;;     %     foo/([^/]+)  \1/bar
+;;
+;; # NOTE: the line with the single % could be the result of
+;; #       itemmap entry in requirements (legacy). The itemmap
+;; #       requirements entry is deprecated
+;;
+(define (tests:get-itemmaps tconfig)
+  (let ((base-itemmap  (configf:lookup tconfig "requirements" "itemmap"))
+	(itemmap-table (configf:get-section tconfig "itemmap")))
+    (append (if base-itemmap
+		(list (cons "%" base-itemmap))
+		'())
+	    (if itemmap-table
+		itemmap-table
+		'()))))
+
+;; given a list of itemmaps (testname . map), return the first match
+;;
+(define (tests:lookup-itemmap itemmaps testname)
+  (let ((best-matches (filter (lambda (itemmap)
+				(tests:match (car itemmap) testname))
+			      itemmaps)))
+    (if (null? best-matches)
+	#f
+	(car best-matches))))
+					     
 ;; given test-b that is waiting on test-a extend test-patt appropriately
 ;;
 ;;  genlib/testconfig               sim/testconfig
 ;;  genlib/sch                      sim/sch/cell1
 ;;
@@ -83,12 +111,13 @@
 ;;                                  mode itemwait
 ;;                                  # trim off the cell to determine what to run for genlib
 ;;                                  itemmap /.*
 ;;
 ;;                                  test-a is waiting on test-b so we need to create a pattern for test-b given test-a and itemmap
-(define (tests:extend-test-patts test-patt test-b test-a itemmap)
-  (let* ((patts      (string-split test-patt ","))
+(define (tests:extend-test-patts test-patt test-b test-a itemmaps)
+  (let* ((itemmap    (tests:lookup-itemmap itemmaps test-b))
+	 (patts      (string-split test-patt ","))
 	 (test-b-len (+ (string-length test-b) 1))
 	 (patts-b    (map (lambda (x)
 			    (let* ((modpatt (if itemmap (db:convert-test-itempath x itemmap) x)) 
 				   (newpatt (conc test-a "/" (substring modpatt test-b-len (string-length modpatt)))))
 				         ;; (conc test-a "/," test-a "/" (substring modpatt test-b-len (string-length modpatt)))))