Skip to content

Commit 8b6d5ab

Browse files
committed
Extract common code for server
1 parent 4ab1e4a commit 8b6d5ab

3 files changed

Lines changed: 143 additions & 66 deletions

File tree

jacodb-ets/src/test/kotlin/org/jacodb/ets/test/GrpcTest.kt

Lines changed: 8 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import mu.KotlinLogging
2020
import org.jacodb.ets.grpc.loadScene
2121
import org.jacodb.ets.model.EtsScene
2222
import org.jacodb.ets.proto.toEts
23+
import org.jacodb.ets.test.utils.TestServer
2324
import org.jacodb.ets.test.utils.assumeNotNull
25+
import org.jacodb.ets.test.utils.startArkAnalyzerGrpcServer
2426
import org.jacodb.ets.test.utils.testFactory
2527
import org.jacodb.ets.utils.getResourcePath
2628
import org.jacodb.ets.utils.getResourcePathOrNull
@@ -44,86 +46,27 @@ private val logger = KotlinLogging.logger {}
4446

4547
class GrpcTest {
4648
companion object {
47-
const val PORT = 50000
49+
private const val PORT = 50101
4850

49-
lateinit var serverProcess: Process
50-
lateinit var serverOutputThread: Thread
51-
lateinit var serverErrorThread: Thread
51+
private lateinit var server: TestServer
5252

5353
@BeforeAll
5454
@JvmStatic
5555
fun beforeAll() {
5656
logger.info { "Setting up test environment..." }
5757

58-
logger.info { "Starting gRPC server on port $PORT..." }
59-
serverProcess = ProcessBuilder("node", "out/src/rpc/grpc-server.js")
60-
.directory(File("arkanalyzer"))
61-
.also {
62-
val env = it.environment()
63-
env["ARKANALYZER_PORT"] = PORT.toString()
64-
}
65-
.start()
66-
67-
// Capture process output (stdout)
68-
val stdout = StringBuilder()
69-
serverOutputThread = thread {
70-
serverProcess.inputStream.bufferedReader().useLines { lines ->
71-
lines.forEach {
72-
logger.info { "[STDOUT] $it" }
73-
stdout.appendLine(it)
74-
}
75-
}
76-
}
77-
78-
// Capture process error output (stderr)
79-
val stderr = StringBuilder()
80-
serverErrorThread = thread {
81-
serverProcess.errorStream.bufferedReader().useLines { lines ->
82-
lines.forEach {
83-
logger.info { "[STDERR] $it" }
84-
stderr.appendLine(it)
85-
}
86-
}
87-
}
88-
89-
// Wait for the server to start
90-
waitForServerToStart()
58+
server = startArkAnalyzerGrpcServer(PORT)
9159

9260
logger.info { "Done setting up test environment" }
9361
}
9462

95-
private fun waitForServerToStart() {
96-
logger.info { "Waiting for gRPC server to start on port $PORT..." }
97-
val maxRetries = 100
98-
val retryDelay = 100L // in milliseconds
99-
repeat(maxRetries) {
100-
try {
101-
Socket("localhost", PORT).use { socket ->
102-
if (socket.isConnected) {
103-
logger.info { "ArkAnalyzer server is ready on port $PORT" }
104-
return@waitForServerToStart
105-
}
106-
}
107-
} catch (_: IOException) {
108-
// Server not ready yet, retry
109-
}
110-
Thread.sleep(retryDelay)
111-
}
112-
throw RuntimeException("ArkAnalyzer gRPC server did not start")
113-
}
114-
11563
@AfterAll
11664
@JvmStatic
11765
fun afterAll() {
11866
logger.info { "Shutting down test environment..." }
119-
serverProcess.destroy()
120-
try {
121-
serverProcess.waitFor()
122-
} catch (e: InterruptedException) {
123-
logger.error(e) { "Error while waiting for server process to finish" }
124-
}
125-
serverOutputThread.join()
126-
serverErrorThread.join()
67+
68+
server.stop()
69+
12770
logger.info { "Test environment shut down" }
12871
}
12972

jacodb-ets/src/test/kotlin/org/jacodb/ets/test/GrpcTest2.kt

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ import mu.KotlinLogging
2020
import org.jacodb.ets.grpc.loadScene2
2121
import org.jacodb.ets.model.EtsScene
2222
import org.jacodb.ets.proto2.toEts
23+
import org.jacodb.ets.test.utils.TestServer
2324
import org.jacodb.ets.test.utils.assumeNotNull
25+
import org.jacodb.ets.test.utils.startArkAnalyzerGrpcServer
2426
import org.jacodb.ets.test.utils.testFactory
2527
import org.jacodb.ets.utils.getResourcePath
2628
import org.jacodb.ets.utils.getResourcePathOrNull
29+
import org.junit.jupiter.api.AfterAll
30+
import org.junit.jupiter.api.BeforeAll
2731
import org.junit.jupiter.api.TestFactory
2832
import java.nio.file.Path
2933
import kotlin.io.path.isDirectory
@@ -38,8 +42,32 @@ private val logger = KotlinLogging.logger {}
3842

3943
class GrpcTest2 {
4044
companion object {
45+
private const val PORT = 50102
46+
47+
private lateinit var server: TestServer
48+
49+
@BeforeAll
50+
@JvmStatic
51+
fun beforeAll() {
52+
logger.info { "Setting up test environment..." }
53+
54+
server = startArkAnalyzerGrpcServer(PORT)
55+
56+
logger.info { "Done setting up test environment" }
57+
}
58+
59+
@AfterAll
60+
@JvmStatic
61+
fun afterAll() {
62+
logger.info { "Shutting down test environment..." }
63+
64+
server.stop()
65+
66+
logger.info { "Test environment shut down" }
67+
}
68+
4169
fun getScene(path: Path): EtsScene {
42-
val scene = loadScene2(path)
70+
val scene = loadScene2(path, PORT)
4371
logger.info { "Converting Scene from ProtoBuf to ETS..." }
4472
val (etsScene, timeConvert) = measureTimedValue {
4573
scene.toEts()
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright 2022 UnitTestBot contributors (utbot.org)
3+
* <p>
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+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
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+
17+
package org.jacodb.ets.test.utils
18+
19+
import mu.KotlinLogging
20+
import java.io.File
21+
import java.io.IOException
22+
import java.net.Socket
23+
import kotlin.concurrent.thread
24+
25+
private val logger = KotlinLogging.logger {}
26+
27+
class TestServer(
28+
val process: Process,
29+
val outputThread: Thread,
30+
val errorThread: Thread,
31+
) {
32+
fun stop() {
33+
process.destroy()
34+
try {
35+
process.waitFor()
36+
} catch (e: InterruptedException) {
37+
logger.error(e) { "Error while waiting for server process to finish" }
38+
}
39+
outputThread.join()
40+
errorThread.join()
41+
}
42+
}
43+
44+
private const val SERVER_SCRIPT = "out/src/rpc/grpc-server.js"
45+
46+
fun startArkAnalyzerGrpcServer(
47+
port: Int,
48+
script: String = SERVER_SCRIPT,
49+
): TestServer {
50+
logger.info { "Starting gRPC server on port $port..." }
51+
val process = ProcessBuilder("node", script)
52+
.directory(File("arkanalyzer"))
53+
.also {
54+
val env = it.environment()
55+
env["ARKANALYZER_PORT"] = port.toString()
56+
}
57+
.start()
58+
59+
// Capture process output (stdout)
60+
val stdout = StringBuilder()
61+
val outputThread = thread {
62+
process.inputStream.bufferedReader().useLines { lines ->
63+
lines.forEach {
64+
logger.info { "[STDOUT] $it" }
65+
stdout.appendLine(it)
66+
}
67+
}
68+
}
69+
70+
// Capture process error output (stderr)
71+
val stderr = StringBuilder()
72+
val errorThread = thread {
73+
process.errorStream.bufferedReader().useLines { lines ->
74+
lines.forEach {
75+
logger.info { "[STDERR] $it" }
76+
stderr.appendLine(it)
77+
}
78+
}
79+
}
80+
81+
// Wait for the server to start
82+
waitForServerToStart(port)
83+
84+
return TestServer(process, outputThread, errorThread)
85+
}
86+
87+
private fun waitForServerToStart(port: Int) {
88+
logger.info { "Waiting for server to start on port $port..." }
89+
val maxRetries = 100
90+
val retryDelay = 100L // in milliseconds
91+
repeat(maxRetries) {
92+
try {
93+
Socket("localhost", port).use { socket ->
94+
if (socket.isConnected) {
95+
logger.info { "ArkAnalyzer server is ready on port $port" }
96+
return@waitForServerToStart
97+
}
98+
}
99+
} catch (_: IOException) {
100+
// Server not ready yet, retry
101+
}
102+
Thread.sleep(retryDelay)
103+
}
104+
val time = maxRetries * retryDelay / 1000
105+
throw RuntimeException("ArkAnalyzer server did not start after $time s")
106+
}

0 commit comments

Comments
 (0)