Skip to content

Commit dc7fd1a

Browse files
Corbin Smithcgruber
Corbin Smith
authored andcommitted
small cleanups:
* check worker status before each test case * use yield instead of delay to improve determinism.
1 parent 3f4698a commit dc7fd1a

File tree

1 file changed

+28
-31
lines changed

1 file changed

+28
-31
lines changed

src/test/kotlin/io/bazel/kotlin/builder/tasks/BazelWorkerTest.kt

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package io.bazel.kotlin.builder.tasks
1919

2020
import com.google.common.truth.Truth.assertThat
21+
import com.google.common.truth.Truth.assertWithMessage
2122
import com.google.devtools.build.lib.worker.WorkerProtocol.WorkRequest
2223
import com.google.devtools.build.lib.worker.WorkerProtocol.WorkResponse
2324
import kotlinx.coroutines.CoroutineName
@@ -27,10 +28,10 @@ import kotlinx.coroutines.channels.Channel
2728
import kotlinx.coroutines.channels.sendBlocking
2829
import kotlinx.coroutines.coroutineScope
2930
import kotlinx.coroutines.debug.junit4.CoroutinesTimeout
30-
import kotlinx.coroutines.delay
3131
import kotlinx.coroutines.launch
3232
import kotlinx.coroutines.runBlocking
3333
import kotlinx.coroutines.test.runBlockingTest
34+
import kotlinx.coroutines.yield
3435
import org.junit.Rule
3536
import org.junit.Test
3637
import java.io.ByteArrayOutputStream
@@ -68,8 +69,6 @@ class BazelWorkerTest {
6869

6970
@Test
7071
fun persistentWorker() {
71-
val workerInput = WorkerChannel("in")
72-
val workerOutput = WorkerChannel("out")
7372
runBlockingTest {
7473
val program = object : CommandLineProgram {
7574
override fun apply(workingDir: Path, args: List<String>): Int {
@@ -83,23 +82,27 @@ class BazelWorkerTest {
8382
}
8483
}
8584

85+
val workerInput = WorkerChannel("in")
86+
val workerOutput = WorkerChannel("out")
8687
val execution = ByteArrayOutputStream()
8788

88-
val done = GlobalScope.async(CoroutineName("worker")) {
89+
val worker = GlobalScope.async(CoroutineName("worker")) {
8990
WorkerIO(workerInput.input,
9091
PrintStream(workerOutput.output),
91-
execution) {}.use { io ->
92-
PersistentWorker(io, program).run(listOf())
93-
}
92+
execution) {}
93+
.use { io ->
94+
PersistentWorker(io, program).run(listOf())
95+
}
9496
}
9597

96-
// asserts scope to ensure all asserts are run.
98+
// asserts scope to ensure all cases are run.
9799
// messy, can be cleaned up -- since kotlin channels love to block and can easily starve a
98100
// dispatcher, it's necessary to read each channel in a different coroutine.
99101
// The coroutineScope prevents the assertions from happening outside of the expected
100102
// asynchronicity.
101103
coroutineScope {
102104
launch {
105+
assertWithMessage("worker is active").that(worker.isActive).isTrue()
103106
workerInput.send(request(1, "ok"))
104107
}
105108
launch {
@@ -110,6 +113,7 @@ class BazelWorkerTest {
110113

111114
coroutineScope {
112115
launch {
116+
assertWithMessage("worker is active").that(worker.isActive).isTrue()
113117
workerInput.send(request(2, "fail"))
114118
}
115119
launch {
@@ -120,6 +124,7 @@ class BazelWorkerTest {
120124

121125
coroutineScope {
122126
launch {
127+
assertWithMessage("worker is active").that(worker.isActive).isTrue()
123128
workerInput.send(request(3, "error"))
124129
}
125130
launch {
@@ -131,6 +136,7 @@ class BazelWorkerTest {
131136
// an interrupt kills the worker.
132137
coroutineScope {
133138
launch {
139+
assertWithMessage("worker is active").that(worker.isActive).isTrue()
134140
workerInput.send(request(4, "interrupt"))
135141
workerInput.close()
136142
}
@@ -140,22 +146,20 @@ class BazelWorkerTest {
140146
}
141147
}
142148

143-
144-
assertThat(done.await()).isEqualTo(0)
149+
assertThat(worker.await()).isEqualTo(0)
145150
}
146151
}
147152

148-
private fun request(id: Int, vararg args: String) = with(WorkRequest.newBuilder()) {
149-
setRequestId(id)
153+
private fun request(id: Int, vararg args: String) = WorkRequest.newBuilder().apply {
154+
requestId = id
150155
addAllArguments(args.asList())
151156
}.build()
152157

153-
private fun response(id: Int, exitCode: Int, output: String = "") =
154-
with(WorkResponse.newBuilder()) {
155-
setExitCode(exitCode)
156-
setOutput(output)
157-
setRequestId(id)
158-
}.build()
158+
private fun response(id: Int, code: Int, out: String = "") = WorkResponse.newBuilder().apply {
159+
exitCode = code
160+
output = out
161+
requestId = id
162+
}.build()
159163

160164
/** WorkerChannel encapsulates the communication between the test and the worker. */
161165
class WorkerChannel(
@@ -181,10 +185,8 @@ class BazelWorkerTest {
181185
class ChannelInputStream(val channel: Channel<Byte>, val name: String) : InputStream() {
182186
override fun read(): Int {
183187
return runBlocking(CoroutineName("$name.read()")) {
184-
// since pipes block until the next event, this simulates that without starving
185-
// other routines.
186-
while (channel.isEmpty) {
187-
delay(5L)
188+
if (channel.isEmpty) {
189+
yield()
188190
}
189191
// read blocking -- this better simulates the java InputStream behaviour.
190192
return@runBlocking channel.receive().toInt()
@@ -193,14 +195,11 @@ class BazelWorkerTest {
193195

194196
override fun read(b: ByteArray, off: Int, len: Int): Int {
195197
return runBlocking(CoroutineName("$name.read(ByteArray,Int,Int)")) {
196-
// since pipes block until the next event, this simulates that without starving
197-
// other routines.
198-
while (channel.isEmpty) {
199-
delay(5L)
198+
if (channel.isEmpty) {
199+
yield()
200200
}
201-
val end = Math.min(b.size, off + len - 1)
202201
var read = 0
203-
for (i in off..end) {
202+
for (i in off..b.size.coerceAtMost(off + len - 1)) {
204203
val rb = channel.receive()
205204
b[i] = rb
206205
read++
@@ -218,10 +217,8 @@ class BazelWorkerTest {
218217

219218
override fun write(ba: ByteArray, off: Int, len: Int) {
220219
runBlocking(CoroutineName("$name.write(ByteArray, Int, Int)")) {
221-
var sent = 0
222-
for (i in off..Math.min(ba.size, off + len - 1)) {
220+
for (i in off..ba.size.coerceAtMost(off + len - 1)) {
223221
channel.sendBlocking(ba[i])
224-
sent++
225222
}
226223
}
227224
}

0 commit comments

Comments
 (0)