@BeforeMethod
  public void resetState() {
    provisioner.clearCoordinators();
    coordinator.updateAllCoordinatorsAndWait();
    assertEquals(coordinator.getCoordinators().size(), 1);

    provisioner.clearAgents();
    coordinator.updateAllAgentsAndWait();
    assertTrue(coordinator.getAgents().isEmpty());

    stateManager.clearAll();
    assertTrue(coordinator.getAllSlotStatus().isEmpty());
  }
  private void initializeOneAgent() {
    apple1SotId = UUID.randomUUID();
    SlotStatus appleSlotStatus1 =
        createSlotStatus(
            apple1SotId,
            URI.create("fake://appleServer1/v1/agent/slot/apple1"),
            URI.create("fake://appleServer1/v1/agent/slot/apple1"),
            "instance",
            "/location",
            STOPPED,
            APPLE_ASSIGNMENT,
            "/apple1",
            ImmutableMap.<String, Integer>of());
    apple2SlotId = UUID.randomUUID();
    SlotStatus appleSlotStatus2 =
        createSlotStatus(
            apple2SlotId,
            URI.create("fake://appleServer2/v1/agent/slot/apple1"),
            URI.create("fake://appleServer2/v1/agent/slot/apple1"),
            "instance",
            "/location",
            STOPPED,
            APPLE_ASSIGNMENT,
            "/apple2",
            ImmutableMap.<String, Integer>of());
    bananaSlotId = UUID.randomUUID();
    SlotStatus bananaSlotStatus =
        createSlotStatus(
            bananaSlotId,
            URI.create("fake://bananaServer/v1/agent/slot/banana"),
            URI.create("fake://bananaServer/v1/agent/slot/banana"),
            "instance",
            "/location",
            STOPPED,
            BANANA_ASSIGNMENT,
            "/banana",
            ImmutableMap.<String, Integer>of());

    agentId = UUID.randomUUID().toString();
    AgentStatus agentStatus =
        new AgentStatus(
            agentId,
            ONLINE,
            "instance-id",
            URI.create("fake://foo/"),
            URI.create("fake://foo/"),
            "/unknown/location",
            "instance.type",
            ImmutableList.of(appleSlotStatus1, appleSlotStatus2, bananaSlotStatus),
            ImmutableMap.of("cpu", 8, "memory", 1024));

    provisioner.addAgents(agentStatus);
    coordinator.updateAllAgentsAndWait();

    stateManager.clearAll();

    slotStatusRepresentationFactory =
        new SlotStatusRepresentationFactory(
            ImmutableList.of(appleSlotStatus1, appleSlotStatus2, bananaSlotStatus), repository);
  }
  @Test
  public void testGetAllAgentsSingle() throws Exception {
    String agentId = UUID.randomUUID().toString();
    URI internalUri = URI.create("fake://agent/" + agentId + "/internal");
    URI externalUri = URI.create("fake://agent/" + agentId + "/external");
    String instanceId = "instance-id";
    String location = "/unknown/location";
    String instanceType = "instance.type";
    Map<String, Integer> resources = ImmutableMap.of("cpu", 8, "memory", 1024);

    AgentStatus status =
        new AgentStatus(
            agentId,
            AgentLifecycleState.ONLINE,
            instanceId,
            internalUri,
            externalUri,
            location,
            instanceType,
            ImmutableList.<SlotStatus>of(),
            resources);

    // add the agent
    provisioner.addAgents(status);
    coordinator.updateAllAgentsAndWait();

    Request request =
        Request.Builder.prepareGet()
            .setUri(coordinatorUriBuilder().appendPath("/v1/admin/agent").build())
            .build();

    List<AgentStatusRepresentation> agents =
        httpClient.execute(
            request, createJsonResponseHandler(agentStatusesCodec, Status.OK.getStatusCode()));
    assertEquals(agents.size(), 1);

    AgentStatusRepresentation actual = agents.get(0);
    assertEquals(actual.getAgentId(), agentId);
    assertEquals(actual.getState(), AgentLifecycleState.ONLINE);
    assertEquals(actual.getInstanceId(), instanceId);
    assertEquals(actual.getLocation(), location);
    assertEquals(actual.getInstanceType(), instanceType);
    assertEquals(actual.getSelf(), internalUri);
    assertEquals(actual.getExternalUri(), externalUri);
    assertEquals(actual.getResources(), resources);
  }
  @Test
  public void testGetAllCoordinatorsSingle() throws Exception {
    // add a coordinator directly to the provisioner
    String coordinatorId = UUID.randomUUID().toString();
    String instanceId = "instance-id";
    URI internalUri = URI.create("fake://coordinator/" + instanceId + "/internal");
    URI externalUri = URI.create("fake://coordinator/" + instanceId + "/external");
    String location = "/unknown/location";
    String instanceType = "instance.type";

    CoordinatorStatus status =
        new CoordinatorStatus(
            coordinatorId,
            CoordinatorLifecycleState.ONLINE,
            instanceId,
            internalUri,
            externalUri,
            location,
            instanceType);
    provisioner.addCoordinators(status);
    coordinator.updateAllCoordinatorsAndWait();

    // verify coordinator appears
    Request request =
        Request.Builder.prepareGet()
            .setUri(coordinatorUriBuilder().appendPath("/v1/admin/coordinator").build())
            .build();

    List<CoordinatorStatusRepresentation> coordinators =
        httpClient.execute(
            request,
            createJsonResponseHandler(coordinatorStatusesCodec, Status.OK.getStatusCode()));
    CoordinatorStatusRepresentation actual = getNonMainCoordinator(coordinators);

    assertEquals(actual.getCoordinatorId(), coordinatorId);
    assertEquals(actual.getState(), CoordinatorLifecycleState.ONLINE);
    assertEquals(actual.getInstanceId(), instanceId);
    assertEquals(actual.getLocation(), location);
    assertEquals(actual.getInstanceType(), instanceType);
    assertEquals(actual.getSelf(), internalUri);
    assertEquals(actual.getExternalUri(), externalUri);
  }
  @BeforeMethod
  public void setup() throws Exception {
    NodeInfo nodeInfo = new NodeInfo("testing");

    MockProvisioner provisioner = new MockProvisioner();
    coordinator =
        new Coordinator(
            nodeInfo,
            new HttpServerInfo(new HttpServerConfig(), nodeInfo),
            new CoordinatorConfig().setStatusExpiration(new Duration(1, TimeUnit.DAYS)),
            provisioner.getCoordinatorFactory(),
            provisioner.getAgentFactory(),
            MOCK_REPO,
            provisioner,
            new InMemoryStateManager(),
            new MockServiceInventory());
    resource = new CoordinatorLifecycleResource(coordinator, MOCK_REPO);

    apple1SlotId = UUID.randomUUID();
    SlotStatus appleSlotStatus1 =
        createSlotStatus(
            apple1SlotId,
            URI.create("fake://foo/v1/agent/slot/apple1"),
            URI.create("fake://foo/v1/agent/slot/apple1"),
            "instance",
            "/location",
            STOPPED,
            APPLE_ASSIGNMENT,
            "/apple1",
            ImmutableMap.<String, Integer>of());
    apple2SlotId = UUID.randomUUID();
    SlotStatus appleSlotStatus2 =
        createSlotStatus(
            apple2SlotId,
            URI.create("fake://foo/v1/agent/slot/apple1"),
            URI.create("fake://foo/v1/agent/slot/apple1"),
            "instance",
            "/location",
            STOPPED,
            APPLE_ASSIGNMENT,
            "/apple2",
            ImmutableMap.<String, Integer>of());
    bananaSlotId = UUID.randomUUID();
    SlotStatus bananaSlotStatus =
        createSlotStatus(
            bananaSlotId,
            URI.create("fake://foo/v1/agent/slot/banana"),
            URI.create("fake://foo/v1/agent/slot/banana"),
            "instance",
            "/location",
            STOPPED,
            BANANA_ASSIGNMENT,
            "/banana",
            ImmutableMap.<String, Integer>of());

    agentId = UUID.randomUUID().toString();
    AgentStatus agentStatus =
        new AgentStatus(
            agentId,
            ONLINE,
            "instance-id",
            URI.create("fake://foo/"),
            URI.create("fake://foo/"),
            "/unknown/location",
            "instance.type",
            ImmutableList.of(appleSlotStatus1, appleSlotStatus2, bananaSlotStatus),
            ImmutableMap.of("cpu", 8, "memory", 1024));

    prefixSize =
        shortestUniquePrefix(
            asList(
                appleSlotStatus1.getId().toString(),
                appleSlotStatus2.getId().toString(),
                bananaSlotStatus.getId().toString()),
            MIN_PREFIX_SIZE);

    provisioner.addAgents(agentStatus);
    coordinator.updateAllAgents();
  }
  @Test
  public void testAgentProvision() throws Exception {
    // provision the agent and verify
    String instanceType = "instance-type";
    AgentProvisioningRepresentation agentProvisioningRepresentation =
        new AgentProvisioningRepresentation(
            "agent:config:1", 1, instanceType, null, null, null, null, null);
    Request request =
        Request.Builder.preparePost()
            .setUri(coordinatorUriBuilder().appendPath("/v1/admin/agent").build())
            .setHeader(CONTENT_TYPE, APPLICATION_JSON)
            .setBodyGenerator(
                jsonBodyGenerator(agentProvisioningCodec, agentProvisioningRepresentation))
            .build();
    List<AgentStatusRepresentation> agents =
        httpClient.execute(
            request, createJsonResponseHandler(agentStatusesCodec, Status.OK.getStatusCode()));

    assertEquals(agents.size(), 1);
    String instanceId = agents.get(0).getInstanceId();
    assertNotNull(instanceId);
    String location = agents.get(0).getLocation();
    assertNotNull(location);
    assertEquals(agents.get(0).getInstanceType(), instanceType);
    assertNull(agents.get(0).getAgentId());
    assertNull(agents.get(0).getSelf());
    assertNull(agents.get(0).getExternalUri());
    assertEquals(agents.get(0).getState(), AgentLifecycleState.PROVISIONING);

    // start the agent and verify
    AgentStatus expectedAgentStatus = provisioner.startAgent(instanceId);
    coordinator.updateAllAgentsAndWait();
    assertEquals(coordinator.getAgents().size(), 1);
    assertEquals(coordinator.getAgent(instanceId).getInstanceId(), instanceId);
    assertEquals(coordinator.getAgent(instanceId).getInstanceType(), instanceType);
    assertEquals(coordinator.getAgent(instanceId).getLocation(), location);
    assertEquals(coordinator.getAgent(instanceId).getAgentId(), expectedAgentStatus.getAgentId());
    assertEquals(
        coordinator.getAgent(instanceId).getInternalUri(), expectedAgentStatus.getInternalUri());
    assertEquals(
        coordinator.getAgent(instanceId).getExternalUri(), expectedAgentStatus.getExternalUri());
    assertEquals(coordinator.getAgent(instanceId).getState(), AgentLifecycleState.ONLINE);

    request =
        Request.Builder.prepareGet()
            .setUri(coordinatorUriBuilder().appendPath("/v1/admin/agent").build())
            .build();

    agents =
        httpClient.execute(
            request, createJsonResponseHandler(agentStatusesCodec, Status.OK.getStatusCode()));
    assertEquals(agents.size(), 1);

    AgentStatusRepresentation actual = agents.get(0);
    assertEquals(actual.getInstanceId(), instanceId);
    assertEquals(actual.getInstanceType(), instanceType);
    assertEquals(actual.getLocation(), location);
    assertEquals(actual.getAgentId(), expectedAgentStatus.getAgentId());
    assertEquals(actual.getSelf(), expectedAgentStatus.getInternalUri());
    assertEquals(actual.getExternalUri(), expectedAgentStatus.getExternalUri());
    assertEquals(actual.getState(), AgentLifecycleState.ONLINE);
  }
  @Test
  public void testCoordinatorProvision() throws Exception {
    // provision the coordinator and verify
    String instanceType = "instance-type";
    CoordinatorProvisioningRepresentation coordinatorProvisioningRepresentation =
        new CoordinatorProvisioningRepresentation(
            "coordinator:config:1", 1, instanceType, null, null, null, null, null);
    Request request =
        Request.Builder.preparePost()
            .setUri(coordinatorUriBuilder().appendPath("/v1/admin/coordinator").build())
            .setHeader(CONTENT_TYPE, APPLICATION_JSON)
            .setBodyGenerator(
                jsonBodyGenerator(
                    coordinatorProvisioningCodec, coordinatorProvisioningRepresentation))
            .build();
    List<CoordinatorStatusRepresentation> coordinators =
        httpClient.execute(
            request,
            createJsonResponseHandler(coordinatorStatusesCodec, Status.OK.getStatusCode()));

    assertEquals(coordinators.size(), 1);
    String instanceId = coordinators.get(0).getInstanceId();
    assertNotNull(instanceId);
    String location = coordinators.get(0).getLocation();
    assertNotNull(location);
    assertEquals(coordinators.get(0).getInstanceType(), instanceType);
    assertNull(coordinators.get(0).getCoordinatorId());
    assertNull(coordinators.get(0).getSelf());
    assertNull(coordinators.get(0).getExternalUri());
    assertEquals(coordinators.get(0).getState(), CoordinatorLifecycleState.PROVISIONING);

    // start the coordinator and verify
    CoordinatorStatus expectedCoordinatorStatus = provisioner.startCoordinator(instanceId);
    coordinator.updateAllCoordinatorsAndWait();
    assertEquals(coordinator.getCoordinators().size(), 2);
    assertEquals(coordinator.getCoordinator(instanceId).getInstanceId(), instanceId);
    assertEquals(coordinator.getCoordinator(instanceId).getInstanceType(), instanceType);
    assertEquals(coordinator.getCoordinator(instanceId).getLocation(), location);
    assertEquals(
        coordinator.getCoordinator(instanceId).getCoordinatorId(),
        expectedCoordinatorStatus.getCoordinatorId());
    assertEquals(
        coordinator.getCoordinator(instanceId).getInternalUri(),
        expectedCoordinatorStatus.getInternalUri());
    assertEquals(
        coordinator.getCoordinator(instanceId).getExternalUri(),
        expectedCoordinatorStatus.getExternalUri());
    assertEquals(
        coordinator.getCoordinator(instanceId).getState(), CoordinatorLifecycleState.ONLINE);

    request =
        Request.Builder.prepareGet()
            .setUri(coordinatorUriBuilder().appendPath("/v1/admin/coordinator").build())
            .build();

    coordinators =
        httpClient.execute(
            request,
            createJsonResponseHandler(coordinatorStatusesCodec, Status.OK.getStatusCode()));
    CoordinatorStatusRepresentation actual = getNonMainCoordinator(coordinators);

    assertEquals(actual.getInstanceId(), instanceId);
    assertEquals(actual.getInstanceType(), instanceType);
    assertEquals(actual.getLocation(), location);
    assertEquals(actual.getCoordinatorId(), expectedCoordinatorStatus.getCoordinatorId());
    assertEquals(actual.getSelf(), expectedCoordinatorStatus.getInternalUri());
    assertEquals(actual.getExternalUri(), expectedCoordinatorStatus.getExternalUri());
    assertEquals(actual.getState(), CoordinatorLifecycleState.ONLINE);
  }