Skip to content
This repository was archived by the owner on Oct 25, 2023. It is now read-only.

Commit fb2dad2

Browse files
authored
Merge pull request #60 from hivemq/develop
Version 1.2.0
2 parents 0e0006a + b9615c5 commit fb2dad2

32 files changed

+328
-180
lines changed

build.gradle

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ plugins {
77
/* ******************** metadata ******************** */
88

99
allprojects {
10-
version '1.1.1'
10+
version '1.2.0'
1111
group 'com.hivemq'
1212
description 'Testcontainers for testing HiveMQ Extensions and Java MQTT Applications.'
1313

@@ -48,16 +48,16 @@ allprojects {
4848
}
4949

5050
ext {
51-
testContainersVersion = '1.13.0'
52-
extensionSDKVersion = '4.3.0'
53-
hmcVersion = '1.1.4'
54-
junit4Version = '4.12'
55-
junit5Version = '5.6.1'
56-
commonsIoVersion = '2.6'
51+
testContainersVersion = '1.14.3'
52+
extensionSDKVersion = '4.4.0'
53+
hmcVersion = '1.2.1'
54+
junit4Version = '4.13'
55+
junit5Version = '5.6.2'
56+
commonsIoVersion = '2.7'
5757
javassistVersion = '3.27.0-GA'
5858
shrinkWrapVersion = '1.2.6'
5959
shrinkwrapResolverDepchainVersion = '3.1.4'
60-
zip4jVersion = '2.6.1'
60+
zip4jVersion = '2.6.2'
6161

6262
// only test
6363
httpClientVersion = '4.5.12'

core/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ ext {
99

1010
dependencies {
1111
api group: 'org.testcontainers', name: 'testcontainers', version: testContainersVersion
12-
implementation group: 'com.hivemq', name: 'hivemq-mqtt-client', version: hmcVersion
1312
implementation group: 'commons-io', name: 'commons-io', version: commonsIoVersion
1413
implementation group: 'org.javassist', name: 'javassist', version: javassistVersion
1514
implementation group: 'org.jboss.shrinkwrap', name: 'shrinkwrap-api', version: shrinkWrapVersion
@@ -30,6 +29,7 @@ dependencies {
3029
compileOnly group: 'com.hivemq', name: 'hivemq-extension-sdk', version: extensionSDKVersion
3130

3231
testImplementation group: 'com.hivemq', name: 'hivemq-extension-sdk', version: extensionSDKVersion
32+
testImplementation group: 'com.hivemq', name: 'hivemq-mqtt-client', version: hmcVersion
3333
testImplementation group: 'com.google.dagger', name: 'dagger', version: daggerVersion
3434
testAnnotationProcessor group: 'com.google.dagger', name: 'dagger-compiler', version: daggerVersion
3535
}

core/src/main/java/com/hivemq/testcontainer/core/HiveMQTestContainerCore.java

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,18 @@ public class HiveMQTestContainerCore<SELF extends HiveMQTestContainerCore<SELF>>
6868
private final @NotNull ConcurrentHashMap<String, CountDownLatch> containerOutputLatches = new ConcurrentHashMap<>();
6969
private volatile boolean silent = false;
7070

71+
private final @NotNull MultiLogMessageWaitStrategy waitStrategy = new MultiLogMessageWaitStrategy();
72+
7173
public HiveMQTestContainerCore() {
7274
this(DEFAULT_HIVEMQ_IMAGE, DEFAULT_HIVEMQ_TAG);
7375
}
7476

7577
public HiveMQTestContainerCore(final @NotNull String image, final @NotNull String tag) {
7678
super(image + ":" + tag);
77-
withExposedPorts(MQTT_PORT);
79+
addExposedPort(MQTT_PORT);
7880

79-
final MqttWaitStrategy mqttWaitStrategy = new MqttWaitStrategy();
80-
waitingFor(mqttWaitStrategy);
81+
waitStrategy.withRegEx("(.*)Started HiveMQ in(.*)");
82+
waitingFor(waitStrategy);
8183

8284
withLogConsumer(outputFrame -> {
8385
if (!silent) {
@@ -98,6 +100,32 @@ public HiveMQTestContainerCore(final @NotNull String image, final @NotNull Strin
98100
});
99101
}
100102

103+
/**
104+
* Adds a wait condition for the extension with this name.
105+
* <p>
106+
* Must be called before the container is started.
107+
*
108+
* @param extensionName the extension to wait for
109+
* @return self
110+
*/
111+
public @NotNull SELF waitForExtension(final @NotNull String extensionName) {
112+
final String regEX = "(.*)Extension \"" + extensionName + "\" version (.*) started successfully(.*)";
113+
waitStrategy.withRegEx(regEX);
114+
return self();
115+
}
116+
117+
/**
118+
* Adds a wait condition for this {@link HiveMQExtension}
119+
* <p>
120+
* Must be called before the container is started.
121+
*
122+
* @param extension the extension to wait for
123+
* @return self
124+
*/
125+
public @NotNull SELF waitForExtension(final @NotNull HiveMQExtension extension) {
126+
return this.waitForExtension(extension.getName());
127+
}
128+
101129
/**
102130
* Enables the possibility for remote debugging clients to connect.
103131
* <p>
@@ -107,8 +135,8 @@ public HiveMQTestContainerCore(final @NotNull String image, final @NotNull Strin
107135
* @return self
108136
*/
109137
public @NotNull SELF withDebugging(final int debuggingPortHost) {
110-
withExposedPorts(DEBUGGING_PORT);
111-
withFixedExposedPort(debuggingPortHost, DEBUGGING_PORT);
138+
addExposedPorts(DEBUGGING_PORT);
139+
addFixedExposedPort(debuggingPortHost, DEBUGGING_PORT);
112140
withEnv("JAVA_OPTS", "-agentlib:jdwp=transport=dt_socket,address=0.0.0.0:" + DEBUGGING_PORT + ",server=y,suspend=n");
113141
return self();
114142
}
@@ -582,8 +610,8 @@ private void putSubclassesIntoJar(
582610
* @return self
583611
*/
584612
public @NotNull SELF withControlCenter(final int controlCenterPort) {
585-
withExposedPorts(CONTROL_CENTER_PORT);
586-
withFixedExposedPort(controlCenterPort, CONTROL_CENTER_PORT);
613+
addExposedPorts(CONTROL_CENTER_PORT);
614+
addFixedExposedPort(controlCenterPort, CONTROL_CENTER_PORT);
587615
return self();
588616
}
589617

core/src/main/java/com/hivemq/testcontainer/core/MqttWaitStrategy.java

Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2020 HiveMQ and the HiveMQ Community
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.hivemq.testcontainer.core;
17+
18+
import org.jetbrains.annotations.NotNull;
19+
import org.testcontainers.DockerClientFactory;
20+
import org.testcontainers.containers.ContainerLaunchException;
21+
import org.testcontainers.containers.output.OutputFrame;
22+
import org.testcontainers.containers.output.WaitingConsumer;
23+
import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy;
24+
import org.testcontainers.utility.LogUtils;
25+
26+
import java.util.concurrent.ConcurrentHashMap;
27+
import java.util.concurrent.TimeUnit;
28+
import java.util.concurrent.TimeoutException;
29+
import java.util.function.Predicate;
30+
31+
/**
32+
* This is a wait strategy to wait for multiple log patterns.
33+
* The wait strategy will continue when every log pattern is matched at least once.
34+
*
35+
* @author Yannick Weber
36+
* @since 1.2.0
37+
*/
38+
class MultiLogMessageWaitStrategy extends AbstractWaitStrategy {
39+
40+
private final @NotNull ConcurrentHashMap<String, Boolean> regexes = new ConcurrentHashMap<>();
41+
42+
@Override
43+
protected void waitUntilReady() {
44+
WaitingConsumer waitingConsumer = new WaitingConsumer();
45+
LogUtils.followOutput(DockerClientFactory.instance().client(), waitStrategyTarget.getContainerId(), waitingConsumer);
46+
47+
Predicate<OutputFrame> waitPredicate = outputFrame -> {
48+
if (regexes.isEmpty()) {
49+
return true;
50+
}
51+
regexes.entrySet().forEach(stringBooleanEntry -> {
52+
final boolean matched = outputFrame.getUtf8String().matches("(?s)" + stringBooleanEntry.getKey());
53+
if (matched) {
54+
stringBooleanEntry.setValue(true);
55+
}
56+
});
57+
return regexes.values().stream().reduce(Boolean::logicalAnd).orElse(true);
58+
};
59+
60+
try {
61+
waitingConsumer.waitUntil(waitPredicate, startupTimeout.getSeconds(), TimeUnit.SECONDS, 1);
62+
} catch (TimeoutException e) {
63+
throw new ContainerLaunchException("Timed out waiting for log output matching '" + regexes + "'");
64+
}
65+
}
66+
67+
public @NotNull MultiLogMessageWaitStrategy withRegEx(final @NotNull String regEx) {
68+
regexes.put(regEx, false);
69+
return this;
70+
}
71+
}

junit4/src/test/java/com/hivemq/testcontainer/junit4/ContainerWithDaggerExtensionIT.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,19 @@ public class ContainerWithDaggerExtensionIT {
2828

2929
@Test(timeout = 200_000)
3030
public void test() throws Exception {
31+
final HiveMQExtension hiveMQExtension = HiveMQExtension.builder()
32+
.id("extension-1")
33+
.name("my-extension")
34+
.version("1.0")
35+
.mainClass(MyExtensionWithDagger.class)
36+
.addAdditionalClass(MyModule.class)
37+
.addAdditionalClass(Class.forName("com.hivemq.testcontainer.util.dagger.MyModule_ProvidePublishModifierFactory"))
38+
.build();
39+
3140
final HiveMQTestContainerRule rule =
3241
new HiveMQTestContainerRule()
33-
.withExtension(HiveMQExtension.builder()
34-
.id("extension-1")
35-
.name("my-extension")
36-
.version("1.0")
37-
.mainClass(MyExtensionWithDagger.class)
38-
.addAdditionalClass(MyModule.class)
39-
.addAdditionalClass(Class.forName("com.hivemq.testcontainer.util.dagger.MyModule_ProvidePublishModifierFactory"))
40-
.build());
42+
.waitForExtension(hiveMQExtension)
43+
.withExtension(hiveMQExtension);
4144

4245
rule.start();
4346

junit4/src/test/java/com/hivemq/testcontainer/junit4/ContainerWithExtensionFromDirectoryIT.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class ContainerWithExtensionFromDirectoryIT {
3030
public void test() throws Exception {
3131
final HiveMQTestContainerRule rule =
3232
new HiveMQTestContainerRule()
33+
.waitForExtension("Modifier Extension")
3334
.withExtension(new File("src/test/resources/modifier-extension"))
3435
.withLogLevel(Level.DEBUG);
3536

junit4/src/test/java/com/hivemq/testcontainer/junit4/ContainerWithExtensionIT.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,16 @@ public class ContainerWithExtensionIT {
2828

2929
@Test(timeout = 200_000)
3030
public void test() throws Exception {
31+
final HiveMQExtension hiveMQExtension = HiveMQExtension.builder()
32+
.id("extension-1")
33+
.name("my-extension")
34+
.version("1.0")
35+
.mainClass(MyExtension.class).build();
36+
3137
final @NotNull HiveMQTestContainerRule rule =
3238
new HiveMQTestContainerRule()
33-
.withExtension(HiveMQExtension.builder()
34-
.id("extension-1")
35-
.name("my-extension")
36-
.version("1.0")
37-
.mainClass(MyExtension.class).build());
39+
.waitForExtension(hiveMQExtension)
40+
.withExtension(hiveMQExtension);
3841

3942
rule.start();
4043
TestPublishModifiedUtil.testPublishModified(rule.getMqttPort());

junit4/src/test/java/com/hivemq/testcontainer/junit4/ContainerWithExtensionSubclassIT.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,17 @@ public class ContainerWithExtensionSubclassIT {
2828

2929
@Test(timeout = 200_000)
3030
public void test() throws Exception {
31+
final HiveMQExtension hiveMQExtension = HiveMQExtension.builder()
32+
.id("extension-1")
33+
.name("my-extension")
34+
.version("1.0")
35+
.priority(100)
36+
.startPriority(1000)
37+
.mainClass(MyExtensionWithSubclasses.class).build();
38+
3139
final HiveMQTestContainerRule rule =
3240
new HiveMQTestContainerRule()
33-
.withExtension(HiveMQExtension.builder()
34-
.id("extension-1")
35-
.name("my-extension")
36-
.version("1.0")
37-
.priority(100)
38-
.startPriority(1000)
39-
.mainClass(MyExtensionWithSubclasses.class).build())
41+
.withExtension(hiveMQExtension)
4042
.withLogLevel(Level.DEBUG);
4143

4244
rule.start();

junit4/src/test/java/com/hivemq/testcontainer/junit4/ContainerWithFileInExtensionHomeIT.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@ public class ContainerWithFileInExtensionHomeIT {
3939

4040
@Test(timeout = 200_000)
4141
public void test() throws Exception {
42+
final HiveMQExtension hiveMQExtension = HiveMQExtension.builder()
43+
.id("extension-1")
44+
.name("my-extension")
45+
.version("1.0")
46+
.mainClass(FileCheckerExtension.class).build();
47+
4248
final HiveMQTestContainerRule rule =
4349
new HiveMQTestContainerRule()
44-
.withExtension(HiveMQExtension.builder()
45-
.id("extension-1")
46-
.name("my-extension")
47-
.version("1.0")
48-
.mainClass(FileCheckerExtension.class).build())
50+
.waitForExtension(hiveMQExtension)
51+
.withExtension(hiveMQExtension)
4952
.withFileInExtensionHomeFolder(
5053
new File("src/test/resources/additionalFile.txt"),
5154
"extension-1",

0 commit comments

Comments
 (0)