Search in sources :

Example 21 with ZooKeeperClient

use of com.spotify.helios.servicescommon.coordination.ZooKeeperClient in project helios by spotify.

the class DeploymentGroupTest method testStopDeploymentGroup.

// A test that...
// * Verifies that the state in ZK is correct after running stop
// * Verifies that the correct exception is thrown when the DG does not exist or there is a
// race condition
@Theory
public void testStopDeploymentGroup(@TestedOn(ints = { 0, 1 }) final int dgExistsInt, @TestedOn(ints = { 0, 1 }) final int tasksExistInt, @TestedOn(ints = { 0, 1 }) final int tasksExistWhenCommittingInt) throws Exception {
    final boolean dgExists = dgExistsInt != 0;
    final boolean tasksExist = tasksExistInt != 0;
    final boolean tasksExistWhenCommitting = tasksExistWhenCommittingInt != 0;
    // To be able to simulate triggering the race condition in stopDeploymentGroup we need to do
    // some mocking, relying on that the implementation uses client.exists() to check for the
    // presence of tasks.
    final ZooKeeperClient client = spy(this.client);
    when(client.exists(Paths.statusDeploymentGroupTasks(GROUP_NAME))).thenReturn(tasksExist ? mock(Stat.class) : null);
    final ZooKeeperMasterModel masterModel = newMasterModel(client);
    if (dgExists) {
        final DeploymentGroup dg = DeploymentGroup.newBuilder().setName(GROUP_NAME).build();
        masterModel.addDeploymentGroup(dg);
    }
    if (tasksExistWhenCommitting) {
        client.ensurePath(Paths.statusDeploymentGroupTasks());
        client.create(Paths.statusDeploymentGroupTasks(GROUP_NAME));
    }
    if (!dgExists) {
        exception.expect(DeploymentGroupDoesNotExistException.class);
    } else if (tasksExist != tasksExistWhenCommitting) {
        exception.expect(HeliosRuntimeException.class);
    }
    masterModel.stopDeploymentGroup(GROUP_NAME);
    // Verify that the state in ZK is correct:
    // * tasks are not present
    // * the status is set to FAILED
    // 
    // When checking for the existence of the tasks make sure we use the client that doesn't have
    // the exists() method mocked out!
    assertNull(this.client.exists(Paths.statusDeploymentGroupTasks(GROUP_NAME)));
    final DeploymentGroupStatus status = masterModel.getDeploymentGroupStatus(GROUP_NAME);
    assertEquals(FAILED, status.getState());
}
Also used : ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) DefaultZooKeeperClient(com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient) HeliosRuntimeException(com.spotify.helios.common.HeliosRuntimeException) DeploymentGroupStatus(com.spotify.helios.common.descriptors.DeploymentGroupStatus) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) Theory(org.junit.experimental.theories.Theory)

Example 22 with ZooKeeperClient

use of com.spotify.helios.servicescommon.coordination.ZooKeeperClient 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.getDefault()).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 23 with ZooKeeperClient

use of com.spotify.helios.servicescommon.coordination.ZooKeeperClient in project helios by spotify.

the class RollingUpdateOpFactoryTest method testStartHostsChanged.

@Test
public void testStartHostsChanged() throws Exception {
    // Create a DeploymentGroupTasks object with some rolloutTasks.
    final ArrayList<RolloutTask> rolloutTasks = Lists.newArrayList(RolloutTask.of(RolloutTask.Action.UNDEPLOY_OLD_JOBS, "host1"), RolloutTask.of(RolloutTask.Action.DEPLOY_NEW_JOB, "host1"), RolloutTask.of(RolloutTask.Action.AWAIT_RUNNING, "host1"));
    final DeploymentGroupTasks deploymentGroupTasks = DeploymentGroupTasks.newBuilder().setTaskIndex(0).setRolloutTasks(rolloutTasks).setDeploymentGroup(HOSTS_CHANGED_DEPLOYMENT_GROUP).build();
    final RollingUpdateOpFactory opFactory = new RollingUpdateOpFactory(deploymentGroupTasks, eventFactory);
    final ZooKeeperClient client = mock(ZooKeeperClient.class);
    when(client.exists(anyString())).thenReturn(null);
    final RollingUpdateOp op = opFactory.start(HOSTS_CHANGED_DEPLOYMENT_GROUP, client);
    // Three ZK operations should return:
    // * create tasks node
    // * set the task index to 0
    // * another to set the status to ROLLING_OUT
    assertEquals(ImmutableSet.of(new CreateEmpty("/status/deployment-group-tasks/my_group"), new SetData("/status/deployment-group-tasks/my_group", DeploymentGroupTasks.newBuilder().setRolloutTasks(rolloutTasks).setTaskIndex(0).setDeploymentGroup(HOSTS_CHANGED_DEPLOYMENT_GROUP).build().toJsonBytes()), new SetData("/status/deployment-groups/my_group", DeploymentGroupStatus.newBuilder().setState(DeploymentGroupStatus.State.ROLLING_OUT).build().toJsonBytes())), ImmutableSet.copyOf(op.operations()));
    // Two events should return: rollingUpdateStarted and rollingUpdateDone
    assertEquals(1, op.events().size());
    verify(eventFactory).rollingUpdateStarted(HOSTS_CHANGED_DEPLOYMENT_GROUP);
}
Also used : ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) DeploymentGroupTasks(com.spotify.helios.common.descriptors.DeploymentGroupTasks) RolloutTask(com.spotify.helios.common.descriptors.RolloutTask) CreateEmpty(com.spotify.helios.servicescommon.coordination.CreateEmpty) SetData(com.spotify.helios.servicescommon.coordination.SetData) Test(org.junit.Test)

Example 24 with ZooKeeperClient

use of com.spotify.helios.servicescommon.coordination.ZooKeeperClient in project helios by spotify.

the class RollingUpdateOpFactoryTest method testStartManualWithHosts.

@Test
public void testStartManualWithHosts() throws Exception {
    // Create a DeploymentGroupTasks object with some rolloutTasks.
    final ArrayList<RolloutTask> rolloutTasks = Lists.newArrayList(RolloutTask.of(RolloutTask.Action.UNDEPLOY_OLD_JOBS, "host1"), RolloutTask.of(RolloutTask.Action.DEPLOY_NEW_JOB, "host1"), RolloutTask.of(RolloutTask.Action.AWAIT_RUNNING, "host1"));
    final DeploymentGroupTasks deploymentGroupTasks = DeploymentGroupTasks.newBuilder().setTaskIndex(0).setRolloutTasks(rolloutTasks).setDeploymentGroup(MANUAL_DEPLOYMENT_GROUP).build();
    final RollingUpdateOpFactory opFactory = new RollingUpdateOpFactory(deploymentGroupTasks, eventFactory);
    final ZooKeeperClient client = mock(ZooKeeperClient.class);
    when(client.exists(anyString())).thenReturn(null);
    final RollingUpdateOp op = opFactory.start(MANUAL_DEPLOYMENT_GROUP, client);
    // Three ZK operations should return:
    // * create tasks node
    // * set the task index to 0
    // * set the status to ROLLING_OUT
    assertEquals(ImmutableSet.of(new CreateEmpty("/status/deployment-group-tasks/my_group"), new SetData("/status/deployment-group-tasks/my_group", DeploymentGroupTasks.newBuilder().setRolloutTasks(rolloutTasks).setTaskIndex(0).setDeploymentGroup(MANUAL_DEPLOYMENT_GROUP).build().toJsonBytes()), new SetData("/status/deployment-groups/my_group", DeploymentGroupStatus.newBuilder().setState(DeploymentGroupStatus.State.ROLLING_OUT).build().toJsonBytes())), ImmutableSet.copyOf(op.operations()));
    // Two events should return: rollingUpdateStarted and rollingUpdateDone
    assertEquals(1, op.events().size());
    verify(eventFactory).rollingUpdateStarted(MANUAL_DEPLOYMENT_GROUP);
}
Also used : ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) DeploymentGroupTasks(com.spotify.helios.common.descriptors.DeploymentGroupTasks) RolloutTask(com.spotify.helios.common.descriptors.RolloutTask) CreateEmpty(com.spotify.helios.servicescommon.coordination.CreateEmpty) SetData(com.spotify.helios.servicescommon.coordination.SetData) Test(org.junit.Test)

Example 25 with ZooKeeperClient

use of com.spotify.helios.servicescommon.coordination.ZooKeeperClient in project helios by spotify.

the class ZooKeeperAclInitializerTest method testInitializeAcl.

@Test
public void testInitializeAcl() throws Exception {
    // setup the initial helios tree
    final ZooKeeperClient zkClient = new DefaultZooKeeperClient(zk.curatorWithSuperAuth());
    zkClient.ensurePath(Paths.configId(CLUSTER_ID));
    new MasterZooKeeperRegistrar("helios-master").tryToRegister(zkClient);
    // to start with, nothing should have permissions
    for (final String path : zkClient.listRecursive("/")) {
        assertEquals(ZooDefs.Ids.OPEN_ACL_UNSAFE, zkClient.getAcl(path));
    }
    // initialize ACL's
    ZooKeeperAclInitializer.initializeAcl(zk.connectString(), CLUSTER_ID, MASTER_USER, MASTER_PASSWORD, AGENT_USER, AGENT_PASSWORD);
    for (final String path : zkClient.listRecursive("/")) {
        final List<ACL> expected = aclProvider.getAclForPath(path);
        final List<ACL> actual = zkClient.getAcl(path);
        assertEquals(expected.size(), actual.size());
        assertTrue(expected.containsAll(actual));
    }
}
Also used : ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) DefaultZooKeeperClient(com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient) MasterZooKeeperRegistrar(com.spotify.helios.master.MasterZooKeeperRegistrar) ACL(org.apache.zookeeper.data.ACL) DefaultZooKeeperClient(com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient) Test(org.junit.Test)

Aggregations

ZooKeeperClient (com.spotify.helios.servicescommon.coordination.ZooKeeperClient)43 HeliosRuntimeException (com.spotify.helios.common.HeliosRuntimeException)20 KeeperException (org.apache.zookeeper.KeeperException)18 NoNodeException (org.apache.zookeeper.KeeperException.NoNodeException)15 DefaultZooKeeperClient (com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient)13 Job (com.spotify.helios.common.descriptors.Job)12 Test (org.junit.Test)12 DeploymentGroup (com.spotify.helios.common.descriptors.DeploymentGroup)11 ZooKeeperOperation (com.spotify.helios.servicescommon.coordination.ZooKeeperOperation)11 IOException (java.io.IOException)10 RolloutTask (com.spotify.helios.common.descriptors.RolloutTask)8 DeploymentGroupTasks (com.spotify.helios.common.descriptors.DeploymentGroupTasks)6 JobId (com.spotify.helios.common.descriptors.JobId)6 Deployment (com.spotify.helios.common.descriptors.Deployment)5 CuratorFramework (org.apache.curator.framework.CuratorFramework)5 ExponentialBackoffRetry (org.apache.curator.retry.ExponentialBackoffRetry)5 DeploymentGroupStatus (com.spotify.helios.common.descriptors.DeploymentGroupStatus)4 SetData (com.spotify.helios.servicescommon.coordination.SetData)4 RetryPolicy (org.apache.curator.RetryPolicy)4 BadVersionException (org.apache.zookeeper.KeeperException.BadVersionException)4