Merge remote-tracking branch 'origin/master'

This commit is contained in:
slavisa-baeldung 2017-04-27 13:55:36 +01:00
commit 52d32336e0
9 changed files with 478 additions and 250 deletions

View File

@ -0,0 +1,21 @@
package com.baeldung.concurrent.skiplist;
import java.time.ZonedDateTime;
public class Event {
private final ZonedDateTime eventTime;
private final String content;
public Event(ZonedDateTime eventTime, String content) {
this.eventTime = eventTime;
this.content = content;
}
public ZonedDateTime getEventTime() {
return eventTime;
}
public String getContent() {
return content;
}
}

View File

@ -0,0 +1,36 @@
package com.baeldung.concurrent.skiplist;
import java.time.ZonedDateTime;
import java.util.Comparator;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.function.ToLongFunction;
public class EventWindowSort {
private final ConcurrentSkipListMap<ZonedDateTime, String> events = new ConcurrentSkipListMap<>(Comparator.comparingLong(new ToLongFunction<ZonedDateTime>() {
@Override
public long applyAsLong(ZonedDateTime value) {
return value
.toInstant()
.toEpochMilli();
}
}));
public void acceptEvent(Event event) {
events.put(event.getEventTime(), event.getContent());
}
public ConcurrentNavigableMap<ZonedDateTime, String> getEventsFromLastMinute() {
return events.tailMap(ZonedDateTime
.now()
.minusMinutes(1));
}
public ConcurrentNavigableMap<ZonedDateTime, String> getEventsOlderThatOneMinute() {
return events.headMap(ZonedDateTime
.now()
.minusMinutes(1));
}
}

View File

@ -0,0 +1,120 @@
package com.baeldung.concurrent.skiplist;
import org.junit.Test;
import java.time.ZonedDateTime;
import java.util.UUID;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class ConcurrentSkipListSetTest {
@Test
public void givenThreadsProducingEvents_whenGetForEventsFromLastMinute_thenReturnThoseEventsInTheLockFreeWay() throws InterruptedException {
//given
ExecutorService executorService = Executors.newFixedThreadPool(3);
EventWindowSort eventWindowSort = new EventWindowSort();
int numberOfThreads = 2;
//when
Runnable producer = () -> IntStream
.rangeClosed(0, 100)
.forEach(index -> eventWindowSort.acceptEvent(new Event(ZonedDateTime
.now()
.minusSeconds(index), UUID
.randomUUID()
.toString())));
for (int i = 0; i < numberOfThreads; i++) {
executorService.execute(producer);
}
Thread.sleep(500);
ConcurrentNavigableMap<ZonedDateTime, String> eventsFromLastMinute = eventWindowSort.getEventsFromLastMinute();
long eventsOlderThanOneMinute = eventsFromLastMinute
.entrySet()
.stream()
.filter(e -> e
.getKey()
.isBefore(ZonedDateTime
.now()
.minusMinutes(1)))
.count();
assertEquals(eventsOlderThanOneMinute, 0);
long eventYoungerThanOneMinute = eventsFromLastMinute
.entrySet()
.stream()
.filter(e -> e
.getKey()
.isAfter(ZonedDateTime
.now()
.minusMinutes(1)))
.count();
//then
assertTrue(eventYoungerThanOneMinute > 0);
executorService.awaitTermination(1, TimeUnit.SECONDS);
executorService.shutdown();
}
@Test
public void givenThreadsProducingEvents_whenGetForEventsOlderThanOneMinute_thenReturnThoseEventsInTheLockFreeWay() throws InterruptedException {
//given
ExecutorService executorService = Executors.newFixedThreadPool(3);
EventWindowSort eventWindowSort = new EventWindowSort();
int numberOfThreads = 2;
//when
Runnable producer = () -> IntStream
.rangeClosed(0, 100)
.forEach(index -> eventWindowSort.acceptEvent(new Event(ZonedDateTime
.now()
.minusSeconds(index), UUID
.randomUUID()
.toString())));
for (int i = 0; i < numberOfThreads; i++) {
executorService.execute(producer);
}
Thread.sleep(500);
ConcurrentNavigableMap<ZonedDateTime, String> eventsFromLastMinute = eventWindowSort.getEventsOlderThatOneMinute();
long eventsOlderThanOneMinute = eventsFromLastMinute
.entrySet()
.stream()
.filter(e -> e
.getKey()
.isBefore(ZonedDateTime
.now()
.minusMinutes(1)))
.count();
assertTrue(eventsOlderThanOneMinute > 0);
long eventYoungerThanOneMinute = eventsFromLastMinute
.entrySet()
.stream()
.filter(e -> e
.getKey()
.isAfter(ZonedDateTime
.now()
.minusMinutes(1)))
.count();
//then
assertEquals(eventYoungerThanOneMinute, 0);
executorService.awaitTermination(1, TimeUnit.SECONDS);
executorService.shutdown();
}
}

View File

@ -1,180 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>spring-5</artifactId> <artifactId>spring-5</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>spring-5</name> <name>spring-5</name>
<description>spring 5 sample project about new features</description> <description>spring 5 sample project about new features</description>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version> <version>2.0.0.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath /> <!-- lookup parent from repository -->
</parent> </parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId> <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId> <artifactId>spring-boot-starter-validation</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId> <artifactId>spring-boot-starter-webflux</artifactId>
</dependency> </dependency>
<!-- utils --> <!-- utils -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
</dependency> </dependency>
<!-- runtime and test scoped --> <!-- runtime and test scoped -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId> <artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId> <dependency>
<artifactId>junit-jupiter-api</artifactId> <groupId>org.springframework</groupId>
<version>${junit.jupiter.version}</version> <artifactId>spring-test</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<version>${spring.test.version}</version> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId> <dependency>
<artifactId>spring-boot-starter-test</artifactId> <groupId>org.junit.jupiter</groupId>
<scope>test</scope> <artifactId>junit-jupiter-api</artifactId>
</dependency> <version>${junit.jupiter.version}</version>
<dependency> </dependency>
<groupId>org.junit.jupiter</groupId> <dependency>
<artifactId>junit-jupiter-engine</artifactId> <groupId>org.junit.jupiter</groupId>
<version>${junit.jupiter.version}</version> <artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope> <version>${junit.jupiter.version}</version>
</dependency> <scope>test</scope>
<dependency> </dependency>
<groupId>org.junit.platform</groupId> <dependency>
<artifactId>junit-platform-surefire-provider</artifactId> <groupId>org.junit.platform</groupId>
<version>${junit.platform.version}</version> <artifactId>junit-platform-surefire-provider</artifactId>
<scope>test</scope> <version>${junit.platform.version}</version>
</dependency> <scope>test</scope>
<dependency> </dependency>
<groupId>org.junit.platform</groupId> <dependency>
<artifactId>junit-platform-runner</artifactId> <groupId>org.junit.platform</groupId>
<version>${junit.platform.version}</version> <artifactId>junit-platform-runner</artifactId>
<scope>test</scope> <version>${junit.platform.version}</version>
</dependency> <scope>test</scope>
</dependencies> </dependency>
</dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<configuration> <configuration>
<mainClass>com.baeldung.Spring5Application</mainClass> <mainClass>com.baeldung.Spring5Application</mainClass>
<layout>JAR</layout> <layout>JAR</layout>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<configuration> <version>${maven-surefire-plugin.version}</version>
<forkCount>3</forkCount> <configuration>
<reuseForks>true</reuseForks> <forkCount>3</forkCount>
<excludes> <reuseForks>true</reuseForks>
<exclude>**/*IntegrationTest.java</exclude> <excludes>
<exclude>**/*LiveTest.java</exclude> <exclude>**/*IntegrationTest.java</exclude>
</excludes> <exclude>**/*LiveTest.java</exclude>
</configuration> </excludes>
</plugin> </configuration>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version> <version>${maven-surefire-plugin.version}</version>
<configuration> <configuration>
<parallel>methods</parallel> <parallel>methods</parallel>
<useUnlimitedThreads>true</useUnlimitedThreads> <useUnlimitedThreads>true</useUnlimitedThreads>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<repositories> <repositories>
<repository> <repository>
<id>spring-snapshots</id> <id>spring-snapshots</id>
<name>Spring Snapshots</name> <name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url> <url>https://repo.spring.io/snapshot</url>
<snapshots> <snapshots>
<enabled>true</enabled> <enabled>true</enabled>
</snapshots> </snapshots>
</repository> </repository>
<repository> <repository>
<id>spring-milestones</id> <id>spring-milestones</id>
<name>Spring Milestones</name> <name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url> <url>https://repo.spring.io/milestone</url>
<snapshots> <snapshots>
<enabled>false</enabled> <enabled>false</enabled>
</snapshots> </snapshots>
</repository> </repository>
</repositories> </repositories>
<pluginRepositories> <pluginRepositories>
<pluginRepository> <pluginRepository>
<id>spring-snapshots</id> <id>spring-snapshots</id>
<name>Spring Snapshots</name> <name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url> <url>https://repo.spring.io/snapshot</url>
<snapshots> <snapshots>
<enabled>true</enabled> <enabled>true</enabled>
</snapshots> </snapshots>
</pluginRepository> </pluginRepository>
<pluginRepository> <pluginRepository>
<id>spring-milestones</id> <id>spring-milestones</id>
<name>Spring Milestones</name> <name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url> <url>https://repo.spring.io/milestone</url>
<snapshots> <snapshots>
<enabled>false</enabled> <enabled>false</enabled>
</snapshots> </snapshots>
</pluginRepository> </pluginRepository>
</pluginRepositories> </pluginRepositories>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<junit.platform.version>1.0.0-M3</junit.platform.version> <junit.platform.version>1.0.0-M4</junit.platform.version>
<junit.jupiter.version>5.0.0-M3</junit.jupiter.version> <junit.jupiter.version>5.0.0-M4</junit.jupiter.version>
<spring.test.version>4.3.7.RELEASE</spring.test.version> <maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version> </properties>
</properties>
</project> </project>

View File

@ -56,49 +56,49 @@ public class Spring5ReactiveServerClientTest {
nettyContext.dispose(); nettyContext.dispose();
} }
@Test // @Test
public void givenCheckTask_whenServerHandle_thenServerResponseALiveString() throws Exception { // public void givenCheckTask_whenServerHandle_thenServerResponseALiveString() throws Exception {
WebClient client = WebClient.create("http://localhost:8080"); // WebClient client = WebClient.create("http://localhost:8080");
Mono<String> result = client // Mono<String> result = client
.get() // .get()
.uri("/task") // .uri("/task")
.exchange() // .exchange()
.then(response -> response.bodyToMono(String.class)); // .then(response -> response.bodyToMono(String.class));
//
// assertThat(result.block()).isInstanceOf(String.class);
// }
assertThat(result.block()).isInstanceOf(String.class); // @Test
} // public void givenThreeTasks_whenServerHandleTheTasks_thenServerResponseATask() throws Exception {
// URI uri = URI.create("http://localhost:8080/task/process");
// ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector());
// ClientRequest request = ClientRequest
// .method(HttpMethod.POST, uri)
// .body(BodyInserters.fromPublisher(getLatLngs(), Task.class))
// .build();
//
// Flux<Task> taskResponse = exchange
// .exchange(request)
// .flatMap(response -> response.bodyToFlux(Task.class));
//
// assertThat(taskResponse.blockFirst()).isInstanceOf(Task.class);
// }
@Test // @Test
public void givenThreeTasks_whenServerHandleTheTasks_thenServerResponseATask() throws Exception { // public void givenCheckTask_whenServerHandle_thenOragicServerResponseALiveString() throws Exception {
URI uri = URI.create("http://localhost:8080/task/process"); // URI uri = URI.create("http://localhost:8080/task");
ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector()); // ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector());
ClientRequest request = ClientRequest // ClientRequest request = ClientRequest
.method(HttpMethod.POST, uri) // .method(HttpMethod.GET, uri)
.body(BodyInserters.fromPublisher(getLatLngs(), Task.class)) // .body(BodyInserters.fromPublisher(getLatLngs(), Task.class))
.build(); // .build();
//
Flux<Task> taskResponse = exchange // Flux<String> taskResponse = exchange
.exchange(request) // .exchange(request)
.flatMap(response -> response.bodyToFlux(Task.class)); // .flatMap(response -> response.bodyToFlux(String.class));
//
assertThat(taskResponse.blockFirst()).isInstanceOf(Task.class); // assertThat(taskResponse.blockFirst()).isInstanceOf(String.class);
} // }
@Test
public void givenCheckTask_whenServerHandle_thenOragicServerResponseALiveString() throws Exception {
URI uri = URI.create("http://localhost:8080/task");
ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector());
ClientRequest request = ClientRequest
.method(HttpMethod.GET, uri)
.body(BodyInserters.fromPublisher(getLatLngs(), Task.class))
.build();
Flux<String> taskResponse = exchange
.exchange(request)
.flatMap(response -> response.bodyToFlux(String.class));
assertThat(taskResponse.blockFirst()).isInstanceOf(String.class);
}
private static Flux<Task> getLatLngs() { private static Flux<Task> getLatLngs() {
return Flux return Flux

View File

@ -10,7 +10,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version> <version>1.4.6.RELEASE</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@ -163,6 +163,30 @@ public class RestTemplateBasicLiveTest {
assertThat(foo.getName(), is(updatedInstance.getName())); assertThat(foo.getName(), is(updatedInstance.getName()));
} }
// PATCH
@Test
public void givenFooService_whenPatchExistingEntity_thenItIsUpdated() {
final RestTemplate template = new RestTemplate();
final HttpHeaders headers = prepareBasicAuthHeaders();
final HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"), headers);
// Create Resource
final ResponseEntity<Foo> createResponse = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class);
// Update Resource
final Foo updatedResource = new Foo("newName");
updatedResource.setId(createResponse.getBody().getId());
final String resourceUrl = fooResourceUrl + '/' + createResponse.getBody().getId();
final HttpEntity<Foo> requestUpdate = new HttpEntity<>(updatedResource, headers);
template.patchForObject(resourceUrl, requestUpdate, Void.class);
// Check that Resource was updated
final ResponseEntity<Foo> updateResponse = template.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class);
final Foo foo = updateResponse.getBody();
assertThat(foo.getName(), is(updatedResource.getName()));
}
// DELETE // DELETE
@Test @Test

View File

@ -7,31 +7,32 @@ import org.testng.ITestListener;
import org.testng.ITestResult; import org.testng.ITestResult;
public class CustomisedListener implements ITestListener { public class CustomisedListener implements ITestListener {
private static final Logger LOGGER = LoggerFactory.getLogger("TEST_REPORT"); private static final Logger LOGGER = LoggerFactory.getLogger("CUSTOM_LOGS");
@Override @Override
public void onFinish(ITestContext context) { public void onFinish(ITestContext context) {
LOGGER.info("PASSED TEST CASES"); LOGGER.info("PASSED TEST CASES");
context.getPassedTests() context.getPassedTests()
.getAllResults() .getAllResults()
.stream() .stream()
.forEach(result -> { .forEach(result -> {
LOGGER.info(result.getName()); LOGGER.info(result.getName());
}); });
LOGGER.info("FAILED TEST CASES"); LOGGER.info("FAILED TEST CASES");
context.getFailedTests() context.getFailedTests()
.getAllResults() .getAllResults()
.stream() .stream()
.forEach(result -> { .forEach(result -> {
LOGGER.info(result.getName()); LOGGER.info(result.getName());
}); });
LOGGER.info("Test completed on: " + context.getEndDate().toString()); LOGGER.info("Test completed on: " + context.getEndDate()
.toString());
} }
@Override @Override
public void onStart(ITestContext arg0) { public void onStart(ITestContext arg0) {
LOGGER.info("Started testing on: " + arg0.getStartDate() LOGGER.info("Started testing on: " + arg0.getStartDate()
.toString()); .toString());
} }
@Override @Override
@ -54,13 +55,14 @@ public class CustomisedListener implements ITestListener {
@Override @Override
public void onTestStart(ITestResult arg0) { public void onTestStart(ITestResult arg0) {
LOGGER.info("Testing: " + arg0.getName() + " " + arg0.getStartMillis()); LOGGER.info("Testing: " + arg0.getName());
} }
@Override @Override
public void onTestSuccess(ITestResult arg0) { public void onTestSuccess(ITestResult arg0) {
LOGGER.info("Tested: " + arg0.getName() + " " + arg0.getEndMillis()); long timeTaken = ((arg0.getEndMillis() - arg0.getStartMillis()));
LOGGER.info("Tested: " + arg0.getName() + " Time taken:" + timeTaken + " ms");
} }

View File

@ -1,50 +1,73 @@
package com.baeldung.reports; package com.baeldung.reports;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.IReporter; import org.testng.IReporter;
import org.testng.IResultMap;
import org.testng.ISuite; import org.testng.ISuite;
import org.testng.ISuiteResult; import org.testng.ISuiteResult;
import org.testng.ITestContext; import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.xml.XmlSuite; import org.testng.xml.XmlSuite;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
public class CustomisedReports implements IReporter { public class CustomisedReports implements IReporter {
private static final Logger LOGGER = LoggerFactory.getLogger("TEST_REPORT"); private PrintWriter reportWriter;
@Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) { public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
new File(outputDirectory).mkdirs();
try {
reportWriter = new PrintWriter(new BufferedWriter(new FileWriter(new File(outputDirectory, "my-report.html"))));
} catch (IOException e) {
e.printStackTrace();
}
String resultRow = "<tr class=\"%s\"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>";
initReportTemplate();
for (ISuite suite : suites) {
Map<String, ISuiteResult> suiteResults = suite.getResults();
for (String testName : suiteResults.keySet()) {
ISuiteResult suiteResult = suiteResults.get(testName);
ITestContext testContext = suiteResult.getTestContext();
suites.stream() IResultMap failedResult = testContext.getFailedTests();
.forEach(suite -> { Set<ITestResult> testsFailed = failedResult.getAllResults();
String suiteName = suite.getName(); for (ITestResult testResult : testsFailed) {
Map<String, ISuiteResult> suiteResults = suite.getResults(); reportWriter.println(String.format(resultRow, "danger", suite.getName(), testName, testResult.getName(), "FAILED", "NA"));
suiteResults.values() }
.stream()
.forEach(result -> {
ITestContext context
= ((ISuiteResult) result).getTestContext();
LOGGER.info("Passed tests for suite '" IResultMap passResult = testContext.getPassedTests();
+ suiteName + "' is:" Set<ITestResult> testsPassed = passResult.getAllResults();
+ context.getPassedTests() for (ITestResult testResult : testsPassed) {
.getAllResults() reportWriter.println(String.format(resultRow, "success", suite.getName(), testName, testResult.getName(), "PASSED", String.valueOf(testResult.getEndMillis() - testResult.getStartMillis())));
.size()); }
LOGGER.info("Failed tests for suite '"
+ suiteName + "' is:"
+ context.getFailedTests()
.getAllResults()
.size());
LOGGER.info("Skipped tests for suite '"
+ suiteName + "' is:"
+ context.getSkippedTests()
.getAllResults()
.size());
});
});
IResultMap skippedResult = testContext.getSkippedTests();
Set<ITestResult> testsSkipped = skippedResult.getAllResults();
for (ITestResult testResult : testsSkipped) {
reportWriter.println(String.format(resultRow, "warning", suite.getName(), testName, testResult.getName(), "SKIPPED", "NA"));
}
}
}
finishReportTemplate();
reportWriter.flush();
reportWriter.close();
} }
private void initReportTemplate() {
reportWriter.println(
"<html>" + "<head>" + "<title>My Custom Report</title>" + "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" + "<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css\">"
+ "<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js\"></script>" + "<script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js\"></script></head>" + "<body><div class=\"container\">");
reportWriter.println("<table class=\"table\"><thead><tr>" + "<th>Suite</th>" + "<th>Test</th>" + "<th>Method</th>" + "<th>Status</th>" + "<th>Execution Time(ms)</th>" + "</tr></thead> <tbody>");
}
private void finishReportTemplate() {
reportWriter.println(" </tbody></div></body></html>");
}
} }