Skip to content

Commit 2d8c601

Browse files
committed
chore: add E2E test for Transcribe Streaming idle streams
1 parent f8a8e5d commit 2d8c601

File tree

1 file changed

+39
-17
lines changed

1 file changed

+39
-17
lines changed

services/transcribestreaming/e2eTest/src/TranscribeStreamingIntegrationTest.kt

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,51 @@ package aws.sdk.kotlin.e2etest
77
import aws.sdk.kotlin.services.transcribestreaming.TranscribeStreamingClient
88
import aws.sdk.kotlin.services.transcribestreaming.model.*
99
import kotlinx.coroutines.Dispatchers
10+
import kotlinx.coroutines.delay
1011
import kotlinx.coroutines.flow.Flow
1112
import kotlinx.coroutines.flow.flow
1213
import kotlinx.coroutines.flow.flowOn
1314
import kotlinx.coroutines.runBlocking
1415
import org.junit.jupiter.api.Test
1516
import org.junit.jupiter.api.TestInstance
17+
import org.junit.jupiter.api.assertThrows
1618
import java.io.File
1719
import java.nio.file.Paths
1820
import javax.sound.sampled.AudioSystem
1921
import kotlin.test.assertTrue
22+
import kotlin.time.Duration
23+
import kotlin.time.Duration.Companion.seconds
2024

2125
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
2226
class TranscribeStreamingIntegrationTest {
27+
private fun resource(path: String): File {
28+
val url = this::class.java.classLoader.getResource(path) ?: error("failed to load test resource $path")
29+
return Paths.get(url.toURI()).toFile()
30+
}
2331

2432
@Test
2533
fun testTranscribeEventStream(): Unit = runBlocking {
26-
val url = this::class.java.classLoader.getResource("hello-kotlin-8000.wav") ?: error("failed to load test resource")
27-
val audioFile = Paths.get(url.toURI()).toFile()
28-
34+
val file = resource("hello-kotlin-8000.wav")
35+
val audioStream = audioStreamFromFile(file)
2936
TranscribeStreamingClient { region = "us-west-2" }.use { client ->
30-
val transcript = getTranscript(client, audioFile)
37+
val transcript = getTranscript(client, audioStream)
3138
assertTrue(transcript.startsWith("Hello from", true), "full transcript: $transcript")
3239
}
3340
}
41+
42+
@Test
43+
fun testTranscribeEventStreamWithLongPause(): Unit = runBlocking {
44+
val file = resource("hello-kotlin-8000.wav")
45+
val audioStream = audioStreamFromFile(file, 20.seconds) // ~15 seconds should cause service to terminate stream
46+
TranscribeStreamingClient { region = "us-west-2" }.use { client ->
47+
assertThrows<BadRequestException> { getTranscript(client, audioStream) }
48+
}
49+
}
3450
}
3551

3652
private const val FRAMES_PER_CHUNK = 4096
3753

38-
private fun audioStreamFromFile(file: File): Flow<AudioStream> {
54+
private fun audioStreamFromFile(file: File, finalDelay: Duration? = null): Flow<AudioStream> {
3955
val format = AudioSystem.getAudioFileFormat(file)
4056
val ais = AudioSystem.getAudioInputStream(file)
4157
val bytesPerFrame = ais.format.frameSize
@@ -46,6 +62,10 @@ private fun audioStreamFromFile(file: File): Flow<AudioStream> {
4662
val frameBuffer = ByteArray(FRAMES_PER_CHUNK * bytesPerFrame)
4763
val rc = ais.read(frameBuffer)
4864
if (rc <= 0) {
65+
finalDelay?.let {
66+
println("Artificially delaying for $finalDelay")
67+
delay(it)
68+
}
4969
break
5070
}
5171

@@ -62,30 +82,32 @@ private fun audioStreamFromFile(file: File): Flow<AudioStream> {
6282
}.flowOn(Dispatchers.IO)
6383
}
6484

65-
private suspend fun getTranscript(client: TranscribeStreamingClient, audioFile: File): String {
85+
private suspend fun getTranscript(client: TranscribeStreamingClient, audioStream: Flow<AudioStream>): String {
6686
val req = StartStreamTranscriptionRequest {
6787
languageCode = LanguageCode.EnUs
6888
mediaSampleRateHertz = 8000
6989
mediaEncoding = MediaEncoding.Pcm
70-
audioStream = audioStreamFromFile(audioFile)
90+
this.audioStream = audioStream
7191
}
7292

7393
val transcript = client.startStreamTranscription(req) { resp ->
7494
val fullMessage = StringBuilder()
75-
resp.transcriptResultStream?.collect { event ->
76-
when (event) {
77-
is TranscriptResultStream.TranscriptEvent -> {
78-
event.value.transcript?.results?.forEach { result ->
79-
val transcript = result.alternatives?.firstOrNull()?.transcript
80-
println("received TranscriptEvent: isPartial=${result.isPartial}; transcript=$transcript")
81-
if (!result.isPartial) {
82-
transcript?.let { fullMessage.append(it) }
95+
resp
96+
.transcriptResultStream
97+
?.collect { event ->
98+
when (event) {
99+
is TranscriptResultStream.TranscriptEvent -> {
100+
event.value.transcript?.results?.forEach { result ->
101+
val transcript = result.alternatives?.firstOrNull()?.transcript
102+
println("received TranscriptEvent: isPartial=${result.isPartial}; transcript=$transcript")
103+
if (!result.isPartial) {
104+
transcript?.let { fullMessage.append(it) }
105+
}
83106
}
84107
}
108+
else -> error("unknown event $event")
85109
}
86-
else -> error("unknown event $event")
87110
}
88-
}
89111
fullMessage.toString()
90112
}
91113

0 commit comments

Comments
 (0)