Search in sources :

Example 1 with JobStatus

use of com.yahoo.vespa.hosted.controller.application.JobStatus in project vespa by vespa-engine.

the class ApplicationApiTest method testJobStatusReportingOutOfCapacity.

@Test
public void testJobStatusReportingOutOfCapacity() {
    ContainerControllerTester tester = new ContainerControllerTester(container, responseFiles);
    tester.containerTester().updateSystemVersion();
    long projectId = 1;
    Application app = tester.createApplication();
    ApplicationPackage applicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("corp-us-east-1").build();
    // Report job failing with out of capacity
    BuildJob job = new BuildJob(report -> notifyCompletion(report, tester), tester.artifactRepository()).application(app).projectId(projectId);
    job.type(DeploymentJobs.JobType.component).uploadArtifact(applicationPackage).submit();
    tester.deploy(app, applicationPackage, TEST_ZONE, projectId);
    job.type(DeploymentJobs.JobType.systemTest).submit();
    tester.deploy(app, applicationPackage, STAGING_ZONE, projectId);
    job.type(DeploymentJobs.JobType.stagingTest).error(DeploymentJobs.JobError.outOfCapacity).submit();
    // Appropriate error is recorded
    JobStatus jobStatus = tester.controller().applications().get(app.id()).get().deploymentJobs().jobStatus().get(DeploymentJobs.JobType.stagingTest);
    assertFalse(jobStatus.isSuccess());
    assertEquals(DeploymentJobs.JobError.outOfCapacity, jobStatus.jobError().get());
}
Also used : JobStatus(com.yahoo.vespa.hosted.controller.application.JobStatus) ContainerControllerTester(com.yahoo.vespa.hosted.controller.restapi.ContainerControllerTester) ApplicationPackageBuilder(com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder) BuildJob(com.yahoo.vespa.hosted.controller.deployment.BuildJob) Application(com.yahoo.vespa.hosted.controller.Application) ApplicationPackage(com.yahoo.vespa.hosted.controller.application.ApplicationPackage) ControllerContainerTest(com.yahoo.vespa.hosted.controller.restapi.ControllerContainerTest) Test(org.junit.Test)

Example 2 with JobStatus

use of com.yahoo.vespa.hosted.controller.application.JobStatus in project vespa by vespa-engine.

the class ApplicationApiTest method testJobStatusReporting.

@Test
public void testJobStatusReporting() throws Exception {
    ContainerControllerTester tester = new ContainerControllerTester(container, responseFiles);
    addUserToHostedOperatorRole(HostedAthenzIdentities.from(HOSTED_VESPA_OPERATOR));
    tester.containerTester().updateSystemVersion();
    long projectId = 1;
    Application app = tester.createApplication();
    ApplicationPackage applicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("corp-us-east-1").build();
    // system version from mock config server client
    Version vespaVersion = new Version("6.1");
    BuildJob job = new BuildJob(report -> notifyCompletion(report, tester), tester.artifactRepository()).application(app).projectId(projectId);
    job.type(DeploymentJobs.JobType.component).uploadArtifact(applicationPackage).submit();
    tester.deploy(app, applicationPackage, TEST_ZONE, projectId);
    job.type(DeploymentJobs.JobType.systemTest).submit();
    // Notifying about unknown job fails
    Request request = request("/application/v4/tenant/tenant1/application/application1/jobreport", POST).data(asJson(job.type(DeploymentJobs.JobType.productionUsEast3).report())).userIdentity(HOSTED_VESPA_OPERATOR).get();
    tester.containerTester().assertResponse(request, new File("jobreport-unexpected-completion.json"), 400);
    // ... and assert it was recorded
    JobStatus recordedStatus = tester.controller().applications().get(app.id()).get().deploymentJobs().jobStatus().get(DeploymentJobs.JobType.component);
    assertNotNull("Status was recorded", recordedStatus);
    assertTrue(recordedStatus.isSuccess());
    assertEquals(vespaVersion, recordedStatus.lastCompleted().get().version());
    recordedStatus = tester.controller().applications().get(app.id()).get().deploymentJobs().jobStatus().get(DeploymentJobs.JobType.productionApNortheast2);
    assertNull("Status of never-triggered jobs is empty", recordedStatus);
    Response response;
    response = container.handleRequest(request("/screwdriver/v1/jobsToRun", GET).get());
    assertTrue("Response contains system-test", response.getBodyAsString().contains(DeploymentJobs.JobType.systemTest.jobName()));
    assertTrue("Response contains staging-test", response.getBodyAsString().contains(DeploymentJobs.JobType.stagingTest.jobName()));
    assertEquals("Response contains only two items", 2, SlimeUtils.jsonToSlime(response.getBody()).get().entries());
    // Check that GET didn't affect the enqueued jobs.
    response = container.handleRequest(request("/screwdriver/v1/jobsToRun", GET).get());
    assertTrue("Response contains system-test", response.getBodyAsString().contains(DeploymentJobs.JobType.systemTest.jobName()));
    assertTrue("Response contains staging-test", response.getBodyAsString().contains(DeploymentJobs.JobType.stagingTest.jobName()));
    assertEquals("Response contains only two items", 2, SlimeUtils.jsonToSlime(response.getBody()).get().entries());
}
Also used : JobStatus(com.yahoo.vespa.hosted.controller.application.JobStatus) Response(com.yahoo.application.container.handler.Response) ContainerControllerTester(com.yahoo.vespa.hosted.controller.restapi.ContainerControllerTester) Version(com.yahoo.component.Version) Request(com.yahoo.application.container.handler.Request) ApplicationPackageBuilder(com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder) BuildJob(com.yahoo.vespa.hosted.controller.deployment.BuildJob) Application(com.yahoo.vespa.hosted.controller.Application) ApplicationPackage(com.yahoo.vespa.hosted.controller.application.ApplicationPackage) File(java.io.File) ControllerContainerTest(com.yahoo.vespa.hosted.controller.restapi.ControllerContainerTest) Test(org.junit.Test)

Example 3 with JobStatus

use of com.yahoo.vespa.hosted.controller.application.JobStatus in project vespa by vespa-engine.

the class DeploymentTrigger method lastSuccessfulIs.

private boolean lastSuccessfulIs(Change change, JobType jobType, Application application) {
    JobStatus status = application.deploymentJobs().jobStatus().get(jobType);
    if (status == null)
        return false;
    Optional<JobStatus.JobRun> lastSuccessfulRun = status.lastSuccess();
    if (!lastSuccessfulRun.isPresent())
        return false;
    if (change.platform().isPresent() && !change.platform().get().equals(lastSuccessfulRun.get().version()))
        return false;
    if (change.application().isPresent() && !change.application().get().equals(lastSuccessfulRun.get().applicationVersion()))
        return false;
    return true;
}
Also used : JobStatus(com.yahoo.vespa.hosted.controller.application.JobStatus)

Example 4 with JobStatus

use of com.yahoo.vespa.hosted.controller.application.JobStatus in project vespa by vespa-engine.

the class ControllerTest method testDeployment.

@Test
public void testDeployment() {
    // Setup system
    DeploymentTester tester = new DeploymentTester();
    ApplicationController applications = tester.controller().applications();
    ApplicationPackage applicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("corp-us-east-1").region("us-east-3").build();
    // staging job - succeeding
    Version version1 = tester.defaultVespaVersion();
    Application app1 = tester.createApplication("app1", "tenant1", 1, 11L);
    tester.jobCompletion(component).application(app1).uploadArtifact(applicationPackage).submit();
    assertEquals("Application version is known from completion of initial job", ApplicationVersion.from(BuildJob.defaultSourceRevision, BuildJob.defaultBuildNumber), tester.controller().applications().require(app1.id()).change().application().get());
    tester.deployAndNotify(app1, applicationPackage, true, systemTest);
    tester.deployAndNotify(app1, applicationPackage, true, stagingTest);
    assertEquals(4, applications.require(app1.id()).deploymentJobs().jobStatus().size());
    ApplicationVersion applicationVersion = tester.controller().applications().require(app1.id()).change().application().get();
    assertTrue("Application version has been set during deployment", applicationVersion != ApplicationVersion.unknown);
    assertStatus(JobStatus.initial(stagingTest).withTriggering(version1, applicationVersion, "", tester.clock().instant().minus(Duration.ofMillis(1))).withCompletion(42, Optional.empty(), tester.clock().instant(), tester.controller()), app1.id(), tester.controller());
    // Causes first deployment job to be triggered
    assertStatus(JobStatus.initial(productionCorpUsEast1).withTriggering(version1, applicationVersion, "", tester.clock().instant()), app1.id(), tester.controller());
    tester.clock().advance(Duration.ofSeconds(1));
    // production job (failing)
    tester.deployAndNotify(app1, applicationPackage, false, productionCorpUsEast1);
    assertEquals(4, applications.require(app1.id()).deploymentJobs().jobStatus().size());
    JobStatus expectedJobStatus = JobStatus.initial(productionCorpUsEast1).withTriggering(version1, applicationVersion, "", // Triggered first without application version info
    tester.clock().instant()).withCompletion(42, Optional.of(JobError.unknown), tester.clock().instant(), tester.controller()).withTriggering(version1, applicationVersion, "", // Re-triggering (due to failure) has application version info
    tester.clock().instant());
    assertStatus(expectedJobStatus, app1.id(), tester.controller());
    // Simulate restart
    tester.restartController();
    applications = tester.controller().applications();
    assertNotNull(tester.controller().tenants().tenant(new TenantId("tenant1")));
    assertNotNull(applications.get(ApplicationId.from(TenantName.from("tenant1"), ApplicationName.from("application1"), InstanceName.from("default"))));
    assertEquals(4, applications.require(app1.id()).deploymentJobs().jobStatus().size());
    tester.clock().advance(Duration.ofHours(1));
    // system and staging test job - succeeding
    tester.jobCompletion(component).application(app1).nextBuildNumber().uploadArtifact(applicationPackage).submit();
    applicationVersion = tester.application("app1").change().application().get();
    tester.deployAndNotify(app1, applicationPackage, true, false, systemTest);
    assertStatus(JobStatus.initial(systemTest).withTriggering(version1, applicationVersion, "", tester.clock().instant().minus(Duration.ofMillis(1))).withCompletion(42, Optional.empty(), tester.clock().instant(), tester.controller()), app1.id(), tester.controller());
    tester.deployAndNotify(app1, applicationPackage, true, stagingTest);
    // production job succeeding now
    tester.jobCompletion(productionCorpUsEast1).application(app1).unsuccessful().submit();
    tester.deployAndNotify(app1, applicationPackage, true, productionCorpUsEast1);
    expectedJobStatus = expectedJobStatus.withTriggering(version1, applicationVersion, "", tester.clock().instant().minus(Duration.ofMillis(1))).withCompletion(42, Optional.empty(), tester.clock().instant(), tester.controller());
    assertStatus(expectedJobStatus, app1.id(), tester.controller());
    // causes triggering of next production job
    assertStatus(JobStatus.initial(productionUsEast3).withTriggering(version1, applicationVersion, "", tester.clock().instant()), app1.id(), tester.controller());
    tester.deployAndNotify(app1, applicationPackage, true, productionUsEast3);
    assertEquals(5, applications.get(app1.id()).get().deploymentJobs().jobStatus().size());
    // prod zone removal is not allowed
    applicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("us-east-3").build();
    tester.jobCompletion(component).application(app1).nextBuildNumber().uploadArtifact(applicationPackage).submit();
    try {
        tester.deploy(systemTest, app1, applicationPackage);
        fail("Expected exception due to unallowed production deployment removal");
    } catch (IllegalArgumentException e) {
        assertEquals("deployment-removal: application 'tenant1.app1' is deployed in corp-us-east-1, but does not include this zone in deployment.xml", e.getMessage());
    }
    assertNotNull("Zone was not removed", applications.require(app1.id()).deployments().get(productionCorpUsEast1.zone(SystemName.main).get()));
    JobStatus jobStatus = applications.require(app1.id()).deploymentJobs().jobStatus().get(productionCorpUsEast1);
    assertNotNull("Deployment job was not removed", jobStatus);
    assertEquals(42, jobStatus.lastCompleted().get().id());
    assertEquals("Available change in staging-test", jobStatus.lastCompleted().get().reason());
    // prod zone removal is allowed with override
    applicationPackage = new ApplicationPackageBuilder().allow(ValidationId.deploymentRemoval).upgradePolicy("default").environment(Environment.prod).region("us-east-3").build();
    tester.jobCompletion(component).application(app1).nextBuildNumber(2).uploadArtifact(applicationPackage).submit();
    tester.deployAndNotify(app1, applicationPackage, true, systemTest);
    assertNull("Zone was removed", applications.require(app1.id()).deployments().get(productionCorpUsEast1.zone(SystemName.main).get()));
    assertNull("Deployment job was removed", applications.require(app1.id()).deploymentJobs().jobStatus().get(productionCorpUsEast1));
}
Also used : JobStatus(com.yahoo.vespa.hosted.controller.application.JobStatus) TenantId(com.yahoo.vespa.hosted.controller.api.identifiers.TenantId) ApplicationVersion(com.yahoo.vespa.hosted.controller.application.ApplicationVersion) ApplicationVersion(com.yahoo.vespa.hosted.controller.application.ApplicationVersion) VespaVersion(com.yahoo.vespa.hosted.controller.versions.VespaVersion) Version(com.yahoo.component.Version) DeploymentTester(com.yahoo.vespa.hosted.controller.deployment.DeploymentTester) ApplicationPackageBuilder(com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder) ApplicationPackage(com.yahoo.vespa.hosted.controller.application.ApplicationPackage) JobType.stagingTest(com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobType.stagingTest) JobType.systemTest(com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobType.systemTest) Test(org.junit.Test)

Example 5 with JobStatus

use of com.yahoo.vespa.hosted.controller.application.JobStatus in project vespa by vespa-engine.

the class ControllerTest method assertStatus.

private void assertStatus(JobStatus expectedStatus, ApplicationId id, Controller controller) {
    Application app = controller.applications().get(id).get();
    JobStatus existingStatus = app.deploymentJobs().jobStatus().get(expectedStatus.type());
    assertNotNull("Status of type " + expectedStatus.type() + " is present", existingStatus);
    assertEquals(expectedStatus, existingStatus);
}
Also used : JobStatus(com.yahoo.vespa.hosted.controller.application.JobStatus)

Aggregations

JobStatus (com.yahoo.vespa.hosted.controller.application.JobStatus)9 Version (com.yahoo.component.Version)5 ApplicationPackage (com.yahoo.vespa.hosted.controller.application.ApplicationPackage)5 ApplicationVersion (com.yahoo.vespa.hosted.controller.application.ApplicationVersion)5 Test (org.junit.Test)5 Application (com.yahoo.vespa.hosted.controller.Application)4 ApplicationPackageBuilder (com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder)4 TenantId (com.yahoo.vespa.hosted.controller.api.identifiers.TenantId)3 Deployment (com.yahoo.vespa.hosted.controller.application.Deployment)3 DeploymentJobs (com.yahoo.vespa.hosted.controller.application.DeploymentJobs)3 SourceRevision (com.yahoo.vespa.hosted.controller.application.SourceRevision)3 DeploymentSpec (com.yahoo.config.application.api.DeploymentSpec)2 ApplicationId (com.yahoo.config.provision.ApplicationId)2 ApplicationName (com.yahoo.config.provision.ApplicationName)2 Environment (com.yahoo.config.provision.Environment)2 RegionName (com.yahoo.config.provision.RegionName)2 TenantName (com.yahoo.config.provision.TenantName)2 NToken (com.yahoo.vespa.athenz.api.NToken)2 SlimeUtils (com.yahoo.vespa.config.SlimeUtils)2 DeployOptions (com.yahoo.vespa.hosted.controller.api.application.v4.model.DeployOptions)2