Adding sequential construct to STC to serially chain sequences based on env properties.
Change-Id: I1df66d2a704309f5450eeca08a6e9b89c02e8346
Showing
4 changed files
with
100 additions
and
7 deletions
tools/test/scenarios/sequential-example.xml
0 → 100644
1 | +<!-- | ||
2 | + ~ Copyright 2015 Open Networking Laboratory | ||
3 | + ~ | ||
4 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + ~ you may not use this file except in compliance with the License. | ||
6 | + ~ You may obtain a copy of the License at | ||
7 | + ~ | ||
8 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + ~ | ||
10 | + ~ Unless required by applicable law or agreed to in writing, software | ||
11 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + ~ See the License for the specific language governing permissions and | ||
14 | + ~ limitations under the License. | ||
15 | + --> | ||
16 | +<scenario name="example" description="sequential scenario example"> | ||
17 | + <group name="Wrapup"> | ||
18 | + <!-- 'starts' is a comma-separated list of patterns that name steps starting the current iteration of the sequence --> | ||
19 | + <!-- 'ends' is a comma-separated list of patterns that name steps ending the previous iteration of the sequence --> | ||
20 | + <!-- In this example each Final-Check-Logs-(N) will become dependent on Fetch-Logs-(N-1), for N > 1 --> | ||
21 | + <sequential var="${OC#}" starts="Final-Check-Logs-${#}" ends="Fetch-Logs-${#-1}"> | ||
22 | + <step name="Final-Check-Logs-${#}" exec="onos-check-logs ${OC#}"/> | ||
23 | + <step name="Fetch-Logs-${#}" exec="onos-fetch-logs ${OC#}" | ||
24 | + cwd="${WORKSPACE}/tmp/stc" requires="~^"/> | ||
25 | + </sequential> | ||
26 | + </group> | ||
27 | +</scenario> |
... | @@ -48,6 +48,7 @@ public class Compiler { | ... | @@ -48,6 +48,7 @@ public class Compiler { |
48 | private static final String GROUP = "group"; | 48 | private static final String GROUP = "group"; |
49 | private static final String STEP = "step"; | 49 | private static final String STEP = "step"; |
50 | private static final String PARALLEL = "parallel"; | 50 | private static final String PARALLEL = "parallel"; |
51 | + private static final String SEQUENTIAL = "sequential"; | ||
51 | private static final String DEPENDENCY = "dependency"; | 52 | private static final String DEPENDENCY = "dependency"; |
52 | 53 | ||
53 | private static final String LOG_DIR = "[@logDir]"; | 54 | private static final String LOG_DIR = "[@logDir]"; |
... | @@ -59,12 +60,16 @@ public class Compiler { | ... | @@ -59,12 +60,16 @@ public class Compiler { |
59 | private static final String IF = "[@if]"; | 60 | private static final String IF = "[@if]"; |
60 | private static final String UNLESS = "[@unless]"; | 61 | private static final String UNLESS = "[@unless]"; |
61 | private static final String VAR = "[@var]"; | 62 | private static final String VAR = "[@var]"; |
63 | + private static final String STARTS = "[@starts]"; | ||
64 | + private static final String ENDS = "[@ends]"; | ||
62 | private static final String FILE = "[@file]"; | 65 | private static final String FILE = "[@file]"; |
63 | private static final String NAMESPACE = "[@namespace]"; | 66 | private static final String NAMESPACE = "[@namespace]"; |
64 | 67 | ||
65 | static final String PROP_START = "${"; | 68 | static final String PROP_START = "${"; |
66 | static final String PROP_END = "}"; | 69 | static final String PROP_END = "}"; |
70 | + | ||
67 | private static final String HASH = "#"; | 71 | private static final String HASH = "#"; |
72 | + private static final String HASH_PREV = "#-1"; | ||
68 | 73 | ||
69 | private final Scenario scenario; | 74 | private final Scenario scenario; |
70 | 75 | ||
... | @@ -72,7 +77,7 @@ public class Compiler { | ... | @@ -72,7 +77,7 @@ public class Compiler { |
72 | private final Map<String, Step> inactiveSteps = Maps.newHashMap(); | 77 | private final Map<String, Step> inactiveSteps = Maps.newHashMap(); |
73 | private final Map<String, String> requirements = Maps.newHashMap(); | 78 | private final Map<String, String> requirements = Maps.newHashMap(); |
74 | private final Set<Dependency> dependencies = Sets.newHashSet(); | 79 | private final Set<Dependency> dependencies = Sets.newHashSet(); |
75 | - private final List<Integer> parallels = Lists.newArrayList(); | 80 | + private final List<Integer> clonables = Lists.newArrayList(); |
76 | 81 | ||
77 | private ProcessFlow processFlow; | 82 | private ProcessFlow processFlow; |
78 | private File logDir; | 83 | private File logDir; |
... | @@ -175,6 +180,10 @@ public class Compiler { | ... | @@ -175,6 +180,10 @@ public class Compiler { |
175 | cfg.configurationsAt(PARALLEL) | 180 | cfg.configurationsAt(PARALLEL) |
176 | .forEach(c -> processParallelGroup(c, namespace, parentGroup)); | 181 | .forEach(c -> processParallelGroup(c, namespace, parentGroup)); |
177 | 182 | ||
183 | + // Scan all sequential groups | ||
184 | + cfg.configurationsAt(SEQUENTIAL) | ||
185 | + .forEach(c -> processSequentialGroup(c, namespace, parentGroup)); | ||
186 | + | ||
178 | // Scan all dependencies | 187 | // Scan all dependencies |
179 | cfg.configurationsAt(DEPENDENCY) | 188 | cfg.configurationsAt(DEPENDENCY) |
180 | .forEach(c -> processDependency(c, namespace)); | 189 | .forEach(c -> processDependency(c, namespace)); |
... | @@ -309,14 +318,62 @@ public class Compiler { | ... | @@ -309,14 +318,62 @@ public class Compiler { |
309 | 318 | ||
310 | int i = 1; | 319 | int i = 1; |
311 | while (condition(var, i).length() > 0) { | 320 | while (condition(var, i).length() > 0) { |
312 | - parallels.add(0, i); | 321 | + clonables.add(0, i); |
322 | + compile(cfg, namespace, parentGroup); | ||
323 | + clonables.remove(0); | ||
324 | + i++; | ||
325 | + } | ||
326 | + } | ||
327 | + | ||
328 | + /** | ||
329 | + * Processes a sequential clone group directive. | ||
330 | + * | ||
331 | + * @param cfg hierarchical definition | ||
332 | + * @param namespace optional namespace | ||
333 | + * @param parentGroup optional parent group | ||
334 | + */ | ||
335 | + private void processSequentialGroup(HierarchicalConfiguration cfg, | ||
336 | + String namespace, Group parentGroup) { | ||
337 | + String var = cfg.getString(VAR); | ||
338 | + String starts = cfg.getString(STARTS); | ||
339 | + String ends = cfg.getString(ENDS); | ||
340 | + print("sequential var=%s", var); | ||
341 | + | ||
342 | + int i = 1; | ||
343 | + while (condition(var, i).length() > 0) { | ||
344 | + clonables.add(0, i); | ||
313 | compile(cfg, namespace, parentGroup); | 345 | compile(cfg, namespace, parentGroup); |
314 | - parallels.remove(0); | 346 | + if (i > 1) { |
347 | + processSequentialRequirements(starts, ends, namespace); | ||
348 | + } | ||
349 | + clonables.remove(0); | ||
315 | i++; | 350 | i++; |
316 | } | 351 | } |
317 | } | 352 | } |
318 | 353 | ||
319 | /** | 354 | /** |
355 | + * Hooks starts of this sequence tier to the previous tier. | ||
356 | + * | ||
357 | + * @param starts comma-separated list of start steps | ||
358 | + * @param ends comma-separated list of end steps | ||
359 | + * @param namespace optional namespace | ||
360 | + */ | ||
361 | + private void processSequentialRequirements(String starts, String ends, | ||
362 | + String namespace) { | ||
363 | + for (String s : split(starts)) { | ||
364 | + String start = expand(prefix(s, namespace)); | ||
365 | + String reqs = requirements.get(s); | ||
366 | + for (String n : split(ends)) { | ||
367 | + boolean isSoft = n.startsWith("~"); | ||
368 | + String name = n.replaceFirst("^~", ""); | ||
369 | + name = (isSoft ? "~" : "") + expand(prefix(name, namespace)); | ||
370 | + reqs = reqs == null ? name : (reqs + "," + name); | ||
371 | + } | ||
372 | + requirements.put(start, reqs); | ||
373 | + } | ||
374 | + } | ||
375 | + | ||
376 | + /** | ||
320 | * Returns the elaborated repetition construct conditional. | 377 | * Returns the elaborated repetition construct conditional. |
321 | * | 378 | * |
322 | * @param var repetition var property | 379 | * @param var repetition var property |
... | @@ -413,9 +470,11 @@ public class Compiler { | ... | @@ -413,9 +470,11 @@ public class Compiler { |
413 | String prop = pString.substring(start + PROP_START.length(), end); | 470 | String prop = pString.substring(start + PROP_START.length(), end); |
414 | String value; | 471 | String value; |
415 | if (prop.equals(HASH)) { | 472 | if (prop.equals(HASH)) { |
416 | - value = parallels.get(0).toString(); | 473 | + value = Integer.toString(clonables.get(0)); |
474 | + } else if (prop.equals(HASH_PREV)) { | ||
475 | + value = Integer.toString(clonables.get(0) - 1); | ||
417 | } else if (prop.endsWith(HASH)) { | 476 | } else if (prop.endsWith(HASH)) { |
418 | - pString = pString.replaceFirst("#}", parallels.get(0).toString() + "}"); | 477 | + pString = pString.replaceFirst("#}", clonables.get(0) + "}"); |
419 | last = start; | 478 | last = start; |
420 | continue; | 479 | continue; |
421 | } else { | 480 | } else { | ... | ... |
... | @@ -69,8 +69,8 @@ public class CompilerTest { | ... | @@ -69,8 +69,8 @@ public class CompilerTest { |
69 | ProcessFlow flow = compiler.processFlow(); | 69 | ProcessFlow flow = compiler.processFlow(); |
70 | 70 | ||
71 | assertSame("incorrect scenario", scenario, compiler.scenario()); | 71 | assertSame("incorrect scenario", scenario, compiler.scenario()); |
72 | - assertEquals("incorrect step count", 24, flow.getVertexes().size()); | 72 | + assertEquals("incorrect step count", 33, flow.getVertexes().size()); |
73 | - assertEquals("incorrect dependency count", 16, flow.getEdges().size()); | 73 | + assertEquals("incorrect dependency count", 26, flow.getEdges().size()); |
74 | assertEquals("incorrect logDir", | 74 | assertEquals("incorrect logDir", |
75 | new File(TEST_DIR.getAbsolutePath(), "foo"), compiler.logDir()); | 75 | new File(TEST_DIR.getAbsolutePath(), "foo"), compiler.logDir()); |
76 | 76 | ... | ... |
... | @@ -44,4 +44,11 @@ | ... | @@ -44,4 +44,11 @@ |
44 | <step name="ding-${#}" exec="asdads" requires="ping-${#},pong-${#}"/> | 44 | <step name="ding-${#}" exec="asdads" requires="ping-${#},pong-${#}"/> |
45 | <dependency name="maybe" requires="ding-${#}"/> | 45 | <dependency name="maybe" requires="ding-${#}"/> |
46 | </parallel> | 46 | </parallel> |
47 | + | ||
48 | + <sequential var="${TOC#}" requires="alpha" starts="fifi-${#},gigi-${#}" ends="gaga-${#-1}"> | ||
49 | + <step name="fifi-${#}" exec="asdads ${TOC#}"/> | ||
50 | + <step name="gigi-${#}" exec="asdads"/> | ||
51 | + <step name="gaga-${#}" exec="asdads" requires="fifi-${#},gigi-${#}"/> | ||
52 | + <dependency name="maybe" requires="gaga-${#}"/> | ||
53 | + </sequential> | ||
47 | </scenario> | 54 | </scenario> |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or login to post a comment