@Test
 public void testValidVersion() {
   UriInfo uriInfo = MockUriInfo.from("http://localhost/v1/slot/lifecycle?binary=*:apple:*");
   String slotsVersion =
       VersionsUtil.createSlotsVersion(
           coordinator.getAllSlotsStatus(
               SlotFilterBuilder.build(uriInfo, false, ImmutableList.<UUID>of())));
   assertOkResponse(
       resource.setState("running", uriInfo, slotsVersion), RUNNING, apple1SlotId, apple2SlotId);
 }
  @Test
  public void testMultipleStateMachineWithFilter() {
    UriInfo uriInfo = MockUriInfo.from("http://localhost/v1/slot/lifecycle?binary=*:apple:*");

    // default state is stopped
    assertSlotState(apple1SlotId, STOPPED);
    assertSlotState(apple2SlotId, STOPPED);
    assertSlotState(bananaSlotId, STOPPED);

    // stopped.start => running
    assertOkResponse(
        resource.setState("running", uriInfo, null), RUNNING, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, RUNNING);
    assertSlotState(apple2SlotId, RUNNING);
    assertSlotState(bananaSlotId, STOPPED);

    // running.start => running
    assertOkResponse(
        resource.setState("running", uriInfo, null), RUNNING, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, RUNNING);
    assertSlotState(apple2SlotId, RUNNING);
    assertSlotState(bananaSlotId, STOPPED);

    // running.stop => stopped
    assertOkResponse(
        resource.setState("stopped", uriInfo, null), STOPPED, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, STOPPED);
    assertSlotState(apple2SlotId, STOPPED);
    assertSlotState(bananaSlotId, STOPPED);

    // stopped.stop => stopped
    assertOkResponse(
        resource.setState("stopped", uriInfo, null), STOPPED, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, STOPPED);
    assertSlotState(apple2SlotId, STOPPED);
    assertSlotState(bananaSlotId, STOPPED);

    // stopped.restart => running
    assertOkResponse(
        resource.setState("restarting", uriInfo, null), RUNNING, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, RUNNING);
    assertSlotState(apple2SlotId, RUNNING);
    assertSlotState(bananaSlotId, STOPPED);

    // running.restart => running
    assertOkResponse(
        resource.setState("restarting", uriInfo, null), RUNNING, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, RUNNING);
    assertSlotState(apple2SlotId, RUNNING);
    assertSlotState(bananaSlotId, STOPPED);
  }
 @Test
 public void testInvalidVersion() {
   UriInfo uriInfo = MockUriInfo.from("http://localhost/v1/slot/lifecycle?binary=*:apple:*");
   try {
     resource.setState("running", uriInfo, "invalid-version");
     fail("Expected VersionConflictException");
   } catch (VersionConflictException e) {
     assertEquals(e.getName(), AIRSHIP_SLOTS_VERSION_HEADER);
     assertEquals(
         e.getVersion(),
         VersionsUtil.createSlotsVersion(
             coordinator.getAllSlotsStatus(
                 SlotFilterBuilder.build(uriInfo, false, ImmutableList.<UUID>of()))));
   }
 }
public class TestCoordinatorLifecycleResource {
  private final UriInfo uriInfo = MockUriInfo.from("http://localhost/v1/slot/lifecycle");
  private CoordinatorLifecycleResource resource;

  private Coordinator coordinator;
  private String agentId;
  private int prefixSize;
  private UUID apple1SlotId;
  private UUID apple2SlotId;
  private UUID bananaSlotId;

  @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 testMultipleStateMachineWithFilter() {
    UriInfo uriInfo = MockUriInfo.from("http://localhost/v1/slot/lifecycle?binary=*:apple:*");

    // default state is stopped
    assertSlotState(apple1SlotId, STOPPED);
    assertSlotState(apple2SlotId, STOPPED);
    assertSlotState(bananaSlotId, STOPPED);

    // stopped.start => running
    assertOkResponse(
        resource.setState("running", uriInfo, null), RUNNING, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, RUNNING);
    assertSlotState(apple2SlotId, RUNNING);
    assertSlotState(bananaSlotId, STOPPED);

    // running.start => running
    assertOkResponse(
        resource.setState("running", uriInfo, null), RUNNING, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, RUNNING);
    assertSlotState(apple2SlotId, RUNNING);
    assertSlotState(bananaSlotId, STOPPED);

    // running.stop => stopped
    assertOkResponse(
        resource.setState("stopped", uriInfo, null), STOPPED, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, STOPPED);
    assertSlotState(apple2SlotId, STOPPED);
    assertSlotState(bananaSlotId, STOPPED);

    // stopped.stop => stopped
    assertOkResponse(
        resource.setState("stopped", uriInfo, null), STOPPED, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, STOPPED);
    assertSlotState(apple2SlotId, STOPPED);
    assertSlotState(bananaSlotId, STOPPED);

    // stopped.restart => running
    assertOkResponse(
        resource.setState("restarting", uriInfo, null), RUNNING, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, RUNNING);
    assertSlotState(apple2SlotId, RUNNING);
    assertSlotState(bananaSlotId, STOPPED);

    // running.restart => running
    assertOkResponse(
        resource.setState("restarting", uriInfo, null), RUNNING, apple1SlotId, apple2SlotId);
    assertSlotState(apple1SlotId, RUNNING);
    assertSlotState(apple2SlotId, RUNNING);
    assertSlotState(bananaSlotId, STOPPED);
  }

  @Test
  public void testSetStateUnknownState() {
    Response response = resource.setState("unknown", uriInfo, null);
    assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
    assertNull(response.getEntity());
  }

  @Test(expectedExceptions = NullPointerException.class)
  public void testSetStateNullState() {
    resource.setState(null, uriInfo, null);
  }

  @Test(expectedExceptions = InvalidSlotFilterException.class)
  public void testSetStateNoFilter() {
    resource.setState("running", MockUriInfo.from("http://localhost/v1/slot/lifecycle"), null);
  }

  @Test
  public void testInvalidVersion() {
    UriInfo uriInfo = MockUriInfo.from("http://localhost/v1/slot/lifecycle?binary=*:apple:*");
    try {
      resource.setState("running", uriInfo, "invalid-version");
      fail("Expected VersionConflictException");
    } catch (VersionConflictException e) {
      assertEquals(e.getName(), AIRSHIP_SLOTS_VERSION_HEADER);
      assertEquals(
          e.getVersion(),
          VersionsUtil.createSlotsVersion(
              coordinator.getAllSlotsStatus(
                  SlotFilterBuilder.build(uriInfo, false, ImmutableList.<UUID>of()))));
    }
  }

  @Test
  public void testValidVersion() {
    UriInfo uriInfo = MockUriInfo.from("http://localhost/v1/slot/lifecycle?binary=*:apple:*");
    String slotsVersion =
        VersionsUtil.createSlotsVersion(
            coordinator.getAllSlotsStatus(
                SlotFilterBuilder.build(uriInfo, false, ImmutableList.<UUID>of())));
    assertOkResponse(
        resource.setState("running", uriInfo, slotsVersion), RUNNING, apple1SlotId, apple2SlotId);
  }

  private void assertOkResponse(Response response, SlotLifecycleState state, UUID... slotIds) {
    assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());

    AgentStatus agentStatus = coordinator.getAgentByAgentId(agentId);
    Builder<SlotStatusRepresentation> builder = ImmutableList.builder();
    for (UUID slotId : slotIds) {
      SlotStatus slotStatus = agentStatus.getSlotStatus(slotId);
      builder.add(
          SlotStatusRepresentation.from(slotStatus.changeState(state), prefixSize, MOCK_REPO));
      assertEquals(slotStatus.getAssignment(), APPLE_ASSIGNMENT);
    }
    assertEqualsNoOrder((Collection<?>) response.getEntity(), builder.build());
    assertNull(
        response
            .getMetadata()
            .get("Content-Type")); // content type is set by jersey based on @Produces
  }

  private void assertSlotState(UUID slotId, SlotLifecycleState state) {
    assertEquals(coordinator.getAgentByAgentId(agentId).getSlotStatus(slotId).getState(), state);
  }
}
 @Test(expectedExceptions = InvalidSlotFilterException.class)
 public void testSetStateNoFilter() {
   resource.setState("running", MockUriInfo.from("http://localhost/v1/slot/lifecycle"), null);
 }