diff options
author | Martin Polden <mpolden@mpolden.no> | 2017-10-02 13:34:54 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2017-10-02 13:34:54 +0200 |
commit | d211c1cce1959a866253292c7fa4eb1569af2a86 (patch) | |
tree | 8d48cbccc640073e86fded2521404be5e42b0301 | |
parent | c51cca11de7b4c2f3974d408028af7160edc9171 (diff) |
Disallow invalid project ID
9 files changed, 198 insertions, 125 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java index 5cc4c441c3b..f68ce3ebfa5 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java @@ -16,6 +16,7 @@ import com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobReport; import com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobType; import java.time.Instant; +import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; @@ -43,8 +44,9 @@ public class Application { /** Creates an empty application */ public Application(ApplicationId id) { - this(id, DeploymentSpec.empty, ValidationOverrides.empty, ImmutableMap.of(), new DeploymentJobs(0L), - Optional.empty(), false); // TODO: Get rid of the 0 + this(id, DeploymentSpec.empty, ValidationOverrides.empty, ImmutableMap.of(), + new DeploymentJobs(Optional.empty(), Collections.emptyList(), Optional.empty()), + Optional.empty(), false); } /** Used from persistence layer: Do not use */ @@ -52,7 +54,7 @@ public class Application { List<Deployment> deployments, DeploymentJobs deploymentJobs, Optional<Change> deploying, boolean outstandingChange) { this(id, deploymentSpec, validationOverrides, - deployments.stream().collect(Collectors.toMap(d -> d.zone(), d -> d)), + deployments.stream().collect(Collectors.toMap(Deployment::zone, d -> d)), deploymentJobs, deploying, outstandingChange); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/DeploymentJobs.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/DeploymentJobs.java index af8617cbf05..26bef06adcf 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/DeploymentJobs.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/DeploymentJobs.java @@ -32,24 +32,20 @@ public class DeploymentJobs { private final ImmutableMap<JobType, JobStatus> status; private final Optional<String> jiraIssueId; - /** Creates an empty set of deployment jobs */ - public DeploymentJobs(long projectId) { - this(Optional.of(projectId), ImmutableMap.of(), Optional.empty()); - } - - public DeploymentJobs(Optional<Long> projectId, Collection<JobStatus> jobStatusEntries, Optional<String> jiraIssueId) { + public DeploymentJobs(Optional<Long> projectId, Collection<JobStatus> jobStatusEntries, + Optional<String> jiraIssueId) { this(projectId, asMap(jobStatusEntries), jiraIssueId); } - + private DeploymentJobs(Optional<Long> projectId, Map<JobType, JobStatus> status, Optional<String> jiraIssueId) { - Objects.requireNonNull(projectId, "projectId cannot be null"); + requireId(projectId, "projectId cannot be null or <= 0"); Objects.requireNonNull(status, "status cannot be null"); Objects.requireNonNull(jiraIssueId, "jiraIssueId cannot be null"); this.projectId = projectId; this.status = ImmutableMap.copyOf(status); this.jiraIssueId = jiraIssueId; } - + private static Map<JobType, JobStatus> asMap(Collection<JobStatus> jobStatusEntries) { ImmutableMap.Builder<JobType, JobStatus> b = new ImmutableMap.Builder<>(); for (JobStatus jobStatusEntry : jobStatusEntries) @@ -306,4 +302,15 @@ public class DeploymentJobs { } } + private static Optional<Long> requireId(Optional<Long> id, String message) { + Objects.requireNonNull(id, message); + if (!id.isPresent()) { + return id; + } + if (id.get() <= 0) { + throw new IllegalArgumentException(message); + } + return id; + } + } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java index 14fce0987b7..81b3cb635ef 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java @@ -121,7 +121,9 @@ public class ApplicationSerializer { } private void toSlime(DeploymentJobs deploymentJobs, Cursor cursor) { - deploymentJobs.projectId().ifPresent(projectId -> cursor.setLong(projectIdField, projectId)); + deploymentJobs.projectId() + .filter(id -> id > 0) // TODO: Discards invalid data. Remove filter after October 2017 + .ifPresent(projectId -> cursor.setLong(projectIdField, projectId)); jobStatusToSlime(deploymentJobs.jobStatus().values(), cursor.setArray(jobStatusField)); deploymentJobs.jiraIssueId().ifPresent(jiraIssueId -> cursor.setString(jiraIssueIdField, jiraIssueId)); } @@ -213,7 +215,8 @@ public class ApplicationSerializer { } private DeploymentJobs deploymentJobsFromSlime(Inspector object) { - Optional<Long> projectId = optionalLong(object.field(projectIdField)); + Optional<Long> projectId = optionalLong(object.field(projectIdField)) + .filter(id -> id > 0); // TODO: Discards invalid data. Remove filter after October 2017 List<JobStatus> jobStatusList = jobStatusListFromSlime(object.field(jobStatusField)); Optional<String> jiraIssueKey = optionalString(object.field(jiraIssueIdField)); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/UpgraderTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/UpgraderTest.java index 5be030b4fd9..bc7b017dd7d 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/UpgraderTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/UpgraderTest.java @@ -39,12 +39,12 @@ public class UpgraderTest { assertEquals("No applications: Nothing to do", 0, tester.buildSystem().jobs().size()); // Setup applications - Application canary0 = tester.createAndDeploy("canary0", 0, "canary"); - Application canary1 = tester.createAndDeploy("canary1", 1, "canary"); - Application default0 = tester.createAndDeploy("default0", 2, "default"); - Application default1 = tester.createAndDeploy("default1", 3, "default"); - Application default2 = tester.createAndDeploy("default2", 4, "default"); - Application conservative0 = tester.createAndDeploy("conservative0", 5, "conservative"); + Application canary0 = tester.createAndDeploy("canary0", 1, "canary"); + Application canary1 = tester.createAndDeploy("canary1", 2, "canary"); + Application default0 = tester.createAndDeploy("default0", 3, "default"); + Application default1 = tester.createAndDeploy("default1", 4, "default"); + Application default2 = tester.createAndDeploy("default2", 5, "default"); + Application conservative0 = tester.createAndDeploy("conservative0", 6, "conservative"); tester.upgrader().maintain(); assertEquals("All already on the right version: Nothing to do", 0, tester.buildSystem().jobs().size()); @@ -163,18 +163,18 @@ public class UpgraderTest { assertEquals("No applications: Nothing to do", 0, tester.buildSystem().jobs().size()); // Setup applications - Application canary0 = tester.createAndDeploy("canary0", 0, "canary"); - Application canary1 = tester.createAndDeploy("canary1", 1, "canary"); - Application default0 = tester.createAndDeploy("default0", 2, "default"); - Application default1 = tester.createAndDeploy("default1", 3, "default"); - Application default2 = tester.createAndDeploy("default2", 4, "default"); - Application default3 = tester.createAndDeploy("default3", 5, "default"); - Application default4 = tester.createAndDeploy("default4", 6, "default"); - Application default5 = tester.createAndDeploy("default5", 7, "default"); - Application default6 = tester.createAndDeploy("default6", 8, "default"); - Application default7 = tester.createAndDeploy("default7", 9, "default"); - Application default8 = tester.createAndDeploy("default8", 10, "default"); - Application default9 = tester.createAndDeploy("default9", 11, "default"); + Application canary0 = tester.createAndDeploy("canary0", 1, "canary"); + Application canary1 = tester.createAndDeploy("canary1", 2, "canary"); + Application default0 = tester.createAndDeploy("default0", 3, "default"); + Application default1 = tester.createAndDeploy("default1", 4, "default"); + Application default2 = tester.createAndDeploy("default2", 5, "default"); + Application default3 = tester.createAndDeploy("default3", 6, "default"); + Application default4 = tester.createAndDeploy("default4", 7, "default"); + Application default5 = tester.createAndDeploy("default5", 8, "default"); + Application default6 = tester.createAndDeploy("default6", 9, "default"); + Application default7 = tester.createAndDeploy("default7", 10, "default"); + Application default8 = tester.createAndDeploy("default8", 11, "default"); + Application default9 = tester.createAndDeploy("default9", 12, "default"); tester.upgrader().maintain(); assertEquals("All already on the right version: Nothing to do", 0, tester.buildSystem().jobs().size()); @@ -275,13 +275,13 @@ public class UpgraderTest { tester.updateVersionStatus(version); // Setup applications - Application canary0 = tester.createAndDeploy("canary0", 0, "canary"); - Application canary1 = tester.createAndDeploy("canary1", 1, "canary"); - Application default0 = tester.createAndDeploy("default0", 2, "default"); - Application default1 = tester.createAndDeploy("default1", 3, "default"); - Application default2 = tester.createAndDeploy("default2", 4, "default"); - Application default3 = tester.createAndDeploy("default3", 5, "default"); - Application default4 = tester.createAndDeploy("default4", 6, "default"); + Application canary0 = tester.createAndDeploy("canary0", 1, "canary"); + Application canary1 = tester.createAndDeploy("canary1", 2, "canary"); + Application default0 = tester.createAndDeploy("default0", 3, "default"); + Application default1 = tester.createAndDeploy("default1", 4, "default"); + Application default2 = tester.createAndDeploy("default2", 5, "default"); + Application default3 = tester.createAndDeploy("default3", 6, "default"); + Application default4 = tester.createAndDeploy("default4", 7, "default"); // New version is released version = Version.fromString("5.1"); @@ -321,13 +321,13 @@ public class UpgraderTest { tester.updateVersionStatus(version); // Setup applications - Application canary0 = tester.createAndDeploy("canary0", 0, "canary"); - Application canary1 = tester.createAndDeploy("canary1", 1, "canary"); - Application default0 = tester.createAndDeploy("default0", 2, "default"); - Application default1 = tester.createAndDeploy("default1", 3, "default"); - Application default2 = tester.createAndDeploy("default2", 4, "default"); - Application default3 = tester.createAndDeploy("default3", 5, "default"); - Application default4 = tester.createAndDeploy("default4", 5, "default"); + Application canary0 = tester.createAndDeploy("canary0", 1, "canary"); + Application canary1 = tester.createAndDeploy("canary1", 2, "canary"); + Application default0 = tester.createAndDeploy("default0", 3, "default"); + Application default1 = tester.createAndDeploy("default1", 4, "default"); + Application default2 = tester.createAndDeploy("default2", 5, "default"); + Application default3 = tester.createAndDeploy("default3", 6, "default"); + Application default4 = tester.createAndDeploy("default4", 7, "default"); // New version is released version = Version.fromString("5.1"); @@ -412,13 +412,13 @@ public class UpgraderTest { .build(); // Setup applications - Application canary0 = tester.createAndDeploy("canary0", 0, "canary"); - Application canary1 = tester.createAndDeploy("canary1", 1, "canary"); - Application default0 = tester.createAndDeploy("default0", 2, "default"); - Application default1 = tester.createAndDeploy("default1", 3, "default"); - Application default2 = tester.createAndDeploy("default2", 4, "default"); - Application default3 = tester.createAndDeploy("default3", 5, "default"); - Application default4 = tester.createAndDeploy("default4", 6, "default"); + Application canary0 = tester.createAndDeploy("canary0", 1, "canary"); + Application canary1 = tester.createAndDeploy("canary1", 2, "canary"); + Application default0 = tester.createAndDeploy("default0", 3, "default"); + Application default1 = tester.createAndDeploy("default1", 4, "default"); + Application default2 = tester.createAndDeploy("default2", 5, "default"); + Application default3 = tester.createAndDeploy("default3", 6, "default"); + Application default4 = tester.createAndDeploy("default4", 7, "default"); // New version is released version = Version.fromString("5.1"); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java index f0a2019d41e..4df7f343522 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java @@ -138,17 +138,30 @@ public class ApplicationSerializerTest { assertFalse(application.deploymentJobs().jobStatus().get(DeploymentJobs.JobType.systemTest).lastCompleted().get().upgrade()); } + // TODO: Remove after October 2017 + @Test + public void testLegacySerializationWithZeroProjectId() { + Application original = applicationSerializer.fromSlime(applicationSlime(0, false)); + assertFalse(original.deploymentJobs().projectId().isPresent()); + Application serialized = applicationSerializer.fromSlime(applicationSerializer.toSlime(original)); + assertFalse(serialized.deploymentJobs().projectId().isPresent()); + } + private Slime applicationSlime(boolean error) { - return SlimeUtils.jsonToSlime(applicationJson(error).getBytes(StandardCharsets.UTF_8)); + return applicationSlime(123, error); + } + + private Slime applicationSlime(long projectId, boolean error) { + return SlimeUtils.jsonToSlime(applicationJson(projectId, error).getBytes(StandardCharsets.UTF_8)); } - private String applicationJson(boolean error) { + private String applicationJson(long projectId, boolean error) { return "{\n" + " \"id\": \"t1:a1:i1\",\n" + " \"deploymentSpecField\": \"<deployment version='1.0'/>\",\n" + " \"deploymentJobs\": {\n" + - " \"projectId\": 123,\n" + + " \"projectId\": " + projectId + ",\n" + " \"jobStatus\": [\n" + " {\n" + " \"jobType\": \"system-test\",\n" + diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java index 4fc6e91039c..b55ee9a195f 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java @@ -78,8 +78,8 @@ public class ContainerTester { public void assertResponse(Request request, String expectedResponse, int expectedStatusCode) throws IOException { Response response = container.handleRequest(request); - assertEquals("Status code", expectedStatusCode, response.getStatus()); assertEquals(expectedResponse, response.getBodyAsString()); + assertEquals("Status code", expectedStatusCode, response.getStatus()); } private Set<String> fieldsToCensor(String fieldNameOrNull, Inspector value, Set<String> fieldsToCensor) { diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java index 50ad84028f1..18073ef06f3 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java @@ -131,27 +131,27 @@ public class ApplicationApiTest extends ControllerContainerTest { new File("application-deployment.json")); // ... systemtest - tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/test-region/instance/default/", + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default/", createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)), Request.Method.POST, athensScrewdriverDomain, "screwdriveruser1"), new File("deploy-result.json")); - tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/test-region/instance/default", + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default", "", Request.Method.DELETE), - "Deactivated tenant/tenant1/application/application1/environment/test/region/test-region/instance/default"); + "Deactivated tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default"); controllerTester.notifyJobCompletion(id, screwdriverProjectId, true, DeploymentJobs.JobType.systemTest); // Called through the separate screwdriver/v1 API // ... staging - tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/staging-region/instance/default/", + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default/", createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)), Request.Method.POST, athensScrewdriverDomain, "screwdriveruser1"), new File("deploy-result.json")); - tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/staging-region/instance/default", + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default", "", Request.Method.DELETE), - "Deactivated tenant/tenant1/application/application1/environment/staging/region/staging-region/instance/default"); + "Deactivated tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default"); controllerTester.notifyJobCompletion(id, screwdriverProjectId, true, DeploymentJobs.JobType.stagingTest); // ... prod zone diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json index 5df690f5bc7..cc17e76642f 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json @@ -8,71 +8,119 @@ "success": true, "lastTriggered": { "version": "(ignore)", + "revision": { + "hash": "(ignore)", + "source": { + "gitRepository": "repository1", + "gitBranch": "master", + "gitCommit": "commit1" + } + }, "at": "(ignore)" }, "lastCompleted": { "version": "(ignore)", + "revision": { + "hash": "(ignore)", + "source": { + "gitRepository": "repository1", + "gitBranch": "master", + "gitCommit": "commit1" + } + }, "at": "(ignore)" }, "lastSuccess": { "version": "(ignore)", + "revision": { + "hash": "(ignore)", + "source": { + "gitRepository": "repository1", + "gitBranch": "master", + "gitCommit": "commit1" + } + }, "at": "(ignore)" } }, { - "type":"staging-test", - "success":true, - "lastTriggered":{ - "version":"(ignore)", - "at":"(ignore)" + "type": "staging-test", + "success": true, + "lastTriggered": { + "version": "(ignore)", + "revision": { + "hash": "(ignore)", + "source": { + "gitRepository": "repository1", + "gitBranch": "master", + "gitCommit": "commit1" + } + }, + "at": "(ignore)" }, - "lastCompleted":{ - "version":"(ignore)", - "at":"(ignore)" + "lastCompleted": { + "version": "(ignore)", + "revision": { + "hash": "(ignore)", + "source": { + "gitRepository": "repository1", + "gitBranch": "master", + "gitCommit": "commit1" + } + }, + "at": "(ignore)" }, - "lastSuccess":{ - "version":"(ignore)", - "at":"(ignore)" + "lastSuccess": { + "version": "(ignore)", + "revision": { + "hash": "(ignore)", + "source": { + "gitRepository": "repository1", + "gitBranch": "master", + "gitCommit": "commit1" + } + }, + "at": "(ignore)" } }, { - "type":"production-corp-us-east-1", - "success":false, - "lastTriggered":{ - "version":"(ignore)", - "revision":{ - "hash":"(ignore)", - "source":{ - "gitRepository":"repository1", - "gitBranch":"master", - "gitCommit":"commit1" + "type": "production-corp-us-east-1", + "success": false, + "lastTriggered": { + "version": "(ignore)", + "revision": { + "hash": "(ignore)", + "source": { + "gitRepository": "repository1", + "gitBranch": "master", + "gitCommit": "commit1" } }, - "at":"(ignore)" + "at": "(ignore)" }, - "lastCompleted":{ - "version":"(ignore)", - "revision":{ - "hash":"(ignore)", - "source":{ - "gitRepository":"repository1", - "gitBranch":"master", - "gitCommit":"commit1" + "lastCompleted": { + "version": "(ignore)", + "revision": { + "hash": "(ignore)", + "source": { + "gitRepository": "repository1", + "gitBranch": "master", + "gitCommit": "commit1" } }, - "at":"(ignore)" + "at": "(ignore)" }, - "firstFailing":{ - "version":"(ignore)", - "revision":{ - "hash":"(ignore)", - "source":{ - "gitRepository":"repository1", - "gitBranch":"master", - "gitCommit":"commit1" + "firstFailing": { + "version": "(ignore)", + "revision": { + "hash": "(ignore)", + "source": { + "gitRepository": "repository1", + "gitBranch": "master", + "gitCommit": "commit1" } }, - "at":"(ignore)" + "at": "(ignore)" } } ], @@ -91,14 +139,14 @@ "environment": "prod", "region": "corp-us-east-1", "instance": "default", - "bcpStatus": {"rotationStatus":"UNKNOWN"}, + "bcpStatus": { + "rotationStatus": "UNKNOWN" + }, "url": "http://localhost:8080/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default" } - ] - , - "metrics": - { - "queryServiceQuality":0.5, - "writeServiceQuality":0.7 - } + ], + "metrics": { + "queryServiceQuality": 0.5, + "writeServiceQuality": 0.7 + } } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java index 6071776edf5..7bbbf8f0499 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java @@ -131,20 +131,20 @@ public class VersionStatusTest { tester.upgradeSystem(version0); // Setup applications - Application canary0 = tester.createAndDeploy("canary0", 0, "canary"); - Application canary1 = tester.createAndDeploy("canary1", 1, "canary"); - Application canary2 = tester.createAndDeploy("canary2", 2, "canary"); - Application default0 = tester.createAndDeploy("default0", 00, "default"); - Application default1 = tester.createAndDeploy("default1", 11, "default"); - Application default2 = tester.createAndDeploy("default2", 22, "default"); - Application default3 = tester.createAndDeploy("default3", 33, "default"); - Application default4 = tester.createAndDeploy("default4", 44, "default"); - Application default5 = tester.createAndDeploy("default5", 55, "default"); - Application default6 = tester.createAndDeploy("default6", 66, "default"); - Application default7 = tester.createAndDeploy("default7", 77, "default"); - Application default8 = tester.createAndDeploy("default8", 88, "default"); - Application default9 = tester.createAndDeploy("default9", 99, "default"); - Application conservative0 = tester.createAndDeploy("conservative1", 000, "conservative"); + Application canary0 = tester.createAndDeploy("canary0", 1, "canary"); + Application canary1 = tester.createAndDeploy("canary1", 2, "canary"); + Application canary2 = tester.createAndDeploy("canary2", 3, "canary"); + Application default0 = tester.createAndDeploy("default0", 4, "default"); + Application default1 = tester.createAndDeploy("default1", 5, "default"); + Application default2 = tester.createAndDeploy("default2", 6, "default"); + Application default3 = tester.createAndDeploy("default3", 7, "default"); + Application default4 = tester.createAndDeploy("default4", 8, "default"); + Application default5 = tester.createAndDeploy("default5", 9, "default"); + Application default6 = tester.createAndDeploy("default6", 10, "default"); + Application default7 = tester.createAndDeploy("default7", 11, "default"); + Application default8 = tester.createAndDeploy("default8", 12, "default"); + Application default9 = tester.createAndDeploy("default9", 13, "default"); + Application conservative0 = tester.createAndDeploy("conservative1", 14, "conservative"); // The following applications should not affect confidence calculation: |