diff --git a/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt b/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt index 84381037c..dab7a4f1b 100644 --- a/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt +++ b/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt @@ -9,6 +9,9 @@ import java.net.http.HttpRequest import java.net.http.HttpResponse import kotlin.io.path.createTempDirectory import kotlin.test.assertEquals +import com.sun.jna.Pointer +import kotlin.test.DefaultAsserter.assertTrue +import kotlin.test.assertTrue fun runCommandAndWait(vararg cmd: String): String { println("Running command \"${cmd.joinToString(" ")}\"") @@ -92,6 +95,59 @@ fun waitForBlock(esploraEndpoint: String, blockHash: String) { } } +class CustomLogWriter(private var currentLogLevel: LogLevel = LogLevel.INFO) : + LogWriter(Pointer.NULL) { + enum class LogLevel { + ERROR, WARN, INFO, DEBUG, TRACE, GOSSIP + } + + private val logMessages = mutableListOf() + + fun setLogLevel(level: LogLevel) { + currentLogLevel = level + } + + fun getLogMessages(): List { + return logMessages.toList() + } + + override fun log(record: LogRecord) { + val recordLevel = + when (record.level.toString().lowercase()) { + "error" -> LogLevel.ERROR + "warn" -> LogLevel.WARN + "info" -> LogLevel.INFO + "debug" -> LogLevel.DEBUG + "trace" -> LogLevel.TRACE + "gossip" -> LogLevel.GOSSIP + else -> LogLevel.INFO + } + + if (isLevelEnabled(recordLevel)) { + val logMessage = formatRecord(record) + logMessages.add(logMessage) + } + } + + private fun formatRecord(record: LogRecord): String { + val timestamp = + java.time.LocalDateTime.now() + .format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + return String.format( + "%s %-5s [%s:%d] %s\n", + timestamp, + record.level, + record.modulePath, + record.line, + record.args + ) + } + + private fun isLevelEnabled(level: LogLevel): Boolean { + return level.ordinal <= currentLogLevel.ordinal + } +} + @TestInstance(TestInstance.Lifecycle.PER_CLASS) class LibraryTest { @@ -106,6 +162,9 @@ class LibraryTest { } @Test fun fullCycle() { + val logWriter1 = CustomLogWriter(CustomLogWriter.LogLevel.GOSSIP) + val logWriter2 = CustomLogWriter(CustomLogWriter.LogLevel.GOSSIP) + val tmpDir1 = createTempDirectory("ldk_node").toString() println("Random dir 1: $tmpDir1") val tmpDir2 = createTempDirectory("ldk_node").toString() @@ -129,8 +188,11 @@ class LibraryTest { val builder1 = Builder.fromConfig(config1) builder1.setChainSourceEsplora(esploraEndpoint, null) + builder1.setCustomLogger(logWriter1) + val builder2 = Builder.fromConfig(config2) builder2.setChainSourceEsplora(esploraEndpoint, null) + builder2.setCustomLogger(logWriter2) val node1 = builder1.build() val node2 = builder2.build() @@ -262,6 +324,9 @@ class LibraryTest { assert(spendableBalance1AfterClose < 100000u) assertEquals(102500uL, spendableBalance2AfterClose) + assertTrue(logWriter1.getLogMessages().isNotEmpty()) + assertTrue(logWriter2.getLogMessages().isNotEmpty()) + node1.stop() node2.stop() }