@Test public void testAddServicesOnNonexistantClusterReturns404() throws Exception { Cluster cluster = Cluster.builder() .setID("123") .setAccount(USER1_ACCOUNT) .setName("test-cluster") .setClusterTemplate(Entities.ClusterTemplateExample.HDFS) .setServices(ImmutableSet.<String>of("namenode", "datanode")) .setStatus(Cluster.Status.ACTIVE) .build(); clusterStoreService.getView(cluster.getAccount()).writeCluster(cluster); AddServicesRequest body = new AddServicesRequest(null, ImmutableSet.of("resourcemanager", "nodemanager")); assertResponseStatus(doPostExternalAPI("/clusters/1123/services", gson.toJson(body), USER1_HEADERS), HttpResponseStatus.NOT_FOUND); assertResponseStatus(doPostExternalAPI("/clusters/123/services", gson.toJson(body), USER2_HEADERS), HttpResponseStatus.NOT_FOUND); }
@Test public void testAddInvalidServicesReturns400() throws Exception { Cluster cluster = Cluster.builder() .setID("123") .setAccount(USER1_ACCOUNT) .setName("test-cluster") .setClusterTemplate(Entities.ClusterTemplateExample.HDFS) .setServices(ImmutableSet.<String>of("namenode", "datanode")) .setStatus(Cluster.Status.ACTIVE) .build(); clusterStoreService.getView(cluster.getAccount()).writeCluster(cluster); // can't add nodemanager without resourcemanager AddServicesRequest body = new AddServicesRequest(null, ImmutableSet.of("nodemanager")); assertResponseStatus(doPostExternalAPI("/clusters/123/services", gson.toJson(body), USER1_HEADERS), HttpResponseStatus.BAD_REQUEST); // can't add nonexistant service body = new AddServicesRequest(null, ImmutableSet.of("fakeservice")); assertResponseStatus(doPostExternalAPI("/clusters/123/services", gson.toJson(body), USER1_HEADERS), HttpResponseStatus.BAD_REQUEST); }
@Test public void testServiceActionsOnNonexistantClusterServiceReturn404() throws Exception { Cluster cluster = Cluster.builder() .setID("123") .setAccount(USER1_ACCOUNT) .setName("test-cluster") .setClusterTemplate(Entities.ClusterTemplateExample.HDFS) .setStatus(Cluster.Status.ACTIVE) .build(); clusterStoreService.getView(cluster.getAccount()).writeCluster(cluster); assertResponseStatus(doPostExternalAPI("/clusters/123/services/fake/stop", "", USER1_HEADERS), HttpResponseStatus.NOT_FOUND); assertResponseStatus(doPostExternalAPI("/clusters/123/services/fake/start", "", USER1_HEADERS), HttpResponseStatus.NOT_FOUND); assertResponseStatus(doPostExternalAPI("/clusters/123/services/fake/restart", "", USER1_HEADERS), HttpResponseStatus.NOT_FOUND); }
@Test public void testAddServicesCanOnlyRunOnActiveCluster() throws Exception { Cluster cluster = Cluster.builder() .setID("123") .setAccount(USER1_ACCOUNT) .setName("test-cluster") .setClusterTemplate(Entities.ClusterTemplateExample.HDFS) .setServices(ImmutableSet.<String>of("namenode", "datanode")) .build(); Set<Cluster.Status> badStatuses = ImmutableSet.of( Cluster.Status.INCOMPLETE, Cluster.Status.PENDING, Cluster.Status.TERMINATED, Cluster.Status.INCONSISTENT); AddServicesRequest body = new AddServicesRequest(null, ImmutableSet.of("resourcemanager", "nodemanager")); for (Cluster.Status status : badStatuses) { cluster.setStatus(status); clusterStoreService.getView(cluster.getAccount()).writeCluster(cluster); assertResponseStatus(doPostExternalAPI("/clusters/123/services", gson.toJson(body), USER1_HEADERS), HttpResponseStatus.CONFLICT); } }
assertResponseStatus(doPostExternalAPI("/clusters/123/services" + entry.getKey(), "", USER1_HEADERS), HttpResponseStatus.OK); Assert.assertEquals(entry.getValue().name(),
@Test public void testMaxClusterSize() throws Exception { Configuration conf = Configuration.create(); int maxClusterSize = conf.getInt(Constants.MAX_CLUSTER_SIZE); ClusterCreateRequest clusterCreateRequest = ClusterCreateRequest.builder() .setName("cluster") .setClusterTemplateName(smallTemplate.getName()) .setNumMachines(maxClusterSize + 1) .build(); assertResponseStatus(doPostExternalAPI("/clusters", gson.toJson(clusterCreateRequest), USER1_HEADERS), HttpResponseStatus.BAD_REQUEST); }
@Test public void testDeleteOnClusterNotOwnedByUserReturns404() throws Exception { ClusterCreateRequest clusterCreateRequest = ClusterCreateRequest.builder() .setName("cluster1") .setClusterTemplateName(reactorTemplate.getName()) .setNumMachines(5) .build(); HttpResponse response = doPostExternalAPI("/clusters", gson.toJson(clusterCreateRequest), USER1_HEADERS); assertResponseStatus(response, HttpResponseStatus.OK); String clusterId = getIdFromResponse(response); assertResponseStatus(doDeleteExternalAPI("/clusters/" + clusterId, USER2_HEADERS), HttpResponseStatus.NOT_FOUND); }
@Test public void testGetClusterNotOwnedByUserReturns404() throws Exception { ClusterCreateRequest clusterCreateRequest = ClusterCreateRequest.builder() .setName("cluster1") .setClusterTemplateName(reactorTemplate.getName()) .setNumMachines(5) .build(); HttpResponse response = doPostExternalAPI("/clusters", gson.toJson(clusterCreateRequest), USER1_HEADERS); assertResponseStatus(response, HttpResponseStatus.OK); String clusterId = getIdFromResponse(response); assertResponseStatus(doGetExternalAPI("/clusters/" + clusterId, USER2_HEADERS), HttpResponseStatus.NOT_FOUND); }
@Test public void testAdminCanGetClustersOwnedByOthers() throws Exception { ClusterCreateRequest clusterCreateRequest = ClusterCreateRequest.builder() .setName("cluster1") .setClusterTemplateName(reactorTemplate.getName()) .setNumMachines(5) .build(); HttpResponse response = doPostExternalAPI("/clusters", gson.toJson(clusterCreateRequest), USER1_HEADERS); assertResponseStatus(response, HttpResponseStatus.OK); String clusterId = getIdFromResponse(response); assertResponseStatus(doGetExternalAPI("/clusters/" + clusterId, ADMIN_HEADERS), HttpResponseStatus.OK); }
@Test public void testServiceActionsOnNonexistantClusterReturn404() throws Exception { Cluster cluster = Cluster.builder() .setID("123") .setAccount(USER1_ACCOUNT) .setName("test-cluster") .setClusterTemplate(Entities.ClusterTemplateExample.HDFS) .setStatus(Cluster.Status.ACTIVE) .build(); clusterStoreService.getView(cluster.getAccount()).writeCluster(cluster); Set<String> actions = ImmutableSet.of( "/stop", "/start", "/restart", "/namenode/stop", "/namenode/start", "/namenode/restart" ); for (String action : actions) { // no cluster 1123 assertResponseStatus(doPostExternalAPI("/clusters/1123/services" + action, "", USER1_HEADERS), HttpResponseStatus.NOT_FOUND); // no cluster for user2 assertResponseStatus(doPostExternalAPI("/clusters/123/services" + action, "", USER2_HEADERS), HttpResponseStatus.NOT_FOUND); } }
@Test public void testServiceActionsCanOnlyRunOnActiveCluster() throws Exception { Cluster cluster = Cluster.builder() .setID("123") .setAccount(USER1_ACCOUNT) .setName("test-cluster") .setClusterTemplate(Entities.ClusterTemplateExample.HDFS) .setServices(ImmutableSet.<String>of("namenode", "datanode")) .build(); Set<Cluster.Status> badStatuses = ImmutableSet.of( Cluster.Status.INCOMPLETE, Cluster.Status.PENDING, Cluster.Status.TERMINATED, Cluster.Status.INCONSISTENT); Set<String> resources = ImmutableSet.of( "/clusters/123/services/stop", "/clusters/123/services/start", "/clusters/123/services/restart", "/clusters/123/services/namenode/stop", "/clusters/123/services/namenode/start", "/clusters/123/services/namenode/restart" ); for (Cluster.Status status : badStatuses) { cluster.setStatus(status); clusterStoreService.getView(cluster.getAccount()).writeCluster(cluster); for (String resource : resources) { assertResponseStatus(doPostExternalAPI(resource, "", USER1_HEADERS), HttpResponseStatus.CONFLICT); } } }
@Test public void testInvalidNumMachines() throws Exception { // when its below the min ClusterCreateRequest clusterCreateRequest =ClusterCreateRequest.builder() .setName("my-cluster") .setClusterTemplateName(reactorTemplate.getName()) .setProviderName(reactorTemplate.getClusterDefaults().getProvider()) .setNumMachines(1) .build(); assertResponseStatus(doPostExternalAPI("/clusters", gson.toJson(clusterCreateRequest), USER1_HEADERS), HttpResponseStatus.BAD_REQUEST); // when its above the max clusterCreateRequest = ClusterCreateRequest.builder() .setName("my-cluster") .setClusterTemplateName(reactorTemplate.getName()) .setProviderName(reactorTemplate.getClusterDefaults().getProvider()) .setNumMachines(500) .build(); assertResponseStatus(doPostExternalAPI("/clusters", gson.toJson(clusterCreateRequest), USER1_HEADERS), HttpResponseStatus.BAD_REQUEST); }
@Test public void testClusterTemplateSync404Conditions() throws Exception { Cluster cluster = Entities.ClusterExample.createCluster(); Account clusterAccount = cluster.getAccount(); cluster.setStatus(Cluster.Status.ACTIVE); clusterStoreService.getView(clusterAccount).writeCluster(cluster); clusterStore.writeNode(Entities.ClusterExample.NODE1); clusterStore.writeNode(Entities.ClusterExample.NODE2); entityStoreService.getView(Entities.ADMIN_ACCOUNT).writeClusterTemplate(cluster.getClusterTemplate()); String path = "/clusters/" + cluster.getId() + "/clustertemplate/sync"; // test cluster that does not exist returns 404 assertResponseStatus( doPostExternalAPI("/clusters/" + cluster.getId() + "1" + "/clustertemplate/sync", "", USER1_HEADERS), HttpResponseStatus.NOT_FOUND); // test cluster owned by another user returns 404 assertResponseStatus(doPostExternalAPI(path, "", USER2_HEADERS), HttpResponseStatus.NOT_FOUND); // test missing template returns 404 entityStoreService.getView(Entities.ADMIN_ACCOUNT).deleteClusterTemplate(cluster.getClusterTemplate().getName()); assertResponseStatus(doPostExternalAPI(path, "", USER1_HEADERS), HttpResponseStatus.NOT_FOUND); // test missing nodes returns 404 entityStoreService.getView(Entities.ADMIN_ACCOUNT).writeClusterTemplate(cluster.getClusterTemplate()); clusterStore.deleteNode(Entities.ClusterExample.NODE1.getId()); clusterStore.deleteNode(Entities.ClusterExample.NODE2.getId()); assertResponseStatus(doPostExternalAPI(path, "", USER1_HEADERS), HttpResponseStatus.NOT_FOUND); }
@Test public void testAddClusterWithOptionalArgs() throws Exception { String clusterName = "my-cluster"; String tenantId = USER1_ACCOUNT.getTenantId(); ClusterCreateRequest clusterCreateRequest = ClusterCreateRequest.builder() .setName(clusterName) .setClusterTemplateName(reactorTemplate.getName()) .setNumMachines(5) .setProviderName("joyent") .setServiceNames(ImmutableSet.of("namenode", "datanode")) .setHardwareTypeName("large") .setImageTypeName("centos6") .setInitialLeaseDuration(-1L) .build(); HttpResponse response = doPostExternalAPI("/clusters", gson.toJson(clusterCreateRequest), USER1_HEADERS); assertResponseStatus(response, HttpResponseStatus.OK); // check there was an element added to the cluster queue for creating this cluster Element element = solverQueues.take(tenantId, "0"); SolverRequest request = gson.fromJson(element.getValue(), SolverRequest.class); ClusterCreateRequest createRequest = gson.fromJson(request.getJsonRequest(), ClusterCreateRequest.class); Assert.assertEquals("joyent", createRequest.getProvider()); Assert.assertEquals("centos6", createRequest.getImageType()); Assert.assertEquals("large", createRequest.getHardwareType()); Assert.assertEquals(ImmutableSet.of("namenode", "datanode"), createRequest.getServices()); }
@Test public void testAddCluster() throws Exception { String clusterName = "my-cluster"; String tenantId = USER1_ACCOUNT.getTenantId(); ClusterCreateRequest clusterCreateRequest = ClusterCreateRequest.builder() .setName(clusterName) .setClusterTemplateName(reactorTemplate.getName()) .setNumMachines(5) .build(); HttpResponse response = doPostExternalAPI("/clusters", gson.toJson(clusterCreateRequest), USER1_HEADERS); assertResponseStatus(response, HttpResponseStatus.OK); String clusterId = getIdFromResponse(response); // check there was an element added to the cluster queue for creating this cluster Element element = solverQueues.take(tenantId, "0"); Assert.assertEquals(clusterId, element.getId()); ClusterCreateRequest expected = ClusterCreateRequest.builder() .setName(clusterName) .setClusterTemplateName(reactorTemplate.getName()) .setNumMachines(5) .setInitialLeaseDuration(-1L) .build(); SolverRequest expectedSolverRequest = new SolverRequest(SolverRequest.Type.CREATE_CLUSTER, gson.toJson(expected)); Assert.assertEquals(expectedSolverRequest, gson.fromJson(element.getValue(), SolverRequest.class)); }
private void verifyInitialLeaseDuration(long expectedExpireTime, HttpResponseStatus expectedStatus, long requestedLeaseDuration, String clusterTemplate) throws Exception { ClusterCreateRequest clusterCreateRequest = ClusterCreateRequest.builder() .setName("test-lease") .setClusterTemplateName(clusterTemplate) .setNumMachines(4) .setInitialLeaseDuration(requestedLeaseDuration) .build(); HttpResponse response = doPostExternalAPI("/clusters", gson.toJson(clusterCreateRequest), USER1_HEADERS); assertResponseStatus(response, expectedStatus); if (expectedStatus == HttpResponseStatus.BAD_REQUEST) { return; } solverScheduler.run(); String clusterId = getIdFromResponse(response); Cluster cluster = clusterStoreService.getView(USER1_ACCOUNT).getCluster(clusterId); Assert.assertEquals(Cluster.Status.PENDING, cluster.getStatus()); if (expectedExpireTime == 0) { Assert.assertEquals(expectedExpireTime, cluster.getExpireTime()); } else { Assert.assertEquals(expectedExpireTime, cluster.getExpireTime() == 0 ? 0 : cluster.getExpireTime() - cluster.getCreateTime()); } }
@Test public void testClusterTemplateSyncOnlyAllowedOnActiveClusters() throws Exception { Cluster cluster = Entities.ClusterExample.createCluster(); Account clusterAccount = cluster.getAccount(); clusterStoreService.getView(clusterAccount).writeCluster(cluster); entityStoreService.getView(Entities.ADMIN_ACCOUNT).writeClusterTemplate(cluster.getClusterTemplate()); String path = "/clusters/" + cluster.getId() + "/clustertemplate/sync"; // test cluster in bad state return 409 entityStoreService.getView(Entities.ADMIN_ACCOUNT).writeClusterTemplate(cluster.getClusterTemplate()); for (Cluster.Status status : Cluster.Status.values()) { if (status != Cluster.Status.ACTIVE) { cluster.setStatus(status); clusterStoreService.getView(clusterAccount).writeCluster(cluster); assertResponseStatus(doPostExternalAPI(path, "", USER1_HEADERS), HttpResponseStatus.CONFLICT); } } }
assertResponseStatus(doPostExternalAPI(path, "", USER1_HEADERS), HttpResponseStatus.OK);
assertResponseStatus(doPostExternalAPI(path, "", USER1_HEADERS), HttpResponseStatus.BAD_REQUEST);
@Test public void testClusterProlongForever() throws Exception { ClusterTemplate foreverTemplate = ClusterTemplate.builder() .setName("forever-template") .setClusterDefaults( ClusterDefaults.builder() .setServices("base") .setProvider("rackspace") .build()) .build(); long currentTime = 10000; Cluster foreverCluster = Cluster.builder() .setID("1002") .setAccount(USER1_ACCOUNT) .setName("prolong-test") .setCreateTime(currentTime) .setClusterTemplate(foreverTemplate) .build(); foreverCluster.setExpireTime(currentTime + 10000); foreverCluster.setStatus(Cluster.Status.ACTIVE); clusterStoreService.getView(USER1_ACCOUNT).writeCluster(foreverCluster); HttpResponse response = doPostExternalAPI("/clusters/" + foreverCluster.getId(), "{'expireTime' : 90000}", ADMIN_HEADERS); assertResponseStatus(response, HttpResponseStatus.OK); foreverCluster = clusterStoreService.getView(USER1_ACCOUNT).getCluster(foreverCluster.getId()); Assert.assertEquals(90000, foreverCluster.getExpireTime()); }