From 331eba39a9da30b55be7b5ce8caf4651f99827f0 Mon Sep 17 00:00:00 2001 From: Zach Bray Date: Fri, 8 Dec 2023 14:50:13 +0000 Subject: [PATCH] Show detecting incorrect write order on SBE flyweight. Adds a new schema and test, which is referenced from the SBE Warnings page. The aim is to show how precedence checks in SBE `1.30.0` can help prevent some incorrect usages of SBE flyweights. --- .../java/com/aeroncookbook/sbe/SbeTests.java | 36 ++++++++++++-- sbe-protocol/build.gradle.kts | 18 +++++++ .../resources/precedence-checked-messages.xml | 48 +++++++++++++++++++ 3 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 sbe-protocol/src/main/resources/precedence-checked-messages.xml diff --git a/sbe-core/src/test/java/com/aeroncookbook/sbe/SbeTests.java b/sbe-core/src/test/java/com/aeroncookbook/sbe/SbeTests.java index 39ff444..be65834 100644 --- a/sbe-core/src/test/java/com/aeroncookbook/sbe/SbeTests.java +++ b/sbe-core/src/test/java/com/aeroncookbook/sbe/SbeTests.java @@ -16,14 +16,16 @@ package com.aeroncookbook.sbe; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.nio.ByteBuffer; - import org.agrona.concurrent.UnsafeBuffer; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.lang.reflect.Field; +import java.nio.ByteBuffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class SbeTests { @@ -175,6 +177,32 @@ public void dataCanBeCorrupted() Assertions.assertNotEquals(DATA_2, decoder.data2()); } + @Test + public void corruptionCanBeDetected() throws NoSuchFieldException, IllegalAccessException + { + assumePrecedenceChecksAreEnabled(); + + final SampleCorruptionDetectedEncoder encoder = new SampleCorruptionDetectedEncoder(); + final MessageHeaderEncoder messageHeaderEncoder = new MessageHeaderEncoder(); + final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(128); + final UnsafeBuffer directBuffer = new UnsafeBuffer(byteBuffer); + + encoder.wrapAndApplyHeader(directBuffer, 0, messageHeaderEncoder); + final IllegalStateException exception = + assertThrows(IllegalStateException.class, () -> encoder.data2(DATA_2)); + final String expectedErrorFragment = + "Illegal field access order. Cannot access field \"data2\" in state: V0_BLOCK."; + Assertions.assertTrue(exception.getMessage().contains(expectedErrorFragment)); + } + + private static void assumePrecedenceChecksAreEnabled() throws NoSuchFieldException, IllegalAccessException + { + final Field enabledField = SampleCorruptionDetectedEncoder.class + .getDeclaredField("SBE_ENABLE_PRECEDENCE_CHECKS"); + enabledField.setAccessible(true); + Assertions.assertTrue((boolean)enabledField.get(null)); + } + @Test public void dataCanBeReadCorrectlyWhenWrittenCorrectly() { diff --git a/sbe-protocol/build.gradle.kts b/sbe-protocol/build.gradle.kts index 64d4ef8..9996330 100644 --- a/sbe-protocol/build.gradle.kts +++ b/sbe-protocol/build.gradle.kts @@ -35,7 +35,25 @@ tasks { outputs.dir(generatedDir) } + task("generateCodecsWithPrecedeceChecks", JavaExec::class) { + group = "sbe" + val codecsFile = "src/main/resources/precedence-checked-messages.xml" + val sbeFile = "src/main/resources/sbe/sbe.xsd" + inputs.files(codecsFile, sbeFile) + outputs.dir(generatedDir) + classpath = codecGeneration + mainClass.set("uk.co.real_logic.sbe.SbeTool") + args = listOf(codecsFile) + systemProperties["sbe.output.dir"] = generatedDir + systemProperties["sbe.target.language"] = "Java" + systemProperties["sbe.validation.xsd"] = sbeFile + systemProperties["sbe.validation.stop.on.error"] = "true" + systemProperties["sbe.generate.precedence.checks"] = "true" + outputs.dir(generatedDir) + } + compileJava { dependsOn("generateCodecs") + dependsOn("generateCodecsWithPrecedeceChecks") } } diff --git a/sbe-protocol/src/main/resources/precedence-checked-messages.xml b/sbe-protocol/src/main/resources/precedence-checked-messages.xml new file mode 100644 index 0000000..4e34b0a --- /dev/null +++ b/sbe-protocol/src/main/resources/precedence-checked-messages.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +