Skip to content

Commit 801b5ba

Browse files
authored
Merge pull request #957 from ZachBray/feature/dtos
[C#,C++,Java] Generate DTOs for non-perf-sensitive usecases.
2 parents e4dd872 + 6e0234b commit 801b5ba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+9391
-223
lines changed

.github/workflows/codeql.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
fail-fast: false
8989
matrix:
9090
language: [ 'csharp' ]
91-
dotnet: [ '3.1.x' ]
91+
dotnet: [ '8.0.x' ]
9292
env:
9393
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
9494
DOTNET_CLI_TELEMETRY_OPTOUT: 1

.github/workflows/slow.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Slow checks
2+
3+
on:
4+
workflow_dispatch:
5+
branches:
6+
- '**'
7+
schedule:
8+
- cron: '0 12 * * *'
9+
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
env:
15+
GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.java.installations.auto-detect=false -Dorg.gradle.warning.mode=fail'
16+
17+
permissions:
18+
contents: read
19+
20+
jobs:
21+
property-tests:
22+
name: Property tests
23+
runs-on: ubuntu-22.04
24+
strategy:
25+
matrix:
26+
java: [ '21' ]
27+
dotnet: [ '8.0.x' ]
28+
env:
29+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
30+
DOTNET_CLI_TELEMETRY_OPTOUT: 1
31+
steps:
32+
- name: Checkout code
33+
uses: actions/checkout@v3
34+
- name: Setup java
35+
uses: actions/setup-java@v3
36+
with:
37+
distribution: 'zulu'
38+
java-version: ${{ matrix.java }}
39+
- name: Setup BUILD_JAVA_HOME & BUILD_JAVA_VERSION
40+
run: |
41+
java -Xinternalversion
42+
echo "BUILD_JAVA_HOME=${JAVA_HOME}" >> $GITHUB_ENV
43+
echo "BUILD_JAVA_VERSION=${{ matrix.java }}" >> $GITHUB_ENV
44+
- name: Setup java 8 to run the Gradle script
45+
uses: actions/setup-java@v3
46+
with:
47+
distribution: 'zulu'
48+
java-version: 8
49+
- name: Setup dotnet
50+
uses: actions/setup-dotnet@v2
51+
with:
52+
dotnet-version: ${{ matrix.dotnet }}
53+
- name: Build .NET library
54+
run: ./csharp/build.sh
55+
- name: Run property tests
56+
run: ./gradlew propertyTest
57+
- name: Upload test results
58+
uses: actions/upload-artifact@v3
59+
if: success() || failure()
60+
with:
61+
name: property-tests
62+
path: sbe-tool/build/reports/tests/propertyTest

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,7 @@ rust/Cargo.lock
119119
.DS_Store
120120
/sbe-tool/src/main/golang/uk_co_real_logic_sbe_ir_generated/
121121

122+
# JQwik
123+
*.jqwik-database
124+
122125
/generated/

build.gradle

Lines changed: 102 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ buildscript {
3131

3232
plugins {
3333
id 'java-library'
34+
id 'jvm-test-suite'
3435
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
3536
id 'com.github.ben-manes.versions' version '0.51.0'
3637
}
@@ -57,6 +58,8 @@ def checkstyleVersion = '9.3'
5758
def hamcrestVersion = '2.2'
5859
def mockitoVersion = '4.11.0'
5960
def junitVersion = '5.10.2'
61+
def jqwikVersion = '1.8.1'
62+
def jsonVersion = '20230618'
6063
def jmhVersion = '1.37'
6164
def agronaVersion = '1.21.2'
6265
def agronaVersionRange = '[1.21.2,2.0[' // allow any release >= 1.21.2 and < 2.0.0
@@ -164,6 +167,7 @@ jar.enabled = false
164167

165168
subprojects {
166169
apply plugin: 'java-library'
170+
apply plugin: 'jvm-test-suite'
167171
apply plugin: 'checkstyle'
168172

169173
group = sbeGroup
@@ -216,22 +220,34 @@ subprojects {
216220
}
217221
}
218222

219-
test {
220-
useJUnitPlatform()
223+
testing {
224+
suites {
225+
test {
226+
useJUnitJupiter junitVersion
221227

222-
testLogging {
223-
for (def level : LogLevel.values())
224-
{
225-
def testLogging = get(level)
226-
testLogging.exceptionFormat = 'full'
227-
testLogging.events = ["FAILED", "STANDARD_OUT", "STANDARD_ERROR"]
228-
}
229-
}
228+
targets {
229+
all {
230+
testTask.configure {
231+
useJUnitPlatform()
230232

231-
javaLauncher.set(toolchainLauncher)
233+
testLogging {
234+
for (def level : LogLevel.values())
235+
{
236+
def testLogging = get(level)
237+
testLogging.exceptionFormat = 'full'
238+
testLogging.events = ["FAILED", "STANDARD_OUT", "STANDARD_ERROR"]
239+
}
240+
}
241+
242+
javaLauncher.set(toolchainLauncher)
232243

233-
systemProperty 'sbe.enable.ir.precedence.checks', 'true'
234-
systemProperty 'sbe.enable.test.precedence.checks', 'true'
244+
systemProperty 'sbe.enable.ir.precedence.checks', 'true'
245+
systemProperty 'sbe.enable.test.precedence.checks', 'true'
246+
}
247+
}
248+
}
249+
}
250+
}
235251
}
236252
}
237253

@@ -248,11 +264,6 @@ project(':sbe-tool') {
248264
prefer(agronaVersion)
249265
}
250266
}
251-
testImplementation files('build/classes/java/generated')
252-
testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}"
253-
testImplementation "org.mockito:mockito-core:${mockitoVersion}"
254-
testImplementation "org.junit.jupiter:junit-jupiter-params:${junitVersion}"
255-
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
256267
}
257268

258269
def generatedDir = 'build/generated-src'
@@ -269,11 +280,55 @@ project(':sbe-tool') {
269280

270281
compileGeneratedJava {
271282
dependsOn 'generateTestCodecs'
283+
dependsOn 'generateTestDtos'
272284
classpath += sourceSets.main.runtimeClasspath
273285
}
274286

275287
compileTestJava.dependsOn compileGeneratedJava
276288

289+
testing {
290+
suites {
291+
test {
292+
dependencies {
293+
implementation files('build/classes/java/generated')
294+
implementation "org.hamcrest:hamcrest:${hamcrestVersion}"
295+
implementation "org.mockito:mockito-core:${mockitoVersion}"
296+
implementation "org.junit.jupiter:junit-jupiter-params:${junitVersion}"
297+
}
298+
}
299+
300+
propertyTest(JvmTestSuite) {
301+
// We should be able to use _only_ the JQwik engine, but this issue is outstanding:
302+
// https://github.com/gradle/gradle/issues/21299
303+
useJUnitJupiter junitVersion
304+
305+
dependencies {
306+
implementation project()
307+
implementation("net.jqwik:jqwik:${jqwikVersion}") {
308+
// Exclude JUnit 5 dependencies that are already provided due to useJUnitJupiter
309+
exclude group: 'org.junit.platform', module: 'junit-platform-commons'
310+
exclude group: 'org.junit.platform', module: 'junit-platform-engine'
311+
}
312+
implementation "org.json:json:${jsonVersion}"
313+
}
314+
315+
316+
targets {
317+
all {
318+
testTask.configure {
319+
minHeapSize = '2g'
320+
maxHeapSize = '2g'
321+
322+
javaLauncher.set(toolchainLauncher)
323+
324+
systemProperty 'sbe.dll', "${rootProject.projectDir}/csharp/sbe-dll/bin/Release/netstandard2.0/SBE.dll"
325+
}
326+
}
327+
}
328+
}
329+
}
330+
}
331+
277332
tasks.register('generateTestCodecs', JavaExec) {
278333
dependsOn 'compileJava'
279334
mainClass.set('uk.co.real_logic.sbe.SbeTool')
@@ -290,6 +345,21 @@ project(':sbe-tool') {
290345
'src/test/resources/field-order-check-schema.xml']
291346
}
292347

348+
tasks.register('generateTestDtos', JavaExec) {
349+
dependsOn 'compileJava'
350+
mainClass.set('uk.co.real_logic.sbe.SbeTool')
351+
classpath = sourceSets.main.runtimeClasspath
352+
systemProperties(
353+
'sbe.output.dir': generatedDir,
354+
'sbe.target.language': 'java',
355+
'sbe.validation.stop.on.error': 'true',
356+
'sbe.validation.xsd': validationXsdPath,
357+
'sbe.generate.precedence.checks': 'true',
358+
'sbe.java.precedence.checks.property.name': 'sbe.enable.test.precedence.checks',
359+
'sbe.java.generate.dtos': 'true')
360+
args = ['src/test/resources/example-extension-schema.xml']
361+
}
362+
293363
jar {
294364
manifest.attributes(
295365
'Specification-Title': 'Simple Binary Encoding',
@@ -735,7 +805,7 @@ tasks.register('generateCSharpCodecsWithXIncludes', JavaExec) {
735805
'sbe-samples/src/main/resources/example-extension-schema.xml']
736806
}
737807

738-
tasks.register('generateCSharpCodecsTests', JavaExec) {
808+
tasks.register('generateCSharpTestCodecs', JavaExec) {
739809
mainClass.set('uk.co.real_logic.sbe.SbeTool')
740810
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
741811
systemProperties(
@@ -754,9 +824,21 @@ tasks.register('generateCSharpCodecsTests', JavaExec) {
754824
'sbe-benchmarks/src/main/resources/fix-message-samples.xml']
755825
}
756826

827+
tasks.register('generateCSharpTestDtos', JavaExec) {
828+
mainClass.set('uk.co.real_logic.sbe.SbeTool')
829+
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
830+
systemProperties(
831+
'sbe.output.dir': 'csharp/sbe-generated',
832+
'sbe.target.language': 'uk.co.real_logic.sbe.generation.csharp.CSharpDtos',
833+
'sbe.xinclude.aware': 'true',
834+
'sbe.validation.xsd': validationXsdPath)
835+
args = ['sbe-samples/src/main/resources/example-extension-schema.xml']
836+
}
837+
757838
tasks.register('generateCSharpCodecs') {
758839
description = 'Generate csharp codecs'
759-
dependsOn 'generateCSharpCodecsTests',
840+
dependsOn 'generateCSharpTestCodecs',
841+
'generateCSharpTestDtos',
760842
'generateCSharpCodecsWithXIncludes'
761843
}
762844

config/checkstyle/suppressions.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
<suppress files=".*generated-src.*" checks="."/>
77
<suppress files=".*generated.*" checks="."/>
88
<suppress files="[\\/]test[\\/]" checks="MissingJavadoc.*"/>
9+
<suppress files="[\\/]propertyTest[\\/]" checks="MissingJavadoc.*"/>
910
<suppress files="[\\/]sbe-benchmarks[\\/]" checks="MissingJavadoc.*"/>
1011
</suppressions>

csharp/sbe-dll/DirectBuffer.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -694,21 +694,16 @@ public int SetBytes(int index, ReadOnlySpan<byte> src)
694694

695695
/// <summary>
696696
/// Writes a string into the underlying buffer, encoding using the provided <see cref="System.Text.Encoding"/>.
697-
/// If there is not enough room in the buffer for the bytes it will throw IndexOutOfRangeException.
698697
/// </summary>
699698
/// <param name="encoding">encoding to use to write the bytes from the string</param>
700699
/// <param name="src">source string</param>
701700
/// <param name="index">index in the underlying buffer to start writing bytes</param>
702701
/// <returns>count of bytes written</returns>
703702
public unsafe int SetBytesFromString(Encoding encoding, string src, int index)
704703
{
705-
int available = _capacity - index;
706704
int byteCount = encoding.GetByteCount(src);
707705

708-
if (byteCount > available)
709-
{
710-
ThrowHelper.ThrowIndexOutOfRangeException(_capacity);
711-
}
706+
CheckLimit(index + byteCount);
712707

713708
fixed (char* ptr = src)
714709
{

0 commit comments

Comments
 (0)