mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
test(debug): Stop leaked recorders in the recorder-module test harness
The realtime harness cancelled its module scope but never stopped the recorder, and cancelling a scope does not uninstall a running recorder's globally installed FileLogger. A test that started a recording therefore left one writing into every test that followed, and an assertion failing before the explicit stop did the same. The harness now stops the module in a nested finally and fails its own test if a file logger survived, removing the straggler afterwards so a single leak cannot cascade. The tracked-recording test gets the same finally treatment.
This commit is contained in:
+28
-8
@@ -39,6 +39,7 @@ import org.robolectric.annotation.Config
|
||||
import testhelpers.BaseTest
|
||||
import testhelpers.TestApplication
|
||||
import testhelpers.coroutine.TestDispatcherProvider
|
||||
import java.io.File
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
@@ -95,12 +96,25 @@ class RecorderModuleDiagnosticsTest : BaseTest() {
|
||||
block: suspend (RecorderModule) -> Unit,
|
||||
) {
|
||||
val moduleScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
val fileLoggersBefore = Logging.loggers.filterIsInstance<FileLogger>()
|
||||
var module: RecorderModule? = null
|
||||
try {
|
||||
val module = buildModule(moduleScope, upgradeDiagnostics, TestDispatcherProvider(Dispatchers.IO))
|
||||
module.headerReadTimeoutMs = headerTimeoutMs
|
||||
runBlocking { block(module) }
|
||||
try {
|
||||
module = buildModule(moduleScope, upgradeDiagnostics, TestDispatcherProvider(Dispatchers.IO))
|
||||
.apply { headerReadTimeoutMs = headerTimeoutMs }
|
||||
runBlocking { block(module) }
|
||||
} finally {
|
||||
// Stop before cancelling: scope cancellation does NOT uninstall a running
|
||||
// recorder's global FileLogger.
|
||||
module?.let { runBlocking { it.stopRecorder() } }
|
||||
}
|
||||
} finally {
|
||||
moduleScope.cancel()
|
||||
// A leaked logger must fail THIS test, not poison later ones. Remove stragglers after
|
||||
// asserting so one failure can't cascade.
|
||||
val leaked = Logging.loggers.filterIsInstance<FileLogger>() - fileLoggersBefore.toSet()
|
||||
leaked.forEach { Logging.remove(it) }
|
||||
leaked shouldBe emptyList<FileLogger>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,11 +125,17 @@ class RecorderModuleDiagnosticsTest : BaseTest() {
|
||||
|
||||
val module = buildModule(backgroundScope, diagnostics)
|
||||
|
||||
val logDir = module.startRecorder()
|
||||
logDir.exists() shouldBe true
|
||||
module.state.first { it.isRecording }.currentLogDir shouldBe logDir
|
||||
|
||||
module.stopRecorder().shouldNotBeNull()
|
||||
// Stopped in a finally: an assertion failing mid-test must not leave a live recorder whose
|
||||
// globally installed FileLogger then writes into every later test.
|
||||
var stopped: File? = null
|
||||
try {
|
||||
val logDir = module.startRecorder()
|
||||
logDir.exists() shouldBe true
|
||||
module.state.first { it.isRecording }.currentLogDir shouldBe logDir
|
||||
} finally {
|
||||
stopped = module.stopRecorder()
|
||||
}
|
||||
stopped.shouldNotBeNull()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user