This is an automated email from the ASF dual-hosted git repository. ofuks pushed a commit to branch feature-integration-tests in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
The following commit(s) were added to refs/heads/feature-integration-tests by this push: new 80ccfa2 [DLAB-1419] Implemented project features 80ccfa2 is described below commit 80ccfa20018e415ac284fc98ba8f7e9867cda821 Author: Oleh Fuks <olegfuk...@gmail.com> AuthorDate: Thu Jan 2 16:09:35 2020 +0200 [DLAB-1419] Implemented project features --- .../java/org/apache/dlab/dto/CreateProjectDTO.java | 6 +- .../main/java/org/apache/dlab/dto/ProjectDTO.java | 16 +++ ...CreateProjectDTO.java => UpdateProjectDTO.java} | 10 +- .../java/org/apache/dlab/util/PropertyHelper.java | 5 +- .../src/test/java/dlab/project/ProjectSteps.java | 151 ++++++++++++++++++--- .../src/test/resources/dlab/project.feature | 143 +++++++------------ 6 files changed, 203 insertions(+), 128 deletions(-) diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/CreateProjectDTO.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/CreateProjectDTO.java index 9d22144..2f38d08 100644 --- a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/CreateProjectDTO.java +++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/CreateProjectDTO.java @@ -1,19 +1,19 @@ package org.apache.dlab.dto; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Data; -import lombok.NoArgsConstructor; import java.util.Set; @Data @AllArgsConstructor -@NoArgsConstructor public class CreateProjectDTO { private String name; private Set<String> groups; private Set<String> endpoints; private String key; private String tag; + @JsonProperty("shared_image_enabled") + private boolean sharedImageEnabled; } - diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/ProjectDTO.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/ProjectDTO.java new file mode 100644 index 0000000..18dd0b9 --- /dev/null +++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/ProjectDTO.java @@ -0,0 +1,16 @@ +package org.apache.dlab.dto; + + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import java.util.Set; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class ProjectDTO { + private String name; + private Set<String> groups; + private Set<EndpointStatusDTO> endpoints; + private boolean sharedImageEnabled; +} diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/CreateProjectDTO.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/UpdateProjectDTO.java similarity index 57% copy from integration-tests-cucumber/src/main/java/org/apache/dlab/dto/CreateProjectDTO.java copy to integration-tests-cucumber/src/main/java/org/apache/dlab/dto/UpdateProjectDTO.java index 9d22144..cbe7cff 100644 --- a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/CreateProjectDTO.java +++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/UpdateProjectDTO.java @@ -1,19 +1,17 @@ package org.apache.dlab.dto; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Data; -import lombok.NoArgsConstructor; import java.util.Set; @Data @AllArgsConstructor -@NoArgsConstructor -public class CreateProjectDTO { +public class UpdateProjectDTO { private String name; private Set<String> groups; private Set<String> endpoints; - private String key; - private String tag; + @JsonProperty("shared_image_enabled") + private boolean sharedImageEnabled; } - diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java index 6b4a60a..d575ff0 100644 --- a/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java +++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java @@ -1,10 +1,12 @@ package org.apache.dlab.util; +import lombok.extern.slf4j.Slf4j; + import java.io.FileInputStream; import java.io.InputStream; -import java.util.Optional; import java.util.Properties; +@Slf4j public class PropertyHelper { private final static Properties PROPERTIES; @@ -14,6 +16,7 @@ public class PropertyHelper { try (InputStream inputStream = new FileInputStream(System.getProperty("config.file"))) { PROPERTIES.load(inputStream); + log.info("Configs: {}", PROPERTIES); } catch (Exception e) { e.printStackTrace(); } diff --git a/integration-tests-cucumber/src/test/java/dlab/project/ProjectSteps.java b/integration-tests-cucumber/src/test/java/dlab/project/ProjectSteps.java index f24c4da..2caefb7 100644 --- a/integration-tests-cucumber/src/test/java/dlab/project/ProjectSteps.java +++ b/integration-tests-cucumber/src/test/java/dlab/project/ProjectSteps.java @@ -13,36 +13,51 @@ import dlab.util.KeycloakUtil; import lombok.extern.slf4j.Slf4j; import org.apache.dlab.dto.CreateProjectDTO; import org.apache.dlab.dto.EndpointStatusDTO; +import org.apache.dlab.dto.ProjectDTO; import org.apache.dlab.dto.ProjectKeyDTO; import org.apache.dlab.dto.ProjectStatusDTO; +import org.apache.dlab.dto.UpdateProjectDTO; import org.apache.dlab.util.JacksonMapper; import org.apache.http.HttpStatus; import java.net.URI; import java.net.URISyntaxException; import java.time.LocalDateTime; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import static com.jayway.restassured.RestAssured.given; -import static dlab.Constants.*; +import static dlab.Constants.API_URI; +import static dlab.Constants.CONNECTION_TIMEOUT; +import static dlab.Constants.CONNECTION_TIMEOUT_LABEL; +import static dlab.Constants.LOCAL_ENDPOINT; +import static dlab.Constants.SOCKET_TIMEOUT; +import static dlab.Constants.SOCKET_TIMEOUT_LABEL; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @Slf4j public class ProjectSteps { - private RequestSpecification createProjectRequest; + private RequestSpecification request; private Response response; private String projectName; private String publicKey; private Set<String> endpoints; private Set<String> groups; + private Set<String> projects; + private boolean sharedImageEnabled; + private ProjectDTO project; @Given("There is no project with name {string} in DLab") @@ -53,6 +68,19 @@ public class ProjectSteps { .statusCode(HttpStatus.SC_NOT_FOUND); } + @Given("There are the following projects") + public void thereAreTheFollowingProjects(List<String> projects) { + this.projects = new HashSet<>(projects); + } + + @Given("There is a project with name {string} in DLab") + public void thereIsAProjectWithNameInDLab(String projectName) { + this.projectName = projectName; + this.project = authenticatedRequest() + .get(API_URI + "project/{project}", projectName) + .as(ProjectDTO.class); + } + @And("There are the following endpoints") public void thereAreTheFollowingEndpoints(List<String> endpoints) { this.endpoints = new HashSet<>(endpoints); @@ -63,40 +91,122 @@ public class ProjectSteps { this.groups = new HashSet<>(groups); } - @And("User generate new publicKey") - public void userTryToGenerateNewPublicKey() { - this.publicKey = authenticatedRequest().contentType(ContentType.JSON) + @And("User generates new publicKey") + public void userGeneratesNewPublicKey() { + this.publicKey = authenticatedRequest() + .contentType(ContentType.JSON) .post(API_URI + "project/keys") .getBody().as(ProjectKeyDTO.class) .getPublicKey(); } - @When("User send create new project request") - public void userSendCreateNewProjectRequest() { - response = createProjectRequest.post(API_URI + "project"); + @And("User tries to create new project with name {string}, endpoints, groups, publicKey and use shared image enable {string}") + public void userTriesToCreateNewProjectWithNameEndpointsGroupsAndKey(String projectName, String sharedImageEnabled) { + this.projectName = projectName; + boolean sharedImage = Boolean.parseBoolean(sharedImageEnabled); + request = authenticatedRequest() + .body(JacksonMapper.marshall(new CreateProjectDTO(projectName, groups, endpoints, publicKey, projectName, sharedImage))) + .contentType(ContentType.JSON); } - @And("User try to create new project with name {string}, endpoints, groups and publicKey") - public void userTryToCreateNewProjectWithNameEndpointsGroupsAndKey(String projectName) { + @And("User tries to get information about project with name {string}") + public void userTriesToGetInformationAboutProjectWithName(String projectName) { this.projectName = projectName; - createProjectRequest = given() - .body(JacksonMapper.marshall(new CreateProjectDTO(projectName, groups, endpoints, publicKey, projectName))) - .auth() - .oauth2(KeycloakUtil.getToken()) + request = authenticatedRequest(); + } + + @And("Use shared image enable {string}") + public void useSharedImageEnable(String sharedImageEnabled) { + this.sharedImageEnabled = Boolean.parseBoolean(sharedImageEnabled); + } + + @And("User tries to edit project with shared image enable opposite to existing") + public void userTriesToEditProjectWithSharedImageEnableOppositeToExisting() { + sharedImageEnabled = !project.isSharedImageEnabled(); + UpdateProjectDTO updateProjectDTO = new UpdateProjectDTO(project.getName(), project.getGroups(), + project.getEndpoints().stream().map(EndpointStatusDTO::getName).collect(Collectors.toSet()), sharedImageEnabled); + + request = authenticatedRequest() + .body(JacksonMapper.marshall(updateProjectDTO)) .contentType(ContentType.JSON); } + @And("User tries to terminate the project with name {string}") + public void userTriesToTerminateTheProjectWithName(String projectName) { + this.projectName = projectName; + request = authenticatedRequest() + .contentType(ContentType.JSON); + } + + @When("User sends create new project request") + public void userSendsCreateNewProjectRequest() { + response = request.post(API_URI + "project"); + } + + @When("User sends request to get information about project") + public void userSendsRequestToGetInformationAboutProject() { + response = request.get(API_URI + "project/{project}", projectName); + } + + @When("User sends edit request") + public void userSendsEditRequest() { + response = request.put(API_URI + "project"); + } + + @When("User sends termination request") + public void userSendsTerminationRequest() { + response = request.delete(API_URI + "project/{project}", projectName); + } + @Then("Status code is {int}") public void statusCodeIs(int code) { assertThat(response.getStatusCode(), equalTo(code)); } - @Then("User wait maximum {int} minutes while project is creating") + @Then("User waits maximum {int} minutes while project is creating") public void userWaitMaximumMinutesWhileProjectIsCreating(int timeout) throws URISyntaxException, InterruptedException { - boolean isRunning = false; + boolean isRunning = waitForStatus(timeout, EndpointStatusDTO.Status.RUNNING); + + assertTrue("Timeout for project status check reached!", isRunning); + log.info("Project {} successfully created", projectName); + } + + @Then("User waits maximum {int} minutes while project is terminated") + public void userWaitsMaximumTimeoutMinutesWhileProjectIsTerminated(int timeout) throws URISyntaxException, InterruptedException { + boolean isTerminated = waitForStatus(timeout, EndpointStatusDTO.Status.TERMINATED); + + assertTrue("Timeout for project status check reached!", isTerminated); + log.info("Project {} successfully terminated", projectName); + } + + @And("Project information is successfully returned with name {string}, endpoints, groups") + public void projectInformationIsSuccessfullyReturnedWithNameEndpointsGroups(String expectedProjectName) { + ProjectDTO project = response.getBody().as(ProjectDTO.class); + Set<String> endpoints = project.getEndpoints().stream().map(EndpointStatusDTO::getName).collect(Collectors.toSet()); + Set<String> groups = project.getGroups(); + + assertEquals(project.getName(), expectedProjectName); + assertFalse(Collections.disjoint(endpoints, this.endpoints)); + assertFalse(Collections.disjoint(groups, this.groups)); + } + + @And("Project information is successfully updated with shared image enable") + public void projectInformationIsSuccessfullyUpdatedWithSharedImageEnable() { + boolean sharedImageEnabled = authenticatedRequest() + .get(API_URI + "project/{project}", projectName) + .as(ProjectDTO.class) + .isSharedImageEnabled(); + + assertSame(this.sharedImageEnabled, sharedImageEnabled); + log.info("Project {} successfully edited", projectName); + } + + private boolean waitForStatus(int timeout, EndpointStatusDTO.Status status) throws URISyntaxException, InterruptedException { + boolean correctStatus = false; LocalDateTime withTimeout = LocalDateTime.now().plusMinutes(timeout); - log.info("User wait till {}", withTimeout); - while (!isRunning && LocalDateTime.now().isBefore(withTimeout)) { + log.info("User wait till {} for project {} to be {}", withTimeout, projectName, status); + + while (!correctStatus && LocalDateTime.now().isBefore(withTimeout)) { ProjectStatusDTO projectDTO = authenticatedRequest() .get(new URI(API_URI + "project/" + projectName)) .getBody().as(ProjectStatusDTO.class); @@ -111,12 +221,11 @@ public class ProjectSteps { assertTrue("local endpoint does not exist!", localEndpoint.isPresent()); assertNotSame("Endpoint with status FAILED", EndpointStatusDTO.Status.FAILED, localEndpoint.get().getStatus()); - isRunning = EndpointStatusDTO.Status.RUNNING == localEndpoint.get().getStatus(); + correctStatus = status == localEndpoint.get().getStatus(); TimeUnit.MINUTES.sleep(1); } - assertTrue("Timeout for project status check reached!", isRunning); - log.info("Project {} successfully created", projectName); + return correctStatus; } private RequestSpecification authenticatedRequest() { diff --git a/integration-tests-cucumber/src/test/resources/dlab/project.feature b/integration-tests-cucumber/src/test/resources/dlab/project.feature index 6828b91..5aa0051 100644 --- a/integration-tests-cucumber/src/test/resources/dlab/project.feature +++ b/integration-tests-cucumber/src/test/resources/dlab/project.feature @@ -1,3 +1,4 @@ +@project Feature: Project management in DLab Such feature allowed to manage projects inside DLab @@ -9,8 +10,8 @@ Feature: Project management in DLab And There are the following groups | $anyuser | And User generates new publicKey - When User tries to create new project with name "<name>", endpoints, groups, publicKey and use shared image enable "<true>" - And User sends create new project request + And User tries to create new project with name "<name>", endpoints, groups, publicKey and use shared image enable "true" + When User sends create new project request Then User waits maximum <timeout> minutes while project is creating Then Status code is 200 Examples: @@ -27,15 +28,15 @@ Feature: Project management in DLab And There are the following groups | $anyuser | And User generates new publicKey - When User tries to create new project with name "<name>", endpoints, groups, publicKey and use shared image enable "<true>" - And User sends create new project request - Then Response status code is 409 + And User tries to create new project with name "<name>", endpoints, groups, publicKey and use shared image enable "true" + When User sends create new project request + Then Status code is 409 Examples: | name | | prj1 | - Scenario Outline: Get information about projects that exits + Scenario Outline: Get information about project that exits Given There are the following projects | prj1 | @@ -43,100 +44,48 @@ Feature: Project management in DLab | local | And There are the following groups | $anyuser | - When User tries to get information about project with name "<name>" - Then Response status code is 200 + And User tries to get information about project with name "<name>" + When User sends request to get information about project + Then Status code is 200 And Project information is successfully returned with name "<name>", endpoints, groups Examples: - | name | endpoint | group | - | prj1 | local | $anyuser | + | name | + | prj1 | Scenario: Get information about a project that does not exists - Given There is no project with name "test1" - When User tries to get information about the project with name "test1" - Then Respone status code is 404 - - - - - Scenario: Edit (change use shared image and add a group) a project that is available - - Given There are the following projects - | prj1 | - And There are the following endpoints - | local | - And There are the following groups - | $anyuser | - And Use shared image enable "<true>" - When User tries to create a new group with name "admin" - And User adds new group with name "admin" - And User changes use shared image to "false" - And User sends request for updating - Then Response status code is 200 - And Project information is successfully updated with groups, use shared image - - - Scenario: Edit (remove endpoint) a project that is available - - Given There are the following projects - | prj1 | - And There are the following endpoints - | local | - And There are the following groups - | $anyuser | - And Use shared image enable "<true>" - When User tries to remove endpoint with name "local" - And User sends request for updating - Then Response status code is 403 - - Scenario: Edit (add group that does not exit) a project that is available - - Given There are the following projects - | prj1 | - And There are the following endpoints - | local | - And There are the following groups - | $anyuser | - And Use shared image enable "<true>" - And There is no group with name "global" - When User tries to add group with name "global" - And User sends request for updating - Then Response status code is 400 - - Scenario: Edit (add endpoint that does not exit) a project that is available - - Given There are the following projects - | prj1 | - And There are the following endpoints - | local | - And There are the following groups - | $anyuser | - And Use shared image enable "<true>" - And There is no endpoint with name "exploring" - When User tries to add endpoint with name "exploring" - And User sends request for updating - Then Response status code is 400 - - Scenario Outline: Terminate a project/edge node that exits - - Given There are the following projects - | prj1 | - And There are the following endpoints - | local | - And There are the following groups - | $anyuser | - When User tries to terminate the project with name "<name>" - And User sends request for termination - Then User waits maximum <timeout> minutes while project is terminated - Then Response status code is 200 - Examples: - | name | timeout | - | prj1 | 20 | - - - Scenario: Terminate a project/edge node that does not exists - - Given There is no project with name "test1" - When User tries to terminate the project with name "test1" - Then Respone status code is 404 + Given There is no project with name "test1" in DLab + And User tries to get information about project with name "test1" + When User sends request to get information about project + Then Status code is 404 + + + Scenario: Edit (change use shared image) a project that is available + + Given There is a project with name "prj1" in DLab + And User tries to edit project with shared image enable opposite to existing + When User sends edit request + Then Status code is 200 + And Project information is successfully updated with shared image enable + + @terminate + Scenario Outline: Terminate a project/edge node that exits + + Given There is a project with name "<name>" in DLab + And User tries to terminate the project with name "<name>" + When User sends termination request + Then User waits maximum <timeout> minutes while project is terminated + Then Status code is 200 + Examples: + | name | timeout | + | prj1 | 20 | + + + @terminate + Scenario: Terminate a project/edge node that does not exists + + Given There is no project with name "test1" in DLab + And User tries to terminate the project with name "test1" + When User sends termination request + Then Status code is 404 --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@dlab.apache.org For additional commands, e-mail: commits-h...@dlab.apache.org