Skip to content

Commit 8505dfe

Browse files
authored
Merge pull request #97 from dalelane/master
tests: add tests for connector
2 parents e535261 + f5cbec9 commit 8505dfe

File tree

7 files changed

+1034
-3
lines changed

7 files changed

+1034
-3
lines changed

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
language: java
2+
3+
services:
4+
- docker
5+
6+
script: mvn clean verify

pom.xml

Lines changed: 142 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<artifactId>connect-api</artifactId>
4848
<version>2.6.0</version>
4949
<scope>provided</scope>
50-
</dependency>
50+
</dependency>
5151
<dependency>
5252
<groupId>org.apache.kafka</groupId>
5353
<artifactId>connect-json</artifactId>
@@ -84,6 +84,15 @@
8484
<version>1.7.25</version>
8585
<scope>test</scope>
8686
</dependency>
87+
88+
<!-- tests in src/integration depend on a running MQ queue manager -->
89+
<!-- in a container, configured using org.testcontainers -->
90+
<dependency>
91+
<groupId>org.testcontainers</groupId>
92+
<artifactId>testcontainers</artifactId>
93+
<version>1.17.3</version>
94+
<scope>test</scope>
95+
</dependency>
8796
</dependencies>
8897

8998
<build>
@@ -97,18 +106,44 @@
97106
<compilerArgument>-Xlint:unchecked</compilerArgument>
98107
</configuration>
99108
</plugin>
109+
110+
<!-- run unit tests -->
100111
<plugin>
101112
<artifactId>maven-surefire-plugin</artifactId>
102-
<version>3.0.0-M1</version>
113+
<version>3.0.0-M7</version>
103114
<configuration>
115+
<argLine>${surefire.jacoco.args}</argLine>
104116
<systemPropertyVariables>
105117
<connectorVersion>${project.version}</connectorVersion>
106118
</systemPropertyVariables>
107119
</configuration>
108120
</plugin>
121+
122+
<!-- run integration tests -->
123+
<plugin>
124+
<artifactId>maven-failsafe-plugin</artifactId>
125+
<version>3.0.0-M7</version>
126+
<configuration>
127+
<argLine>${failsafe.jacoco.args}</argLine>
128+
<systemPropertyVariables>
129+
<connectorVersion>${project.version}</connectorVersion>
130+
</systemPropertyVariables>
131+
</configuration>
132+
<executions>
133+
<execution>
134+
<id>integration-tests</id>
135+
<goals>
136+
<goal>integration-test</goal>
137+
<goal>verify</goal>
138+
</goals>
139+
</execution>
140+
</executions>
141+
</plugin>
142+
143+
<!-- build the release jar -->
109144
<plugin>
110145
<artifactId>maven-assembly-plugin</artifactId>
111-
<version>3.1.1</version>
146+
<version>3.4.1</version>
112147
<executions>
113148
<execution>
114149
<phase>package</phase>
@@ -123,6 +158,110 @@
123158
</descriptors>
124159
</configuration>
125160
</plugin>
161+
162+
<!-- add the src/integration folder as a test folder, which lets us keep -->
163+
<!-- tests that have a dependency on testcontainers separate from pure -->
164+
<!-- unit tests with no external dependency -->
165+
<plugin>
166+
<groupId>org.codehaus.mojo</groupId>
167+
<artifactId>build-helper-maven-plugin</artifactId>
168+
<version>3.3.0</version>
169+
<executions>
170+
<execution>
171+
<id>add-test-source</id>
172+
<phase>process-test-sources</phase>
173+
<goals>
174+
<goal>add-test-source</goal>
175+
</goals>
176+
<configuration>
177+
<sources>
178+
<source>src/integration/java</source>
179+
</sources>
180+
</configuration>
181+
</execution>
182+
</executions>
183+
</plugin>
184+
185+
<!-- generate test code coverage report -->
186+
<plugin>
187+
<groupId>org.jacoco</groupId>
188+
<artifactId>jacoco-maven-plugin</artifactId>
189+
<version>0.8.8</version>
190+
<executions>
191+
<execution>
192+
<id>before-unit-test-execution</id>
193+
<goals>
194+
<goal>prepare-agent</goal>
195+
</goals>
196+
<configuration>
197+
<destFile>${project.build.directory}/jacoco-output/jacoco-unit-tests.exec</destFile>
198+
<propertyName>surefire.jacoco.args</propertyName>
199+
</configuration>
200+
</execution>
201+
<execution>
202+
<id>after-unit-test-execution</id>
203+
<phase>test</phase>
204+
<goals>
205+
<goal>report</goal>
206+
</goals>
207+
<configuration>
208+
<dataFile>${project.build.directory}/jacoco-output/jacoco-unit-tests.exec</dataFile>
209+
<outputDirectory>${project.reporting.outputDirectory}/jacoco-unit-test-coverage-report</outputDirectory>
210+
</configuration>
211+
</execution>
212+
<execution>
213+
<id>before-integration-test-execution</id>
214+
<phase>pre-integration-test</phase>
215+
<goals>
216+
<goal>prepare-agent</goal>
217+
</goals>
218+
<configuration>
219+
<destFile>${project.build.directory}/jacoco-output/jacoco-integration-tests.exec</destFile>
220+
<propertyName>failsafe.jacoco.args</propertyName>
221+
</configuration>
222+
</execution>
223+
<execution>
224+
<id>after-integration-test-execution</id>
225+
<phase>post-integration-test</phase>
226+
<goals>
227+
<goal>report</goal>
228+
</goals>
229+
<configuration>
230+
<dataFile>${project.build.directory}/jacoco-output/jacoco-integration-tests.exec</dataFile>
231+
<outputDirectory>${project.reporting.outputDirectory}/jacoco-integration-test-coverage-report</outputDirectory>
232+
</configuration>
233+
</execution>
234+
<execution>
235+
<id>merge-unit-and-integration</id>
236+
<phase>post-integration-test</phase>
237+
<goals>
238+
<goal>merge</goal>
239+
</goals>
240+
<configuration>
241+
<fileSets>
242+
<fileSet>
243+
<directory>${project.build.directory}/jacoco-output/</directory>
244+
<includes>
245+
<include>*.exec</include>
246+
</includes>
247+
</fileSet>
248+
</fileSets>
249+
<destFile>${project.build.directory}/jacoco-output/merged.exec</destFile>
250+
</configuration>
251+
</execution>
252+
<execution>
253+
<id>create-merged-report</id>
254+
<phase>post-integration-test</phase>
255+
<goals>
256+
<goal>report</goal>
257+
</goals>
258+
<configuration>
259+
<dataFile>${project.build.directory}/jacoco-output/merged.exec</dataFile>
260+
<outputDirectory>${project.reporting.outputDirectory}/jacoco-merged-test-coverage-report</outputDirectory>
261+
</configuration>
262+
</execution>
263+
</executions>
264+
</plugin>
126265
</plugins>
127266
</build>
128267
</project>
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/**
2+
* Copyright 2022 IBM Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.ibm.eventstreams.connect.mqsource;
17+
18+
import java.util.List;
19+
import java.util.concurrent.TimeoutException;
20+
21+
import javax.jms.Connection;
22+
import javax.jms.Destination;
23+
import javax.jms.JMSContext;
24+
import javax.jms.JMSException;
25+
import javax.jms.Message;
26+
import javax.jms.MessageProducer;
27+
import javax.jms.Session;
28+
29+
import org.junit.ClassRule;
30+
import org.testcontainers.containers.GenericContainer;
31+
import org.testcontainers.containers.output.WaitingConsumer;
32+
33+
import com.ibm.mq.jms.MQConnectionFactory;
34+
import com.ibm.msg.client.jms.JmsConnectionFactory;
35+
import com.ibm.msg.client.jms.JmsFactoryFactory;
36+
import com.ibm.msg.client.wmq.WMQConstants;
37+
38+
/**
39+
* Helper class for integration tests that have a dependency on JMSContext.
40+
*
41+
* It starts a queue manager in a test container, and uses it to create
42+
* a JMSContext instance, that can be used in tests.
43+
*/
44+
public class AbstractJMSContextIT {
45+
46+
private static final String QMGR_NAME = "MYQMGR";
47+
private static final String CHANNEL_NAME = "DEV.APP.SVRCONN";
48+
49+
@ClassRule
50+
public static GenericContainer<?> MQ_CONTAINER = new GenericContainer<>("icr.io/ibm-messaging/mq:latest")
51+
.withEnv("LICENSE", "accept")
52+
.withEnv("MQ_QMGR_NAME", QMGR_NAME)
53+
.withEnv("MQ_ENABLE_EMBEDDED_WEB_SERVER", "false")
54+
.withExposedPorts(1414);
55+
56+
private JMSContext jmsContext;
57+
58+
59+
/**
60+
* Returns a JMS context pointing at a developer queue manager running in a
61+
* test container.
62+
*/
63+
public JMSContext getJmsContext() throws Exception {
64+
if (jmsContext == null) {
65+
waitForQueueManagerStartup();
66+
67+
MQConnectionFactory mqcf = new MQConnectionFactory();
68+
mqcf.setTransportType(WMQConstants.WMQ_CM_CLIENT);
69+
mqcf.setChannel(CHANNEL_NAME);
70+
mqcf.setQueueManager(QMGR_NAME);
71+
mqcf.setConnectionNameList(getConnectionName());
72+
73+
jmsContext = mqcf.createContext();
74+
}
75+
76+
return jmsContext;
77+
}
78+
79+
80+
/**
81+
* Gets the host port that has been mapped to the default MQ 1414 port in the test container.
82+
*/
83+
public Integer getMQPort() {
84+
return MQ_CONTAINER.getMappedPort(1414);
85+
}
86+
87+
public String getQmgrName() {
88+
return QMGR_NAME;
89+
}
90+
public String getChannelName() {
91+
return CHANNEL_NAME;
92+
}
93+
public String getConnectionName() {
94+
return "localhost(" + getMQPort().toString() + ")";
95+
}
96+
97+
98+
/**
99+
* Waits until we see a log line in the queue manager test container that indicates
100+
* the queue manager is ready.
101+
*/
102+
private void waitForQueueManagerStartup() throws TimeoutException {
103+
WaitingConsumer logConsumer = new WaitingConsumer();
104+
MQ_CONTAINER.followOutput(logConsumer);
105+
logConsumer.waitUntil(logline -> logline.getUtf8String().contains("AMQ5975I"));
106+
}
107+
108+
109+
110+
111+
/**
112+
* Puts all messages to the specified MQ queue. Used in tests to
113+
* give the Connector something to get.
114+
*/
115+
public void putAllMessagesToQueue(String queueName, List<Message> messages) throws JMSException {
116+
Connection connection = null;
117+
Session session = null;
118+
Destination destination = null;
119+
MessageProducer producer = null;
120+
121+
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
122+
123+
JmsConnectionFactory cf = ff.createConnectionFactory();
124+
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, "localhost");
125+
cf.setIntProperty(WMQConstants.WMQ_PORT, getMQPort());
126+
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, getChannelName());
127+
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
128+
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, getQmgrName());
129+
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, false);
130+
131+
connection = cf.createConnection();
132+
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
133+
134+
destination = session.createQueue(queueName);
135+
producer = session.createProducer(destination);
136+
137+
connection.start();
138+
139+
for (Message message : messages) {
140+
message.setJMSDestination(destination);
141+
producer.send(message);
142+
}
143+
144+
connection.close();
145+
}
146+
}

0 commit comments

Comments
 (0)