You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2017/05/10 13:37:36 UTC
[13/22] ambari git commit: AMBARI-20955. Integrate Log Search
integration test framework with Selenium (oleewere)
AMBARI-20955. Integrate Log Search integration test framework with Selenium (oleewere)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3153b9bc
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3153b9bc
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3153b9bc
Branch: refs/heads/branch-feature-AMBARI-12556
Commit: 3153b9bc2f3ea9b3330e84aa34c34fc9457f01ad
Parents: 8dae74c
Author: oleewere <ol...@gmail.com>
Authored: Mon May 8 16:31:22 2017 +0200
Committer: oleewere <ol...@gmail.com>
Committed: Tue May 9 14:05:50 2017 +0200
----------------------------------------------------------------------
ambari-logsearch/README.md | 8 +-
ambari-logsearch/ambari-logsearch-it/pom.xml | 173 ++++++++++++---
.../logsearch/domain/StoryDataRegistry.java | 10 +
.../logsearch/steps/AbstractLogSearchSteps.java | 162 ++++++++++++++
.../logsearch/steps/LogSearchDockerSteps.java | 116 +---------
.../logsearch/steps/LogSearchUISteps.java | 212 +++++++++++++++++++
.../logsearch/story/LogSearchApiQueryStory.java | 22 --
.../story/LogSearchBackendStories.java | 84 ++++++++
.../ambari/logsearch/story/LogSearchStory.java | 60 ------
.../logsearch/story/LogSearchUIStories.java | 93 ++++++++
.../logsearch/story/LogfeederParsingStory.java | 22 --
.../ambari/logsearch/web/AbstractPage.java | 63 ++++++
.../org/apache/ambari/logsearch/web/Home.java | 39 ++++
.../story/log_search_api_query_story.story | 17 --
.../story/logfeeder_parsing_story.story | 20 --
.../backend/log_search_api_query_story.story | 17 ++
.../backend/logfeeder_parsing_story.story | 20 ++
.../resources/stories/selenium/login.ui.story | 20 ++
ambari-logsearch/docker/Dockerfile | 17 +-
ambari-logsearch/docker/bin/start.sh | 8 +
ambari-logsearch/docker/logsearch-docker.sh | 10 +-
21 files changed, 901 insertions(+), 292 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/README.md
----------------------------------------------------------------------
diff --git a/ambari-logsearch/README.md b/ambari-logsearch/README.md
index 5c41fcd..4123a52 100644
--- a/ambari-logsearch/README.md
+++ b/ambari-logsearch/README.md
@@ -36,10 +36,14 @@ mvn -Dbuild-deb clean package
## Running Integration Tests
-By default integration tests are not a part of the build process, you need to set ${it.skip} variable to true (docker needed here too)
+By default integration tests are not a part of the build process, you need to set -Dbackend-tests or -Dselenium-tests (or you can use -Dall-tests to run both). To running the tests you will need docker here as well (right now docker-for-mac and unix are supported only).
```bash
# from ambari-logsearch folder
-mvn clean integration-test -Dit.skip=false
+mvn clean integration-test -Dbackend-tests failsafe:verify
+# or run selenium tests with docker for mac, but before that you nedd to start xquartz
+xquartz
+# then in an another window you can start ui tests
+mvn clean integration-test -Dselenium-tests failsafe:verify
```
Also you can run from the IDE, but make sure all of the ambari logsearch modules are built.
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/pom.xml b/ambari-logsearch/ambari-logsearch-it/pom.xml
index ee97e99..cdb76a5 100644
--- a/ambari-logsearch/ambari-logsearch-it/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-it/pom.xml
@@ -33,8 +33,10 @@
<properties>
<it.skip>true</it.skip>
<jbehave.version>4.0.5</jbehave.version>
+ <jbehave-selenium>3.5.5</jbehave-selenium>
<jersey.version>2.23.1</jersey.version>
<jackson-jaxrs.version>2.6.4</jackson-jaxrs.version>
+ <failsafe-plugin.version>2.20</failsafe-plugin.version>
<forkCount>1</forkCount>
</properties>
@@ -45,6 +47,11 @@
<version>${jbehave.version}</version>
</dependency>
<dependency>
+ <groupId>org.jbehave.web</groupId>
+ <artifactId>jbehave-web-selenium</artifactId>
+ <version>${jbehave-selenium}</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>${solr.version}</version>
@@ -82,6 +89,12 @@
<groupId>com.flipkart.zjsonpatch</groupId>
<artifactId>zjsonpatch</artifactId>
<version>0.2.4</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.apache.ambari</groupId>
@@ -98,6 +111,11 @@
<artifactId>ambari-logsearch-logfeeder</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>11.0.1</version>
+ </dependency>
</dependencies>
<build>
@@ -113,35 +131,132 @@
<directory>src/test/resources</directory>
</testResource>
</testResources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- <executions>
- <execution>
- <id>run-integration-tests</id>
- <phase>integration-test</phase>
- <goals>
- <goal>integration-test</goal>
- </goals>
- <configuration>
- <includes>
- <include>**/*Stories.java</include>
- <include>**/*Story.java</include>
- </includes>
- <skip>${it.skip}</skip>
- </configuration>
- </execution>
- <execution>
- <id>verify-integration-tests</id>
- <phase>verify</phase>
- <goals>
- <goal>verify</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
</build>
+ <profiles>
+ <profile>
+ <id>selenium-tests</id>
+ <activation>
+ <property>
+ <name>selenium-tests</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>${failsafe-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>run-integration-tests</id>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>integration-test</goal>
+ </goals>
+ <configuration>
+ <includes>
+ <include>**/*UIStories.java</include>
+ </includes>
+ <systemPropertyVariables>
+ <log4j.configuration>file:${project.build.testOutputDirectory}/log4j.properties</log4j.configuration>
+ </systemPropertyVariables>
+ </configuration>
+ </execution>
+ <execution>
+ <id>verify-integration-tests</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>backend-tests</id>
+ <activation>
+ <property>
+ <name>backend-tests</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>${failsafe-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>run-integration-tests</id>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>integration-test</goal>
+ </goals>
+ <configuration>
+ <includes>
+ <include>**/*BackendStories.java</include>
+ </includes>
+ <systemPropertyVariables>
+ <log4j.configuration>file:${project.build.testOutputDirectory}/log4j.properties</log4j.configuration>
+ </systemPropertyVariables>
+ </configuration>
+ </execution>
+ <execution>
+ <id>verify-integration-tests</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>all-tests</id>
+ <activation>
+ <property>
+ <name>all-tests</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>${failsafe-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>run-integration-tests</id>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>integration-test</goal>
+ </goals>
+ <configuration>
+ <includes>
+ <include>**/*Stories.java</include>
+ </includes>
+ <systemPropertyVariables>
+ <log4j.configuration>file:${project.build.testOutputDirectory}/log4j.properties</log4j.configuration>
+ </systemPropertyVariables>
+ </configuration>
+ </execution>
+ <execution>
+ <id>verify-integration-tests</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/domain/StoryDataRegistry.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/domain/StoryDataRegistry.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/domain/StoryDataRegistry.java
index cb72376..41d6391 100644
--- a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/domain/StoryDataRegistry.java
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/domain/StoryDataRegistry.java
@@ -19,6 +19,7 @@
package org.apache.ambari.logsearch.domain;
import org.apache.solr.client.solrj.SolrClient;
+import org.jbehave.web.selenium.WebDriverProvider;
public class StoryDataRegistry {
public static final StoryDataRegistry INSTANCE = new StoryDataRegistry();
@@ -33,6 +34,7 @@ public class StoryDataRegistry {
private final int zookeeperPort = 9983;
private final String serviceLogsCollection = "hadoop_logs";
private final String auditLogsCollection = "audit_logs";
+ private WebDriverProvider webDriverProvider;
private StoryDataRegistry() {
}
@@ -96,4 +98,12 @@ public class StoryDataRegistry {
public void setLogsearchContainerStarted(boolean logsearchContainerStarted) {
this.logsearchContainerStarted = logsearchContainerStarted;
}
+
+ public WebDriverProvider getWebDriverProvider() {
+ return webDriverProvider;
+ }
+
+ public void setWebDriverProvider(WebDriverProvider webDriverProvider) {
+ this.webDriverProvider = webDriverProvider;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/AbstractLogSearchSteps.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/AbstractLogSearchSteps.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/AbstractLogSearchSteps.java
new file mode 100644
index 0000000..a7dd409
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/AbstractLogSearchSteps.java
@@ -0,0 +1,162 @@
+/*
+ * 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.ambari.logsearch.steps;
+
+import org.apache.ambari.logsearch.domain.StoryDataRegistry;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.impl.LBHttpSolrClient;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.client.solrj.response.SolrPingResponse;
+import org.apache.solr.common.SolrDocumentList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.URL;
+
+public class AbstractLogSearchSteps {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractLogSearchSteps.class);
+
+ protected void initDockerContainer() throws Exception{
+ boolean logsearchStarted = StoryDataRegistry.INSTANCE.isLogsearchContainerStarted();
+ if (!logsearchStarted) {
+ LOG.info("Create new docker container for Log Search ...");
+ URL location = LogSearchDockerSteps.class.getProtectionDomain().getCodeSource().getLocation();
+ String ambariFolder = new File(location.toURI()).getParentFile().getParentFile().getParentFile().getParent();
+ StoryDataRegistry.INSTANCE.setAmbariFolder(ambariFolder);
+ String shellScriptLocation = ambariFolder + "/ambari-logsearch/docker/logsearch-docker.sh";
+ StoryDataRegistry.INSTANCE.setShellScriptLocation(shellScriptLocation);
+ String output = runCommand(new String[]{StoryDataRegistry.INSTANCE.getShellScriptLocation(), "start"});
+ LOG.info("Command output: {}", output);
+ StoryDataRegistry.INSTANCE.setLogsearchContainerStarted(true);
+
+ // TODO: create a script which returns the proper host for docker, use: runCommand or an env variable
+ String dockerHostFromUri = "localhost";
+
+ StoryDataRegistry.INSTANCE.setDockerHost(dockerHostFromUri);
+ checkHostAndPortReachable(dockerHostFromUri, StoryDataRegistry.INSTANCE.getLogsearchPort(), "LogSearch");
+ waitUntilSolrIsUp();
+ waitUntilSolrHasAnyData();
+
+ LOG.info("Waiting for logfeeder to finish the test log parsings... (10 sec)");
+ Thread.sleep(10000);
+ }
+ }
+
+ private void waitUntilSolrIsUp() throws Exception {
+ int maxTries = 30;
+ boolean solrIsUp = false;
+ String lastExceptionMessage = null;
+ for (int tries = 1; tries < maxTries; tries++) {
+ try {
+ SolrClient solrClient = new LBHttpSolrClient(String.format("http://%s:%d/solr/%s_shard0_replica1",
+ StoryDataRegistry.INSTANCE.getDockerHost(),
+ StoryDataRegistry.INSTANCE.getSolrPort(),
+ StoryDataRegistry.INSTANCE.getServiceLogsCollection()));
+ StoryDataRegistry.INSTANCE.setSolrClient(solrClient);
+ SolrPingResponse pingResponse = solrClient.ping();
+ if (pingResponse.getStatus() != 0) {
+ LOG.info("Solr is not up yet, Retrying... ({} tries)", tries);
+ Thread.sleep(2000);
+ } else {
+ solrIsUp = true;
+ LOG.info("Solr is up and running");
+ break;
+ }
+ } catch (Exception e) {
+ LOG.info("Error occurred during pinging solr. Retrying... ({} tries)", tries);
+ lastExceptionMessage = e.getMessage();
+ Thread.sleep(2000);
+ }
+ }
+
+ if (!solrIsUp) {
+ throw new IllegalStateException(String.format("Solr is not up after %d tries. Exception: %s", maxTries, lastExceptionMessage));
+ }
+ }
+
+ protected void waitUntilSolrHasAnyData() throws IOException, SolrServerException, InterruptedException {
+ boolean solrHasData = false;
+ int maxTries = 60;
+ String lastExceptionMessage = null;
+ for (int tries = 1; tries < maxTries; tries++) {
+ try {
+ SolrClient solrClient = StoryDataRegistry.INSTANCE.getSolrClient();
+ SolrQuery solrQuery = new SolrQuery();
+ solrQuery.setQuery("*:*");
+ QueryResponse queryResponse = solrClient.query(solrQuery);
+ SolrDocumentList list = queryResponse.getResults();
+ if (list.size() > 0) {
+ solrHasData = true;
+ break;
+ } else {
+ Thread.sleep(2000);
+ LOG.info("Solr has no data yet. Retrying... ({} tries)", tries);
+ }
+ } catch (Exception e) {
+ LOG.info("Error occurred during checking solr. Retrying... ({} tries)", tries);
+ lastExceptionMessage = e.getMessage();
+ Thread.sleep(2000);
+ }
+ }
+ if (!solrHasData) {
+ throw new IllegalStateException(String.format("Solr has no data after %d tries. Exception: %s", maxTries, lastExceptionMessage));
+ }
+ }
+
+
+ protected void checkHostAndPortReachable(String host, int port, String serviceName) throws InterruptedException {
+ boolean reachable = false;
+ int maxTries = 60;
+ for (int tries = 1; tries < maxTries; tries++ ) {
+ try (Socket socket = new Socket()) {
+ socket.connect(new InetSocketAddress(host, port), 1000);
+ reachable = true;
+ break;
+ } catch (IOException e) {
+ Thread.sleep(2000);
+ LOG.info("{} is not reachable yet. Retrying... ({} tries)", serviceName, tries);
+ }
+ }
+ if (!reachable) {
+ throw new IllegalStateException(String.format("%s is not reachable after %s tries", serviceName, maxTries));
+ }
+ }
+
+
+ protected String runCommand(String[] command) {
+ try {
+ LOG.info("Exec command: {}", StringUtils.join(command, " "));
+ Process process = Runtime.getRuntime().exec(command);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ return reader.readLine();
+ } catch (Exception e) {
+ throw new RuntimeException("Error during execute shell command: ", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/LogSearchDockerSteps.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/LogSearchDockerSteps.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/LogSearchDockerSteps.java
index 32e8cba..cb67fcc 100644
--- a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/LogSearchDockerSteps.java
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/LogSearchDockerSteps.java
@@ -41,35 +41,13 @@ import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URL;
-public class LogSearchDockerSteps {
+public class LogSearchDockerSteps extends AbstractLogSearchSteps {
private static final Logger LOG = LoggerFactory.getLogger(LogSearchDockerSteps.class);
@Given("logsearch docker container")
public void setupLogSearchContainer() throws Exception {
- boolean logsearchStarted = StoryDataRegistry.INSTANCE.isLogsearchContainerStarted();
- if (!logsearchStarted) {
- LOG.info("Create new docker container for Log Search ..");
- URL location = LogSearchDockerSteps.class.getProtectionDomain().getCodeSource().getLocation();
- String ambariFolder = new File(location.toURI()).getParentFile().getParentFile().getParentFile().getParent();
- StoryDataRegistry.INSTANCE.setAmbariFolder(ambariFolder);
- String shellScriptLocation = ambariFolder + "/ambari-logsearch/docker/logsearch-docker.sh";
- StoryDataRegistry.INSTANCE.setShellScriptLocation(shellScriptLocation);
- String output = runCommand(new String[]{StoryDataRegistry.INSTANCE.getShellScriptLocation(), "start"});
- LOG.info("Command output: {}", output);
- StoryDataRegistry.INSTANCE.setLogsearchContainerStarted(true);
-
- // TODO: create a script which returns the proper host for docker, use: runCommand or an env variable
- String dockerHostFromUri = "localhost";
-
- StoryDataRegistry.INSTANCE.setDockerHost(dockerHostFromUri);
- checkHostAndPortReachable(dockerHostFromUri, StoryDataRegistry.INSTANCE.getLogsearchPort(), "LogSearch");
- waitUntilSolrIsUp();
- waitUntilSolrHasAnyData();
-
- LOG.info("Waiting for logfeeder to finish the test log parsings... (10 sec)");
- Thread.sleep(10000);
- }
+ initDockerContainer();
}
@When("logfeeder started (parse logs & send data to solr)")
@@ -78,7 +56,7 @@ public class LogSearchDockerSteps {
}
@BeforeStories
- public void checkDockerApi() {
+ public void initDocker() throws Exception {
// TODO: check docker is up
}
@@ -86,92 +64,4 @@ public class LogSearchDockerSteps {
public void removeLogSearchContainer() {
runCommand(new String[]{StoryDataRegistry.INSTANCE.getShellScriptLocation(), "stop"});
}
-
- private void waitUntilSolrIsUp() throws Exception {
- int maxTries = 30;
- boolean solrIsUp = false;
- for (int tries = 1; tries < maxTries; tries++) {
- try {
- SolrClient solrClient = new LBHttpSolrClient(String.format("http://%s:%d/solr/%s_shard0_replica1",
- StoryDataRegistry.INSTANCE.getDockerHost(),
- StoryDataRegistry.INSTANCE.getSolrPort(),
- StoryDataRegistry.INSTANCE.getServiceLogsCollection()));
- StoryDataRegistry.INSTANCE.setSolrClient(solrClient);
- SolrPingResponse pingResponse = solrClient.ping();
- if (pingResponse.getStatus() != 0) {
- LOG.info("Solr is not up yet, retrying... ({})", tries);
- Thread.sleep(2000);
- } else {
- solrIsUp = true;
- LOG.info("Solr is up and running");
- break;
- }
- } catch (Exception e) {
- LOG.error("Error occurred during pinging solr ({}). retrying {} times", e.getMessage(), tries);
- Thread.sleep(2000);
- }
- }
-
- if (!solrIsUp) {
- throw new IllegalStateException(String.format("Solr is not up after %d tries", maxTries));
- }
- }
-
- private void waitUntilSolrHasAnyData() throws IOException, SolrServerException, InterruptedException {
- boolean solrHasData = false;
-
- int maxTries = 60;
- for (int tries = 1; tries < maxTries; tries++) {
- try {
- SolrClient solrClient = StoryDataRegistry.INSTANCE.getSolrClient();
- SolrQuery solrQuery = new SolrQuery();
- solrQuery.setQuery("*:*");
- QueryResponse queryResponse = solrClient.query(solrQuery);
- SolrDocumentList list = queryResponse.getResults();
- if (list.size() > 0) {
- solrHasData = true;
- break;
- } else {
- Thread.sleep(2000);
- LOG.info("Solr has no data yet, retrying... ({} tries)", tries);
- }
- } catch (Exception e) {
- LOG.error("Error occurred during checking solr ({}). retrying {} times", e.getMessage(), tries);
- Thread.sleep(2000);
- }
- }
- if (!solrHasData) {
- throw new IllegalStateException(String.format("Solr has no data after %d tries", maxTries));
- }
- }
-
-
- private void checkHostAndPortReachable(String host, int port, String serviceName) throws InterruptedException {
- boolean reachable = false;
- int maxTries = 60;
- for (int tries = 1; tries < maxTries; tries++ ) {
- try (Socket socket = new Socket()) {
- socket.connect(new InetSocketAddress(host, port), 1000);
- reachable = true;
- break;
- } catch (IOException e) {
- Thread.sleep(2000);
- LOG.info("{} is not reachable yet, retrying..", serviceName);
- }
- }
- if (!reachable) {
- throw new IllegalStateException(String.format("%s is not reachable after %s tries", serviceName, maxTries));
- }
- }
-
-
- private String runCommand(String[] command) {
- try {
- Process process = Runtime.getRuntime().exec(command);
- BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
- return reader.readLine();
- } catch (Exception e) {
- throw new RuntimeException("Error during execute shell command: ", e);
- }
- }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/LogSearchUISteps.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/LogSearchUISteps.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/LogSearchUISteps.java
new file mode 100644
index 0000000..b40a2bc
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/steps/LogSearchUISteps.java
@@ -0,0 +1,212 @@
+/*
+ * 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.ambari.logsearch.steps;
+
+import junit.framework.Assert;
+import org.apache.ambari.logsearch.domain.StoryDataRegistry;
+import org.apache.ambari.logsearch.web.Home;
+import org.jbehave.core.annotations.AfterScenario;
+import org.jbehave.core.annotations.AfterStories;
+import org.jbehave.core.annotations.AfterStory;
+import org.jbehave.core.annotations.BeforeScenario;
+import org.jbehave.core.annotations.BeforeStories;
+import org.jbehave.core.annotations.BeforeStory;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Named;
+import org.jbehave.core.annotations.Then;
+import org.jbehave.core.annotations.When;
+import org.jbehave.web.selenium.WebDriverProvider;
+import org.openqa.selenium.By;
+import org.openqa.selenium.NoSuchElementException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.TimeUnit;
+
+public class LogSearchUISteps extends AbstractLogSearchSteps {
+
+ private static final Logger LOG = LoggerFactory.getLogger(LogSearchUISteps.class);
+
+ private final WebDriverProvider driverProvider;
+
+ private Home home;
+
+ public LogSearchUISteps(WebDriverProvider driverProvider) {
+ this.driverProvider = driverProvider;
+ }
+
+ @BeforeScenario
+ public void initHomePage() {
+ home = new Home(driverProvider);
+ LOG.info("Init home page: {}", home.getCurrentUrl());
+ }
+
+ @AfterScenario
+ public void deleteCookies() {
+ LOG.info("Delete all cookies...");
+ home.manage().deleteAllCookies();
+ }
+
+ @BeforeStories
+ public void beforeStories() throws Exception {
+ initDockerContainer();
+ LOG.info("Initialize web driver...");
+ StoryDataRegistry.INSTANCE.getWebDriverProvider().initialize();
+ LOG.info("Web driver details: {}", StoryDataRegistry.INSTANCE.getWebDriverProvider().get().toString());
+ }
+
+ @AfterStory
+ public void closePage() throws Exception {
+ LOG.info("Closing web driver");
+ StoryDataRegistry.INSTANCE.getWebDriverProvider().end();
+ }
+
+ @Given("open logsearch home page")
+ public void initBrowser() {
+ LOG.info("Delete all cookies...");
+ home.manage().deleteAllCookies();
+ LOG.info("Open home page: {}", home.getCurrentUrl());
+ home.open();
+ }
+
+ @When("login with $username / $password")
+ public void login(@Named("username") String userName, @Named("password") String password) {
+ LOG.info("Type username: {}", userName);
+ home.findElement(By.id("username")).sendKeys(userName);
+ LOG.info("Type password: {}", password);
+ home.findElement(By.id("password")).sendKeys(password);
+ LOG.info("Click on Sign In button.");
+ home.findElement(By.className("custLogin")).click();
+ closeTourPopup();
+ }
+
+ @Then("page contains text: '$text'")
+ public void contains(@Named("text") String text) {
+ LOG.info("Check page contains text: '{}'", text);
+ home.found(text);
+ }
+
+ @Then("page does not contain text: '$text'")
+ public void notContains(@Named("text") String text) {
+ LOG.info("Check page does not contain text: '{}'", text);
+ home.notFound(text);
+ }
+
+ @When("wait $seconds seconds")
+ public void waitSeconds(@Named("second") String second) {
+ LOG.info("Wait {} seconds...", second);
+ home.manage().timeouts().implicitlyWait(Integer.parseInt(second), TimeUnit.SECONDS);
+ }
+
+ @When("click on element: $xpath (xpath)")
+ public void clickOnElementByXPath(@Named("xpath") String xPath) {
+ LOG.info("Click on element by xpath: '{}'", xPath);
+ driverProvider.get().findElement(By.xpath(xPath)).click();
+ }
+
+ @When("click on element: $id (id)")
+ public void clickOnElementById(@Named("id") String id) {
+ LOG.info("Click on element by id: '{}'", id);
+ driverProvider.get().findElement(By.xpath(id)).click();
+ }
+
+ @When("click on element: $css (css selector)")
+ public void clickOnElementByCssSelector(@Named("css") String cssSelector) {
+ LOG.info("Click on element by css selector: '{}'", cssSelector);
+ driverProvider.get().findElement(By.cssSelector(cssSelector)).click();
+ }
+
+ @Then("element exists with xpath: $xpath")
+ public void findByXPath(@Named("xpath") String xPath) {
+ LOG.info("Find element by xpath: '{}'", xPath);
+ Assert.assertNotNull(home.findElement(By.xpath(xPath)));
+ }
+
+ @Then("element exists with xpath: $id")
+ public void findById(@Named("id") String id) {
+ LOG.info("Find element by id: '{}'", id);
+ Assert.assertNotNull(home.findElement(By.id(id)));
+ }
+
+ @Then("element exists with css selector: $css")
+ public void findByCssSelector(@Named("css") String cssSelector) {
+ LOG.info("Find element by css selector: '{}'", cssSelector);
+ Assert.assertNotNull(home.findElement(By.cssSelector(cssSelector)));
+ }
+
+ @Then("element text equals '$text', with xpath $xpath")
+ public void equalsByXPath(@Named("text") String text, @Named("xpath") String xPath) {
+ LOG.info("Check text of the element (xpath: '{}') equals with '{}'", xPath, text);
+ Assert.assertEquals(text, home.findElement(By.xpath(xPath)).getText());
+ }
+
+ @Then("element text equals '$text' with id $id")
+ public void equalsyId(@Named("text") String text, @Named("id") String id) {
+ LOG.info("Check text of the element (id: '{}') equals with '{}'", id, text);
+ Assert.assertEquals(text, home.findElement(By.id(id)).getText());
+ }
+
+ @Then("element text equals '$text' with css selector $css")
+ public void equalsCssSelector(@Named("text") String text, @Named("css") String cssSelector) {
+ LOG.info("Check text of the element (css selector: '{}') equals with '{}'", cssSelector, text);
+ Assert.assertEquals(text, home.findElement(By.cssSelector(cssSelector)).getText());
+ }
+
+ @Then("element does not exist with xpath: $xpath")
+ public void doNotFindByXPath(@Named("xpath") String xPath) {
+ try {
+ LOG.info("Check that element does not exist with xpath: {}", xPath);
+ home.findElement(By.xpath(xPath));
+ Assert.fail(String.format("Element is found. xPath: '%s'", xPath));
+ } catch (NoSuchElementException e) {
+ // success
+ }
+ }
+
+ @Then("element does not exist with xpath: $id")
+ public void doNotFindById(@Named("id") String id) {
+ try {
+ LOG.info("Check that element does not exist with id: {}", id);
+ home.findElement(By.xpath(id));
+ Assert.fail(String.format("Element is found. id: '%s'", id));
+ } catch (NoSuchElementException e) {
+ // success
+ }
+ }
+
+ @Then("element does not exist with css selector: $css")
+ public void doNotFindByCssSelector(@Named("css") String cssSelector) {
+ try {
+ LOG.info("Check that element does not exist with css selector: {}", cssSelector);
+ home.findElement(By.xpath(cssSelector));
+ Assert.fail(String.format("Element is found. css selector: '%s'", cssSelector));
+ } catch (NoSuchElementException e) {
+ // success
+ }
+ }
+
+ private void closeTourPopup() {
+ LOG.info("Close Tour popup if needed.");
+ try {
+ home.findElement(By.cssSelector("div.modal-footer > button.btn.btn-default")).click();
+ } catch (NoSuchElementException ex) {
+ // do nothing - no popup
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchApiQueryStory.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchApiQueryStory.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchApiQueryStory.java
deleted file mode 100644
index 45455bf..0000000
--- a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchApiQueryStory.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.ambari.logsearch.story;
-
-public class LogSearchApiQueryStory extends LogSearchStory {
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchBackendStories.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchBackendStories.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchBackendStories.java
new file mode 100644
index 0000000..46f2928
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchBackendStories.java
@@ -0,0 +1,84 @@
+/*
+ * 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.ambari.logsearch.story;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import org.apache.ambari.logsearch.steps.LogSearchApiSteps;
+import org.apache.ambari.logsearch.steps.SolrSteps;
+import org.apache.ambari.logsearch.steps.LogSearchDockerSteps;
+import org.jbehave.core.configuration.Configuration;
+import org.jbehave.core.configuration.MostUsefulConfiguration;
+import org.jbehave.core.embedder.executors.SameThreadExecutors;
+import org.jbehave.core.io.LoadFromClasspath;
+import org.jbehave.core.io.StoryFinder;
+import org.jbehave.core.io.StoryPathResolver;
+import org.jbehave.core.io.UnderscoredCamelCaseResolver;
+import org.jbehave.core.junit.JUnitStories;
+import org.jbehave.core.junit.JUnitStory;
+import org.jbehave.core.reporters.Format;
+import org.jbehave.core.reporters.StoryReporterBuilder;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+import org.junit.Test;
+
+import javax.annotation.Nullable;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.jbehave.core.io.CodeLocations.codeLocationFromClass;
+
+public class LogSearchBackendStories extends JUnitStories {
+
+ @Override
+ public Configuration configuration() {
+ return new MostUsefulConfiguration()
+ .useStoryLoader(new LoadFromClasspath(this.getClass()))
+ .useStoryReporterBuilder(
+ new StoryReporterBuilder().withFailureTrace(true).withDefaultFormats().withFormats(Format.CONSOLE, Format.TXT));
+ }
+
+ @Override
+ public InjectableStepsFactory stepsFactory() {
+ return new InstanceStepsFactory(configuration(),
+ new LogSearchDockerSteps(),
+ new SolrSteps(),
+ new LogSearchApiSteps());
+ }
+
+ @Test
+ public void run() throws Throwable {
+ super.run();
+ }
+
+ @Override
+ protected List<String> storyPaths() {
+ List<String> backendStories = new StoryFinder()
+ .findPaths(codeLocationFromClass(this.getClass()).getFile(), Arrays.asList("**/*.story"), null);
+ return Lists.newArrayList(Collections2.filter(backendStories, new Predicate<String>() {
+ @Override
+ public boolean apply(String storyFileName) {
+ return !storyFileName.endsWith("ui.story");
+ }
+ }));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchStory.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchStory.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchStory.java
deleted file mode 100644
index ce6b9cb..0000000
--- a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchStory.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.ambari.logsearch.story;
-
-import org.apache.ambari.logsearch.steps.LogSearchApiSteps;
-import org.apache.ambari.logsearch.steps.SolrSteps;
-import org.apache.ambari.logsearch.steps.LogSearchDockerSteps;
-import org.jbehave.core.configuration.Configuration;
-import org.jbehave.core.configuration.MostUsefulConfiguration;
-import org.jbehave.core.io.LoadFromClasspath;
-import org.jbehave.core.io.StoryPathResolver;
-import org.jbehave.core.io.UnderscoredCamelCaseResolver;
-import org.jbehave.core.junit.JUnitStory;
-import org.jbehave.core.reporters.Format;
-import org.jbehave.core.reporters.StoryReporterBuilder;
-import org.jbehave.core.steps.InjectableStepsFactory;
-import org.jbehave.core.steps.InstanceStepsFactory;
-import org.junit.Test;
-
-abstract public class LogSearchStory extends JUnitStory {
- @Override
- public Configuration configuration() {
- StoryPathResolver storyPathResolver = new UnderscoredCamelCaseResolver(".story");
- return new MostUsefulConfiguration()
- .useStoryPathResolver(storyPathResolver)
- .useStoryLoader(new LoadFromClasspath(this.getClass()))
- .useStoryReporterBuilder(
- new StoryReporterBuilder().withFailureTrace(true).withDefaultFormats().withFormats(Format.CONSOLE, Format.TXT));
- }
-
- @Override
- public InjectableStepsFactory stepsFactory() {
- return new InstanceStepsFactory(configuration(),
- new LogSearchDockerSteps(),
- new SolrSteps(),
- new LogSearchApiSteps());
- }
-
- @Test
- public void run() throws Throwable {
- super.run();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchUIStories.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchUIStories.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchUIStories.java
new file mode 100644
index 0000000..eb2a180
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogSearchUIStories.java
@@ -0,0 +1,93 @@
+/*
+ * 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.ambari.logsearch.story;
+
+import org.apache.ambari.logsearch.domain.StoryDataRegistry;
+import org.apache.ambari.logsearch.steps.LogSearchDockerSteps;
+import org.apache.ambari.logsearch.steps.LogSearchUISteps;
+import org.jbehave.core.configuration.Configuration;
+import org.jbehave.core.Embeddable;
+import org.jbehave.core.embedder.executors.SameThreadExecutors;
+import org.jbehave.core.io.LoadFromClasspath;
+import org.jbehave.core.io.StoryFinder;
+import org.jbehave.core.junit.JUnitStories;
+import org.jbehave.core.reporters.StoryReporterBuilder;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+import org.jbehave.web.selenium.RemoteWebDriverProvider;
+import org.jbehave.web.selenium.SeleniumConfiguration;
+import org.jbehave.web.selenium.SeleniumContext;
+import org.jbehave.web.selenium.WebDriverProvider;
+import org.jbehave.web.selenium.WebDriverScreenshotOnFailure;
+import org.openqa.selenium.Platform;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.jbehave.core.io.CodeLocations.codeLocationFromClass;
+import static org.jbehave.core.reporters.Format.CONSOLE;
+import static org.jbehave.core.reporters.Format.HTML;
+import static org.jbehave.core.reporters.Format.TXT;
+import static org.jbehave.core.reporters.Format.XML;
+
+public class LogSearchUIStories extends JUnitStories {
+
+ private WebDriverProvider driverProvider;
+ private SeleniumContext context;
+
+ public LogSearchUIStories() {
+ // TODO: get docker host from a runCommand funtion
+ String hubUrl = "http://localhost:4444/wd/hub";
+ System.setProperty("REMOTE_WEBDRIVER_URL", hubUrl);
+ DesiredCapabilities capability = DesiredCapabilities.firefox();
+ capability.setPlatform(Platform.LINUX);
+ capability.setVersion("45.8.0");
+ driverProvider = new RemoteWebDriverProvider(capability);
+ StoryDataRegistry.INSTANCE.setWebDriverProvider(driverProvider);
+ context = new SeleniumContext();
+ configuredEmbedder().useExecutorService(new SameThreadExecutors().create(configuredEmbedder().embedderControls()));
+ }
+
+ @Override
+ public Configuration configuration() {
+ Class<? extends Embeddable> embeddableClass = this.getClass();
+ return new SeleniumConfiguration()
+ .useSeleniumContext(context)
+ .useWebDriverProvider(driverProvider)
+ .useStoryLoader(new LoadFromClasspath(embeddableClass))
+ .useStoryReporterBuilder(new StoryReporterBuilder()
+ .withCodeLocation(codeLocationFromClass(embeddableClass))
+ .withDefaultFormats()
+ .withFormats(CONSOLE, TXT, HTML, XML));
+ }
+
+ @Override
+ public InjectableStepsFactory stepsFactory() {
+ Configuration configuration = configuration();
+ return new InstanceStepsFactory(configuration, new LogSearchDockerSteps(), new LogSearchUISteps(driverProvider),
+ new WebDriverScreenshotOnFailure(driverProvider, configuration.storyReporterBuilder()));
+ }
+
+ @Override
+ protected List<String> storyPaths() {
+ return new StoryFinder()
+ .findPaths(codeLocationFromClass(this.getClass()).getFile(), Arrays.asList("**/*.ui.story"), null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogfeederParsingStory.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogfeederParsingStory.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogfeederParsingStory.java
deleted file mode 100644
index c502cc4..0000000
--- a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/story/LogfeederParsingStory.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.ambari.logsearch.story;
-
-public class LogfeederParsingStory extends LogSearchStory {
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/web/AbstractPage.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/web/AbstractPage.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/web/AbstractPage.java
new file mode 100644
index 0000000..b6d0a58
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/web/AbstractPage.java
@@ -0,0 +1,63 @@
+/*
+ * 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.ambari.logsearch.web;
+
+import org.jbehave.web.selenium.WebDriverPage;
+import org.jbehave.web.selenium.WebDriverProvider;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.fail;
+
+public abstract class AbstractPage extends WebDriverPage {
+
+ public AbstractPage(WebDriverProvider driverProvider) {
+ super(driverProvider);
+ }
+
+ public void found(String text) {
+ found(getPageSource(), text);
+ }
+
+ public void found(String pageSource, String text) {
+ if (!pageSource.contains(escapeHtml(text))) {
+ fail("Text: '" + text + "' not found in page '" + pageSource + "'");
+ }
+ }
+
+ public void found(List<String> texts) {
+ for (String text : texts) {
+ found(text);
+ }
+ }
+
+ public void notFound(String text) {
+ notFound(getPageSource(), text);
+ }
+
+ public void notFound(String pageSource, String text) {
+ assertThat(pageSource.contains(escapeHtml(text)), is(false));
+ }
+
+ private String escapeHtml(String text) {
+ return text.replace("<", "<").replace(">", ">");
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/web/Home.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/web/Home.java b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/web/Home.java
new file mode 100644
index 0000000..6c576d4
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/java/org/apache/ambari/logsearch/web/Home.java
@@ -0,0 +1,39 @@
+/*
+ * 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.ambari.logsearch.web;
+
+import org.apache.ambari.logsearch.domain.StoryDataRegistry;
+import org.jbehave.web.selenium.WebDriverProvider;
+
+import java.util.concurrent.TimeUnit;
+
+public class Home extends AbstractPage {
+
+ public Home(WebDriverProvider driverProvider) {
+ super(driverProvider);
+ }
+
+ public void open() {
+ get(String.format("http://%s:%d/index.html",
+ StoryDataRegistry.INSTANCE.getDockerHost(),
+ StoryDataRegistry.INSTANCE.getLogsearchPort()));
+ manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/resources/org/apache/ambari/logsearch/story/log_search_api_query_story.story
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/resources/org/apache/ambari/logsearch/story/log_search_api_query_story.story b/ambari-logsearch/ambari-logsearch-it/src/test/resources/org/apache/ambari/logsearch/story/log_search_api_query_story.story
deleted file mode 100644
index cfaa359..0000000
--- a/ambari-logsearch/ambari-logsearch-it/src/test/resources/org/apache/ambari/logsearch/story/log_search_api_query_story.story
+++ /dev/null
@@ -1,17 +0,0 @@
-Meta:
-
-Narrative:
-As a user
-I want to perform queries against Log Search api
-So that I can validate the json outputs
-
-Scenario: scenario description
-
-Given logsearch docker container
-When LogSearch api query sent: <apiQuery>
-Then The api query result is <jsonResult>
-
-Examples:
-|apiQuery|jsonResult|
-|/api/v1/service/logs/schema/fields|service-log-schema.json|
-|/api/v1/service/logs/levels/counts?page=0&pageSize=25&startIndex=0&q=*%3A*|service-log-level-counts-values.json|
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/resources/org/apache/ambari/logsearch/story/logfeeder_parsing_story.story
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/resources/org/apache/ambari/logsearch/story/logfeeder_parsing_story.story b/ambari-logsearch/ambari-logsearch-it/src/test/resources/org/apache/ambari/logsearch/story/logfeeder_parsing_story.story
deleted file mode 100644
index 388e624..0000000
--- a/ambari-logsearch/ambari-logsearch-it/src/test/resources/org/apache/ambari/logsearch/story/logfeeder_parsing_story.story
+++ /dev/null
@@ -1,20 +0,0 @@
-Story Service logs are parsed and stored into Solr
-
-Narrative:
-As a user
-I want to start logsearch/logfeeder/solr components in a docker container with test logs
-So that I can parse and store the logs into Solr
-
-Scenario: Number of logs for components
-
-Given logsearch docker container
-When logfeeder started (parse logs & send data to solr)
-Then the number of <component> docs is: <docSize>
-
-Examples:
-|component|docSize|
-|logsearch_app|1|
-|zookeeper|3|
-|hst_agent|4|
-|secure_log|11|
-|system_message|17|
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/backend/log_search_api_query_story.story
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/backend/log_search_api_query_story.story b/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/backend/log_search_api_query_story.story
new file mode 100644
index 0000000..0af00f5
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/backend/log_search_api_query_story.story
@@ -0,0 +1,17 @@
+Meta:
+
+Narrative:
+As a user
+I want to perform queries against Log Search api
+So that I can validate the json outputs
+
+Scenario: Log Search API JSON responses
+
+Given logsearch docker container
+When LogSearch api query sent: <apiQuery>
+Then The api query result is <jsonResult>
+
+Examples:
+|apiQuery|jsonResult|
+|/api/v1/service/logs/schema/fields|service-log-schema.json|
+|/api/v1/service/logs/levels/counts?page=0&pageSize=25&startIndex=0&q=*%3A*|service-log-level-counts-values.json|
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/backend/logfeeder_parsing_story.story
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/backend/logfeeder_parsing_story.story b/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/backend/logfeeder_parsing_story.story
new file mode 100644
index 0000000..388e624
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/backend/logfeeder_parsing_story.story
@@ -0,0 +1,20 @@
+Story Service logs are parsed and stored into Solr
+
+Narrative:
+As a user
+I want to start logsearch/logfeeder/solr components in a docker container with test logs
+So that I can parse and store the logs into Solr
+
+Scenario: Number of logs for components
+
+Given logsearch docker container
+When logfeeder started (parse logs & send data to solr)
+Then the number of <component> docs is: <docSize>
+
+Examples:
+|component|docSize|
+|logsearch_app|1|
+|zookeeper|3|
+|hst_agent|4|
+|secure_log|11|
+|system_message|17|
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/selenium/login.ui.story
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/selenium/login.ui.story b/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/selenium/login.ui.story
new file mode 100644
index 0000000..543c211
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-it/src/test/resources/stories/selenium/login.ui.story
@@ -0,0 +1,20 @@
+Meta:
+
+Narrative:
+As a user
+I want to start LogSearch services and login to the UI
+So that I can validate the proper user
+
+Scenario: login with admin/admin
+
+Given logsearch docker container
+And open logsearch home page
+When login with admin / admin
+Then page contains text: 'Service Logs'
+
+Scenario: login with admin and wrong password
+
+Given logsearch docker container
+And open logsearch home page
+When login with admin / wrongpassword
+Then page does not contain text: 'Service Logs'
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/docker/Dockerfile
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/Dockerfile b/ambari-logsearch/docker/Dockerfile
index 6e8ea3e..d399fc6 100644
--- a/ambari-logsearch/docker/Dockerfile
+++ b/ambari-logsearch/docker/Dockerfile
@@ -15,17 +15,22 @@ FROM centos:centos6
RUN echo root:changeme | chpasswd
RUN yum clean all -y && yum update -y
-RUN yum -y install vim wget rpm-build sudo which telnet tar openssh-server openssh-clients ntp git python-setuptools python-devel httpd lsof
+RUN yum -y install firefox-45.8.0-2.el6.centos xvfb xeyes vim wget rpm-build sudo which telnet tar openssh-server openssh-clients ntp git python-setuptools python-devel httpd lsof
RUN rpm -e --nodeps --justdb glibc-common
RUN yum -y install glibc-common
ENV HOME /root
#Install JAVA
-RUN wget --no-check-certificate --no-cookies --header "Cookie:oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/7u55-b13/jdk-7u55-linux-x64.rpm -O jdk-7u55-linux-x64.rpm
-RUN rpm -ivh jdk-7u55-linux-x64.rpm
+ENV JAVA_VERSION 8u31
+ENV BUILD_VERSION b13
+RUN wget --no-cookies --no-check-certificate --header "Cookie: oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/$JAVA_VERSION-$BUILD_VERSION/jdk-$JAVA_VERSION-linux-x64.rpm" -O jdk-8-linux-x64.rpm
+RUN rpm -ivh jdk-8-linux-x64.rpm
ENV JAVA_HOME /usr/java/default/
+#Install Selenium server
+RUN wget --no-check-certificate -O /root/selenium-server-standalone.jar http://selenium-release.storage.googleapis.com/2.53/selenium-server-standalone-2.53.1.jar
+
#Install Maven
RUN mkdir -p /opt/maven
WORKDIR /opt/maven
@@ -34,7 +39,7 @@ RUN tar -xvzf /opt/maven/apache-maven-3.0.5-bin.tar.gz
RUN rm -rf /opt/maven/apache-maven-3.0.5-bin.tar.gz
ENV M2_HOME /opt/maven/apache-maven-3.0.5
-ENV MAVEN_OPTS -Xmx2048m -XX:MaxPermSize=256m
+ENV MAVEN_OPTS -Xmx2048m
ENV PATH $PATH:$JAVA_HOME/bin:$M2_HOME/bin
# SSH key
@@ -42,6 +47,8 @@ RUN ssh-keygen -f /root/.ssh/id_rsa -t rsa -N ''
RUN cat /root/.ssh/id_rsa.pub > /root/.ssh/authorized_keys
RUN chmod 600 /root/.ssh/authorized_keys
RUN sed -ri 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
+RUN echo 'X11Forwarding yes\n' /etc/ssh/sshd_config
+RUN echo 'X11DisplayOffset 10\n' /etc/ssh/sshd_config
#To allow bower install behind proxy. See https://github.com/bower/bower/issues/731
RUN git config --global url."https://".insteadOf git://
@@ -54,7 +61,7 @@ RUN npm install -g brunch@1.7.20
# Install Solr
ENV SOLR_VERSION 5.5.2
-RUN wget --no-check-certificate -O /root/solr-$SOLR_VERSION.tgz http://archive.apache.org/dist/lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz
+RUN wget --no-check-certificate -O /root/solr-$SOLR_VERSION.tgz http://public-repo-1.hortonworks.com/ARTIFACTS/dist/lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz
RUN cd /root && tar -zxvf /root/solr-$SOLR_VERSION.tgz
ADD bin/start.sh /root/start.sh
ADD test-config /root/test-config
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/docker/bin/start.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/bin/start.sh b/ambari-logsearch/docker/bin/start.sh
index 1efc85c..28ebf65 100644
--- a/ambari-logsearch/docker/bin/start.sh
+++ b/ambari-logsearch/docker/bin/start.sh
@@ -92,6 +92,10 @@ function start_logfeeder() {
touch /var/log/ambari-logsearch-logfeeder/logsearch-logfeeder.log
}
+function start_selenium_server() {
+ nohup java -jar /root/selenium-server-standalone.jar > /var/log/selenium-test.log &
+}
+
function log() {
component_log=${COMPONENT_LOG:-"logsearch"}
case $component_log in
@@ -101,6 +105,9 @@ function log() {
"solr")
tail -f /var/log/ambari-logsearch-solr/solr.log
;;
+ "selenium")
+ tail -f /var/log/selenium-test.log
+ ;;
*)
tail -f /var/log/ambari-logsearch-portal/logsearch-app.log
;;
@@ -109,6 +116,7 @@ function log() {
create_config
generate_keys
+start_selenium_server
start_solr
start_logsearch
start_logfeeder
http://git-wip-us.apache.org/repos/asf/ambari/blob/3153b9bc/ambari-logsearch/docker/logsearch-docker.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/docker/logsearch-docker.sh b/ambari-logsearch/docker/logsearch-docker.sh
index eab850e..4d53fa1 100755
--- a/ambari-logsearch/docker/logsearch-docker.sh
+++ b/ambari-logsearch/docker/logsearch-docker.sh
@@ -30,6 +30,11 @@ function build_logsearch_container() {
popd
}
+function get_docker_ip() {
+ local ip=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
+ echo $ip
+}
+
function start_logsearch_container() {
setup_profile
source $sdir/Profile
@@ -38,9 +43,10 @@ function start_logsearch_container() {
popd
: ${MAVEN_REPOSITORY_LOCATION:?"Please set the MAVEN_REPOSITORY_LOCATION in Profile"}
kill_logsearch_container
+ local docker_ip=$(get_docker_ip)
echo "Run Log Search container"
- docker run -d --name logsearch --hostname logsearch.apache.org \
- -v $AMBARI_LOCATION:/root/ambari -v $MAVEN_REPOSITORY_LOCATION:/root/.m2 $LOGSEARCH_EXPOSED_PORTS $LOGSEARCH_ENV_OPTS $LOGSEARCH_EXTRA_OPTS $LOGSEARCH_VOLUME_OPTS -p 9983:9983 \
+ docker run -d --name logsearch --hostname logsearch.apache.org -e DISPLAY=$docker_ip:0 \
+ -v $AMBARI_LOCATION:/root/ambari -v $MAVEN_REPOSITORY_LOCATION:/root/.m2 $LOGSEARCH_EXPOSED_PORTS $LOGSEARCH_ENV_OPTS $LOGSEARCH_EXTRA_OPTS $LOGSEARCH_VOLUME_OPTS -p 9983:9983 -p 4444:4444 -p 5910:5910 \
-v $AMBARI_LOCATION/ambari-logsearch/ambari-logsearch-logfeeder/target/classes:/root/ambari/ambari-logsearch/ambari-logsearch-logfeeder/target/package/classes \
-v $AMBARI_LOCATION/ambari-logsearch/ambari-logsearch-server/target/classes:/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/classes \
-v $AMBARI_LOCATION/ambari-logsearch/ambari-logsearch-web/src/main/webapp:/root/ambari/ambari-logsearch/ambari-logsearch-server/target/package/classes/webapps/app \