Skip to content

syshlted/mondonode-sdk-testing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MondoNode SDK Testing

License: MIT Maven Central

Instrumented test doubles for MondoNode plugin development.

Provides fake implementations of every SDK callback interface and the host interfaces, so you can test your plugin service logic in instrumented tests (androidTest) without a running host app.


Installation

// build.gradle.kts
dependencies {
    implementation("com.systemhalted:mondonode-sdk:<version>")
    androidTestImplementation("com.systemhalted:mondonode-sdk-testing:<version>")
}

Both artifacts share the same version number. Replace <version> with the latest release from Maven Central.


Two testing layers

Layer 1 — Pure JVM unit tests (recommended for business logic)

Extract your plugin's computation into a stateless Kotlin object (no Android imports). Test it directly with JUnit from src/test/ — no device required.

// MyTransformerTransforms.kt — pure Kotlin, no Android
object MyTransformerTransforms {
    fun process(input: String, params: Map<String, String>): Map<String, String> {
        val result = /* your logic */
        return mapOf("value" to result)
    }
}

// src/test/MyTransformerTransformsTest.kt
class MyTransformerTransformsTest {
    @Test fun `reverse returns reversed string`() {
        val out = MyTransformerTransforms.process("hello", emptyMap())
        assertEquals("olleh", out["value"])
    }
}

The official MondoNode transformer APKs all follow this pattern (see mondonode-transformer-* repositories for examples).

Layer 2 — Instrumented tests (this library)

Test your *Service class end-to-end on a device or emulator using the fakes provided here. These verify AIDL wiring, threading behaviour, and Binder lifecycle in addition to business logic.

// src/androidTest/MyTransformerServiceTest.kt
@RunWith(AndroidJUnit4::class)
class MyTransformerServiceTest {

    @get:Rule
    val serviceRule = ServiceTestRule()

    @Test
    fun `transform reverse returns reversed string`() {
        val binder = serviceRule.bindService(
            Intent(ApplicationProvider.getApplicationContext(), MyTransformerService::class.java)
        )
        val plugin = ITransformerPlugin.Stub.asInterface(binder)

        val cb = FakeTransformCallback()
        plugin.transform("""{"value":"hello"}""", """{"capability_id":"reverse"}""", cb)

        assertTrue(cb.awaitResult())
        assertTrue(cb.succeeded)
        assertEquals("olleh", JSONObject(cb.result!!).getString("value"))
    }
}

Provided fakes

Class Fakes Use for
FakeDataCallback IDataCallback Monitoring plugin metric delivery
FakeTransformCallback ITransformCallback Transformer plugin results
FakeOutputCallback IOutputCallback Output plugin write outcomes
FakeRouteCallback IRouteCallback Router plugin routing decisions
FakeStorageWriteCallback IStorageWriteCallback Storage plugin stream writes
FakeStorageQueryCallback IStorageQueryCallback Storage plugin query results
FakeStorageStreamCallback IStorageStreamCallback Storage plugin stream data
FakeManagementCallback IManagementCallback Management app event delivery
FakePluginDependencyCallback IPluginDependencyCallback Cross-plugin dependency results
FakePluginHostBridge IPluginHostBridge Injecting mock cross-plugin calls
FakeMondoNodeHost IMondoNodeHost Driving management plugin services
FakeEventCallback IEventCallback Event plugin event/error/stopped delivery
FakeEventPlugin IEventPlugin Driving host code that activates event sources

All callback fakes provide an awaitResult() / awaitEvent() / awaitEnd() helper that blocks up to a configurable timeout (default 5 s), returning false on timeout.


FakeMondoNodeHost

FakeMondoNodeHost drives ManagementServiceBase subclasses without a real host process. Configure its response properties, call myManagementBinder.onHostConnected(host), then use the fire* helpers to push events:

val host = FakeMondoNodeHost()
host.connectedPluginsJson = Json.encodeToString(listOf(myManifest))
val cb = FakeManagementCallback(expectedEvents = 1)
host.register(cb)

myManagementBinder.onHostConnected(host)
host.fireMetricReceived("com.example.plugin", metricJson)

assertTrue(cb.awaitEvent())
assertEquals(1, cb.receivedMetrics.size)

FakePluginHostBridge

Inject a FakePluginHostBridge to control cross-plugin dependency calls in monitoring plugin tests:

val bridge = FakePluginHostBridge()
bridge.setAvailable("com.example.dep")
bridge.onRequestExecute("com.example.dep") { _, cb ->
    cb.onResult("com.example.dep", """{"values":{"rtt":"12"}}""")
}
myPluginBinder.setHostBridge(bridge)

License

MIT License — Copyright (c) 2025 SystemHalted

About

Instrumented test doubles for MondoNode plugin development.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors