From 11a19f9a43dfa4e6fb5f8dc500a61fe233751e1b Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 1 Dec 2023 13:24:34 +0300 Subject: [PATCH] tests: added test to check jboss serialization and java 17 compatibility (related to #5862, part of #6197) (#11499) --- .travis.yml | 2 +- .../performance/SerializationTest.java | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f665f8924cdb..db07ebf68d6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ git: depth: 3 submodules: false before_install: - - echo "MAVEN_OPTS='-Xmx2g'" > ~/.mavenrc + - echo "MAVEN_OPTS='-Xmx2g --illegal-access=deny'" > ~/.mavenrc script: - mvn test -B -Dlog4j.configuration=file:${TRAVIS_BUILD_DIR}/.travis/log4j.properties cache: diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/performance/SerializationTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/performance/SerializationTest.java index 8313e97c6f07..cb03549240f8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/performance/SerializationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/performance/SerializationTest.java @@ -18,12 +18,18 @@ import mage.remote.traffic.ZippedObjectImpl; import mage.util.CardUtil; import mage.utils.CompressUtil; +import mage.utils.ThreadUtils; import mage.view.GameView; +import org.jboss.remoting.serialization.impl.java.ClearableObjectOutputStream; +import org.jboss.serial.io.JBossObjectInputStream; +import org.jboss.serial.io.JBossObjectOutputStream; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; +import java.io.*; +import java.lang.reflect.Constructor; import java.util.*; import java.util.stream.Collectors; @@ -199,4 +205,93 @@ public void test_Choices_MustSupportSerialization() { Choice uncompressed = (Choice) CompressUtil.decompress(compressed); Assert.assertEquals("Must be same", choice.getChoices().size(), uncompressed.getChoices().size()); } + + static class SerializationTestData { + + String name; + GameView gameView; + Class writerClass; + Class readerClass; + + void SerializationTest( + String name, + GameView gameView, + Class writerClass, + Class readerClass + ) { + this.name = name; + this.gameView = gameView; + this.writerClass = writerClass; + this.readerClass = readerClass; + } + } + + private void assertSerializationClass( + String name, + GameView gameView, + Class writerClass, + Class readerClass + ) { + byte[] compressedGameView; + GameView uncompressedGameView; + + // write + try { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + Constructor writerCon = writerClass.getConstructor(OutputStream.class); + ObjectOutputStream writerStream = (ObjectOutputStream) writerCon.newInstance(outStream); + writerStream.writeObject(gameView); + compressedGameView = outStream.toByteArray(); + Assert.assertNotNull(compressedGameView); + Assert.assertNotEquals(0, compressedGameView.length); + } catch (Throwable t) { + ThreadUtils.findRootException(t).printStackTrace(); // write full stack + throw new IllegalStateException("Can't use [" + name + "] serialization on write: " + t.getMessage(), t); + } + + // read + try { + ByteArrayInputStream inputStream = new ByteArrayInputStream(compressedGameView); + Constructor readCon = readerClass.getConstructor(InputStream.class); + ObjectInputStream readerStream = (ObjectInputStream) readCon.newInstance(inputStream); + uncompressedGameView = (GameView) readerStream.readObject(); + Assert.assertNotNull(uncompressedGameView); + Assert.assertEquals(1, uncompressedGameView.getMyHand().size()); + Assert.assertEquals("Grizzly Bears", uncompressedGameView.getMyHand().values().stream().findFirst().get().getName()); + } catch (Throwable t) { + ThreadUtils.findRootException(t).printStackTrace(); // write full stack + throw new IllegalStateException("Can't use [" + name + "] serialization on read: " + t.getMessage(), t); + } + } + + @Test + @Ignore // TODO: enable to test migration to new java + public void test_SerializationEngines_Java17Support() { + // compatibility testing with new java version, see details at https://github.com/magefree/mage/issues/5862 + // original problem: jboss's inner stream classes (static code) used outdated access to private fields + // must be run under java 9+ with --illegal-access=deny or under java 17+ without additional commands + + // WORKAROUND for migration (InaccessibleObjectException): if it's impossible to update library then use + // additional java commands to open access to java modules: add-opens - https://stackoverflow.com/a/69160452/1276632 + + addCard(Zone.HAND, playerA, "Grizzly Bears", 1); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + GameView gameView = getGameView(playerA); + Assert.assertEquals(1, gameView.getMyHand().size()); + Assert.assertEquals("Grizzly Bears", gameView.getMyHand().values().stream().findFirst().get().getName()); + + // test diff serialization engines + + // java - current default serialization + assertSerializationClass("java", gameView, ObjectOutputStream.class, ObjectInputStream.class); + + // jboss client/server - jboss inner code for real client/server app (original error from #5862) + assertSerializationClass("jboss client/server", gameView, ClearableObjectOutputStream.class, ObjectInputStream.class); + + // jboss serial - jboss serilization (no longer used in the project) + assertSerializationClass("jboss serial", gameView, JBossObjectOutputStream.class, JBossObjectInputStream.class); + } }