use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class DeploymentTriggerTest method testHandleMultipleNotificationsFromLastJob.
@Test
public void testHandleMultipleNotificationsFromLastJob() {
DeploymentTester tester = new DeploymentTester();
DeploymentQueue deploymentQueue = tester.deploymentQueue();
TenantId tenant = tester.controllerTester().createTenant("tenant1", "domain1", 1L);
Application application = tester.controllerTester().createApplication(tenant, "app1", "default", 1L);
ApplicationPackage applicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("corp-us-east-1").build();
// Component job finishes
tester.jobCompletion(component).application(application).uploadArtifact(applicationPackage).submit();
// Application is deployed to all test environments and declared zones
tester.deployAndNotify(application, applicationPackage, true, JobType.systemTest);
tester.deployAndNotify(application, applicationPackage, true, JobType.stagingTest);
tester.deployAndNotify(application, applicationPackage, true, JobType.productionCorpUsEast1);
// Extra notification for last job
tester.jobCompletion(JobType.productionCorpUsEast1).application(application).submit();
assertFalse("Change has been deployed", tester.applications().require(application.id()).change().isPresent());
assertTrue("All jobs consumed", deploymentQueue.jobs().isEmpty());
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class DeploymentTriggerTest method testSuccessfulDeploymentApplicationPackageChanged.
@Test
public void testSuccessfulDeploymentApplicationPackageChanged() {
DeploymentTester tester = new DeploymentTester();
DeploymentQueue deploymentQueue = tester.deploymentQueue();
TenantId tenant = tester.controllerTester().createTenant("tenant1", "domain1", 1L);
Application application = tester.controllerTester().createApplication(tenant, "app1", "default", 1L);
ApplicationPackage previousApplicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("corp-us-east-1").region("us-central-1").region("us-west-1").build();
ApplicationPackage newApplicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("corp-us-east-1").region("us-central-1").region("us-west-1").region("eu-west-1").build();
// Component job finishes
tester.jobCompletion(component).application(application).uploadArtifact(newApplicationPackage).submit();
// Application is deployed to all test environments and declared zones
tester.deployAndNotify(application, newApplicationPackage, true, JobType.systemTest);
tester.deploy(JobType.stagingTest, application, previousApplicationPackage, true);
tester.deployAndNotify(application, newApplicationPackage, true, JobType.stagingTest);
tester.deployAndNotify(application, newApplicationPackage, true, JobType.productionCorpUsEast1);
tester.deployAndNotify(application, newApplicationPackage, true, JobType.productionUsCentral1);
tester.deployAndNotify(application, newApplicationPackage, true, JobType.productionUsWest1);
tester.deployAndNotify(application, newApplicationPackage, true, JobType.productionEuWest1);
assertTrue("All jobs consumed", deploymentQueue.jobs().isEmpty());
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class DeploymentTriggerTest method applicationVersionIsNotDowngraded.
@Test
public void applicationVersionIsNotDowngraded() {
DeploymentTester tester = new DeploymentTester();
Application application = tester.createApplication("app1", "tenant1", 1, 1L);
Supplier<Application> app = () -> tester.application(application.id());
ApplicationPackage applicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("us-central-1").region("eu-west-1").build();
tester.deployCompletely(application, applicationPackage);
// productionUsCentral1 fails after deployment, causing a mismatch between deployed and successful state.
tester.completeDeploymentWithError(application, applicationPackage, BuildJob.defaultBuildNumber + 1, productionUsCentral1);
// deployAndNotify doesn't actually deploy if the job fails, so we need to do that manually.
tester.deployAndNotify(application, Optional.empty(), false, true, productionUsCentral1);
tester.deploy(productionUsCentral1, application, Optional.empty(), false);
ApplicationVersion appVersion1 = ApplicationVersion.from(BuildJob.defaultSourceRevision, BuildJob.defaultBuildNumber + 1);
assertEquals(appVersion1, app.get().deployments().get(ZoneId.from("prod.us-central-1")).applicationVersion());
// Verify the application change is not removed when change is cancelled.
tester.deploymentTrigger().cancelChange(application.id(), true);
assertEquals(Change.of(appVersion1), app.get().change());
// Now cancel the change as is done through the web API.
tester.deploymentTrigger().cancelChange(application.id(), false);
assertEquals(Change.empty(), app.get().change());
// A new version is released, which should now deploy the currently deployed application version to avoid downgrades.
Version version1 = new Version("6.2");
tester.upgradeSystem(version1);
tester.jobCompletion(productionUsCentral1).application(application).unsuccessful().submit();
tester.completeUpgrade(application, version1, applicationPackage);
assertEquals(appVersion1, app.get().deployments().get(ZoneId.from("prod.us-central-1")).applicationVersion());
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class ApplicationOwnershipConfirmerTest method testConfirmation.
@Test
public void testConfirmation() {
TenantId property = tester.controllerTester().createTenant("property", "domain", 1L);
tester.createAndDeploy(property, "application", 1, "default");
Supplier<Application> propertyApp = () -> tester.controller().applications().require(ApplicationId.from("property", "application", "default"));
TenantId user = new TenantId("by-user");
tester.controller().tenants().createUserTenant("user");
tester.createAndDeploy(user, "application", 2, "default");
Supplier<Application> userApp = () -> tester.controller().applications().require(ApplicationId.from("by-user", "application", "default"));
assertFalse("No issue is initially stored for a new application.", propertyApp.get().ownershipIssueId().isPresent());
assertFalse("No issue is initially stored for a new application.", userApp.get().ownershipIssueId().isPresent());
assertFalse("No escalation has been attempted for a new application", issues.escalatedForProperty || issues.escalatedForUser);
// Set response from the issue mock, which will be obtained by the maintainer on issue filing.
Optional<IssueId> issueId = Optional.of(IssueId.from("1"));
issues.response = issueId;
confirmer.maintain();
confirmer.maintain();
assertEquals("Confirmation issue has been filed for property owned application.", issueId, propertyApp.get().ownershipIssueId());
assertEquals("Confirmation issue has been filed for user owned application.", issueId, userApp.get().ownershipIssueId());
assertTrue("Both applications have had their responses ensured.", issues.escalatedForProperty && issues.escalatedForUser);
// No new issue is created, so return empty now.
issues.response = Optional.empty();
confirmer.maintain();
confirmer.maintain();
assertEquals("Confirmation issue reference is not updated when no issue id is returned.", issueId, propertyApp.get().ownershipIssueId());
assertEquals("Confirmation issue reference is not updated when no issue id is returned.", issueId, userApp.get().ownershipIssueId());
// The user deletes all production deployments — see that the issue is forgotten.
assertEquals("Confirmation issue for user is sitll open.", issueId, userApp.get().ownershipIssueId());
tester.controller().applications().deactivate(userApp.get(), userApp.get().productionDeployments().keySet().stream().findAny().get());
tester.controller().applications().deactivate(userApp.get(), userApp.get().productionDeployments().keySet().stream().findAny().get());
assertTrue("No production deployments are listed for user.", userApp.get().productionDeployments().isEmpty());
confirmer.maintain();
confirmer.maintain();
// Time has passed, and a new confirmation issue is in order for the property which is still in production.
Optional<IssueId> issueId2 = Optional.of(IssueId.from("2"));
issues.response = issueId2;
confirmer.maintain();
confirmer.maintain();
assertEquals("A new confirmation issue id is stored when something is returned to the maintainer.", issueId2, propertyApp.get().ownershipIssueId());
assertEquals("Confirmation issue for application without production deployments has not been filed.", issueId, userApp.get().ownershipIssueId());
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class ApplicationApiHandler method rotationStatus.
private HttpResponse rotationStatus(String tenantName, String applicationName, String instanceName, String environment, String region) {
ApplicationId applicationId = ApplicationId.from(tenantName, applicationName, instanceName);
Application application = controller.applications().require(applicationId);
if (!application.rotation().isPresent()) {
throw new NotExistsException("global rotation does not exist for '" + environment + "." + region + "'");
}
Slime slime = new Slime();
Cursor response = slime.setObject();
Map<String, RotationStatus> rotationHealthStatus = controller.getHealthStatus(application.rotation().get().dnsName());
for (String rotationEndpoint : rotationHealthStatus.keySet()) {
if (rotationEndpoint.contains(toDns(environment)) && rotationEndpoint.contains(toDns(region))) {
Cursor bcpStatusObject = response.setObject("bcpStatus");
bcpStatusObject.setString("rotationStatus", rotationHealthStatus.getOrDefault(rotationEndpoint, RotationStatus.UNKNOWN).name());
}
}
return new SlimeJsonResponse(slime);
}
Aggregations