From ab2395845b242c3b676cca52f663836d245455ac Mon Sep 17 00:00:00 2001 From: nathan Date: Sun, 30 Aug 2020 23:16:09 +0200 Subject: [PATCH] Moved serialization validation to it's own test (it's has nothing to do with RMI), refactored RmiTest --- ...Test.kt => SerializationValidationTest.kt} | 100 +++++------- test/dorkboxTest/network/rmi/RmiCommonTest.kt | 149 ++++++++++++++++++ .../rmi/{RmiTest.kt => RmiSimpleTest.kt} | 127 ++------------- .../network/rmi/multiJVM/TestClient.kt | 4 +- .../network/rmi/multiJVM/TestServer.kt | 4 +- 5 files changed, 199 insertions(+), 185 deletions(-) rename test/dorkboxTest/network/{rmi/RmiInitValidationTest.kt => SerializationValidationTest.kt} (95%) create mode 100644 test/dorkboxTest/network/rmi/RmiCommonTest.kt rename test/dorkboxTest/network/rmi/{RmiTest.kt => RmiSimpleTest.kt} (63%) diff --git a/test/dorkboxTest/network/rmi/RmiInitValidationTest.kt b/test/dorkboxTest/network/SerializationValidationTest.kt similarity index 95% rename from test/dorkboxTest/network/rmi/RmiInitValidationTest.kt rename to test/dorkboxTest/network/SerializationValidationTest.kt index 7e737ea6..9e3106aa 100644 --- a/test/dorkboxTest/network/rmi/RmiInitValidationTest.kt +++ b/test/dorkboxTest/network/SerializationValidationTest.kt @@ -13,34 +13,53 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package dorkboxTest.network.rmi +package dorkboxTest.network import dorkbox.network.Client -import dorkbox.network.Configuration import dorkbox.network.Server import dorkbox.network.connection.Connection import dorkbox.network.serialization.Serialization -import dorkbox.util.exceptions.SecurityException -import dorkboxTest.network.BaseTest import kotlinx.coroutines.runBlocking import org.junit.Test -import java.io.IOException -class RmiInitValidationTest : BaseTest() { +class SerializationValidationTest : BaseTest() { @Test - @Throws(SecurityException::class, IOException::class) - fun rmiNetwork() { - rmi() - } + fun checkObjects() { + run { + val configuration = serverConfig() + register(configuration.serialization) - @Test - @Throws(SecurityException::class, IOException::class) - fun rmiLocal() { -// rmi(object : Config() { -// fun apply(configuration: Configuration) { -// configuration.localChannelName = EndPoint.LOCAL_CHANNEL -// } -// }) + val server = Server(configuration) + addEndPoint(server) + + server.onMessage { connection, message -> + stopEndPoints() + } + + runBlocking { + server.bind(false) + } + } + + + run { + val configuration = clientConfig() + register(configuration.serialization) + + val client = Client(configuration) + addEndPoint(client) + + client.onConnect { connection -> + connection.send(FinishedCommand()) + } + + + runBlocking { + client.connect(LOOPBACK) + } + } + + waitForThreads() } private fun register(serialization: Serialization) { @@ -246,51 +265,6 @@ class RmiInitValidationTest : BaseTest() { serialization.register(FinishedCommand::class.java) } - /** - * In this test the server has two objects in an object space. The client - * uses the first remote object to get the second remote object. - */ - fun rmi(config: (Configuration) -> Unit = {}) { - run { - val configuration = serverConfig() - config(configuration) - register(configuration.serialization) - - val server = Server(configuration) - addEndPoint(server) - - server.onMessage { connection, message -> - stopEndPoints() - } - - runBlocking { - server.bind(false) - } - } - - - run { - val configuration = clientConfig() - config(configuration) - register(configuration.serialization) - - val client = Client(configuration) - addEndPoint(client) - - client.onConnect { connection -> - connection.send(FinishedCommand()) - } - - - runBlocking { - client.connect(LOOPBACK) - } - } - -// waitForThreads() - waitForThreads(99999999) - } - private class Command1 private class Command2 private class Command3 diff --git a/test/dorkboxTest/network/rmi/RmiCommonTest.kt b/test/dorkboxTest/network/rmi/RmiCommonTest.kt new file mode 100644 index 00000000..65372c04 --- /dev/null +++ b/test/dorkboxTest/network/rmi/RmiCommonTest.kt @@ -0,0 +1,149 @@ +/* + * Copyright 2016 dorkbox, llc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (c) 2008, Nathan Sweet + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the distribution. + * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package dorkboxTest.network.rmi + +import dorkbox.network.connection.Connection +import dorkbox.network.rmi.RemoteObject +import dorkbox.network.serialization.Serialization +import dorkboxTest.network.rmi.classes.MessageWithTestCow +import dorkboxTest.network.rmi.classes.TestCow +import org.junit.Assert + +object RmiCommonTest { + suspend fun runTests(connection: Connection, test: TestCow, remoteObjectID: Int) { + val remoteObject = test as RemoteObject + + // Default behavior. RMI is transparent, method calls behave like normal + // (return values and exceptions are returned, call is synchronous) + connection.logger.error("hashCode: " + test.hashCode()) + connection.logger.error("toString: $test") + + test.withSuspend("test", 32) + val s1 = test.withSuspendAndReturn("test", 32) + Assert.assertEquals(s1, 32) + + + // see what the "remote" toString() method is + val s = remoteObject.toString() + remoteObject.enableToString(true) + Assert.assertFalse(s == remoteObject.toString()) + test.moo() + test.moo("Cow") + Assert.assertEquals(remoteObjectID, test.id()) + + // Test that RMI correctly waits for the remotely invoked method to exit + remoteObject.responseTimeout = 5000 + test.moo("You should see this two seconds before...", 2000) + connection.logger.error("...This") + remoteObject.responseTimeout = 3000 + + // Try exception handling + try { + test.throwException() + Assert.fail("sync should be throwing an exception!") + } catch (e: UnsupportedOperationException) { + connection.logger.error("Expected exception (exception log should also be on the object impl side).", e) + } + + try { + test.throwSuspendException() + Assert.fail("sync should be throwing an exception!") + } catch (e: UnsupportedOperationException) { + connection.logger.error("\tExpected exception (exception log should also be on the object impl side).", e) + } + + // Non-blocking call tests + // Non-blocking call tests + // Non-blocking call tests + connection.logger.error("I'm currently async: ${remoteObject.async}. Now testing ASYNC") + + remoteObject.async = true + + + // calls that ignore the return value + test.moo("Meow") + // Non-blocking call that ignores the return value + Assert.assertEquals(0, test.id().toLong()) + + + // exceptions are still dealt with properly + test.moo("Baa") + + try { + test.throwException() + } catch (e: IllegalStateException) { + // exceptions are not caught when async = true! + Assert.fail("Async should not be throwing an exception!") + } + + try { + test.throwSuspendException() + } catch (e: IllegalStateException) { + // exceptions are not caught when async = true! + Assert.fail("Async should not be throwing an exception!") + } + + + + + // Call will time out if non-blocking isn't working properly + test.moo("Mooooooooo", 4000) + + + // should wait for a small time + remoteObject.async = false + remoteObject.responseTimeout = 6000 + connection.logger.error("You should see this 2 seconds before") + val slow = test.slow() + connection.logger.error("...This") + Assert.assertEquals(slow.toDouble(), 123.0, 0.0001) + + + // Test sending a reference to a remote object. + val m = MessageWithTestCow(test) + m.number = 678 + m.text = "sometext" + connection.send(m) + + connection.logger.error("Finished tests") + } + + fun register(manager: Serialization) { + manager.register(Any::class.java) // Needed for Object#toString, hashCode, etc. + manager.register(TestCow::class.java) + manager.register(MessageWithTestCow::class.java) + manager.register(UnsupportedOperationException::class.java) + } +} diff --git a/test/dorkboxTest/network/rmi/RmiTest.kt b/test/dorkboxTest/network/rmi/RmiSimpleTest.kt similarity index 63% rename from test/dorkboxTest/network/rmi/RmiTest.kt rename to test/dorkboxTest/network/rmi/RmiSimpleTest.kt index 5ddba34b..46dd861e 100644 --- a/test/dorkboxTest/network/rmi/RmiTest.kt +++ b/test/dorkboxTest/network/rmi/RmiSimpleTest.kt @@ -38,8 +38,6 @@ import dorkbox.network.Client import dorkbox.network.Configuration import dorkbox.network.Server import dorkbox.network.connection.Connection -import dorkbox.network.rmi.RemoteObject -import dorkbox.network.serialization.Serialization import dorkboxTest.network.BaseTest import dorkboxTest.network.rmi.classes.MessageWithTestCow import dorkboxTest.network.rmi.classes.TestCow @@ -48,114 +46,7 @@ import kotlinx.coroutines.runBlocking import org.junit.Assert import org.junit.Test -class RmiTest : BaseTest() { - - companion object { - suspend fun runTests(connection: Connection, test: TestCow, remoteObjectID: Int) { - val remoteObject = test as RemoteObject - - // Default behavior. RMI is transparent, method calls behave like normal - // (return values and exceptions are returned, call is synchronous) - connection.logger.error("hashCode: " + test.hashCode()) - connection.logger.error("toString: $test") - - test.withSuspend("test", 32) - val s1 = test.withSuspendAndReturn("test", 32) - Assert.assertEquals(s1, 32) - - - // see what the "remote" toString() method is - val s = remoteObject.toString() - remoteObject.enableToString(true) - Assert.assertFalse(s == remoteObject.toString()) - test.moo() - test.moo("Cow") - Assert.assertEquals(remoteObjectID, test.id()) - - // Test that RMI correctly waits for the remotely invoked method to exit - remoteObject.responseTimeout = 5000 - test.moo("You should see this two seconds before...", 2000) - connection.logger.error("...This") - remoteObject.responseTimeout = 3000 - - // Try exception handling - try { - test.throwException() - Assert.fail("sync should be throwing an exception!") - } catch (e: UnsupportedOperationException) { - connection.logger.error("Expected exception (exception log should also be on the object impl side).", e) - } - - try { - test.throwSuspendException() - Assert.fail("sync should be throwing an exception!") - } catch (e: UnsupportedOperationException) { - connection.logger.error("\tExpected exception (exception log should also be on the object impl side).", e) - } - - // Non-blocking call tests - // Non-blocking call tests - // Non-blocking call tests - connection.logger.error("I'm currently async: ${remoteObject.async}. Now testing ASYNC") - - remoteObject.async = true - - - // calls that ignore the return value - test.moo("Meow") - // Non-blocking call that ignores the return value - Assert.assertEquals(0, test.id().toLong()) - - - // exceptions are still dealt with properly - test.moo("Baa") - - try { - test.throwException() - } catch (e: IllegalStateException) { - // exceptions are not caught when async = true! - Assert.fail("Async should not be throwing an exception!") - } - - try { - test.throwSuspendException() - } catch (e: IllegalStateException) { - // exceptions are not caught when async = true! - Assert.fail("Async should not be throwing an exception!") - } - - - - - // Call will time out if non-blocking isn't working properly - test.moo("Mooooooooo", 4000) - - - // should wait for a small time - remoteObject.async = false - remoteObject.responseTimeout = 6000 - connection.logger.error("You should see this 2 seconds before") - val slow = test.slow() - connection.logger.error("...This") - Assert.assertEquals(slow.toDouble(), 123.0, 0.0001) - - - // Test sending a reference to a remote object. - val m = MessageWithTestCow(test) - m.number = 678 - m.text = "sometext" - connection.send(m) - - connection.logger.error("Finished tests") - } - - fun register(manager: Serialization) { - manager.register(Any::class.java) // Needed for Object#toString, hashCode, etc. - manager.register(TestCow::class.java) - manager.register(MessageWithTestCow::class.java) - manager.register(UnsupportedOperationException::class.java) - } - } +class RmiSimpleTest : BaseTest() { @Test fun rmiNetworkGlobal() { @@ -181,7 +72,7 @@ class RmiTest : BaseTest() { run { val configuration = serverConfig() config(configuration) - register(configuration.serialization) + RmiCommonTest.register(configuration.serialization) // for Client -> Server RMI configuration.serialization.registerRmi(TestCow::class.java, TestCowImpl::class.java) @@ -204,7 +95,7 @@ class RmiTest : BaseTest() { System.err.println("Starting test for: Server -> Client") connection.createObject(123) { rmiId, remoteObject -> System.err.println("Running test for: Server -> Client") - runTests(connection, remoteObject, 123) + RmiCommonTest.runTests(connection, remoteObject, 123) System.err.println("Done with test for: Server -> Client") } } @@ -213,7 +104,7 @@ class RmiTest : BaseTest() { run { val configuration = clientConfig() config(configuration) - register(configuration.serialization) + RmiCommonTest.register(configuration.serialization) // for Server -> Client RMI configuration.serialization.registerRmi(TestCow::class.java, TestCowImpl::class.java) @@ -224,7 +115,7 @@ class RmiTest : BaseTest() { client.onConnect { connection -> connection.createObject(23) { rmiId, remoteObject -> System.err.println("Running test for: Client -> Server") - runTests(connection, remoteObject, 23) + RmiCommonTest.runTests(connection, remoteObject, 23) System.err.println("Done with test for: Client -> Server") } } @@ -250,7 +141,7 @@ class RmiTest : BaseTest() { run { val configuration = serverConfig() config(configuration) - register(configuration.serialization) + RmiCommonTest.register(configuration.serialization) // for Client -> Server RMI configuration.serialization.registerRmi(TestCow::class.java, TestCowImpl::class.java) @@ -275,7 +166,7 @@ class RmiTest : BaseTest() { // normally this is in the 'connected', but we do it here, so that it's more linear and easier to debug connection.createObject(4) { rmiId, remoteObject -> System.err.println("Running test for: Server -> Client") - runTests(connection, remoteObject, 4) + RmiCommonTest.runTests(connection, remoteObject, 4) System.err.println("Done with test for: Server -> Client") } } @@ -284,7 +175,7 @@ class RmiTest : BaseTest() { run { val configuration = clientConfig() config(configuration) - register(configuration.serialization) + RmiCommonTest.register(configuration.serialization) // for Server -> Client RMI configuration.serialization.registerRmi(TestCow::class.java, TestCowImpl::class.java) @@ -308,7 +199,7 @@ class RmiTest : BaseTest() { // this creates a GLOBAL object on the server (instead of a connection specific object) client.createObject(44) { rmiId, remoteObject -> System.err.println("Running test for: Client -> Server") - runTests(client.getConnection(), remoteObject, 44) + RmiCommonTest.runTests(client.getConnection(), remoteObject, 44) System.err.println("Done with test for: Client -> Server") } } diff --git a/test/dorkboxTest/network/rmi/multiJVM/TestClient.kt b/test/dorkboxTest/network/rmi/multiJVM/TestClient.kt index e27f6a20..0f7681f8 100644 --- a/test/dorkboxTest/network/rmi/multiJVM/TestClient.kt +++ b/test/dorkboxTest/network/rmi/multiJVM/TestClient.kt @@ -25,7 +25,7 @@ import ch.qos.logback.core.ConsoleAppender import dorkbox.network.Client import dorkbox.network.connection.Connection import dorkboxTest.network.BaseTest -import dorkboxTest.network.rmi.RmiTest +import dorkboxTest.network.rmi.RmiCommonTest import dorkboxTest.network.rmi.classes.TestBabyCow import dorkboxTest.network.rmi.classes.TestBabyCowImpl import dorkboxTest.network.rmi.classes.TestCow @@ -68,7 +68,7 @@ object TestClient { setup() val configuration = BaseTest.clientConfig() - RmiTest.register(configuration.serialization) + RmiCommonTest.register(configuration.serialization) configuration.serialization.registerRmi(TestBabyCow::class.java, TestBabyCowImpl::class.java) configuration.serialization.register(TestCow::class.java) configuration.enableRemoteSignatureValidation = false diff --git a/test/dorkboxTest/network/rmi/multiJVM/TestServer.kt b/test/dorkboxTest/network/rmi/multiJVM/TestServer.kt index ca4d2167..a9286fd7 100644 --- a/test/dorkboxTest/network/rmi/multiJVM/TestServer.kt +++ b/test/dorkboxTest/network/rmi/multiJVM/TestServer.kt @@ -18,7 +18,7 @@ package dorkboxTest.network.rmi.multiJVM import dorkbox.network.Server import dorkbox.network.connection.Connection import dorkboxTest.network.BaseTest -import dorkboxTest.network.rmi.RmiTest +import dorkboxTest.network.rmi.RmiCommonTest import dorkboxTest.network.rmi.classes.MessageWithTestCow import dorkboxTest.network.rmi.classes.TestBabyCow import dorkboxTest.network.rmi.classes.TestCow @@ -37,7 +37,7 @@ object TestServer { val configuration = BaseTest.serverConfig() - RmiTest.register(configuration.serialization) + RmiCommonTest.register(configuration.serialization) configuration.serialization.register(TestBabyCow::class.java) configuration.serialization.registerRmi(TestCow::class.java, TestCowImpl::class.java) configuration.enableRemoteSignatureValidation = false