Search in sources :

Example 11 with Job

use of com.spotify.helios.common.descriptors.Job in project helios by spotify.

the class DeploymentGroupTest method testRollingUpdateWithToken.

@Test
public void testRollingUpdateWithToken() throws Exception {
    final String host = testHost();
    startDefaultAgent(host, "--labels", TEST_LABEL);
    // Wait for agent to come up
    final HeliosClient client = defaultClient();
    awaitHostStatus(client, testHost(), UP, LONG_WAIT_SECONDS, SECONDS);
    // Manually deploy a job with a token on the host (i.e. a job not part of the deployment group)
    final Job job = Job.newBuilder().setName(testJobName).setVersion(testJobVersion).setImage(BUSYBOX).setCommand(IDLE_COMMAND).setToken(TOKEN).build();
    final JobId jobId = createJob(job);
    // Create a deployment-group and trigger a migration rolling-update
    cli("create-deployment-group", "--json", TEST_GROUP, TEST_LABEL);
    cli("rolling-update", "--async", "--token", TOKEN, testJobNameAndVersion, TEST_GROUP);
    // rolling-update should succeed & job should be running
    awaitDeploymentGroupStatus(defaultClient(), TEST_GROUP, DeploymentGroupStatus.State.DONE);
    awaitTaskState(jobId, host, TaskStatus.State.RUNNING);
    // Check that we cannot manually undeploy the job with a token
    final String output = cli("undeploy", jobId.toString(), host);
    assertThat(output, containsString("FORBIDDEN"));
    awaitDeploymentGroupStatus(defaultClient(), TEST_GROUP, DeploymentGroupStatus.State.DONE);
    awaitTaskState(jobId, host, TaskStatus.State.RUNNING);
}
Also used : Matchers.containsString(org.hamcrest.Matchers.containsString) HeliosClient(com.spotify.helios.client.HeliosClient) Job(com.spotify.helios.common.descriptors.Job) JobId(com.spotify.helios.common.descriptors.JobId) Test(org.junit.Test)

Example 12 with Job

use of com.spotify.helios.common.descriptors.Job in project helios by spotify.

the class DeploymentGroupTest method testRollingUpdateMigrateWithToken.

@Test
public void testRollingUpdateMigrateWithToken() throws Exception {
    final String host = testHost();
    startDefaultAgent(host, "--labels", TEST_LABEL);
    // Wait for agent to come up
    final HeliosClient client = defaultClient();
    awaitHostStatus(client, testHost(), UP, LONG_WAIT_SECONDS, SECONDS);
    // Manually deploy a job with a token on the host (i.e. a job not part of the deployment group)
    final Job job = Job.newBuilder().setName(testJobName).setVersion(testJobVersion).setImage(BUSYBOX).setCommand(IDLE_COMMAND).setToken(TOKEN).build();
    final JobId jobId = createJob(job);
    deployJob(jobId, host, TOKEN);
    awaitTaskState(jobId, host, TaskStatus.State.RUNNING);
    // Create a deployment-group and trigger a migration rolling-update
    cli("create-deployment-group", "--json", TEST_GROUP, TEST_LABEL);
    cli("rolling-update", "--async", "--migrate", "--token", TOKEN, testJobNameAndVersion, TEST_GROUP);
    // Check that the deployment's deployment-group name eventually changes to TEST_GROUP
    // (should be null or empty before)
    final String jobDeploymentGroup = Polling.await(LONG_WAIT_SECONDS, SECONDS, new Callable<String>() {

        @Override
        public String call() throws Exception {
            final Deployment deployment = defaultClient().hostStatus(host).get().getJobs().get(jobId);
            if (deployment != null && !isNullOrEmpty(deployment.getDeploymentGroupName())) {
                return deployment.getDeploymentGroupName();
            } else {
                return null;
            }
        }
    });
    assertEquals(TEST_GROUP, jobDeploymentGroup);
    // rolling-update should succeed & job should be running
    awaitDeploymentGroupStatus(defaultClient(), TEST_GROUP, DeploymentGroupStatus.State.DONE);
    awaitTaskState(jobId, host, TaskStatus.State.RUNNING);
}
Also used : Deployment(com.spotify.helios.common.descriptors.Deployment) Matchers.containsString(org.hamcrest.Matchers.containsString) HeliosClient(com.spotify.helios.client.HeliosClient) Job(com.spotify.helios.common.descriptors.Job) JobId(com.spotify.helios.common.descriptors.JobId) Test(org.junit.Test)

Example 13 with Job

use of com.spotify.helios.common.descriptors.Job in project helios by spotify.

the class DeploymentGroupTest method testUpdateFailedManualDeploymentGroupHosts.

// A test that ensures deployment groups that failed during a manual rolling update will not
// perform a new rolling update if the hosts change.
@Test
public void testUpdateFailedManualDeploymentGroupHosts() throws Exception {
    final ZooKeeperClient client = spy(this.client);
    final ZooKeeperMasterModel masterModel = spy(newMasterModel(client));
    // Return a job so we can add a real deployment group.
    final Job job = Job.newBuilder().setCommand(ImmutableList.of("COMMAND")).setImage("IMAGE").setName("JOB_NAME").setVersion("VERSION").build();
    doReturn(job).when(masterModel).getJob(job.getId());
    // Add a real deployment group.
    final DeploymentGroup dg = DeploymentGroup.newBuilder().setName(GROUP_NAME).setHostSelectors(ImmutableList.of(HostSelector.parse("role=melmac"))).setJobId(job.getId()).setRolloutOptions(RolloutOptions.newBuilder().build()).setRollingUpdateReason(MANUAL).build();
    masterModel.addDeploymentGroup(dg);
    // Give the deployment group a host.
    client.setData(Paths.statusDeploymentGroupHosts(dg.getName()), Json.asBytes(ImmutableList.of("host1")));
    // And a status...
    client.setData(Paths.statusDeploymentGroup(dg.getName()), DeploymentGroupStatus.newBuilder().setState(FAILED).build().toJsonBytes());
    // Pretend our new host is UP.
    final HostStatus statusUp = mock(HostStatus.class);
    doReturn(HostStatus.Status.UP).when(statusUp).getStatus();
    doReturn(statusUp).when(masterModel).getHostStatus("host2");
    // Switch out our host!
    masterModel.updateDeploymentGroupHosts(dg.getName(), ImmutableList.of("host2"));
    // Ensure we do not set the DG status to HOSTS_CHANGED.
    // We don't want to trigger a rolling update because the last one was manual, and failed.
    final ZooKeeperOperation setDeploymentGroupHostChanged = set(Paths.configDeploymentGroup(dg.getName()), dg.toBuilder().setRollingUpdateReason(HOSTS_CHANGED).build());
    verify(client, times(2)).transaction(opCaptor.capture());
    assertThat(opCaptor.getValue(), not(hasItem(setDeploymentGroupHostChanged)));
}
Also used : ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) DefaultZooKeeperClient(com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient) ZooKeeperOperation(com.spotify.helios.servicescommon.coordination.ZooKeeperOperation) HostStatus(com.spotify.helios.common.descriptors.HostStatus) Job(com.spotify.helios.common.descriptors.Job) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) Test(org.junit.Test)

Example 14 with Job

use of com.spotify.helios.common.descriptors.Job in project helios by spotify.

the class DeploymentGroupTest method testUpdateFailedHostsChangedDeploymentGroupHosts.

// A test that ensures deployment groups that failed during a rolling update triggered by
// changing hosts will perform a new rolling update if the hosts change again.
@Test
public void testUpdateFailedHostsChangedDeploymentGroupHosts() throws Exception {
    final ZooKeeperClient client = spy(this.client);
    final ZooKeeperMasterModel masterModel = spy(newMasterModel(client));
    // Return a job so we can add a real deployment group.
    final Job job = Job.newBuilder().setCommand(ImmutableList.of("COMMAND")).setImage("IMAGE").setName("JOB_NAME").setVersion("VERSION").build();
    doReturn(job).when(masterModel).getJob(job.getId());
    // Add a real deployment group.
    final DeploymentGroup dg = DeploymentGroup.newBuilder().setName(GROUP_NAME).setHostSelectors(ImmutableList.of(HostSelector.parse("role=melmac"))).setJobId(job.getId()).setRolloutOptions(RolloutOptions.newBuilder().build()).setRollingUpdateReason(HOSTS_CHANGED).build();
    masterModel.addDeploymentGroup(dg);
    // Give the deployment group a host.
    client.setData(Paths.statusDeploymentGroupHosts(dg.getName()), Json.asBytes(ImmutableList.of("host1")));
    // And a status...
    client.setData(Paths.statusDeploymentGroup(dg.getName()), DeploymentGroupStatus.newBuilder().setState(FAILED).build().toJsonBytes());
    // Pretend our new host is UP.
    final HostStatus statusUp = mock(HostStatus.class);
    doReturn(HostStatus.Status.UP).when(statusUp).getStatus();
    doReturn(statusUp).when(masterModel).getHostStatus("host2");
    // Switch out our host!
    masterModel.updateDeploymentGroupHosts(dg.getName(), ImmutableList.of("host2"));
    // Ensure we write the same DG status again.
    // This is a no-op, but it means we triggered a rolling update.
    final ZooKeeperOperation setDeploymentGroup = set(Paths.configDeploymentGroup(dg.getName()), dg);
    verify(client, times(2)).transaction(opCaptor.capture());
    assertThat(opCaptor.getValue(), hasItem(setDeploymentGroup));
}
Also used : ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) DefaultZooKeeperClient(com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient) ZooKeeperOperation(com.spotify.helios.servicescommon.coordination.ZooKeeperOperation) HostStatus(com.spotify.helios.common.descriptors.HostStatus) Job(com.spotify.helios.common.descriptors.Job) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) Test(org.junit.Test)

Example 15 with Job

use of com.spotify.helios.common.descriptors.Job in project helios by spotify.

the class CliJobCreationTest method testMergeFileAndCliArgs.

@Test
public void testMergeFileAndCliArgs() throws Exception {
    final Map<String, PortMapping> ports = ImmutableMap.of("foo", PortMapping.of(4711), "bar", PortMapping.of(5000, externalPort));
    final Map<ServiceEndpoint, ServicePorts> registration = ImmutableMap.of(ServiceEndpoint.of("foo-service", "tcp"), ServicePorts.of("foo"), ServiceEndpoint.of("bar-service", "http"), ServicePorts.of("bar"));
    final String registrationDomain = "my-domain";
    final Map<String, String> env = ImmutableMap.of("BAD", "f00d");
    final Map<String, String> volumes = Maps.newHashMap();
    volumes.put("/etc/spotify/secret-keys.yaml:ro", "/etc/spotify/secret-keys.yaml");
    // Create a new job, serialize it to JSON
    final Job.Builder builder = Job.newBuilder().setCommand(Lists.newArrayList("server", "foo-service.yaml")).setEnv(env).setPorts(ports).setRegistration(registration).setRegistrationDomain(registrationDomain).setVolumes(volumes).setCreatingUser(TEST_USER).setToken("foo-token").setNetworkMode("host").setSecurityOpt(ImmutableList.of("label:user:dxia", "apparmor:foo"));
    final Job job = builder.build();
    final String jobConfigJsonString = job.toJsonString();
    // Create temporary job config file
    final File file = temporaryFolder.newFile();
    final String absolutePath = file.getAbsolutePath();
    // Write JSON config to temp file
    try (final FileOutputStream outFile = new FileOutputStream(file)) {
        outFile.write(Charsets.UTF_8.encode(jobConfigJsonString).array());
        // Create job and specify the temp file.
        cli("create", "--file", absolutePath, testJobNameAndVersion, BUSYBOX);
        // Inspect the job.
        final String actualJobConfigJson = cli("inspect", testJobNameAndVersion, "--json");
        // Compare to make sure the created job has the expected configuration,
        // i.e. the configuration resulting from a merge of the JSON file and CLI args.
        final Job actualJob = Json.read(actualJobConfigJson, Job.class);
        final Job.Builder actualJobBuilder = actualJob.toBuilder();
        builder.setName(testJobName).setVersion(testJobVersion).setImage(BUSYBOX);
        assertJobEquals(builder.build(), actualJobBuilder.build());
    }
}
Also used : ServicePorts(com.spotify.helios.common.descriptors.ServicePorts) FileOutputStream(java.io.FileOutputStream) PortMapping(com.spotify.helios.common.descriptors.PortMapping) Job(com.spotify.helios.common.descriptors.Job) File(java.io.File) ServiceEndpoint(com.spotify.helios.common.descriptors.ServiceEndpoint) Test(org.junit.Test)

Aggregations

Job (com.spotify.helios.common.descriptors.Job)79 Test (org.junit.Test)57 JobId (com.spotify.helios.common.descriptors.JobId)38 HeliosClient (com.spotify.helios.client.HeliosClient)25 Deployment (com.spotify.helios.common.descriptors.Deployment)21 CreateJobResponse (com.spotify.helios.common.protocol.CreateJobResponse)16 TaskStatus (com.spotify.helios.common.descriptors.TaskStatus)15 JobStatus (com.spotify.helios.common.descriptors.JobStatus)12 JobDeployResponse (com.spotify.helios.common.protocol.JobDeployResponse)11 ZooKeeperClient (com.spotify.helios.servicescommon.coordination.ZooKeeperClient)10 KeeperException (org.apache.zookeeper.KeeperException)10 NoNodeException (org.apache.zookeeper.KeeperException.NoNodeException)10 PortMapping (com.spotify.helios.common.descriptors.PortMapping)9 HeliosRuntimeException (com.spotify.helios.common.HeliosRuntimeException)8 ServiceEndpoint (com.spotify.helios.common.descriptors.ServiceEndpoint)8 Matchers.containsString (org.hamcrest.Matchers.containsString)8 DockerClient (com.spotify.docker.client.DockerClient)7 ZooKeeperOperation (com.spotify.helios.servicescommon.coordination.ZooKeeperOperation)7 IOException (java.io.IOException)7 ServicePorts (com.spotify.helios.common.descriptors.ServicePorts)6