You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by of...@apache.org on 2020/01/08 09:42:12 UTC
[incubator-dlab] branch feature-integration-tests updated:
[DLAB-1424] Added notebook feature part 1
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 e0f5fd4 [DLAB-1424] Added notebook feature part 1
e0f5fd4 is described below
commit e0f5fd4b272f5680221661fcff0e35a024039994
Author: Oleh Fuks <ol...@gmail.com>
AuthorDate: Wed Jan 8 11:41:51 2020 +0200
[DLAB-1424] Added notebook feature part 1
---
doc/.DS_Store | Bin 12292 -> 0 bytes
.../org/apache/dlab/dto/NotebookCreateDTO.java | 61 ++++++++
.../main/java/org/apache/dlab/dto/NotebookDTO.java | 70 +++++++++
.../org/apache/dlab/dto/ProjectNotebookDTO.java | 34 +++++
.../src/test/java/dlab/Constants.java | 6 +-
.../src/test/java/dlab/notebook/NotebookSteps.java | 167 +++++++++++++++++++++
.../src/test/java/dlab/project/ProjectSteps.java | 8 +-
.../src/test/resources/dlab/notebook.feature | 16 ++
.../src/test/resources/dlab/project.feature | 8 +-
9 files changed, 360 insertions(+), 10 deletions(-)
diff --git a/doc/.DS_Store b/doc/.DS_Store
deleted file mode 100644
index 3a993d5..0000000
Binary files a/doc/.DS_Store and /dev/null differ
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/NotebookCreateDTO.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/NotebookCreateDTO.java
new file mode 100644
index 0000000..0752285
--- /dev/null
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/NotebookCreateDTO.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.dlab.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+public class NotebookCreateDTO {
+
+ @JsonProperty
+ private String image;
+
+ @JsonProperty("template_name")
+ private String templateName;
+
+ @JsonProperty
+ private String name;
+
+ @JsonProperty
+ private String project;
+
+ @JsonProperty("custom_tag")
+ private String exploratoryTag;
+
+ @JsonProperty
+ private String endpoint;
+
+ @JsonProperty
+ private String shape;
+
+ @JsonProperty
+ private String version;
+
+ @JsonProperty("notebook_image_name")
+ private String imageName;
+
+ @JsonProperty("cluster_config")
+ private List<String> clusterConfig;
+}
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/NotebookDTO.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/NotebookDTO.java
new file mode 100644
index 0000000..d91d9cd
--- /dev/null
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/NotebookDTO.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.dlab.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.Data;
+
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class NotebookDTO {
+ @JsonProperty("exploratory_name")
+ private String name;
+ private String endpoint;
+ private String project;
+ private String user;
+ private Status status;
+
+
+ public enum Status {
+ CREATING("creating"),
+ CREATED("created"),
+ STARTING("starting"),
+ CONFIGURING("configuring"),
+ RUNNING("running"),
+ STOPPING("stopping"),
+ STOPPED("stopped"),
+ TERMINATING("terminating"),
+ TERMINATED("terminated"),
+ FAILED("failed"),
+ CREATING_IMAGE("creating image"),
+ RECONFIGURING("reconfiguring");
+
+ private String name;
+
+ Status(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ @JsonValue
+ public String getName() {
+ return name;
+ }
+ }
+}
+
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/ProjectNotebookDTO.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/ProjectNotebookDTO.java
new file mode 100644
index 0000000..639ce5f
--- /dev/null
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/ProjectNotebookDTO.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.dlab.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ProjectNotebookDTO {
+ private String project;
+ @JsonProperty("exploratory")
+ private List<NotebookDTO> notebooks;
+}
diff --git a/integration-tests-cucumber/src/test/java/dlab/Constants.java b/integration-tests-cucumber/src/test/java/dlab/Constants.java
index 5641cd0..92cdbf6 100644
--- a/integration-tests-cucumber/src/test/java/dlab/Constants.java
+++ b/integration-tests-cucumber/src/test/java/dlab/Constants.java
@@ -3,10 +3,12 @@ package dlab;
import org.apache.dlab.util.PropertyHelper;
public interface Constants {
- String API_URI = PropertyHelper.read("dlab.api.base.uri");
- String LOCAL_ENDPOINT = "local";
String CONNECTION_TIMEOUT_LABEL = "http.connection.timeout";
int CONNECTION_TIMEOUT = Integer.parseInt(PropertyHelper.read(CONNECTION_TIMEOUT_LABEL));
String SOCKET_TIMEOUT_LABEL = "http.socket.timeout";
int SOCKET_TIMEOUT = Integer.parseInt(PropertyHelper.read(SOCKET_TIMEOUT_LABEL));
+
+ String API_URI = PropertyHelper.read("dlab.api.base.uri");
+ String LOCAL_ENDPOINT = "local";
+ String CLIENT_ID = PropertyHelper.read("keycloak.clientId");
}
diff --git a/integration-tests-cucumber/src/test/java/dlab/notebook/NotebookSteps.java b/integration-tests-cucumber/src/test/java/dlab/notebook/NotebookSteps.java
new file mode 100644
index 0000000..1f4d026
--- /dev/null
+++ b/integration-tests-cucumber/src/test/java/dlab/notebook/NotebookSteps.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package dlab.notebook;
+
+import com.jayway.restassured.config.HttpClientConfig;
+import com.jayway.restassured.config.RestAssuredConfig;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.response.Response;
+import com.jayway.restassured.specification.RequestSpecification;
+import cucumber.api.java.en.And;
+import cucumber.api.java.en.Given;
+import cucumber.api.java.en.Then;
+import cucumber.api.java.en.When;
+import dlab.util.KeycloakUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dlab.dto.EndpointStatusDTO;
+import org.apache.dlab.dto.NotebookCreateDTO;
+import org.apache.dlab.dto.NotebookDTO;
+import org.apache.dlab.dto.ProjectDTO;
+import org.apache.dlab.dto.ProjectNotebookDTO;
+import org.apache.dlab.util.JacksonMapper;
+
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static com.jayway.restassured.RestAssured.given;
+import static dlab.Constants.API_URI;
+import static dlab.Constants.CLIENT_ID;
+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.*;
+
+
+@Slf4j
+public class NotebookSteps {
+ private static final String SERVICE_ACCOUNT_FORMAT = "service-account-%s";
+
+ private RequestSpecification request;
+ private Response response;
+ private String name;
+ private String projectName;
+
+
+ @Given("There is active project {string} in DLab")
+ public void thereIsActiveProjectInDLab(String project) {
+ this.projectName = project;
+ Response response = authenticatedRequest().get(API_URI + "project/{project}", project);
+
+ assertThat("Status code doesn't match!", response.getStatusCode(), equalTo(200));
+
+ boolean runningProjectExists = response.as(ProjectDTO.class).getEndpoints().stream()
+ .anyMatch(e -> LOCAL_ENDPOINT.equals(e.getName()) && e.getStatus() == EndpointStatusDTO.Status.RUNNING);
+
+ assertTrue(String.format("There is no active project %s.", project), runningProjectExists);
+ log.info("There is an active project {}", project);
+ }
+
+ @And("There is no notebook with name {string}")
+ public void thereIsNoNotebookWithName(String name) throws URISyntaxException {
+ this.name = name;
+ Optional<NotebookDTO> notebook = getNotebookDTO();
+
+ assertFalse("Notebook exists!", notebook.isPresent());
+ }
+
+ @And("User tries to create new notebook with name {string}, endpoint {string}, image {string}, template {string}, project {string}, exploratory tag {string}, shape {string}, version {string}, image name {string}")
+ public void userTriesToCreateNewNotebookWithNameEndpointImageTemplateProjectExploratoryTagShapeVersionImageName(String name, String endpoint, String image, String template, String project, String exploratoryTag, String shape, String version, String imageName) {
+ this.name = name;
+ NotebookCreateDTO notebookCreateDTO = new NotebookCreateDTO(image, template, name, project, exploratoryTag, endpoint, shape, version, imageName, null);
+ request = authenticatedRequest()
+ .body(JacksonMapper.marshall(notebookCreateDTO))
+ .contentType(ContentType.JSON);
+ }
+
+ @When("User sends create new notebook request")
+ public void userSendsCreateNewNotebookRequest() {
+ response = request.put(API_URI + "infrastructure_provision/exploratory_environment");
+ log.info("Sending request to create notebook {} in project {}", name, projectName);
+ }
+
+ @Then("Status code is {int} for notebook")
+ public void statusCodeIs(int code) {
+ assertThat("Status codes don't match!", response.getStatusCode(), equalTo(code));
+ }
+
+ @And("User waits maximum {int} minutes while notebook is creating")
+ public void userWaitsMaximumTimeoutMinutesWhileNotebookIsCreating(int timeout) throws URISyntaxException, InterruptedException {
+ boolean isRunning = waitForStatus(timeout, NotebookDTO.Status.RUNNING);
+
+ assertTrue("Timeout for notebook status check reached!", isRunning);
+ log.info("Notebook {} successfully started", projectName);
+ }
+
+ private boolean waitForStatus(int timeout, NotebookDTO.Status status) throws URISyntaxException, InterruptedException {
+ boolean correctStatus = false;
+ LocalDateTime withTimeout = LocalDateTime.now().plusMinutes(timeout);
+ log.info("User wait till {} for notebook {} to be {}", withTimeout, projectName, status);
+
+ while (!correctStatus && LocalDateTime.now().isBefore(withTimeout)) {
+ Optional<NotebookDTO> notebook = getNotebookDTO();
+
+ assertTrue("Notebook does not exist!", notebook.isPresent());
+ assertNotSame("Notebook with status FAILED", NotebookDTO.Status.FAILED.toString(), notebook.get().getStatus().toString());
+
+ correctStatus = status == notebook.get().getStatus();
+ TimeUnit.MINUTES.sleep(1);
+ }
+
+ return correctStatus;
+ }
+
+ private Optional<NotebookDTO> getNotebookDTO() throws URISyntaxException {
+ Response response = authenticatedRequest().get(new URI(API_URI + "infrastructure/info"));
+
+ assertThat("Status code doesn't match!", response.getStatusCode(), equalTo(200));
+
+ List<NotebookDTO> notebooks = Arrays.stream(response.getBody().as(ProjectNotebookDTO[].class))
+ .filter(projectNotebook -> projectName.equals(projectNotebook.getProject()))
+ .map(ProjectNotebookDTO::getNotebooks)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+
+ return notebooks.stream()
+ .filter(n -> name.equals(n.getName()) && String.format(SERVICE_ACCOUNT_FORMAT, CLIENT_ID).equals(n.getUser()) &&
+ projectName.equals(n.getProject()))
+ .findAny();
+ }
+
+ private RequestSpecification authenticatedRequest() {
+ return given()
+ .auth()
+ .oauth2(KeycloakUtil.getToken())
+ .config(RestAssuredConfig.config().httpClient(HttpClientConfig.httpClientConfig()
+ .setParam(CONNECTION_TIMEOUT_LABEL, CONNECTION_TIMEOUT)
+ .setParam(SOCKET_TIMEOUT_LABEL, SOCKET_TIMEOUT)));
+ }
+}
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 d8250ea..e1f6ced 100644
--- a/integration-tests-cucumber/src/test/java/dlab/project/ProjectSteps.java
+++ b/integration-tests-cucumber/src/test/java/dlab/project/ProjectSteps.java
@@ -193,7 +193,7 @@ public class ProjectSteps {
assertThat(response.getStatusCode(), equalTo(code));
}
- @Then("User waits maximum {int} minutes while project is creating")
+ @And("User waits maximum {int} minutes while project is creating")
public void userWaitMaximumMinutesWhileProjectIsCreating(int timeout) throws URISyntaxException, InterruptedException {
boolean isRunning = waitForStatus(timeout, EndpointStatusDTO.Status.RUNNING);
@@ -201,7 +201,7 @@ public class ProjectSteps {
log.info("Project {} successfully created", projectName);
}
- @Then("User waits maximum {int} minutes while project is terminating")
+ @And("User waits maximum {int} minutes while project is terminating")
public void userWaitsMaximumTimeoutMinutesWhileProjectIsTerminated(int timeout) throws URISyntaxException, InterruptedException {
boolean isTerminated = waitForStatus(timeout, EndpointStatusDTO.Status.TERMINATED);
@@ -209,7 +209,7 @@ public class ProjectSteps {
log.info("Project {} successfully terminated", projectName);
}
- @Then("User waits maximum {int} minutes while project is stopping")
+ @And("User waits maximum {int} minutes while project is stopping")
public void userWaitsMaximumTimeoutMinutesWhileProjectIsStopping(int timeout) throws URISyntaxException, InterruptedException {
boolean isStopped = waitForStatus(timeout, EndpointStatusDTO.Status.STOPPED);
@@ -217,7 +217,7 @@ public class ProjectSteps {
log.info("Project {} successfully stopped", projectName);
}
- @Then("User waits maximum {int} minutes while project is starting")
+ @And("User waits maximum {int} minutes while project is starting")
public void userWaitsMaximumTimeoutMinutesWhileProjectIsStarting(int timeout) throws URISyntaxException, InterruptedException {
boolean isRunning = waitForStatus(timeout, EndpointStatusDTO.Status.RUNNING);
diff --git a/integration-tests-cucumber/src/test/resources/dlab/notebook.feature b/integration-tests-cucumber/src/test/resources/dlab/notebook.feature
new file mode 100644
index 0000000..02bdffb
--- /dev/null
+++ b/integration-tests-cucumber/src/test/resources/dlab/notebook.feature
@@ -0,0 +1,16 @@
+@notebook
+Feature: Notebook management in DLab
+ Such feature allowed to manage notebook inside DLab
+
+ Scenario Outline: Create new notebook when it does not exist
+
+ Given There is active project "<project>" in DLab
+ And There is no notebook with name "<name>"
+ And User tries to create new notebook with name "<name>", endpoint "<endpoint>", image "<image>", template "<template>", project "<project>", exploratory tag "<exploratoryTag>", shape "<shape>", version "<version>", image name "<imageName>"
+ When User sends create new notebook request
+ Then Status code is 200 for notebook
+ And User waits maximum <timeout> minutes while notebook is creating
+ @aws @v1 @jupyter
+ Examples:
+ | name | endpoint | image | template | project | exploratoryTag | shape | version | imageName | timeout |
+ | jup1 | local | docker.dlab-jupyter | Jupyter notebook 6.0.2 | prj1 | integration test tag | t2.medium | jupyter_notebook-6.0.2 | | 20 |
\ No newline at end of file
diff --git a/integration-tests-cucumber/src/test/resources/dlab/project.feature b/integration-tests-cucumber/src/test/resources/dlab/project.feature
index c478c7f..b8c5fbc 100644
--- a/integration-tests-cucumber/src/test/resources/dlab/project.feature
+++ b/integration-tests-cucumber/src/test/resources/dlab/project.feature
@@ -12,8 +12,8 @@ Feature: Project management in DLab
And User generates new publicKey
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
+ And User waits maximum <timeout> minutes while project is creating
@v1
Examples:
| name | timeout |
@@ -124,7 +124,7 @@ Feature: Project management in DLab
And User tries to stop the project
When User sends request to stop the project
Then Status code is 202
- Then User waits maximum <timeout> minutes while project is stopping
+ And User waits maximum <timeout> minutes while project is stopping
@v1
Examples:
| name | timeout |
@@ -141,7 +141,7 @@ Feature: Project management in DLab
And User tries to start the project
When User sends request to start the project
Then Status code is 202
- Then User waits maximum <timeout> minutes while project is starting
+ And User waits maximum <timeout> minutes while project is starting
@v1
Examples:
| name | timeout |
@@ -158,8 +158,8 @@ Feature: Project management in DLab
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 terminating
Then Status code is 200
+ And User waits maximum <timeout> minutes while project is terminating
@v1
Examples:
| name | timeout |
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org