Skip to content

Commit b13a212

Browse files
Integration test (#135)
* Add IT folder structure * Add IT goal and property filter * Add cucumber and SpringRunner to test * Add base for making tests and DownloadRunner * Add Subscription test * Add Information test * Add Rules test * Add Rules and Query test * Minor fix * Fix * Fix * Exlcude individual tests * Rename test files and add integration test backend properties file * Update .travis.yml * Add amqp credentials to test * Update .travis.yml * Integration test travis 1 (#2) * Update .travis.yml * Use env variable for amqp port * Remove unused files * Some fixes * Fixes to Utils classes * Code reduction * Fix * Add amqp credentials in constructor before channel creation * Use only one event for aggregation and code reduction * Print stacktrace and use path builder for file paths * Read exchange and key from backend properties file * Read constants through system properties * Remove constructor * Download test only finds an identifier in response * Fix to undefined cucumber string * Files read from src dir instead of target dir * Add back execution block in pom * Add credentials to subscription requests
1 parent d002d49 commit b13a212

26 files changed

+1334
-6
lines changed

.travis.yml

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,33 @@ sudo: required
22

33
language: java
44

5-
services:
5+
services:
6+
- docker
67

78
jdk:
8-
- oraclejdk8
9+
- oraclejdk8
10+
11+
env:
12+
- EI_BACKEND_PORT=8099 MONGODB_PORT=27017 RABBITMQ_AMQP_PORT=5672 RABBITMQ_WEB_PORT=15672 EIFFEL_ER_PORT=8084 JENKINS_PORT=8081 MAIL_SMTP_PORT=1025 MAIL_WEB_PORT=8025
913

1014
before_install:
11-
- chmod +x pom.xml
12-
15+
- chmod +x pom.xml
16+
- git clone --depth=50 --branch=master https://github.com/eiffel-community/eiffel-intelligence.git
17+
- cd eiffel-intelligence
18+
- docker-compose up -d
19+
- mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
20+
- cd target
21+
- export EIFFEL_WAR=$(ls *.war)
22+
- java -Dspring.config.location=file:../../src/integrationtest/resources/integration-test.properties -Dserver.port=${EI_BACKEND_PORT} -jar ${EIFFEL_WAR} &
23+
- cd ../..
24+
1325
script:
14-
- mvn test
26+
- "mvn verify -Dei.backendInstancesListJsonContent=\"[{ 'contextPath': '', 'port': '${EI_BACKEND_PORT}', 'name': 'EI-Backend-1', 'host': 'localhost', 'https': false, 'defaultBackend': true}]\""
27+
28+
after_script:
29+
- cd eiffel-intelligence
30+
- docker-compose down
31+
- fuser -k ${EI_BACKEND_PORT}/tcp
1532

1633
before_deploy:
1734
- rm -rf docs
@@ -24,4 +41,4 @@ deploy:
2441
github-token: $GITHUB_TOKEN
2542
local_dir: docs/
2643
on:
27-
branch: master
44+
branch: master

pom.xml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
3838
<java.version>1.8</java.version>
3939
<output-relative-path>src/main/java</output-relative-path>
40+
<skipTests>false</skipTests>
41+
<skipITs>${skipTests}</skipITs>
42+
<skipUTs>${skipTests}</skipUTs>
4043
</properties>
4144

4245
<dependencies>
@@ -130,6 +133,31 @@
130133
<artifactId>jarchivelib</artifactId>
131134
<version>0.7.1</version>
132135
</dependency>
136+
<!-- Cucumber -->
137+
<dependency>
138+
<groupId>info.cukes</groupId>
139+
<artifactId>cucumber-junit</artifactId>
140+
<version>1.2.5</version>
141+
<scope>test</scope>
142+
</dependency>
143+
<dependency>
144+
<groupId>info.cukes</groupId>
145+
<artifactId>cucumber-java</artifactId>
146+
<version>1.2.5</version>
147+
<scope>test</scope>
148+
</dependency>
149+
<dependency>
150+
<groupId>info.cukes</groupId>
151+
<artifactId>cucumber-spring</artifactId>
152+
<version>1.2.5</version>
153+
<scope>test</scope>
154+
</dependency>
155+
<!-- RabbitMQ -->
156+
<dependency>
157+
<groupId>com.rabbitmq</groupId>
158+
<artifactId>amqp-client</artifactId>
159+
<scope>test</scope>
160+
</dependency>
133161
</dependencies>
134162

135163
<build>
@@ -149,6 +177,15 @@
149177
</excludes>
150178
</resource>
151179
</resources>
180+
<testResources>
181+
<testResource>
182+
<directory>src/integrationtest/resources</directory>
183+
<filtering>true</filtering>
184+
<includes>
185+
<include>**/*.*</include>
186+
</includes>
187+
</testResource>
188+
</testResources>
152189
<plugins>
153190
<plugin>
154191
<groupId>org.springframework.boot</groupId>
@@ -176,6 +213,8 @@
176213
<sources>
177214
<source>src/functionaltest/java</source>
178215
<source>src/functionaltest/resources</source>
216+
<source>src/integrationtest/java</source>
217+
<source>src/integrationtest/resources</source>
179218
</sources>
180219
</configuration>
181220
</execution>
@@ -187,10 +226,12 @@
187226
<artifactId>maven-surefire-plugin</artifactId>
188227
<version>2.20</version>
189228
<configuration>
229+
<skipTests>${skipUTs}</skipTests>
190230
<forkCount>2.5C</forkCount>
191231
<reuseForks>false</reuseForks>
192232
<useSystemClassLoader>false</useSystemClassLoader>
193233
<excludes>
234+
<exclude>**/*IT.java</exclude>
194235
<exclude>${someModule.test.excludes}</exclude>
195236
</excludes>
196237
<includes>
@@ -199,6 +240,34 @@
199240
</configuration>
200241
</plugin>
201242

243+
<plugin>
244+
<groupId>org.apache.maven.plugins</groupId>
245+
<artifactId>maven-failsafe-plugin</artifactId>
246+
<version>3.0.0-M1</version>
247+
<configuration>
248+
<skipTests>${skipTests}</skipTests>
249+
<skipITs>${skipITs}</skipITs>
250+
<systemPropertyVariables>
251+
<rabbit.host>localhost</rabbit.host>
252+
<rabbit.port>5672</rabbit.port>
253+
<rabbit.username>myuser</rabbit.username>
254+
<rabbit.password>myuser</rabbit.password>
255+
<rabbit.exchange>ei-exchange</rabbit.exchange>
256+
<rabbit.key>#</rabbit.key>
257+
</systemPropertyVariables>
258+
</configuration>
259+
<executions>
260+
<execution>
261+
<id>integration-test</id>
262+
<goals>
263+
<goal>integration-test</goal>
264+
<goal>verify</goal>
265+
</goals>
266+
<phase>integration-test</phase>
267+
</execution>
268+
</executions>
269+
</plugin>
270+
202271
<plugin>
203272
<groupId>org.apache.maven.plugins</groupId>
204273
<artifactId>maven-site-plugin</artifactId>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.ericsson.ei.frontend;
2+
3+
import org.junit.runner.RunWith;
4+
5+
import cucumber.api.CucumberOptions;
6+
import cucumber.api.junit.Cucumber;
7+
8+
@RunWith(Cucumber.class)
9+
@CucumberOptions(features = "src/integrationtest/resources/features/auth.feature", glue = {
10+
"com.ericsson.ei.frontend" }, plugin = {
11+
"html:target/cucumber-reports/AuthRunnerIT" })
12+
public class AuthRunnerIT {
13+
14+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
package com.ericsson.ei.frontend;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import java.io.File;
6+
import java.io.IOException;
7+
import java.nio.file.Paths;
8+
import java.util.concurrent.TimeoutException;
9+
10+
import org.apache.commons.io.FileUtils;
11+
import org.apache.tomcat.util.codec.binary.Base64;
12+
import org.json.JSONArray;
13+
import org.json.JSONObject;
14+
import org.junit.Ignore;
15+
import org.junit.runner.RunWith;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
18+
import org.springframework.boot.test.context.SpringBootContextLoader;
19+
import org.springframework.boot.test.context.SpringBootTest;
20+
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
21+
import org.springframework.boot.web.server.LocalServerPort;
22+
import org.springframework.http.HttpStatus;
23+
import org.springframework.http.ResponseEntity;
24+
import org.springframework.test.context.ContextConfiguration;
25+
import org.springframework.test.context.TestExecutionListeners;
26+
import org.springframework.test.context.junit4.SpringRunner;
27+
import org.springframework.test.context.support.AbstractTestExecutionListener;
28+
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
29+
30+
import com.ericsson.ei.utils.AMQPCommunication;
31+
import com.ericsson.ei.utils.HttpRequest;
32+
import com.ericsson.ei.utils.HttpRequest.HttpMethod;
33+
34+
import cucumber.api.java.Before;
35+
import cucumber.api.java.en.Given;
36+
import cucumber.api.java.en.Then;
37+
import cucumber.api.java.en.When;
38+
39+
@Ignore
40+
@RunWith(SpringRunner.class)
41+
@SpringBootTest(classes = EIFrontendApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
42+
@ContextConfiguration(classes = EIFrontendApplication.class, loader = SpringBootContextLoader.class)
43+
@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class, CommonSteps.class })
44+
public class CommonSteps extends AbstractTestExecutionListener {
45+
46+
@LocalServerPort
47+
private int frontendPort;
48+
private String frontendHost = "localhost";
49+
private String rabbitHost;
50+
private int rabbitPort;
51+
private String rabbitUsername;
52+
private String rabbitPassword;
53+
private String rabbitExchange;
54+
private String rabbitKey;
55+
56+
private HttpRequest httpRequest;
57+
private ResponseEntity<String> response;
58+
59+
private static final String RESOURCE_PATH = "src/integrationtest/resources/";
60+
private static final String BODIES_PATH = "bodies/";
61+
private static final String RESPONSES_PATH = "responses/";
62+
private static final String EIFFEL_EVENT_FILE = "eiffel_event.json";
63+
64+
private static final Logger LOGGER = LoggerFactory.getLogger(CommonSteps.class);
65+
66+
@Before("@QueryByIdScenario, @QueryFreestyleScenario")
67+
public void beforeQueryScenario() {
68+
rabbitHost = System.getProperty("rabbit.host");
69+
rabbitPort = Integer.getInteger("rabbit.port");
70+
rabbitUsername = System.getProperty("rabbit.username");
71+
rabbitPassword = System.getProperty("rabbit.password");
72+
rabbitExchange = System.getProperty("rabbit.exchange");
73+
rabbitKey = System.getProperty("rabbit.key");
74+
}
75+
76+
@Given("^frontend is up and running$")
77+
public void frontend_running() {
78+
LOGGER.info("Front-end port: {}", frontendPort);
79+
assertEquals(true, frontendPort != 0);
80+
}
81+
82+
@Given("^an aggregated object is created$")
83+
public void aggregated_object_created() throws IOException, TimeoutException {
84+
LOGGER.debug("Sending Eiffel events for aggregation.");
85+
String eventFilePath = Paths.get(RESOURCE_PATH, EIFFEL_EVENT_FILE).toString();
86+
String eventFileContent = FileUtils.readFileToString(new File(eventFilePath), "UTF-8");
87+
88+
AMQPCommunication amqp = new AMQPCommunication(rabbitHost, rabbitPort, rabbitUsername, rabbitPassword);
89+
assertEquals(true, amqp.produceMessage(eventFileContent, rabbitExchange, rabbitKey));
90+
amqp.closeConnection();
91+
LOGGER.debug("Eiffel events sent.");
92+
}
93+
94+
@When("^a \'(\\w+)\' request is prepared for REST API \'(.*)\'$")
95+
public void request_to_rest_api(String method, String endpoint) throws Throwable {
96+
LOGGER.info("Method: {}, Endpoint: {}", method, endpoint);
97+
httpRequest = new HttpRequest(HttpMethod.valueOf(method));
98+
httpRequest.setHost(frontendHost).setPort(frontendPort).setEndpoint(endpoint);
99+
}
100+
101+
@When("^\'(.*)\' is appended to endpoint$")
102+
public void append_to_endpoint(String append) throws Throwable {
103+
String endpoint = httpRequest.getEndpoint() + append;
104+
httpRequest.setEndpoint(endpoint);
105+
}
106+
107+
@When("^param key \'(.*)\' with value \'(.*)\' is added$")
108+
public void add_param(String key, String value) throws Throwable {
109+
httpRequest.addParam(key, value);
110+
}
111+
112+
@When("^body is set to file \'(.*)\'$")
113+
public void set_body(String filename) throws Throwable {
114+
String filePath = Paths.get(RESOURCE_PATH, BODIES_PATH, filename).toString();
115+
String fileContent = FileUtils.readFileToString(new File(filePath), "UTF-8");
116+
httpRequest.addHeader("Content-type", "application/json").setBody(fileContent);
117+
}
118+
119+
@When("^aggregation is prepared with rules file \'(.*)\' and events file \'(.*)\'$")
120+
public void aggregation_is_prepared(String rulesFileName, String eventsFileName) throws Throwable {
121+
String rulesPath = Paths.get(RESOURCE_PATH, BODIES_PATH, rulesFileName).toString();
122+
String eventsPath = Paths.get(RESOURCE_PATH, BODIES_PATH, eventsFileName).toString();
123+
String rules = FileUtils.readFileToString(new File(rulesPath), "UTF-8");
124+
String events = FileUtils.readFileToString(new File(eventsPath), "UTF-8");
125+
String body = new JSONObject().put("listRulesJson", new JSONArray(rules))
126+
.put("listEventsJson", new JSONArray(events)).toString();
127+
httpRequest.setBody(body);
128+
}
129+
130+
@When("^username \"(\\w+)\" and password \"(\\w+)\" is used as credentials$")
131+
public void with_credentials(String username, String password) throws Throwable {
132+
String auth = username + ":" + password;
133+
String encodedAuth = new String(Base64.encodeBase64(auth.getBytes()), "UTF-8");
134+
httpRequest.addHeader("Authorization", "Basic " + encodedAuth);
135+
}
136+
137+
@When("^request is sent$")
138+
public void request_sent() throws Throwable {
139+
response = httpRequest.performRequest();
140+
}
141+
142+
@Then("^response code (\\d+) is received$")
143+
public void get_response_code(int statusCode) throws Throwable {
144+
LOGGER.info("Response code: {}", response.getStatusCode());
145+
assertEquals(HttpStatus.valueOf(statusCode), response.getStatusCode());
146+
}
147+
148+
@Then("^response body \'(.*)\' is received$")
149+
public void get_response_body(String body) throws Throwable {
150+
LOGGER.info("Response body: {}", response.getBody());
151+
assertEquals(body, response.getBody());
152+
}
153+
154+
@Then("^response body from file \'(.*)\' is received$")
155+
public void get_response_body_from_file(String filename) throws Throwable {
156+
String filePath = Paths.get(RESOURCE_PATH, RESPONSES_PATH, filename).toString();
157+
String fileContent = FileUtils.readFileToString(new File(filePath), "UTF-8");
158+
LOGGER.info("File path: {}", filePath);
159+
LOGGER.info("Response body: {}", response.getBody());
160+
assertEquals(fileContent.replaceAll("\\s+", ""), response.getBody().replaceAll("\\s+", ""));
161+
}
162+
163+
@Then("^response body contains \'(.*)\'$")
164+
public void response_body_contains(String contains) throws Throwable {
165+
LOGGER.info("Response body: {}", response.getBody());
166+
assertEquals(true, response.getBody().contains(contains));
167+
}
168+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.ericsson.ei.frontend;
2+
3+
import org.junit.runner.RunWith;
4+
5+
import cucumber.api.CucumberOptions;
6+
import cucumber.api.junit.Cucumber;
7+
8+
@RunWith(Cucumber.class)
9+
@CucumberOptions(features = "src/integrationtest/resources/features/download.feature", glue = {
10+
"com.ericsson.ei.frontend" }, plugin = {
11+
"html:target/cucumber-reports/DownloadRunnerIT" })
12+
public class DownloadRunnerIT {
13+
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.ericsson.ei.frontend;
2+
3+
import org.junit.runner.RunWith;
4+
5+
import cucumber.api.CucumberOptions;
6+
import cucumber.api.junit.Cucumber;
7+
8+
@RunWith(Cucumber.class)
9+
@CucumberOptions(features = "src/integrationtest/resources/features/information.feature", glue = {
10+
"com.ericsson.ei.frontend" }, plugin = {
11+
"html:target/cucumber-reports/InformationRunnerIT" })
12+
public class InformationRunnerIT {
13+
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.ericsson.ei.frontend;
2+
3+
import org.junit.runner.RunWith;
4+
5+
import cucumber.api.CucumberOptions;
6+
import cucumber.api.junit.Cucumber;
7+
8+
@RunWith(Cucumber.class)
9+
@CucumberOptions(features = "src/integrationtest/resources/features/query.feature", glue = {
10+
"com.ericsson.ei.frontend" }, plugin = {
11+
"html:target/cucumber-reports/QueryRunnerIT" })
12+
public class QueryRunnerIT {
13+
14+
}

0 commit comments

Comments
 (0)