Skip to content

Commit 76f4d6a

Browse files
authored
Merge pull request #118 from openbase/117-fix-test-container-setup
2 parents 6249611 + 6e3840a commit 76f4d6a

14 files changed

Lines changed: 537 additions & 156 deletions

File tree

.github/workflows/build-and-test.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ jobs:
2222

2323
steps:
2424
- name: "Checkout Branch"
25-
uses: actions/checkout@v4
25+
uses: actions/checkout@v6
2626

2727
- name: "Setup Java"
28-
uses: actions/setup-java@v4
28+
uses: actions/setup-java@v5
2929
with:
3030
distribution: 'temurin'
3131
java-version: '21'
3232

3333
- name: Setup Gradle cache
34-
uses: actions/cache@v4
34+
uses: actions/cache@v5
3535
with:
3636
path: ~/.gradle
3737
key: ${{ runner.os }}-gradle-${{ hashFiles('build.gradle') }}
@@ -59,16 +59,16 @@ jobs:
5959

6060
steps:
6161
- name: "Checkout Branch"
62-
uses: actions/checkout@v4
62+
uses: actions/checkout@v6
6363

6464
- name: "Setup Java"
65-
uses: actions/setup-java@v4
65+
uses: actions/setup-java@v5
6666
with:
6767
distribution: 'temurin'
6868
java-version: '21'
6969

7070
- name: Setup Gradle cache
71-
uses: actions/cache@v4
71+
uses: actions/cache@v5
7272
with:
7373
path: ~/.gradle
7474
key: ${{ runner.os }}-gradle-${{ hashFiles('build.gradle') }}
@@ -81,7 +81,7 @@ jobs:
8181
RUN_LONG_INTEGRATION_TESTS: false
8282

8383
- name: Upload Gradle reports
84-
uses: actions/upload-artifact@v4
84+
uses: actions/upload-artifact@v7
8585
if: ${{ failure() }}
8686
with:
8787
name: Test Backend Reports

.github/workflows/inspect-code.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
# Steps represent a sequence of tasks that will be executed as part of the job
4141
steps:
4242
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
43-
- uses: actions/checkout@v2
43+
- uses: actions/checkout@v6
4444

4545
# Gets the download URL associated with the $DETEKT_RELEASE_TAG
4646
- name: Get Detekt download URL
@@ -62,7 +62,8 @@ jobs:
6262
}
6363
' | \
6464
jq --raw-output '.data.repository.release.releaseAssets.nodes[0].downloadUrl' )
65-
echo "::set-output name=download_url::$DETEKT_DOWNLOAD_URL"
65+
echo "download_url=$DETEKT_DOWNLOAD_URL" >> $GITHUB_OUTPUT
66+
echo "Detekt download URL: $DETEKT_DOWNLOAD_URL"
6667
6768
# Sets up the detekt cli
6869
- name: Setup Detekt
@@ -96,7 +97,7 @@ jobs:
9697
)" > ${{ github.workspace }}/detekt.sarif.json
9798
9899
# Uploads results to GitHub repository using the upload-sarif action
99-
- uses: github/codeql-action/upload-sarif@v1
100+
- uses: github/codeql-action/upload-sarif@v4
100101
with:
101102
# Path to SARIF file relative to the root of the repository
102103
sarif_file: ${{ github.workspace }}/detekt.sarif.json

.github/workflows/publish-jars.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ jobs:
1414
packages: write
1515
steps:
1616
- name: Checkout
17-
uses: actions/checkout@v4
17+
uses: actions/checkout@v6
1818

1919
- name: Set up Java
20-
uses: actions/setup-java@v4
20+
uses: actions/setup-java@v5
2121
with:
2222
java-version: '21'
2323
distribution: 'adopt'
2424

2525
- name: Validate Gradle wrapper
26-
uses: gradle/actions/wrapper-validation@v3.5.0
26+
uses: gradle/actions/wrapper-validation@v6
2727

2828
- name: Publish Packages
29-
uses: gradle/actions/setup-gradle@v3.5.0
29+
uses: gradle/actions/setup-gradle@v6
3030
with:
3131
arguments: publishToSonatype closeAndReleaseSonatypeStagingRepository
3232
env:

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
version=3.7.2
1+
version=3.7.3
22
org.gradle.caching=true
33
org.gradle.parallel=true

module/communication/controller/src/test/java/org/openbase/jul/communication/controller/AbstractControllerServerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ public void testReinit() throws Exception {
405405
*
406406
* @throws Exception if any error occurs
407407
*/
408-
@Timeout(5)
408+
@Timeout(20)
409409
@Test
410410
public void testParallelMethodCall() throws Exception {
411411
final String scope = "/test/parallel";

module/communication/mqtt/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ dependencies {
88
api(project(":jul.extension.type.processing"))
99
api("com.hivemq:hivemq-mqtt-client:_")
1010
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:_")
11+
testImplementation(project(":jul.communication.mqtt.test"))
1112
testImplementation("org.testcontainers:junit-jupiter:_") {
1213
exclude(group = "junit", module = "junit")
1314
}

module/communication/mqtt/src/main/java/org/openbase/jul/communication/mqtt/SharedMqttClient.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ object SharedMqttClient : Shutdownable {
5252
sharedClients.values
5353
.filter { (it as Mqtt5ClientWrapper).isConnected() }
5454
.map { it.disconnect() }
55-
.map { it.get() }
55+
.map {
56+
runCatching { it.get() }
57+
.getOrElse { t -> check(t.message == "com.hivemq.client.mqtt.exceptions.MqttClientStateException: MQTT client is not connected.") {
58+
"Could not disconnect client connection: ${t.message}" }
59+
null
60+
}
61+
}
5662
.run { sharedClients.clear() }
5763

5864
@Synchronized

module/communication/mqtt/src/test/java/org/openbase/jul/communication/mqtt/AbstractIntegrationTest.kt

Lines changed: 17 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,77 +4,31 @@ import com.hivemq.client.mqtt.mqtt5.datatypes.Mqtt5UserProperties
44
import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5Publish
55
import org.junit.jupiter.api.AfterAll
66
import org.junit.jupiter.api.BeforeAll
7+
import org.junit.jupiter.api.TestInstance
78
import org.junit.jupiter.api.Timeout
8-
import org.testcontainers.containers.BindMode
9-
import org.testcontainers.containers.GenericContainer
9+
import org.openbase.jul.communication.config.CommunicatorConfig
10+
import org.openbase.jul.communication.mqtt.test.MqttBrokerManager
1011
import org.testcontainers.junit.jupiter.Testcontainers
11-
import org.testcontainers.utility.DockerImageName
12-
import java.time.Duration
13-
import kotlin.io.path.absolute
14-
import kotlin.io.path.deleteIfExists
15-
import kotlin.io.path.writeLines
1612

17-
@Testcontainers
18-
abstract class AbstractIntegrationTest {
13+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
14+
open class AbstractIntegrationTest {
1915

20-
// the companion object makes sure that the container is started once before all tests instead of restarting for every test
21-
companion object {
22-
23-
private const val port: Int = 1883
24-
25-
private val mosquittoConfig = kotlin.io.path.createTempFile(prefix = "mosquitto_", suffix = ".conf")
26-
private lateinit var broker: MqttBrokerContainer
27-
28-
private var usageCounter = 0
29-
private val lock = Any()
30-
31-
@JvmStatic
32-
@BeforeAll
33-
@Timeout(30)
34-
fun setup() {
35-
synchronized(lock) {
36-
if (usageCounter == 0) {
37-
mosquittoConfig.writeLines(
38-
listOf(
39-
"allow_anonymous true",
40-
"listener 1883"
41-
)
42-
)
43-
44-
broker = MqttBrokerContainer()
45-
.withExposedPorts(port)
46-
.withFileSystemBind(
47-
mosquittoConfig.absolute().toString(),
48-
"/mosquitto/config/mosquitto.conf",
49-
BindMode.READ_ONLY
50-
)
51-
broker.withStartupTimeout(Duration.ofSeconds(30)).start()
52-
}
53-
usageCounter++
54-
}
55-
}
56-
57-
@JvmStatic
58-
@AfterAll
59-
@Timeout(30)
60-
fun cleanup() {
61-
synchronized(lock) {
62-
usageCounter--
63-
if (usageCounter == 0) {
64-
SharedMqttClient.waitForShutdown()
65-
broker.stop()
66-
mosquittoConfig.deleteIfExists()
67-
}
68-
}
69-
}
16+
@BeforeAll
17+
@Timeout(30)
18+
fun setupMqtt() {
19+
MqttBrokerManager.setupMqtt(this::class.java.simpleName)
7020
}
7121

72-
protected val brokerHost: String get() = broker.host
22+
protected val brokerHost: String? get() = MqttBrokerManager.broker?.host
7323

74-
protected val brokerPort: Int get() = broker.firstMappedPort
75-
}
24+
protected val brokerPort: Int? get() = MqttBrokerManager.broker?.firstMappedPort
7625

77-
class MqttBrokerContainer : GenericContainer<MqttBrokerContainer>(DockerImageName.parse("eclipse-mosquitto"))
26+
protected val config
27+
get() = CommunicatorConfig(
28+
hostname = brokerHost ?: error("Host not defined!"),
29+
port = brokerPort ?: error("Port not defined!"),
30+
)
31+
}
7832

7933
fun Mqtt5Publish.clearTimestamp() = let {
8034
this.extend().userProperties(Mqtt5UserProperties.of()).build()

module/communication/mqtt/src/test/java/org/openbase/jul/communication/mqtt/IntegrationTest.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import kotlin.concurrent.withLock
2222
class IntegrationTest : AbstractIntegrationTest() {
2323

2424
private val scope = ScopeProcessor.generateScope("/test/integration")
25-
private val config = CommunicatorConfig(brokerHost, brokerPort)
2625

2726
internal class MethodMock {
2827
val lock = ReentrantLock()

module/communication/mqtt/src/test/java/org/openbase/jul/communication/mqtt/SharedMqttClientTest.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package org.openbase.jul.communication.mqtt
22

3-
import com.hivemq.client.internal.mqtt.util.MqttChecks.unsubscribe
43
import com.hivemq.client.mqtt.datatypes.MqttQos
5-
import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5Publish
64
import com.hivemq.client.mqtt.mqtt5.message.subscribe.Mqtt5Subscribe
75
import com.hivemq.client.mqtt.mqtt5.message.unsubscribe.Mqtt5Unsubscribe
86
import org.junit.jupiter.api.Test
@@ -15,7 +13,6 @@ internal class SharedMqttClientTest : AbstractIntegrationTest() {
1513
@Test
1614
@Timeout(value = 30)
1715
fun `shutdown should be work as expected`() {
18-
val config = CommunicatorConfig(brokerHost, brokerPort)
1916
val client = SharedMqttClient
2017
client.get(config).apply {
2118
disconnect()
@@ -27,7 +24,6 @@ internal class SharedMqttClientTest : AbstractIntegrationTest() {
2724
@Test
2825
@Timeout(value = 30)
2926
fun `subscription should be work as expected`() {
30-
val config = CommunicatorConfig(brokerHost, brokerPort)
3127
val topic = "/a/b/c"
3228
val client = SharedMqttClient
3329

0 commit comments

Comments
 (0)