Skip to content

Commit 6387275

Browse files
authored
Merge pull request #84 from jroper/streams-tck-with-arquillian
Added support for running the TCK in Arquillian
2 parents 14cc69c + 4a1ee95 commit 6387275

File tree

5 files changed

+372
-3
lines changed

5 files changed

+372
-3
lines changed

Diff for: streams/pom.xml

+18
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<modules>
3838
<module>api</module>
3939
<module>tck</module>
40+
<module>tck-arquillian</module>
4041
<module>spec</module>
4142
</modules>
4243

@@ -67,6 +68,23 @@
6768
<artifactId>org.osgi.annotation.versioning</artifactId>
6869
<version>1.0.0</version>
6970
</dependency>
71+
<dependency>
72+
<groupId>org.jboss.arquillian</groupId>
73+
<artifactId>arquillian-bom</artifactId>
74+
<version>1.1.15.Final</version>
75+
<scope>import</scope>
76+
<type>pom</type>
77+
</dependency>
78+
<dependency>
79+
<groupId>org.testng</groupId>
80+
<artifactId>testng</artifactId>
81+
<version>6.11</version>
82+
</dependency>
83+
<dependency>
84+
<groupId>javax.enterprise</groupId>
85+
<artifactId>cdi-api</artifactId>
86+
<version>2.0</version>
87+
</dependency>
7088
</dependencies>
7189
</dependencyManagement>
7290
</project>

Diff for: streams/tck-arquillian/pom.xml

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
~ Copyright (c) 2018 Contributors to the Eclipse Foundation
4+
~
5+
~ See the NOTICE file(s) distributed with this work for additional
6+
~ information regarding copyright ownership.
7+
~
8+
~ Licensed under the Apache License, Version 2.0 (the "License");
9+
~ You may not use this file except in compliance with the License.
10+
~ You may obtain a copy of the License at
11+
~
12+
~ http://www.apache.org/licenses/LICENSE-2.0
13+
~
14+
~ Unless required by applicable law or agreed to in writing, software
15+
~ distributed under the License is distributed on an "AS IS" BASIS,
16+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
~ See the License for the specific language governing permissions and
18+
~ limitations under the License.
19+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
20+
21+
<!--
22+
Licensed under the Apache License, Version 2.0 (the
23+
"License"); you may not use this file except in compliance
24+
with the License. You may obtain a copy of the License at
25+
26+
http://www.apache.org/licenses/LICENSE-2.0
27+
28+
Unless required by applicable law or agreed to in writing,
29+
software distributed under the License is distributed on an
30+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
31+
KIND, either express or implied. See the License for the
32+
specific language governing permissions and limitations
33+
under the License.
34+
-->
35+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
36+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
37+
<modelVersion>4.0.0</modelVersion>
38+
39+
<parent>
40+
<groupId>org.eclipse.microprofile.reactive.streams</groupId>
41+
<artifactId>microprofile-reactive-streams-parent</artifactId>
42+
<version>1.0-SNAPSHOT</version>
43+
</parent>
44+
45+
<artifactId>microprofile-reactive-streams-operators-tck-arquillian</artifactId>
46+
<name>MicroProfile Reactive Streams Operators TCK Arquillian</name>
47+
<description>MicroProfile Reactive Streams Operators :: TCK Arquillian runner</description>
48+
49+
<dependencies>
50+
<dependency>
51+
<groupId>org.eclipse.microprofile.reactive.streams</groupId>
52+
<artifactId>microprofile-reactive-streams-operators</artifactId>
53+
<version>${project.version}</version>
54+
<scope>provided</scope>
55+
</dependency>
56+
<dependency>
57+
<groupId>org.eclipse.microprofile.reactive.streams</groupId>
58+
<artifactId>microprofile-reactive-streams-operators-tck</artifactId>
59+
<version>${project.version}</version>
60+
</dependency>
61+
<dependency>
62+
<groupId>org.jboss.arquillian.test</groupId>
63+
<artifactId>arquillian-test-spi</artifactId>
64+
</dependency>
65+
<dependency>
66+
<groupId>org.jboss.arquillian.testng</groupId>
67+
<artifactId>arquillian-testng-container</artifactId>
68+
</dependency>
69+
<dependency>
70+
<groupId>javax.enterprise</groupId>
71+
<artifactId>cdi-api</artifactId>
72+
<scope>provided</scope>
73+
</dependency>
74+
</dependencies>
75+
76+
<build>
77+
<plugins>
78+
<plugin>
79+
<groupId>org.apache.maven.plugins</groupId>
80+
<artifactId>maven-javadoc-plugin</artifactId>
81+
<executions>
82+
<execution>
83+
<id>attach-javadocs</id>
84+
<goals>
85+
<goal>jar</goal>
86+
</goals>
87+
</execution>
88+
</executions>
89+
</plugin>
90+
<plugin>
91+
<groupId>org.apache.maven.plugins</groupId>
92+
<artifactId>maven-source-plugin</artifactId>
93+
<executions>
94+
<execution>
95+
<id>attach-sources</id>
96+
<goals>
97+
<goal>jar</goal>
98+
</goals>
99+
</execution>
100+
</executions>
101+
</plugin>
102+
<plugin>
103+
<groupId>org.eclipse.microprofile.maven</groupId>
104+
<artifactId>microprofile-maven-build-extension</artifactId>
105+
<extensions>true</extensions>
106+
</plugin>
107+
</plugins>
108+
</build>
109+
110+
<profiles>
111+
<profile>
112+
<id>eclipse-jarsigner</id>
113+
<build>
114+
<plugins>
115+
<plugin>
116+
<groupId>org.eclipse.cbi.maven.plugins</groupId>
117+
<artifactId>eclipse-jarsigner-plugin</artifactId>
118+
<executions>
119+
<execution>
120+
<goals>
121+
<goal>sign</goal>
122+
</goals>
123+
</execution>
124+
</executions>
125+
</plugin>
126+
</plugins>
127+
</build>
128+
</profile>
129+
</profiles>
130+
131+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2018 Contributors to the Eclipse Foundation
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information regarding copyright ownership.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* You may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
******************************************************************************/
19+
20+
package org.eclipse.microprofile.reactive.streams.tck.arquillian;
21+
22+
import org.eclipse.microprofile.reactive.streams.tck.ReactiveStreamsTck;
23+
import org.jboss.arquillian.container.test.api.Deployment;
24+
import org.jboss.arquillian.testng.Arquillian;
25+
import org.jboss.shrinkwrap.api.ShrinkWrap;
26+
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
27+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
28+
import org.reactivestreams.tck.TestEnvironment;
29+
import org.testng.IClassListener;
30+
import org.testng.IMethodInstance;
31+
import org.testng.IMethodInterceptor;
32+
import org.testng.IObjectFactory;
33+
import org.testng.ITestClass;
34+
import org.testng.ITestContext;
35+
import org.testng.ITestListener;
36+
import org.testng.ITestNGListener;
37+
import org.testng.ITestResult;
38+
import org.testng.TestNG;
39+
import org.testng.annotations.Test;
40+
import org.testng.internal.ObjectFactoryImpl;
41+
42+
import javax.inject.Inject;
43+
import java.util.ArrayList;
44+
import java.util.Collections;
45+
import java.util.Comparator;
46+
import java.util.List;
47+
import java.util.concurrent.atomic.AtomicInteger;
48+
import java.util.concurrent.atomic.AtomicReference;
49+
50+
/**
51+
* Test runner for running the TCK in Arquillian.
52+
* <p>
53+
* It would be nice if this was able to run the tests properly, and I did get something working, but it was so complex
54+
* and fragile because Arquillian really isn't that flexible that I decided it simply wasn't worth it, this is much
55+
* simpler.
56+
*/
57+
public class ReactiveStreamsArquillianTck extends Arquillian {
58+
@Deployment
59+
public static JavaArchive tckDeployment() {
60+
return ShrinkWrap.create(JavaArchive.class)
61+
// Add everything from the TCK
62+
.addPackages(true, ReactiveStreamsTck.class.getPackage())
63+
// And add the reactive streams TCK
64+
.addPackages(true, TestEnvironment.class.getPackage())
65+
// And we need a CDI descriptor
66+
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
67+
68+
}
69+
70+
@Inject
71+
private ReactiveStreamsCdiTck tck;
72+
73+
@Test
74+
public void runAllTckTests() throws Throwable {
75+
TestNG testng = new TestNG();
76+
77+
ObjectFactoryImpl delegate = new ObjectFactoryImpl();
78+
testng.setObjectFactory((IObjectFactory) (constructor, params) -> {
79+
if (constructor.getDeclaringClass().equals(ReactiveStreamsCdiTck.class)) {
80+
return tck;
81+
}
82+
else {
83+
return delegate.newInstance(constructor, params);
84+
}
85+
});
86+
87+
testng.setUseDefaultListeners(false);
88+
ResultListener resultListener = new ResultListener();
89+
testng.addListener((ITestNGListener) resultListener);
90+
testng.setTestClasses(new Class[]{ ReactiveStreamsCdiTck.class });
91+
testng.setMethodInterceptor(new IMethodInterceptor() {
92+
@Override
93+
public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
94+
methods.sort(Comparator.comparing(m -> m.getInstance().getClass().getName()));
95+
return methods;
96+
}
97+
});
98+
testng.run();
99+
int total = resultListener.success.get() + resultListener.failed.get() + resultListener.skipped.get();
100+
System.out.println(String.format("Ran %d tests, %d passed, %d failed, %d skipped.", total, resultListener.success.get(),
101+
resultListener.failed.get(), resultListener.skipped.get()));
102+
System.out.println("Failed tests:");
103+
resultListener.failures.forEach(result -> {
104+
System.out.println(result.getInstance().getClass().getName() + "." + result.getMethod().getMethodName());
105+
});
106+
if (resultListener.failed.get() > 0) {
107+
if (resultListener.lastFailure.get() != null) {
108+
throw resultListener.lastFailure.get();
109+
}
110+
else {
111+
throw new Exception("Tests failed with no exception");
112+
}
113+
}
114+
}
115+
116+
private static class ResultListener implements IClassListener, ITestListener {
117+
private final AtomicInteger success = new AtomicInteger();
118+
private final AtomicInteger failed = new AtomicInteger();
119+
private final AtomicInteger skipped = new AtomicInteger();
120+
private final AtomicReference<Throwable> lastFailure = new AtomicReference<>();
121+
private final List<ITestResult> failures = Collections.synchronizedList(new ArrayList<>());
122+
123+
@Override
124+
public void onBeforeClass(ITestClass testClass) {
125+
System.out.println(testClass.getName() + ":");
126+
}
127+
128+
@Override
129+
public void onAfterClass(ITestClass testClass) {
130+
}
131+
132+
@Override
133+
public void onTestStart(ITestResult result) {
134+
}
135+
136+
@Override
137+
public void onTestSuccess(ITestResult result) {
138+
printResult(result, "SUCCESS");
139+
success.incrementAndGet();
140+
}
141+
142+
@Override
143+
public void onTestFailure(ITestResult result) {
144+
printResult(result, "FAILED");
145+
if (result.getThrowable() != null) {
146+
result.getThrowable().printStackTrace(System.out);
147+
lastFailure.set(result.getThrowable());
148+
}
149+
failures.add(result);
150+
failed.incrementAndGet();
151+
}
152+
153+
@Override
154+
public void onTestSkipped(ITestResult result) {
155+
printResult(result, "SKIPPED");
156+
skipped.incrementAndGet();
157+
}
158+
159+
@Override
160+
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
161+
}
162+
163+
@Override
164+
public void onStart(ITestContext context) {
165+
}
166+
167+
@Override
168+
public void onFinish(ITestContext context) {
169+
170+
}
171+
172+
private static void printResult(ITestResult result, String status) {
173+
String methodName = String.format("%-100s", result.getMethod().getMethodName()).replace(' ', '.');
174+
System.out.println(" - " + methodName + "." + status);
175+
}
176+
}
177+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2018 Contributors to the Eclipse Foundation
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information regarding copyright ownership.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* You may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
******************************************************************************/
19+
20+
package org.eclipse.microprofile.reactive.streams.tck.arquillian;
21+
22+
import org.eclipse.microprofile.reactive.streams.spi.ReactiveStreamsEngine;
23+
import org.eclipse.microprofile.reactive.streams.tck.ReactiveStreamsTck;
24+
import org.reactivestreams.tck.TestEnvironment;
25+
26+
import javax.enterprise.context.ApplicationScoped;
27+
import javax.inject.Inject;
28+
29+
@ApplicationScoped
30+
public class ReactiveStreamsCdiTck extends ReactiveStreamsTck<ReactiveStreamsEngine> {
31+
32+
public ReactiveStreamsCdiTck() {
33+
super(new TestEnvironment());
34+
}
35+
36+
@Inject
37+
private ReactiveStreamsEngine engine;
38+
39+
@Override
40+
protected ReactiveStreamsEngine createEngine() {
41+
return engine;
42+
}
43+
}

0 commit comments

Comments
 (0)