summaryrefslogtreecommitdiffstats
path: root/config-model-api
diff options
context:
space:
mode:
authorValerij Fredriksen <freva@users.noreply.github.com>2019-11-29 19:13:36 +0100
committerGitHub <noreply@github.com>2019-11-29 19:13:36 +0100
commit12fcbd278a5fadb085456f0cde9059755c0fe231 (patch)
tree4023bb0e6c835026ffb18f5f00580121455a906c /config-model-api
parent21620abb46bbfb18abeb6c8cc917b39fb0e316b8 (diff)
Revert "Jvenstad/test steps in deployment spec"
Diffstat (limited to 'config-model-api')
-rw-r--r--config-model-api/abi-spec.json68
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java115
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java165
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java23
-rw-r--r--config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java223
-rw-r--r--config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecWithoutInstanceTest.java207
6 files changed, 199 insertions, 602 deletions
diff --git a/config-model-api/abi-spec.json b/config-model-api/abi-spec.json
index 163653f703b..edf83fe4475 100644
--- a/config-model-api/abi-spec.json
+++ b/config-model-api/abi-spec.json
@@ -188,7 +188,7 @@
"fields": []
},
"com.yahoo.config.application.api.DeploymentInstanceSpec": {
- "superClass": "com.yahoo.config.application.api.DeploymentSpec$Steps",
+ "superClass": "com.yahoo.config.application.api.DeploymentSpec$Step",
"interfaces": [],
"attributes": [
"public"
@@ -196,16 +196,20 @@
"methods": [
"public void <init>(com.yahoo.config.provision.InstanceName, java.util.List, com.yahoo.config.application.api.DeploymentSpec$UpgradePolicy, java.util.List, java.util.Optional, java.util.Optional, java.util.Optional, com.yahoo.config.application.api.Notifications, java.util.List)",
"public com.yahoo.config.provision.InstanceName name()",
+ "public java.time.Duration delay()",
+ "public java.util.List steps()",
"public com.yahoo.config.application.api.DeploymentSpec$UpgradePolicy upgradePolicy()",
"public java.util.List changeBlocker()",
"public java.util.Optional globalServiceId()",
"public boolean canUpgradeAt(java.time.Instant)",
"public boolean canChangeRevisionAt(java.time.Instant)",
+ "public java.util.List zones()",
+ "public boolean deploysTo(com.yahoo.config.provision.Environment, java.util.Optional)",
"public java.util.Optional athenzDomain()",
"public java.util.Optional athenzService(com.yahoo.config.provision.Environment, com.yahoo.config.provision.RegionName)",
"public com.yahoo.config.application.api.Notifications notifications()",
"public java.util.List endpoints()",
- "public boolean deploysTo(com.yahoo.config.provision.Environment, java.util.Optional)",
+ "public boolean includes(com.yahoo.config.provision.Environment, java.util.Optional)",
"public boolean equals(java.lang.Object)",
"public int hashCode()",
"public java.lang.String toString()"
@@ -227,23 +231,6 @@
],
"fields": []
},
- "com.yahoo.config.application.api.DeploymentSpec$DeclaredTest": {
- "superClass": "com.yahoo.config.application.api.DeploymentSpec$Step",
- "interfaces": [],
- "attributes": [
- "public"
- ],
- "methods": [
- "public void <init>(com.yahoo.config.provision.RegionName)",
- "public boolean concerns(com.yahoo.config.provision.Environment, java.util.Optional)",
- "public boolean isTest()",
- "public com.yahoo.config.provision.RegionName region()",
- "public boolean equals(java.lang.Object)",
- "public int hashCode()",
- "public java.lang.String toString()"
- ],
- "fields": []
- },
"com.yahoo.config.application.api.DeploymentSpec$DeclaredZone": {
"superClass": "com.yahoo.config.application.api.DeploymentSpec$Step",
"interfaces": [],
@@ -259,8 +246,7 @@
"public java.util.Optional testerFlavor()",
"public java.util.Optional athenzService()",
"public java.util.List zones()",
- "public boolean concerns(com.yahoo.config.provision.Environment, java.util.Optional)",
- "public boolean isTest()",
+ "public boolean deploysTo(com.yahoo.config.provision.Environment, java.util.Optional)",
"public int hashCode()",
"public boolean equals(java.lang.Object)",
"public java.lang.String toString()"
@@ -276,21 +262,22 @@
"methods": [
"public void <init>(java.time.Duration)",
"public java.time.Duration delay()",
- "public boolean concerns(com.yahoo.config.provision.Environment, java.util.Optional)",
+ "public boolean deploysTo(com.yahoo.config.provision.Environment, java.util.Optional)",
"public java.lang.String toString()"
],
"fields": []
},
- "com.yahoo.config.application.api.DeploymentSpec$ParallelSteps": {
- "superClass": "com.yahoo.config.application.api.DeploymentSpec$Steps",
+ "com.yahoo.config.application.api.DeploymentSpec$ParallelZones": {
+ "superClass": "com.yahoo.config.application.api.DeploymentSpec$Step",
"interfaces": [],
"attributes": [
"public"
],
"methods": [
"public void <init>(java.util.List)",
- "public java.time.Duration delay()",
- "public boolean isOrdered()",
+ "public java.util.List zones()",
+ "public java.util.List steps()",
+ "public boolean deploysTo(com.yahoo.config.provision.Environment, java.util.Optional)",
"public boolean equals(java.lang.Object)",
"public int hashCode()",
"public java.lang.String toString()"
@@ -306,31 +293,11 @@
],
"methods": [
"public void <init>()",
- "public final boolean concerns(com.yahoo.config.provision.Environment)",
- "public abstract boolean concerns(com.yahoo.config.provision.Environment, java.util.Optional)",
+ "public final boolean deploysTo(com.yahoo.config.provision.Environment)",
+ "public abstract boolean deploysTo(com.yahoo.config.provision.Environment, java.util.Optional)",
"public java.util.List zones()",
"public java.time.Duration delay()",
- "public java.util.List steps()",
- "public boolean isTest()",
- "public boolean isOrdered()"
- ],
- "fields": []
- },
- "com.yahoo.config.application.api.DeploymentSpec$Steps": {
- "superClass": "com.yahoo.config.application.api.DeploymentSpec$Step",
- "interfaces": [],
- "attributes": [
- "public"
- ],
- "methods": [
- "public void <init>(java.util.List)",
- "public java.util.List zones()",
- "public java.util.List steps()",
- "public boolean concerns(com.yahoo.config.provision.Environment, java.util.Optional)",
- "public java.time.Duration delay()",
- "public boolean equals(java.lang.Object)",
- "public int hashCode()",
- "public java.lang.String toString()"
+ "public java.util.List steps()"
],
"fields": []
},
@@ -364,6 +331,7 @@
"public java.util.List steps()",
"public java.util.Optional athenzDomain()",
"public java.util.Optional athenzService()",
+ "public java.util.Optional athenzService(com.yahoo.config.provision.InstanceName, com.yahoo.config.provision.Environment, com.yahoo.config.provision.RegionName)",
"public java.lang.String xmlForm()",
"public java.util.Optional instance(com.yahoo.config.provision.InstanceName)",
"public com.yahoo.config.application.api.DeploymentInstanceSpec requireInstance(java.lang.String)",
@@ -604,4 +572,4 @@
"public static final com.yahoo.config.application.api.ValidationOverrides all"
]
}
-} \ No newline at end of file
+}
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java
index 541e52cf6e9..f96400fc9a9 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
+import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;
@@ -21,11 +22,12 @@ import java.util.stream.Collectors;
*
* @author bratseth
*/
-public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
+public class DeploymentInstanceSpec extends DeploymentSpec.Step {
/** The name of the instance this step deploys */
private final InstanceName name;
+ private final List<DeploymentSpec.Step> steps;
private final DeploymentSpec.UpgradePolicy upgradePolicy;
private final List<DeploymentSpec.ChangeBlocker> changeBlockers;
private final Optional<String> globalServiceId;
@@ -43,54 +45,34 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
Optional<AthenzService> athenzService,
Notifications notifications,
List<Endpoint> endpoints) {
- super(steps);
this.name = name;
+ this.steps = steps;
this.upgradePolicy = upgradePolicy;
this.changeBlockers = changeBlockers;
this.globalServiceId = globalServiceId;
this.athenzDomain = athenzDomain;
this.athenzService = athenzService;
this.notifications = notifications;
- this.endpoints = List.copyOf(validateEndpoints(endpoints, steps()));
- validateZones(new HashSet<>(), this);
- validateEndpoints(steps(), globalServiceId, this.endpoints);
+ this.endpoints = List.copyOf(validateEndpoints(endpoints, this.steps));
+ validateZones(this.steps);
+ validateEndpoints(this.steps, globalServiceId, this.endpoints);
validateAthenz();
}
public InstanceName name() { return name; }
- /**
- * Throws an IllegalArgumentException if any production deployment or test is declared multiple times,
- * or if any production test is declared not after its corresponding deployment.
- *
- * @param deployments previously seen deployments
- * @param step step whose members to validate
- * @return all contained tests
- */
- private static Set<RegionName> validateZones(Set<RegionName> deployments, DeploymentSpec.Step step) {
- if ( ! step.steps().isEmpty()) {
- Set<RegionName> oldDeployments = Set.copyOf(deployments);
- Set<RegionName> tests = new HashSet<>();
- for (DeploymentSpec.Step nested : step.steps()) {
- for (RegionName test : validateZones(deployments, nested)) {
- if ( ! (step.isOrdered() ? deployments : oldDeployments).contains(test))
- throw new IllegalArgumentException("tests for prod." + test + " must be after the corresponding deployment in deployment.xml");
-
- if ( ! tests.add(test))
- throw new IllegalArgumentException("tests for prod." + test + " arelisted twice in deployment.xml");
- }
- }
- return tests;
- }
- if (step.concerns(Environment.prod)) {
- if (step.isTest())
- return Set.of(((DeploymentSpec.DeclaredTest) step).region());
+ /** Throw an IllegalArgumentException if any production zone is declared multiple times */
+ private void validateZones(List<DeploymentSpec.Step> steps) {
+ Set<DeploymentSpec.DeclaredZone> zones = new HashSet<>();
- RegionName region = ((DeploymentSpec.DeclaredZone) step).region().get();
- if ( ! deployments.add(region))
- throw new IllegalArgumentException("prod." + region + " is listed twice in deployment.xml");
- }
- return Set.of();
+ for (DeploymentSpec.Step step : steps)
+ for (DeploymentSpec.DeclaredZone zone : step.zones())
+ ensureUnique(zone, zones);
+ }
+
+ private void ensureUnique(DeploymentSpec.DeclaredZone zone, Set<DeploymentSpec.DeclaredZone> zones) {
+ if ( ! zones.add(zone))
+ throw new IllegalArgumentException(zone + " is listed twice in deployment.xml");
}
/** Validates the endpoints and makes sure default values are respected */
@@ -98,7 +80,7 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
Objects.requireNonNull(endpoints, "Missing endpoints parameter");
var productionRegions = steps.stream()
- .filter(step -> step.concerns(Environment.prod))
+ .filter(step -> step.deploysTo(Environment.prod))
.flatMap(step -> step.zones().stream())
.flatMap(zone -> zone.region().stream())
.map(RegionName::value)
@@ -161,6 +143,15 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
}
}
+ @Override
+ public Duration delay() {
+ return Duration.ofSeconds(steps.stream().mapToLong(step -> (step.delay().getSeconds())).sum());
+ }
+
+ /** Returns the deployment steps inside this in the order they will be performed */
+ @Override
+ public List<DeploymentSpec.Step> steps() { return steps; }
+
/** Returns the upgrade policy of this, which is defaultPolicy if none is specified */
public DeploymentSpec.UpgradePolicy upgradePolicy() { return upgradePolicy; }
@@ -182,16 +173,32 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
.noneMatch(block -> block.window().includes(instant));
}
+ /** Returns all the deployment steps which are zones in the order they are declared */
+ public List<DeploymentSpec.DeclaredZone> zones() {
+ return steps.stream()
+ .flatMap(step -> step.zones().stream())
+ .collect(Collectors.toList());
+ }
+
+ /** Returns whether this deployment spec specifies the given zone, either implicitly or explicitly */
+ @Override
+ public boolean deploysTo(Environment environment, Optional<RegionName> region) {
+ for (DeploymentSpec.Step step : steps)
+ if (step.deploysTo(environment, region)) return true;
+ return false;
+ }
+
/** Returns the athenz domain if configured */
public Optional<AthenzDomain> athenzDomain() { return athenzDomain; }
/** Returns the athenz service for environment/region if configured */
public Optional<AthenzService> athenzService(Environment environment, RegionName region) {
- return zones().stream()
- .filter(zone -> zone.concerns(environment, Optional.of(region)))
- .findFirst()
- .flatMap(DeploymentSpec.DeclaredZone::athenzService)
- .or(() -> this.athenzService);
+ AthenzService athenzService = zones().stream()
+ .filter(zone -> zone.deploysTo(environment, Optional.of(region)))
+ .findFirst()
+ .flatMap(DeploymentSpec.DeclaredZone::athenzService)
+ .orElse(this.athenzService.orElse(null));
+ return Optional.ofNullable(athenzService);
}
/** Returns the notification configuration of these instances */
@@ -200,9 +207,23 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
/** Returns the rotations configuration of these instances */
public List<Endpoint> endpoints() { return endpoints; }
- /** Returns whether this instance deploys to the given zone, either implicitly or explicitly */
- public boolean deploysTo(Environment environment, Optional<RegionName> region) {
- return zones().stream().anyMatch(zone -> zone.concerns(environment, region));
+ /** Returns whether this instances deployment specifies the given zone, either implicitly or explicitly */
+ public boolean includes(Environment environment, Optional<RegionName> region) {
+ for (DeploymentSpec.Step step : steps)
+ if (step.deploysTo(environment, region)) return true;
+ return false;
+ }
+
+ DeploymentInstanceSpec withSteps(List<DeploymentSpec.Step> steps) {
+ return new DeploymentInstanceSpec(name,
+ steps,
+ upgradePolicy,
+ changeBlockers,
+ globalServiceId,
+ athenzDomain,
+ athenzService,
+ notifications,
+ endpoints);
}
@Override
@@ -213,7 +234,7 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
return globalServiceId.equals(other.globalServiceId) &&
upgradePolicy == other.upgradePolicy &&
changeBlockers.equals(other.changeBlockers) &&
- steps().equals(other.steps()) &&
+ steps.equals(other.steps) &&
athenzDomain.equals(other.athenzDomain) &&
athenzService.equals(other.athenzService) &&
notifications.equals(other.notifications) &&
@@ -222,7 +243,7 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
@Override
public int hashCode() {
- return Objects.hash(globalServiceId, upgradePolicy, changeBlockers, steps(), athenzDomain, athenzService, notifications, endpoints);
+ return Objects.hash(globalServiceId, upgradePolicy, changeBlockers, steps, athenzDomain, athenzService, notifications, endpoints);
}
@Override
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
index 67b3d585881..ea7df677e0f 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
@@ -13,12 +13,10 @@ import java.io.Reader;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
/**
* Specifies the environments and regions to which an application should be deployed.
@@ -77,14 +75,14 @@ public class DeploymentSpec {
List<Step> steps = new ArrayList<>(inputSteps);
// Add staging if required and missing
- if (steps.stream().anyMatch(step -> step.concerns(Environment.prod)) &&
- steps.stream().noneMatch(step -> step.concerns(Environment.staging))) {
+ if (steps.stream().anyMatch(step -> step.deploysTo(Environment.prod)) &&
+ steps.stream().noneMatch(step -> step.deploysTo(Environment.staging))) {
steps.add(new DeploymentSpec.DeclaredZone(Environment.staging));
}
// Add test if required and missing
- if (steps.stream().anyMatch(step -> step.concerns(Environment.staging)) &&
- steps.stream().noneMatch(step -> step.concerns(Environment.test))) {
+ if (steps.stream().anyMatch(step -> step.deploysTo(Environment.staging)) &&
+ steps.stream().noneMatch(step -> step.deploysTo(Environment.test))) {
steps.add(new DeploymentSpec.DeclaredZone(Environment.test));
}
@@ -164,6 +162,13 @@ public class DeploymentSpec {
// to have environment, instance or region variants on those.
public Optional<AthenzService> athenzService() { return this.athenzService; }
+ // TODO remove when 7.135 is the oldest version
+ public Optional<AthenzService> athenzService(InstanceName instanceName, Environment environment, RegionName region) {
+ Optional<DeploymentInstanceSpec> instance = instance(instanceName);
+ if (instance.isEmpty()) return this.athenzService;
+ return instance.get().athenzService(environment, region).or(() -> this.athenzService);
+ }
+
/** Returns the XML form of this spec, or null if it was not created by fromXml, nor is empty */
public String xmlForm() { return xmlForm; }
@@ -200,15 +205,11 @@ public class DeploymentSpec {
private static List<DeploymentInstanceSpec> instances(List<DeploymentSpec.Step> steps) {
return steps.stream()
- .flatMap(DeploymentSpec::flatten)
+ .flatMap(step -> step instanceof ParallelZones ? ((ParallelZones) step).steps.stream() : List.of(step).stream())
+ .filter(step -> step instanceof DeploymentInstanceSpec).map(DeploymentInstanceSpec.class::cast)
.collect(Collectors.toList());
}
- private static Stream<DeploymentInstanceSpec> flatten(Step step) {
- if (step instanceof DeploymentInstanceSpec) return Stream.of((DeploymentInstanceSpec) step);
- return step.steps().stream().flatMap(DeploymentSpec::flatten);
- }
-
/**
* Creates a deployment spec from XML.
*
@@ -271,31 +272,23 @@ public class DeploymentSpec {
/** A deployment step */
public abstract static class Step {
- /** Returns whether this step specifies the given environment. */
- public final boolean concerns(Environment environment) {
- return concerns(environment, Optional.empty());
+ /** Returns whether this step deploys to the given region */
+ public final boolean deploysTo(Environment environment) {
+ return deploysTo(environment, Optional.empty());
}
- /** Returns whether this step specifies the given environment, and, optionally, region. */
- public abstract boolean concerns(Environment environment, Optional<RegionName> region);
+ /** Returns whether this step deploys to the given environment, and (if specified) region */
+ public abstract boolean deploysTo(Environment environment, Optional<RegionName> region);
- /** Returns the zones deployed to in this step. */
+ /** Returns the zones deployed to in this step */
public List<DeclaredZone> zones() { return Collections.emptyList(); }
- /** The delay introduced by this step (beyond the time it takes to execute the step). */
+ /** The delay introduced by this step (beyond the time it takes to execute the step). Default is zero. */
public Duration delay() { return Duration.ZERO; }
- /** Returns any steps nested in this. */
+ /** Returns all the steps nested in this. This default implementatiino returns an empty list. */
public List<Step> steps() { return List.of(); }
- /** Returns whether this step is a test step. */
- public boolean isTest() { return false; }
-
- /** Returns whether the nested steps in this, if any, should be performed in declaration order. */
- public boolean isOrdered() {
- return true;
- }
-
}
/** A deployment step which is to wait for some time before progressing to the next step */
@@ -311,7 +304,7 @@ public class DeploymentSpec {
public Duration delay() { return duration; }
@Override
- public boolean concerns(Environment environment, Optional<RegionName> region) { return false; }
+ public boolean deploysTo(Environment environment, Optional<RegionName> region) { return false; }
@Override
public String toString() {
@@ -362,16 +355,13 @@ public class DeploymentSpec {
public List<DeclaredZone> zones() { return Collections.singletonList(this); }
@Override
- public boolean concerns(Environment environment, Optional<RegionName> region) {
+ public boolean deploysTo(Environment environment, Optional<RegionName> region) {
if (environment != this.environment) return false;
if (region.isPresent() && ! region.equals(this.region)) return false;
return true;
}
@Override
- public boolean isTest() { return environment.isTest(); }
-
- @Override
public int hashCode() {
return Objects.hash(environment, region);
}
@@ -393,82 +383,39 @@ public class DeploymentSpec {
}
- /** A declared production test */
- public static class DeclaredTest extends Step {
-
- private final RegionName region;
-
- public DeclaredTest(RegionName region) {
- this.region = Objects.requireNonNull(region);
- }
-
- @Override
- public boolean concerns(Environment environment, Optional<RegionName> region) {
- return region.map(this.region::equals).orElse(true) && environment == Environment.prod;
- }
-
- @Override
- public boolean isTest() { return true; }
-
- /** Returns the region this test is for. */
- public RegionName region() {
- return region;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- DeclaredTest that = (DeclaredTest) o;
- return region.equals(that.region);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(region);
- }
-
- @Override
- public String toString() {
- return "tests for prod." + region;
- }
-
- }
-
- /** A container for several steps, by default in serial order */
- public static class Steps extends Step {
+ /** A deployment step which is to run multiple steps (zones or instances) in parallel */
+ public static class ParallelZones extends Step {
private final List<Step> steps;
- public Steps(List<Step> steps) {
+ public ParallelZones(List<Step> steps) {
this.steps = List.copyOf(steps);
}
+ /** Returns the steps inside this which are zones */
@Override
public List<DeclaredZone> zones() {
- return steps.stream()
- .flatMap(step -> step.zones().stream())
- .collect(Collectors.toUnmodifiableList());
+ return this.steps.stream()
+ .filter(step -> step instanceof DeclaredZone)
+ .map(DeclaredZone.class::cast)
+ .collect(Collectors.toList());
}
+ /** Returns all the steps nested in this */
@Override
public List<Step> steps() { return steps; }
@Override
- public boolean concerns(Environment environment, Optional<RegionName> region) {
- return steps.stream().anyMatch(step -> step.concerns(environment, region));
- }
-
- @Override
- public Duration delay() {
- return steps.stream().map(Step::delay).reduce(Duration.ZERO, Duration::plus);
+ public boolean deploysTo(Environment environment, Optional<RegionName> region) {
+ return steps().stream().anyMatch(zone -> zone.deploysTo(environment, region));
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- return steps.equals(((Steps) o).steps);
+ if (!(o instanceof ParallelZones)) return false;
+ ParallelZones that = (ParallelZones) o;
+ return Objects.equals(steps, that.steps);
}
@Override
@@ -478,43 +425,7 @@ public class DeploymentSpec {
@Override
public String toString() {
- return steps.size() + " steps";
- }
-
- }
-
- /** A container for multiple other steps, which are executed in parallel */
- public static class ParallelSteps extends Steps {
-
- public ParallelSteps(List<Step> steps) {
- super(steps);
- }
-
- @Override
- public Duration delay() {
- return steps().stream().map(Step::delay).max(Comparator.naturalOrder()).orElse(Duration.ZERO);
- }
-
- @Override
- public boolean isOrdered() {
- return false;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if ( ! (o instanceof ParallelSteps)) return false;
- return Objects.equals(steps(), ((ParallelSteps) o).steps());
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(steps());
- }
-
- @Override
- public String toString() {
- return steps().size() + " parallel steps";
+ return steps.size() + " parallel steps";
}
}
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
index c14e6ce5966..bc17ee0cb2b 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
@@ -3,12 +3,10 @@ package com.yahoo.config.application.api.xml;
import com.yahoo.config.application.api.DeploymentInstanceSpec;
import com.yahoo.config.application.api.DeploymentSpec;
-import com.yahoo.config.application.api.DeploymentSpec.DeclaredTest;
import com.yahoo.config.application.api.DeploymentSpec.DeclaredZone;
import com.yahoo.config.application.api.DeploymentSpec.Delay;
-import com.yahoo.config.application.api.DeploymentSpec.ParallelSteps;
+import com.yahoo.config.application.api.DeploymentSpec.ParallelZones;
import com.yahoo.config.application.api.DeploymentSpec.Step;
-import com.yahoo.config.application.api.DeploymentSpec.Steps;
import com.yahoo.config.application.api.Endpoint;
import com.yahoo.config.application.api.Notifications;
import com.yahoo.config.application.api.Notifications.Role;
@@ -22,7 +20,6 @@ import com.yahoo.config.provision.RegionName;
import com.yahoo.io.IOUtils;
import com.yahoo.text.XML;
import org.w3c.dom.Element;
-import org.w3c.dom.Node;
import java.io.IOException;
import java.io.Reader;
@@ -35,10 +32,8 @@ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
/**
* @author bratseth
@@ -55,7 +50,6 @@ public class DeploymentSpecXmlReader {
private static final String regionTag = "region";
private static final String delayTag = "delay";
private static final String parallelTag = "parallel";
- private static final String stepsTag = "steps";
private static final String endpointsTag = "endpoints";
private static final String endpointTag = "endpoint";
private static final String notificationsTag = "notifications";
@@ -124,7 +118,7 @@ public class DeploymentSpecXmlReader {
*
* @param instanceNameString a comma-separated list of the names of the instances this is for
* @param instanceTag the element having the content of this instance
- * @param parentTag the parent of instanceTag (or the same, if this instance is implicitly defined, which means instanceTag is the root)
+ * @param parentTag the parent of instanceTag (or the same, if this instances is implicitly defined which means instanceTag is the root)
* @return the instances specified, one for each instance name element
*/
private List<DeploymentInstanceSpec> readInstanceContent(String instanceNameString,
@@ -175,7 +169,6 @@ public class DeploymentSpecXmlReader {
}
// Consume the given tag as 0-N steps. 0 if it is not a step, >1 if it contains multiple nested steps that should be flattened
- @SuppressWarnings("fallthrough")
private List<Step> readNonInstanceSteps(Element stepTag, MutableOptional<String> globalServiceId, Element parentTag) {
Optional<AthenzService> athenzService = stringAttribute(athenzServiceAttribute, stepTag)
.or(() -> stringAttribute(athenzServiceAttribute, parentTag))
@@ -189,11 +182,7 @@ public class DeploymentSpecXmlReader {
throw new IllegalArgumentException("Attribute 'global-service-id' is only valid on 'prod' tag.");
switch (stepTag.getTagName()) {
- case testTag:
- if (Stream.iterate(stepTag, Objects::nonNull, Node::getParentNode)
- .anyMatch(node -> prodTag.equals(node.getNodeName())))
- return List.of(new DeclaredTest(RegionName.from(XML.getValue(stepTag).trim())));
- case stagingTag:
+ case testTag: case stagingTag:
return List.of(new DeclaredZone(Environment.from(stepTag.getTagName()), Optional.empty(), false, athenzService, testerFlavor));
case prodTag: // regions, delay and parallel may be nested within, but we can flatten them
return XML.getChildren(stepTag).stream()
@@ -204,13 +193,9 @@ public class DeploymentSpecXmlReader {
longAttribute("minutes", stepTag) * 60 +
longAttribute("seconds", stepTag))));
case parallelTag: // regions and instances may be nested within
- return List.of(new ParallelSteps(XML.getChildren(stepTag).stream()
+ return List.of(new ParallelZones(XML.getChildren(stepTag).stream()
.flatMap(child -> readSteps(child, globalServiceId, parentTag).stream())
.collect(Collectors.toList())));
- case stepsTag: // regions and instances may be nested within
- return List.of(new Steps(XML.getChildren(stepTag).stream()
- .flatMap(child -> readSteps(child, globalServiceId, parentTag).stream())
- .collect(Collectors.toList())));
case regionTag:
return List.of(readDeclaredZone(Environment.prod, athenzService, testerFlavor, stepTag));
default:
diff --git a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
index 584664b6ef1..987e13c0e86 100644
--- a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
+++ b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
@@ -3,11 +3,11 @@ package com.yahoo.config.application.api;
import com.google.common.collect.ImmutableSet;
import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
import org.junit.Test;
import java.io.StringReader;
-import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Collections;
@@ -42,11 +42,11 @@ public class DeploymentSpecTest {
assertEquals(specXml, spec.xmlForm());
assertEquals(1, spec.requireInstance("default").steps().size());
assertFalse(spec.majorVersion().isPresent());
- assertTrue(spec.requireInstance("default").steps().get(0).concerns(Environment.test));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.test, Optional.empty()));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.test, Optional.of(RegionName.from("region1"))));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.staging, Optional.empty()));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.prod, Optional.empty()));
+ assertTrue(spec.requireInstance("default").steps().get(0).deploysTo(Environment.test));
+ assertTrue(spec.requireInstance("default").includes(Environment.test, Optional.empty()));
+ assertFalse(spec.requireInstance("default").includes(Environment.test, Optional.of(RegionName.from("region1"))));
+ assertFalse(spec.requireInstance("default").includes(Environment.staging, Optional.empty()));
+ assertFalse(spec.requireInstance("default").includes(Environment.prod, Optional.empty()));
assertFalse(spec.requireInstance("default").globalServiceId().isPresent());
}
@@ -79,11 +79,11 @@ public class DeploymentSpecTest {
DeploymentSpec spec = DeploymentSpec.fromXml(r);
assertEquals(2, spec.steps().size());
assertEquals(1, spec.requireInstance("default").steps().size());
- assertTrue(spec.steps().get(0).concerns(Environment.test));
- assertTrue(spec.requireInstance("default").steps().get(0).concerns(Environment.staging));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.test, Optional.empty()));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.staging, Optional.empty()));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.prod, Optional.empty()));
+ assertTrue(spec.steps().get(0).deploysTo(Environment.test));
+ assertTrue(spec.requireInstance("default").steps().get(0).deploysTo(Environment.staging));
+ assertFalse(spec.requireInstance("default").includes(Environment.test, Optional.empty()));
+ assertTrue(spec.requireInstance("default").includes(Environment.staging, Optional.empty()));
+ assertFalse(spec.requireInstance("default").includes(Environment.prod, Optional.empty()));
assertFalse(spec.requireInstance("default").globalServiceId().isPresent());
}
@@ -104,21 +104,21 @@ public class DeploymentSpecTest {
assertEquals(3, spec.steps().size());
assertEquals(2, spec.requireInstance("default").steps().size());
- assertTrue(spec.steps().get(0).concerns(Environment.test));
+ assertTrue(spec.steps().get(0).deploysTo(Environment.test));
- assertTrue(spec.steps().get(1).concerns(Environment.staging));
+ assertTrue(spec.steps().get(1).deploysTo(Environment.staging));
- assertTrue(spec.requireInstance("default").steps().get(0).concerns(Environment.prod, Optional.of(RegionName.from("us-east1"))));
+ assertTrue(spec.requireInstance("default").steps().get(0).deploysTo(Environment.prod, Optional.of(RegionName.from("us-east1"))));
assertFalse(((DeploymentSpec.DeclaredZone)spec.requireInstance("default").steps().get(0)).active());
- assertTrue(spec.requireInstance("default").steps().get(1).concerns(Environment.prod, Optional.of(RegionName.from("us-west1"))));
+ assertTrue(spec.requireInstance("default").steps().get(1).deploysTo(Environment.prod, Optional.of(RegionName.from("us-west1"))));
assertTrue(((DeploymentSpec.DeclaredZone)spec.requireInstance("default").steps().get(1)).active());
- assertFalse(spec.requireInstance("default").deploysTo(Environment.test, Optional.empty()));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.staging, Optional.empty()));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.prod, Optional.of(RegionName.from("us-east1"))));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.prod, Optional.of(RegionName.from("us-west1"))));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.prod, Optional.of(RegionName.from("no-such-region"))));
+ assertFalse(spec.requireInstance("default").includes(Environment.test, Optional.empty()));
+ assertFalse(spec.requireInstance("default").includes(Environment.staging, Optional.empty()));
+ assertTrue(spec.requireInstance("default").includes(Environment.prod, Optional.of(RegionName.from("us-east1"))));
+ assertTrue(spec.requireInstance("default").includes(Environment.prod, Optional.of(RegionName.from("us-west1"))));
+ assertFalse(spec.requireInstance("default").includes(Environment.prod, Optional.of(RegionName.from("no-such-region"))));
assertFalse(spec.requireInstance("default").globalServiceId().isPresent());
assertEquals(DeploymentSpec.UpgradePolicy.defaultPolicy, spec.requireInstance("default").upgradePolicy());
@@ -145,84 +145,6 @@ public class DeploymentSpecTest {
}
@Test
- public void productionTests() {
- StringReader r = new StringReader(
- "<deployment version='1.0'>" +
- " <instance id='default'>" +
- " <test/>" +
- " <staging/>" +
- " <prod>" +
- " <region active='false'>us-east-1</region>" +
- " <region active='true'>us-west-1</region>" +
- " <delay hours='1' />" +
- " <test>us-west-1</test>" +
- " <test>us-east-1</test>" +
- " </prod>" +
- " </instance>" +
- "</deployment>"
- );
-
- DeploymentSpec spec = DeploymentSpec.fromXml(r);
- List<DeploymentSpec.Step> instanceSteps = spec.steps().get(0).steps();
- assertEquals(7, instanceSteps.size());
- assertEquals("test", instanceSteps.get(0).toString());
- assertEquals("staging", instanceSteps.get(1).toString());
- assertEquals("prod.us-east-1", instanceSteps.get(2).toString());
- assertEquals("prod.us-west-1", instanceSteps.get(3).toString());
- assertEquals("delay PT1H", instanceSteps.get(4).toString());
- assertEquals("tests for prod.us-west-1", instanceSteps.get(5).toString());
- assertEquals("tests for prod.us-east-1", instanceSteps.get(6).toString());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void duplicateProductionTest() {
- StringReader r = new StringReader(
- "<deployment version='1.0'>" +
- " <instance id='default'>" +
- " <prod>" +
- " <region active='true'>us-east1</region>" +
- " <test>us-east1</test>" +
- " <test>us-east1</test>" +
- " </prod>" +
- " </instance>" +
- "</deployment>"
- );
- DeploymentSpec.fromXml(r);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void productionTestBeforeDeployment() {
- StringReader r = new StringReader(
- "<deployment version='1.0'>" +
- " <instance id='default'>" +
- " <prod>" +
- " <test>us-east1</test>" +
- " <region active='true'>us-east1</region>" +
- " </prod>" +
- " </instance>" +
- "</deployment>"
- );
- DeploymentSpec.fromXml(r);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void productionTestInParallelWithDeployment() {
- StringReader r = new StringReader(
- "<deployment version='1.0'>" +
- " <instance id='default'>" +
- " <prod>" +
- " <parallel>" +
- " <region active='true'>us-east1</region>" +
- " <test>us-east1</test>" +
- " </parallel>" +
- " </prod>" +
- " </instance>" +
- "</deployment>"
- );
- DeploymentSpec.fromXml(r);
- }
-
- @Test
public void maximalProductionSpecMultipleInstances() {
StringReader r = new StringReader(
"<deployment version='1.0'>" +
@@ -251,7 +173,7 @@ public class DeploymentSpecTest {
assertEquals(1, instance2.steps().size());
assertEquals(1, instance2.zones().size());
- assertTrue(instance2.steps().get(0).concerns(Environment.prod, Optional.of(RegionName.from("us-central1"))));
+ assertTrue(instance2.steps().get(0).deploysTo(Environment.prod, Optional.of(RegionName.from("us-central1"))));
}
@Test
@@ -280,25 +202,25 @@ public class DeploymentSpecTest {
assertEquals(5, instance.steps().size());
assertEquals(4, instance.zones().size());
- assertTrue(instance.steps().get(0).concerns(Environment.test));
+ assertTrue(instance.steps().get(0).deploysTo(Environment.test));
- assertTrue(instance.steps().get(1).concerns(Environment.staging));
+ assertTrue(instance.steps().get(1).deploysTo(Environment.staging));
- assertTrue(instance.steps().get(2).concerns(Environment.prod, Optional.of(RegionName.from("us-east1"))));
+ assertTrue(instance.steps().get(2).deploysTo(Environment.prod, Optional.of(RegionName.from("us-east1"))));
assertFalse(((DeploymentSpec.DeclaredZone)instance.steps().get(2)).active());
assertTrue(instance.steps().get(3) instanceof DeploymentSpec.Delay);
assertEquals(3 * 60 * 60 + 30 * 60, instance.steps().get(3).delay().getSeconds());
- assertTrue(instance.steps().get(4).concerns(Environment.prod, Optional.of(RegionName.from("us-west1"))));
+ assertTrue(instance.steps().get(4).deploysTo(Environment.prod, Optional.of(RegionName.from("us-west1"))));
assertTrue(((DeploymentSpec.DeclaredZone)instance.steps().get(4)).active());
- assertTrue(instance.deploysTo(Environment.test, Optional.empty()));
- assertFalse(instance.deploysTo(Environment.test, Optional.of(RegionName.from("region1"))));
- assertTrue(instance.deploysTo(Environment.staging, Optional.empty()));
- assertTrue(instance.deploysTo(Environment.prod, Optional.of(RegionName.from("us-east1"))));
- assertTrue(instance.deploysTo(Environment.prod, Optional.of(RegionName.from("us-west1"))));
- assertFalse(instance.deploysTo(Environment.prod, Optional.of(RegionName.from("no-such-region"))));
+ assertTrue(instance.includes(Environment.test, Optional.empty()));
+ assertFalse(instance.includes(Environment.test, Optional.of(RegionName.from("region1"))));
+ assertTrue(instance.includes(Environment.staging, Optional.empty()));
+ assertTrue(instance.includes(Environment.prod, Optional.of(RegionName.from("us-east1"))));
+ assertTrue(instance.includes(Environment.prod, Optional.of(RegionName.from("us-west1"))));
+ assertFalse(instance.includes(Environment.prod, Optional.of(RegionName.from("no-such-region"))));
assertFalse(instance.globalServiceId().isPresent());
}
@@ -450,10 +372,10 @@ public class DeploymentSpecTest {
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
- DeploymentSpec.ParallelSteps parallelSteps = ((DeploymentSpec.ParallelSteps) spec.requireInstance("default").steps().get(1));
- assertEquals(2, parallelSteps.zones().size());
- assertEquals(RegionName.from("us-central-1"), parallelSteps.zones().get(0).region().get());
- assertEquals(RegionName.from("us-east-3"), parallelSteps.zones().get(1).region().get());
+ DeploymentSpec.ParallelZones parallelZones = ((DeploymentSpec.ParallelZones) spec.requireInstance("default").steps().get(1));
+ assertEquals(2, parallelZones.zones().size());
+ assertEquals(RegionName.from("us-central-1"), parallelZones.zones().get(0).region().get());
+ assertEquals(RegionName.from("us-east-3"), parallelZones.zones().get(1).region().get());
}
@Test
@@ -497,77 +419,6 @@ public class DeploymentSpecTest {
}
@Test
- public void testNestedParallelAndSteps() {
- StringReader r = new StringReader(
- "<deployment athenz-domain='domain'>" +
- " <instance id='instance' athenz-service='in-service'>" +
- " <prod>" +
- " <parallel>" +
- " <region active='true'>us-west-1</region>" +
- " <steps>" +
- " <region active='true'>us-east-3</region>" +
- " <delay hours='2' />" +
- " <region active='true'>eu-west-1</region>" +
- " <delay hours='2' />" +
- " </steps>" +
- " <steps>" +
- " <delay hours='3' />" +
- " <region active='true'>aws-us-east-1a</region>" +
- " <parallel>" +
- " <region active='true' athenz-service='no-service'>ap-northeast-1</region>" +
- " <region active='true'>ap-southeast-2</region>" +
- " </parallel>" +
- " </steps>" +
- " <delay hours='3' minutes='30' />" +
- " </parallel>" +
- " <region active='true'>us-north-7</region>" +
- " </prod>" +
- " </instance>" +
- "</deployment>"
- );
-
- DeploymentSpec spec = DeploymentSpec.fromXml(r);
- List<DeploymentSpec.Step> steps = spec.steps();
- assertEquals(3, steps.size());
- assertEquals("test", steps.get(0).toString());
- assertEquals("staging", steps.get(1).toString());
- assertEquals("instance 'instance'", steps.get(2).toString());
- assertEquals(Duration.ofHours(4), steps.get(2).delay());
-
- List<DeploymentSpec.Step> instanceSteps = steps.get(2).steps();
- assertEquals(2, instanceSteps.size());
- assertEquals("4 parallel steps", instanceSteps.get(0).toString());
- assertEquals("prod.us-north-7", instanceSteps.get(1).toString());
-
- List<DeploymentSpec.Step> parallelSteps = instanceSteps.get(0).steps();
- assertEquals(4, parallelSteps.size());
- assertEquals("prod.us-west-1", parallelSteps.get(0).toString());
- assertEquals("4 steps", parallelSteps.get(1).toString());
- assertEquals("3 steps", parallelSteps.get(2).toString());
- assertEquals("delay PT3H30M", parallelSteps.get(3).toString());
-
- List<DeploymentSpec.Step> firstSerialSteps = parallelSteps.get(1).steps();
- assertEquals(4, firstSerialSteps.size());
- assertEquals("prod.us-east-3", firstSerialSteps.get(0).toString());
- assertEquals("delay PT2H", firstSerialSteps.get(1).toString());
- assertEquals("prod.eu-west-1", firstSerialSteps.get(2).toString());
- assertEquals("delay PT2H", firstSerialSteps.get(3).toString());
-
- List<DeploymentSpec.Step> secondSerialSteps = parallelSteps.get(2).steps();
- assertEquals(3, secondSerialSteps.size());
- assertEquals("delay PT3H", secondSerialSteps.get(0).toString());
- assertEquals("prod.aws-us-east-1a", secondSerialSteps.get(1).toString());
- assertEquals("2 parallel steps", secondSerialSteps.get(2).toString());
-
- List<DeploymentSpec.Step> innerParallelSteps = secondSerialSteps.get(2).steps();
- assertEquals(2, innerParallelSteps.size());
- assertEquals("prod.ap-northeast-1", innerParallelSteps.get(0).toString());
- assertEquals("no-service", spec.requireInstance("instance").athenzService(Environment.prod, RegionName.from("ap-northeast-1")).get().value());
- assertEquals("prod.ap-southeast-2", innerParallelSteps.get(1).toString());
- assertEquals("in-service", spec.requireInstance("instance").athenzService(Environment.prod, RegionName.from("ap-southeast-2")).get().value());
- }
-
- @Test
public void testParallelInstances() {
StringReader r = new StringReader(
"<deployment>" +
@@ -635,8 +486,8 @@ public class DeploymentSpecTest {
" <region active='true'>us-west-1</region>" +
" <parallel>" +
" <region active='true'>us-west-1</region>" +
- " <region active='true'>us-central-1</region>" +
- " <region active='true'>us-east-3</region>" +
+ " <region active='true'>us-central-1</region>" +
+ " <region active='true'>us-east-3</region>" +
" </parallel>" +
" </prod>" +
" </instance>" +
diff --git a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecWithoutInstanceTest.java b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecWithoutInstanceTest.java
index 13ec7bf1a8b..31a30e5bd83 100644
--- a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecWithoutInstanceTest.java
+++ b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecWithoutInstanceTest.java
@@ -3,11 +3,11 @@ package com.yahoo.config.application.api;
import com.google.common.collect.ImmutableSet;
import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
import org.junit.Test;
import java.io.StringReader;
-import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Collections;
@@ -40,11 +40,11 @@ public class DeploymentSpecWithoutInstanceTest {
assertEquals(specXml, spec.xmlForm());
assertEquals(1, spec.steps().size());
assertFalse(spec.majorVersion().isPresent());
- assertTrue(spec.steps().get(0).concerns(Environment.test));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.test, Optional.empty()));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.test, Optional.of(RegionName.from("region1"))));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.staging, Optional.empty()));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.prod, Optional.empty()));
+ assertTrue(spec.steps().get(0).deploysTo(Environment.test));
+ assertTrue(spec.requireInstance("default").includes(Environment.test, Optional.empty()));
+ assertFalse(spec.requireInstance("default").includes(Environment.test, Optional.of(RegionName.from("region1"))));
+ assertFalse(spec.requireInstance("default").includes(Environment.staging, Optional.empty()));
+ assertFalse(spec.requireInstance("default").includes(Environment.prod, Optional.empty()));
assertFalse(spec.requireInstance("default").globalServiceId().isPresent());
}
@@ -73,11 +73,11 @@ public class DeploymentSpecWithoutInstanceTest {
DeploymentSpec spec = DeploymentSpec.fromXml(r);
assertEquals(2, spec.steps().size());
assertEquals(1, spec.requireInstance("default").steps().size());
- assertTrue(spec.steps().get(0).concerns(Environment.test));
- assertTrue(spec.requireInstance("default").steps().get(0).concerns(Environment.staging));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.test, Optional.empty()));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.staging, Optional.empty()));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.prod, Optional.empty()));
+ assertTrue(spec.steps().get(0).deploysTo(Environment.test));
+ assertTrue(spec.requireInstance("default").steps().get(0).deploysTo(Environment.staging));
+ assertFalse(spec.requireInstance("default").includes(Environment.test, Optional.empty()));
+ assertTrue(spec.requireInstance("default").includes(Environment.staging, Optional.empty()));
+ assertFalse(spec.requireInstance("default").includes(Environment.prod, Optional.empty()));
assertFalse(spec.requireInstance("default").globalServiceId().isPresent());
}
@@ -96,21 +96,21 @@ public class DeploymentSpecWithoutInstanceTest {
assertEquals(3, spec.steps().size());
assertEquals(2, spec.requireInstance("default").steps().size());
- assertTrue(spec.steps().get(0).concerns(Environment.test));
+ assertTrue(spec.steps().get(0).deploysTo(Environment.test));
- assertTrue(spec.steps().get(1).concerns(Environment.staging));
+ assertTrue(spec.steps().get(1).deploysTo(Environment.staging));
- assertTrue(spec.requireInstance("default").steps().get(0).concerns(Environment.prod, Optional.of(RegionName.from("us-east1"))));
+ assertTrue(spec.requireInstance("default").steps().get(0).deploysTo(Environment.prod, Optional.of(RegionName.from("us-east1"))));
assertFalse(((DeploymentSpec.DeclaredZone)spec.requireInstance("default").steps().get(0)).active());
- assertTrue(spec.requireInstance("default").steps().get(1).concerns(Environment.prod, Optional.of(RegionName.from("us-west1"))));
+ assertTrue(spec.requireInstance("default").steps().get(1).deploysTo(Environment.prod, Optional.of(RegionName.from("us-west1"))));
assertTrue(((DeploymentSpec.DeclaredZone)spec.requireInstance("default").steps().get(1)).active());
- assertFalse(spec.requireInstance("default").deploysTo(Environment.test, Optional.empty()));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.staging, Optional.empty()));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.prod, Optional.of(RegionName.from("us-east1"))));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.prod, Optional.of(RegionName.from("us-west1"))));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.prod, Optional.of(RegionName.from("no-such-region"))));
+ assertFalse(spec.requireInstance("default").includes(Environment.test, Optional.empty()));
+ assertFalse(spec.requireInstance("default").includes(Environment.staging, Optional.empty()));
+ assertTrue(spec.requireInstance("default").includes(Environment.prod, Optional.of(RegionName.from("us-east1"))));
+ assertTrue(spec.requireInstance("default").includes(Environment.prod, Optional.of(RegionName.from("us-west1"))));
+ assertFalse(spec.requireInstance("default").includes(Environment.prod, Optional.of(RegionName.from("no-such-region"))));
assertFalse(spec.requireInstance("default").globalServiceId().isPresent());
assertEquals(DeploymentSpec.UpgradePolicy.defaultPolicy, spec.requireInstance("default").upgradePolicy());
@@ -134,99 +134,29 @@ public class DeploymentSpecWithoutInstanceTest {
assertEquals(5, spec.requireInstance("default").steps().size());
assertEquals(4, spec.requireInstance("default").zones().size());
- assertTrue(spec.requireInstance("default").steps().get(0).concerns(Environment.test));
+ assertTrue(spec.requireInstance("default").steps().get(0).deploysTo(Environment.test));
- assertTrue(spec.requireInstance("default").steps().get(1).concerns(Environment.staging));
+ assertTrue(spec.requireInstance("default").steps().get(1).deploysTo(Environment.staging));
- assertTrue(spec.requireInstance("default").steps().get(2).concerns(Environment.prod, Optional.of(RegionName.from("us-east1"))));
+ assertTrue(spec.requireInstance("default").steps().get(2).deploysTo(Environment.prod, Optional.of(RegionName.from("us-east1"))));
assertFalse(((DeploymentSpec.DeclaredZone)spec.requireInstance("default").steps().get(2)).active());
assertTrue(spec.requireInstance("default").steps().get(3) instanceof DeploymentSpec.Delay);
assertEquals(3 * 60 * 60 + 30 * 60, spec.requireInstance("default").steps().get(3).delay().getSeconds());
- assertTrue(spec.requireInstance("default").steps().get(4).concerns(Environment.prod, Optional.of(RegionName.from("us-west1"))));
+ assertTrue(spec.requireInstance("default").steps().get(4).deploysTo(Environment.prod, Optional.of(RegionName.from("us-west1"))));
assertTrue(((DeploymentSpec.DeclaredZone)spec.requireInstance("default").steps().get(4)).active());
- assertTrue(spec.requireInstance("default").deploysTo(Environment.test, Optional.empty()));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.test, Optional.of(RegionName.from("region1"))));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.staging, Optional.empty()));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.prod, Optional.of(RegionName.from("us-east1"))));
- assertTrue(spec.requireInstance("default").deploysTo(Environment.prod, Optional.of(RegionName.from("us-west1"))));
- assertFalse(spec.requireInstance("default").deploysTo(Environment.prod, Optional.of(RegionName.from("no-such-region"))));
+ assertTrue(spec.requireInstance("default").includes(Environment.test, Optional.empty()));
+ assertFalse(spec.requireInstance("default").includes(Environment.test, Optional.of(RegionName.from("region1"))));
+ assertTrue(spec.requireInstance("default").includes(Environment.staging, Optional.empty()));
+ assertTrue(spec.requireInstance("default").includes(Environment.prod, Optional.of(RegionName.from("us-east1"))));
+ assertTrue(spec.requireInstance("default").includes(Environment.prod, Optional.of(RegionName.from("us-west1"))));
+ assertFalse(spec.requireInstance("default").includes(Environment.prod, Optional.of(RegionName.from("no-such-region"))));
assertFalse(spec.requireInstance("default").globalServiceId().isPresent());
}
@Test
- public void productionTests() {
- StringReader r = new StringReader(
- "<deployment version='1.0'>" +
- " <test/>" +
- " <staging/>" +
- " <prod>" +
- " <region active='false'>us-east-1</region>" +
- " <region active='true'>us-west-1</region>" +
- " <delay hours='1' />" +
- " <test>us-west-1</test>" +
- " <test>us-east-1</test>" +
- " </prod>" +
- "</deployment>"
- );
-
- DeploymentSpec spec = DeploymentSpec.fromXml(r);
- List<DeploymentSpec.Step> instanceSteps = spec.steps().get(0).steps();
- assertEquals(7, instanceSteps.size());
- assertEquals("test", instanceSteps.get(0).toString());
- assertEquals("staging", instanceSteps.get(1).toString());
- assertEquals("prod.us-east-1", instanceSteps.get(2).toString());
- assertEquals("prod.us-west-1", instanceSteps.get(3).toString());
- assertEquals("delay PT1H", instanceSteps.get(4).toString());
- assertEquals("tests for prod.us-west-1", instanceSteps.get(5).toString());
- assertEquals("tests for prod.us-east-1", instanceSteps.get(6).toString());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void duplicateProductionTests() {
- StringReader r = new StringReader(
- "<deployment version='1.0'>" +
- " <prod>" +
- " <region active='true'>us-east1</region>" +
- " <test>us-east1</test>" +
- " <test>us-east1</test>" +
- " </prod>" +
- "</deployment>"
- );
- DeploymentSpec.fromXml(r);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void productionTestBeforeDeployment() {
- StringReader r = new StringReader(
- "<deployment version='1.0'>" +
- " <prod>" +
- " <test>us-east1</test>" +
- " <region active='true'>us-east1</region>" +
- " </prod>" +
- "</deployment>"
- );
- DeploymentSpec.fromXml(r);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void productionTestInParallelWithDeployment() {
- StringReader r = new StringReader(
- "<deployment version='1.0'>" +
- " <prod>" +
- " <parallel>" +
- " <region active='true'>us-east1</region>" +
- " <test>us-east1</test>" +
- " </parallel>" +
- " </prod>" +
- "</deployment>"
- );
- DeploymentSpec.fromXml(r);
- }
-
- @Test
public void productionSpecWithGlobalServiceId() {
StringReader r = new StringReader(
"<deployment version='1.0'>" +
@@ -342,79 +272,10 @@ public class DeploymentSpecWithoutInstanceTest {
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
- DeploymentSpec.ParallelSteps parallelSteps = ((DeploymentSpec.ParallelSteps) spec.requireInstance("default").steps().get(1));
- assertEquals(2, parallelSteps.zones().size());
- assertEquals(RegionName.from("us-central-1"), parallelSteps.zones().get(0).region().get());
- assertEquals(RegionName.from("us-east-3"), parallelSteps.zones().get(1).region().get());
- }
-
- @Test
- public void testNestedParallelAndSteps() {
- StringReader r = new StringReader(
- "<deployment athenz-domain='domain' athenz-service='service'>" +
- " <prod>" +
- " <parallel>" +
- " <region active='true'>us-west-1</region>" +
- " <steps>" +
- " <region active='true'>us-east-3</region>" +
- " <delay hours='2' />" +
- " <region active='true'>eu-west-1</region>" +
- " <delay hours='2' />" +
- " </steps>" +
- " <steps>" +
- " <delay hours='3' />" +
- " <region active='true'>aws-us-east-1a</region>" +
- " <parallel>" +
- " <region active='true' athenz-service='no-service'>ap-northeast-1</region>" +
- " <region active='true'>ap-southeast-2</region>" +
- " </parallel>" +
- " </steps>" +
- " <delay hours='3' minutes='30' />" +
- " </parallel>" +
- " <region active='true'>us-north-7</region>" +
- " </prod>" +
- "</deployment>"
- );
-
- DeploymentSpec spec = DeploymentSpec.fromXml(r);
- List<DeploymentSpec.Step> steps = spec.steps();
- assertEquals(3, steps.size());
- assertEquals("test", steps.get(0).toString());
- assertEquals("staging", steps.get(1).toString());
- assertEquals("instance 'default'", steps.get(2).toString());
- assertEquals(Duration.ofHours(4), steps.get(2).delay());
-
- List<DeploymentSpec.Step> instanceSteps = steps.get(2).steps();
- assertEquals(2, instanceSteps.size());
- assertEquals("4 parallel steps", instanceSteps.get(0).toString());
- assertEquals("prod.us-north-7", instanceSteps.get(1).toString());
-
- List<DeploymentSpec.Step> parallelSteps = instanceSteps.get(0).steps();
- assertEquals(4, parallelSteps.size());
- assertEquals("prod.us-west-1", parallelSteps.get(0).toString());
- assertEquals("4 steps", parallelSteps.get(1).toString());
- assertEquals("3 steps", parallelSteps.get(2).toString());
- assertEquals("delay PT3H30M", parallelSteps.get(3).toString());
-
- List<DeploymentSpec.Step> firstSerialSteps = parallelSteps.get(1).steps();
- assertEquals(4, firstSerialSteps.size());
- assertEquals("prod.us-east-3", firstSerialSteps.get(0).toString());
- assertEquals("delay PT2H", firstSerialSteps.get(1).toString());
- assertEquals("prod.eu-west-1", firstSerialSteps.get(2).toString());
- assertEquals("delay PT2H", firstSerialSteps.get(3).toString());
-
- List<DeploymentSpec.Step> secondSerialSteps = parallelSteps.get(2).steps();
- assertEquals(3, secondSerialSteps.size());
- assertEquals("delay PT3H", secondSerialSteps.get(0).toString());
- assertEquals("prod.aws-us-east-1a", secondSerialSteps.get(1).toString());
- assertEquals("2 parallel steps", secondSerialSteps.get(2).toString());
-
- List<DeploymentSpec.Step> innerParallelSteps = secondSerialSteps.get(2).steps();
- assertEquals(2, innerParallelSteps.size());
- assertEquals("prod.ap-northeast-1", innerParallelSteps.get(0).toString());
- assertEquals("no-service", spec.requireInstance("default").athenzService(Environment.prod, RegionName.from("ap-northeast-1")).get().value());
- assertEquals("prod.ap-southeast-2", innerParallelSteps.get(1).toString());
- assertEquals("service", spec.requireInstance("default").athenzService(Environment.prod, RegionName.from("ap-southeast-2")).get().value());
+ DeploymentSpec.ParallelZones parallelZones = ((DeploymentSpec.ParallelZones) spec.requireInstance("default").steps().get(1));
+ assertEquals(2, parallelZones.zones().size());
+ assertEquals(RegionName.from("us-central-1"), parallelZones.zones().get(0).region().get());
+ assertEquals(RegionName.from("us-east-3"), parallelZones.zones().get(1).region().get());
}
@Test