Skip to content

Commit c0b8cdb

Browse files
committed
[Java] Add tests for variable-length data in nested group.
These tests are based on Mike's review comments.
1 parent 6794fc3 commit c0b8cdb

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

sbe-tool/src/test/java/uk/co/real_logic/sbe/FieldAccessOrderCheckTest.java

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import org.junit.jupiter.api.BeforeAll;
2424
import org.junit.jupiter.api.Disabled;
2525
import org.junit.jupiter.api.Test;
26+
import org.junit.jupiter.params.ParameterizedTest;
27+
import org.junit.jupiter.params.provider.CsvSource;
2628

2729
import java.nio.charset.StandardCharsets;
2830

@@ -2934,6 +2936,186 @@ void disallowsEncodingElementOfEmptyGroup6()
29342936
assertThat(exception.getMessage(), containsString("Cannot access field \"b.c\" in state: V0_D_DONE"));
29352937
}
29362938

2939+
@Test
2940+
void allowsEncodingAndDecodingNestedGroupWithVarDataInSchemaDefinedOrder()
2941+
{
2942+
final NestedGroupWithVarLengthEncoder encoder = new NestedGroupWithVarLengthEncoder()
2943+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderEncoder);
2944+
encoder.a(1);
2945+
final NestedGroupWithVarLengthEncoder.BEncoder bEncoder = encoder.bCount(3);
2946+
bEncoder.next().c(2).dCount(0);
2947+
bEncoder.next().c(3).dCount(1).next().e(4).f("abc");
2948+
bEncoder.next().c(5).dCount(2).next().e(6).f("def").next().e(7).f("ghi");
2949+
2950+
final NestedGroupWithVarLengthDecoder decoder = new NestedGroupWithVarLengthDecoder()
2951+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderDecoder);
2952+
assertThat(decoder.a(), equalTo(1));
2953+
final NestedGroupWithVarLengthDecoder.BDecoder bDecoder = decoder.b();
2954+
assertThat(bDecoder.count(), equalTo(3));
2955+
assertThat(bDecoder.next().c(), equalTo(2));
2956+
assertThat(bDecoder.d().count(), equalTo(0));
2957+
assertThat(bDecoder.next().c(), equalTo(3));
2958+
final NestedGroupWithVarLengthDecoder.BDecoder.DDecoder dDecoder = bDecoder.d();
2959+
assertThat(dDecoder.count(), equalTo(1));
2960+
assertThat(dDecoder.next().e(), equalTo(4));
2961+
assertThat(dDecoder.f(), equalTo("abc"));
2962+
assertThat(bDecoder.next().c(), equalTo(5));
2963+
assertThat(bDecoder.d(), sameInstance(dDecoder));
2964+
assertThat(dDecoder.count(), equalTo(2));
2965+
assertThat(dDecoder.next().e(), equalTo(6));
2966+
assertThat(dDecoder.f(), equalTo("def"));
2967+
assertThat(dDecoder.next().e(), equalTo(7));
2968+
assertThat(dDecoder.f(), equalTo("ghi"));
2969+
}
2970+
2971+
@CsvSource(value = {
2972+
"1,V0_B_1_D_N_BLOCK",
2973+
"2,V0_B_N_D_N_BLOCK"
2974+
})
2975+
@ParameterizedTest
2976+
void disallowsMissedEncodingOfVarLengthFieldInNestedGroupToNextInnerElement(
2977+
final int bCount,
2978+
final String expectedState)
2979+
{
2980+
final NestedGroupWithVarLengthEncoder encoder = new NestedGroupWithVarLengthEncoder()
2981+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderEncoder);
2982+
encoder.a(1);
2983+
final NestedGroupWithVarLengthEncoder.BEncoder bEncoder = encoder.bCount(bCount);
2984+
final NestedGroupWithVarLengthEncoder.BEncoder.DEncoder dEncoder = bEncoder.next().c(5).dCount(2);
2985+
dEncoder.next().e(7);
2986+
final IllegalStateException exception =
2987+
assertThrows(INCORRECT_ORDER_EXCEPTION_CLASS, dEncoder::next);
2988+
assertThat(exception.getMessage(),
2989+
containsString("Cannot access next element in repeating group \"b.d\" in state: " + expectedState));
2990+
assertThat(exception.getMessage(),
2991+
containsString("Expected one of these transitions: [\"b.d.e(?)\", \"b.d.f(?)\"]."));
2992+
}
2993+
2994+
@CsvSource(value = {
2995+
"1,V0_B_N_D_1_BLOCK",
2996+
"2,V0_B_N_D_N_BLOCK",
2997+
})
2998+
@ParameterizedTest
2999+
void disallowsMissedEncodingOfVarLengthFieldInNestedGroupToNextOuterElement(
3000+
final int dCount,
3001+
final String expectedState)
3002+
{
3003+
final NestedGroupWithVarLengthEncoder encoder = new NestedGroupWithVarLengthEncoder()
3004+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderEncoder);
3005+
encoder.a(1);
3006+
final NestedGroupWithVarLengthEncoder.BEncoder bEncoder = encoder.bCount(2);
3007+
bEncoder.next().c(3).dCount(dCount).next().e(4);
3008+
final IllegalStateException exception =
3009+
assertThrows(INCORRECT_ORDER_EXCEPTION_CLASS, bEncoder::next);
3010+
assertThat(exception.getMessage(),
3011+
containsString("Cannot access next element in repeating group \"b\" in state: " + expectedState));
3012+
assertThat(exception.getMessage(),
3013+
containsString("Expected one of these transitions: [\"b.d.e(?)\", \"b.d.f(?)\"]."));
3014+
}
3015+
3016+
@Test
3017+
void disallowsMissedDecodingOfVarLengthFieldInNestedGroupToNextInnerElement1()
3018+
{
3019+
final NestedGroupWithVarLengthEncoder encoder = new NestedGroupWithVarLengthEncoder()
3020+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderEncoder);
3021+
encoder.a(1);
3022+
final NestedGroupWithVarLengthEncoder.BEncoder bEncoder = encoder.bCount(1);
3023+
bEncoder.next().c(2).dCount(2).next().e(3).f("abc").next().e(4).f("def");
3024+
3025+
final NestedGroupWithVarLengthDecoder decoder = new NestedGroupWithVarLengthDecoder()
3026+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderDecoder);
3027+
assertThat(decoder.a(), equalTo(1));
3028+
final NestedGroupWithVarLengthDecoder.BDecoder bDecoder = decoder.b();
3029+
assertThat(bDecoder.count(), equalTo(1));
3030+
assertThat(bDecoder.next().c(), equalTo(2));
3031+
final NestedGroupWithVarLengthDecoder.BDecoder.DDecoder dDecoder = bDecoder.d();
3032+
assertThat(dDecoder.count(), equalTo(2));
3033+
assertThat(dDecoder.next().e(), equalTo(3));
3034+
final Exception exception = assertThrows(INCORRECT_ORDER_EXCEPTION_CLASS, dDecoder::next);
3035+
assertThat(exception.getMessage(),
3036+
containsString("Cannot access next element in repeating group \"b.d\" in state: V0_B_1_D_N_BLOCK."));
3037+
assertThat(exception.getMessage(),
3038+
containsString("Expected one of these transitions: [\"b.d.e(?)\", \"b.d.f(?)\"]."));
3039+
}
3040+
3041+
@Test
3042+
void disallowsMissedDecodingOfVarLengthFieldInNestedGroupToNextInnerElement2()
3043+
{
3044+
final NestedGroupWithVarLengthEncoder encoder = new NestedGroupWithVarLengthEncoder()
3045+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderEncoder);
3046+
encoder.a(1);
3047+
final NestedGroupWithVarLengthEncoder.BEncoder bEncoder = encoder.bCount(2);
3048+
bEncoder.next().c(2).dCount(2).next().e(3).f("abc").next().e(4).f("def");
3049+
bEncoder.next().c(5).dCount(0);
3050+
3051+
final NestedGroupWithVarLengthDecoder decoder = new NestedGroupWithVarLengthDecoder()
3052+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderDecoder);
3053+
assertThat(decoder.a(), equalTo(1));
3054+
final NestedGroupWithVarLengthDecoder.BDecoder bDecoder = decoder.b();
3055+
assertThat(bDecoder.count(), equalTo(2));
3056+
assertThat(bDecoder.next().c(), equalTo(2));
3057+
final NestedGroupWithVarLengthDecoder.BDecoder.DDecoder dDecoder = bDecoder.d();
3058+
assertThat(dDecoder.count(), equalTo(2));
3059+
assertThat(dDecoder.next().e(), equalTo(3));
3060+
final Exception exception = assertThrows(INCORRECT_ORDER_EXCEPTION_CLASS, dDecoder::next);
3061+
assertThat(exception.getMessage(),
3062+
containsString("Cannot access next element in repeating group \"b.d\" in state: V0_B_N_D_N_BLOCK."));
3063+
assertThat(exception.getMessage(),
3064+
containsString("Expected one of these transitions: [\"b.d.e(?)\", \"b.d.f(?)\"]."));
3065+
}
3066+
3067+
@Test
3068+
void disallowsMissedDecodingOfVarLengthFieldInNestedGroupToNextOuterElement1()
3069+
{
3070+
final NestedGroupWithVarLengthEncoder encoder = new NestedGroupWithVarLengthEncoder()
3071+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderEncoder);
3072+
encoder.a(1);
3073+
final NestedGroupWithVarLengthEncoder.BEncoder bEncoder = encoder.bCount(2);
3074+
bEncoder.next().c(2).dCount(2).next().e(3).f("abc").next().e(4).f("def");
3075+
bEncoder.next().c(5).dCount(0);
3076+
3077+
final NestedGroupWithVarLengthDecoder decoder = new NestedGroupWithVarLengthDecoder()
3078+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderDecoder);
3079+
assertThat(decoder.a(), equalTo(1));
3080+
final NestedGroupWithVarLengthDecoder.BDecoder bDecoder = decoder.b();
3081+
assertThat(bDecoder.count(), equalTo(2));
3082+
assertThat(bDecoder.next().c(), equalTo(2));
3083+
final NestedGroupWithVarLengthDecoder.BDecoder.DDecoder dDecoder = bDecoder.d();
3084+
assertThat(dDecoder.count(), equalTo(2));
3085+
assertThat(dDecoder.next().e(), equalTo(3));
3086+
final Exception exception = assertThrows(INCORRECT_ORDER_EXCEPTION_CLASS, bDecoder::next);
3087+
assertThat(exception.getMessage(),
3088+
containsString("Cannot access next element in repeating group \"b\" in state: V0_B_N_D_N_BLOCK."));
3089+
assertThat(exception.getMessage(),
3090+
containsString("Expected one of these transitions: [\"b.d.e(?)\", \"b.d.f(?)\"]."));
3091+
}
3092+
3093+
@Test
3094+
void disallowsMissedDecodingOfVarLengthFieldInNestedGroupToNextOuterElement2()
3095+
{
3096+
final NestedGroupWithVarLengthEncoder encoder = new NestedGroupWithVarLengthEncoder()
3097+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderEncoder);
3098+
encoder.a(1);
3099+
final NestedGroupWithVarLengthEncoder.BEncoder bEncoder = encoder.bCount(2);
3100+
bEncoder.next().c(2).dCount(1).next().e(3).f("abc");
3101+
bEncoder.next().c(5).dCount(0);
3102+
3103+
final NestedGroupWithVarLengthDecoder decoder = new NestedGroupWithVarLengthDecoder()
3104+
.wrapAndApplyHeader(buffer, OFFSET, messageHeaderDecoder);
3105+
assertThat(decoder.a(), equalTo(1));
3106+
final NestedGroupWithVarLengthDecoder.BDecoder bDecoder = decoder.b();
3107+
assertThat(bDecoder.count(), equalTo(2));
3108+
assertThat(bDecoder.next().c(), equalTo(2));
3109+
final NestedGroupWithVarLengthDecoder.BDecoder.DDecoder dDecoder = bDecoder.d();
3110+
assertThat(dDecoder.count(), equalTo(1));
3111+
assertThat(dDecoder.next().e(), equalTo(3));
3112+
final Exception exception = assertThrows(INCORRECT_ORDER_EXCEPTION_CLASS, bDecoder::next);
3113+
assertThat(exception.getMessage(),
3114+
containsString("Cannot access next element in repeating group \"b\" in state: V0_B_N_D_1_BLOCK."));
3115+
assertThat(exception.getMessage(),
3116+
containsString("Expected one of these transitions: [\"b.d.e(?)\", \"b.d.f(?)\"]."));
3117+
}
3118+
29373119
private void modifyHeaderToLookLikeVersion0()
29383120
{
29393121
messageHeaderDecoder.wrap(buffer, OFFSET);

sbe-tool/src/test/resources/field-order-check-schema.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,4 +278,15 @@
278278
<data name="b" id="2" type="varDataEncoding"/>
279279
</group>
280280
</sbe:message>
281+
282+
<sbe:message name="NestedGroupWithVarLength" id="24">
283+
<field name="a" id="1" type="int32"/>
284+
<group name="b" id="2">
285+
<field name="c" id="3" type="int32"/>
286+
<group name="d" id="4">
287+
<field name="e" id="5" type="int32"/>
288+
<data name="f" id="6" type="varDataEncoding"/>
289+
</group>
290+
</group>
291+
</sbe:message>
281292
</sbe:messageSchema>

0 commit comments

Comments
 (0)