From: David ‘Bombe’ Roden Date: Sun, 27 Oct 2019 20:36:10 +0000 (+0100) Subject: ♻️ Extract interface for plugin connector X-Git-Tag: v81^2~101 X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=8788d5ab31bba7dd145c25b979f99a8bc640c37e;p=Sone.git ♻️ Extract interface for plugin connector --- diff --git a/src/main/kotlin/net/pterodactylus/sone/freenet/plugin/PluginConnector.kt b/src/main/kotlin/net/pterodactylus/sone/freenet/plugin/PluginConnector.kt index fa7c651..c55859b 100644 --- a/src/main/kotlin/net/pterodactylus/sone/freenet/plugin/PluginConnector.kt +++ b/src/main/kotlin/net/pterodactylus/sone/freenet/plugin/PluginConnector.kt @@ -28,15 +28,30 @@ import net.pterodactylus.sone.freenet.plugin.event.* * Interface for talking to other plugins. Other plugins are identified by their * name and a unique connection identifier. */ -@Singleton -class PluginConnector @Inject constructor( +interface PluginConnector { + + /** + * Sends a message to another plugin running in the same node. + * + * @param pluginName The fully qualified name of the plugin + * @param identifier The unique identifier of the request + * @param fields The message being sent + * @param data Optional data + */ + @Throws(PluginException::class) + fun sendRequest(pluginName: String, identifier: String, fields: SimpleFieldSet, data: Bucket? = null): Unit + +} + +/** + * Fred-based [PluginConnector] implementation. + */ +class FredPluginConnector @Inject constructor( private val eventBus: EventBus, private val pluginRespiratorFacade: PluginRespiratorFacade -) : FredPluginTalker { +) : PluginConnector, FredPluginTalker { - @Throws(PluginException::class) - @JvmOverloads - fun sendRequest(pluginName: String, identifier: String, fields: SimpleFieldSet, data: Bucket? = null) = + override fun sendRequest(pluginName: String, identifier: String, fields: SimpleFieldSet, data: Bucket?) = getPluginTalker(pluginName, identifier).send(fields, data) private fun getPluginTalker(pluginName: String, identifier: String) = diff --git a/src/main/kotlin/net/pterodactylus/sone/main/FreenetModule.kt b/src/main/kotlin/net/pterodactylus/sone/main/FreenetModule.kt index fe3b3af..1438c2a 100644 --- a/src/main/kotlin/net/pterodactylus/sone/main/FreenetModule.kt +++ b/src/main/kotlin/net/pterodactylus/sone/main/FreenetModule.kt @@ -16,6 +16,7 @@ class FreenetModule(private val pluginRespirator: PluginRespirator) : Module { override fun configure(binder: Binder): Unit = binder.run { bind(PluginRespiratorFacade::class.java).toProvider(Provider { FredPluginRespiratorFacade(pluginRespirator) }).`in`(Singleton::class.java) + bind(PluginConnector::class.java).to(FredPluginConnector::class.java).`in`(Singleton::class.java) bind(Node::class.java).toProvider(Provider { pluginRespirator.node }) bind(HighLevelSimpleClient::class.java).toProvider(Provider { pluginRespirator.hlSimpleClient!! }) bind(ToadletContainer::class.java).toProvider(Provider { pluginRespirator.toadletContainer }) diff --git a/src/test/kotlin/net/pterodactylus/sone/freenet/plugin/FredPluginConnectorTest.kt b/src/test/kotlin/net/pterodactylus/sone/freenet/plugin/FredPluginConnectorTest.kt new file mode 100644 index 0000000..7c1775b --- /dev/null +++ b/src/test/kotlin/net/pterodactylus/sone/freenet/plugin/FredPluginConnectorTest.kt @@ -0,0 +1,112 @@ +/* EventBus and Subscribe are marked @Beta, ignore that. And Fred stuff is + * often marked as deprecated even though there is no replacement. */ +@file:Suppress("UnstableApiUsage", "DEPRECATION") + +package net.pterodactylus.sone.freenet.plugin + +import com.google.common.eventbus.* +import freenet.pluginmanager.* +import freenet.support.* +import freenet.support.api.* +import freenet.support.io.* +import net.pterodactylus.sone.freenet.* +import net.pterodactylus.sone.freenet.plugin.event.* +import org.hamcrest.MatcherAssert.* +import org.hamcrest.Matchers.* +import org.junit.* +import org.junit.rules.* + +/** + * Unit test for [PluginConnector]. + */ +class PluginConnectorTest { + + @Rule + @JvmField + val expectedException = ExpectedException.none()!! + + private val eventBus = EventBus() + private val pluginRespirator = object : PluginRespiratorFacade { + val call1Parameters = mutableListOf() + val call2Parameters = mutableListOf() + override fun getPluginTalker(pluginTalker: FredPluginTalker, pluginName: String, identifier: String) = + if ("wrong" in pluginName) { + throw PluginNotFoundException() + } else { + object : PluginTalkerFacade { + override fun send(pluginParameters: SimpleFieldSet, data: Bucket?) = Unit + .also { call2Parameters += Call2Parameters(pluginParameters, data) } + }.also { call1Parameters += Call1Parameters(pluginTalker, pluginName, identifier) } + } + } + private val pluginConnector = FredPluginConnector(eventBus, pluginRespirator) + + @Test + fun `sending request calls correct method on plugin respirator`() { + pluginConnector.sendRequest("test.plugin", "test-request-1", fields) + assertThat(pluginRespirator.call1Parameters, hasSize(1)) + assertThat(pluginRespirator.call1Parameters[0].pluginTalker, sameInstance(pluginConnector)) + assertThat(pluginRespirator.call1Parameters[0].pluginName, equalTo("test.plugin")) + assertThat(pluginRespirator.call1Parameters[0].identifier, equalTo("test-request-1")) + } + + @Test + fun `sending request with bucket calls correct method on plugin respirator`() { + pluginConnector.sendRequest("test.plugin", "test-request-1", fields, data) + assertThat(pluginRespirator.call1Parameters, hasSize(1)) + assertThat(pluginRespirator.call1Parameters[0].pluginTalker, sameInstance(pluginConnector)) + assertThat(pluginRespirator.call1Parameters[0].pluginName, equalTo("test.plugin")) + assertThat(pluginRespirator.call1Parameters[0].identifier, equalTo("test-request-1")) + } + + @Test + fun `sending request to incorrect plugin translates exception correctly`() { + expectedException.expect(PluginException::class.java) + pluginConnector.sendRequest("wrong.plugin", "test-request-1", fields) + } + + @Test + fun `sending request with bucket to incorrect plugin translates exception correctly`() { + expectedException.expect(PluginException::class.java) + pluginConnector.sendRequest("wrong.plugin", "test-request-1", fields, data) + } + + @Test + fun `sending request calls correct method on plugin talker`() { + pluginConnector.sendRequest("test.plugin", "test-request-1", fields) + assertThat(pluginRespirator.call2Parameters, hasSize(1)) + assertThat(pluginRespirator.call2Parameters[0].pluginParameters, equalTo(fields)) + assertThat(pluginRespirator.call2Parameters[0].data, nullValue()) + } + + @Test + fun `sending request with bucket calls correct method on plugin talker`() { + pluginConnector.sendRequest("test.plugin", "test-request-1", fields, data) + assertThat(pluginRespirator.call2Parameters, hasSize(1)) + assertThat(pluginRespirator.call2Parameters[0].pluginParameters, equalTo(fields)) + assertThat(pluginRespirator.call2Parameters[0].data, equalTo(data)) + } + + @Test + fun `reply is sent to event bus correctly`() { + val listener = object { + val receivedReplyEvents = mutableListOf() + @Subscribe + fun onReply(receivedReplyEvent: ReceivedReplyEvent) = Unit.also { receivedReplyEvents += receivedReplyEvent } + } + eventBus.register(listener) + pluginConnector.onReply("test.plugin", "test-request-1", fields, data) + assertThat(listener.receivedReplyEvents, hasSize(1)) + assertThat(listener.receivedReplyEvents[0].pluginName(), equalTo("test.plugin")) + assertThat(listener.receivedReplyEvents[0].identifier(), equalTo("test-request-1")) + assertThat(listener.receivedReplyEvents[0].fieldSet(), equalTo(fields)) + assertThat(listener.receivedReplyEvents[0].data(), equalTo(data)) + } + +} + +private val fields = SimpleFieldSetBuilder().put("foo", "bar").get() +private val data = ArrayBucket(byteArrayOf(1, 2)) + +private data class Call1Parameters(val pluginTalker: FredPluginTalker, val pluginName: String, val identifier: String) +private data class Call2Parameters(val pluginParameters: SimpleFieldSet, val data: Bucket?) diff --git a/src/test/kotlin/net/pterodactylus/sone/freenet/plugin/PluginConnectorTest.kt b/src/test/kotlin/net/pterodactylus/sone/freenet/plugin/PluginConnectorTest.kt deleted file mode 100644 index a7c940d..0000000 --- a/src/test/kotlin/net/pterodactylus/sone/freenet/plugin/PluginConnectorTest.kt +++ /dev/null @@ -1,112 +0,0 @@ -/* EventBus and Subscribe are marked @Beta, ignore that. And Fred stuff is - * often marked as deprecated even though there is no replacement. */ -@file:Suppress("UnstableApiUsage", "DEPRECATION") - -package net.pterodactylus.sone.freenet.plugin - -import com.google.common.eventbus.* -import freenet.pluginmanager.* -import freenet.support.* -import freenet.support.api.* -import freenet.support.io.* -import net.pterodactylus.sone.freenet.* -import net.pterodactylus.sone.freenet.plugin.event.* -import org.hamcrest.MatcherAssert.* -import org.hamcrest.Matchers.* -import org.junit.* -import org.junit.rules.* - -/** - * Unit test for [PluginConnector]. - */ -class PluginConnectorTest { - - @Rule - @JvmField - val expectedException = ExpectedException.none()!! - - private val eventBus = EventBus() - private val pluginRespirator = object : PluginRespiratorFacade { - val call1Parameters = mutableListOf() - val call2Parameters = mutableListOf() - override fun getPluginTalker(pluginTalker: FredPluginTalker, pluginName: String, identifier: String) = - if ("wrong" in pluginName) { - throw PluginNotFoundException() - } else { - object : PluginTalkerFacade { - override fun send(pluginParameters: SimpleFieldSet, data: Bucket?) = Unit - .also { call2Parameters += Call2Parameters(pluginParameters, data) } - }.also { call1Parameters += Call1Parameters(pluginTalker, pluginName, identifier) } - } - } - private val pluginConnector = PluginConnector(eventBus, pluginRespirator) - - @Test - fun `sending request calls correct method on plugin respirator`() { - pluginConnector.sendRequest("test.plugin", "test-request-1", fields) - assertThat(pluginRespirator.call1Parameters, hasSize(1)) - assertThat(pluginRespirator.call1Parameters[0].pluginTalker, sameInstance(pluginConnector)) - assertThat(pluginRespirator.call1Parameters[0].pluginName, equalTo("test.plugin")) - assertThat(pluginRespirator.call1Parameters[0].identifier, equalTo("test-request-1")) - } - - @Test - fun `sending request with bucket calls correct method on plugin respirator`() { - pluginConnector.sendRequest("test.plugin", "test-request-1", fields, data) - assertThat(pluginRespirator.call1Parameters, hasSize(1)) - assertThat(pluginRespirator.call1Parameters[0].pluginTalker, sameInstance(pluginConnector)) - assertThat(pluginRespirator.call1Parameters[0].pluginName, equalTo("test.plugin")) - assertThat(pluginRespirator.call1Parameters[0].identifier, equalTo("test-request-1")) - } - - @Test - fun `sending request to incorrect plugin translates exception correctly`() { - expectedException.expect(PluginException::class.java) - pluginConnector.sendRequest("wrong.plugin", "test-request-1", fields) - } - - @Test - fun `sending request with bucket to incorrect plugin translates exception correctly`() { - expectedException.expect(PluginException::class.java) - pluginConnector.sendRequest("wrong.plugin", "test-request-1", fields, data) - } - - @Test - fun `sending request calls correct method on plugin talker`() { - pluginConnector.sendRequest("test.plugin", "test-request-1", fields) - assertThat(pluginRespirator.call2Parameters, hasSize(1)) - assertThat(pluginRespirator.call2Parameters[0].pluginParameters, equalTo(fields)) - assertThat(pluginRespirator.call2Parameters[0].data, nullValue()) - } - - @Test - fun `sending request with bucket calls correct method on plugin talker`() { - pluginConnector.sendRequest("test.plugin", "test-request-1", fields, data) - assertThat(pluginRespirator.call2Parameters, hasSize(1)) - assertThat(pluginRespirator.call2Parameters[0].pluginParameters, equalTo(fields)) - assertThat(pluginRespirator.call2Parameters[0].data, equalTo(data)) - } - - @Test - fun `reply is sent to event bus correctly`() { - val listener = object { - val receivedReplyEvents = mutableListOf() - @Subscribe - fun onReply(receivedReplyEvent: ReceivedReplyEvent) = Unit.also { receivedReplyEvents += receivedReplyEvent } - } - eventBus.register(listener) - pluginConnector.onReply("test.plugin", "test-request-1", fields, data) - assertThat(listener.receivedReplyEvents, hasSize(1)) - assertThat(listener.receivedReplyEvents[0].pluginName(), equalTo("test.plugin")) - assertThat(listener.receivedReplyEvents[0].identifier(), equalTo("test-request-1")) - assertThat(listener.receivedReplyEvents[0].fieldSet(), equalTo(fields)) - assertThat(listener.receivedReplyEvents[0].data(), equalTo(data)) - } - -} - -private val fields = SimpleFieldSetBuilder().put("foo", "bar").get() -private val data = ArrayBucket(byteArrayOf(1, 2)) - -private data class Call1Parameters(val pluginTalker: FredPluginTalker, val pluginName: String, val identifier: String) -private data class Call2Parameters(val pluginParameters: SimpleFieldSet, val data: Bucket?) diff --git a/src/test/kotlin/net/pterodactylus/sone/main/FreenetModuleTest.kt b/src/test/kotlin/net/pterodactylus/sone/main/FreenetModuleTest.kt index 32d2ca4..d3a2a3c 100644 --- a/src/test/kotlin/net/pterodactylus/sone/main/FreenetModuleTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/main/FreenetModuleTest.kt @@ -109,4 +109,14 @@ class FreenetModuleTest { verifySingletonInstance() } + @Test + fun `plugin connector is returned correctly`() { + assertThat(injector.getInstance(), notNullValue()) + } + + @Test + fun `plugin connector facade is returned as singleton`() { + verifySingletonInstance() + } + } diff --git a/src/test/kotlin/net/pterodactylus/sone/main/SoneModuleTest.kt b/src/test/kotlin/net/pterodactylus/sone/main/SoneModuleTest.kt index 123269c..7b5b4af 100644 --- a/src/test/kotlin/net/pterodactylus/sone/main/SoneModuleTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/main/SoneModuleTest.kt @@ -42,7 +42,8 @@ class SoneModuleTest { createInjector( SoneModule(sonePlugin, EventBus()), FreenetInterface::class.isProvidedByDeepMock(), - PluginRespiratorFacade::class.isProvidedByDeepMock() + PluginRespiratorFacade::class.isProvidedByDeepMock(), + PluginConnector::class.isProvidedByDeepMock() ) } @@ -199,7 +200,8 @@ class SoneModuleTest { val injector = createInjector( SoneModule(sonePlugin, eventBus), FreenetInterface::class.isProvidedByDeepMock(), - PluginRespiratorFacade::class.isProvidedByDeepMock() + PluginRespiratorFacade::class.isProvidedByDeepMock(), + PluginConnector::class.isProvidedByDeepMock() ) val core = injector.getInstance() verify(eventBus).register(core)