Skip to content

Commit ddea75c

Browse files
committed
test(jsonata): use -Xss512k + depth=49999 to guarantee stack overflow in CI
Linux default thread stack is ~8 MB (OS RLIMIT_STACK), far too large to reproduce the crash without -Xss. Pin test JVM to -Xss512k (above HotSpot minimum, safe for Kestra framework). Use depth=49999 so 49999 JVM frames × minimum 16 bytes/frame = 800 KB > 512k — overflow guaranteed regardless of JIT optimization level.
1 parent dd35c34 commit ddea75c

2 files changed

Lines changed: 15 additions & 7 deletions

File tree

plugin-transform-json/build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
project.description = 'Kestra Plugin Transformation for Json.'
22

3+
// -Xss512k matches the constrained stack that triggered the production crash (Windows default is
4+
// ~320 KB; 512k is slightly above the HotSpot minimum and safely above the Kestra framework needs).
5+
// Without this, the Linux default thread stack (~8 MB) is far too large to reproduce the overflow.
6+
test {
7+
jvmArgs '-Xss512k'
8+
}
9+
310
jar {
411
manifest {
512
attributes(

plugin-transform-json/src/test/java/io/kestra/plugin/transform/jsonata/TransformValueTest.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,15 +151,15 @@ void shouldHandleNestedArrayExpressionFromIssue40() throws Exception {
151151

152152
@Test
153153
void shouldThrowStackOverflowWithDeepRecursionOnWindowsStack() throws Exception {
154-
// Windows default ~256 KB: historically crashed at depth=999.
155-
// depth=4999 ensures the crash is also reproducible on Linux CI (default stack ~512 KB–1 MB).
154+
// Windows default ~320 KB: historically crashed at depth=999 with recursive Frame.lookup().
155+
// depth=49999 guarantees overflow on -Xss512k regardless of JIT (49999 × min 16 bytes/frame > 512k).
156156
RunContext runContext = runContextFactory.of();
157157
TransformValue task = TransformValue.builder()
158158
.from(Property.ofValue("{}"))
159159
.expression(Property.ofValue(
160-
"($f := function($n) { $n > 0 ? $f($n - 1) : 0 }; $f(4999))"
160+
"($f := function($n) { $n > 0 ? $f($n - 1) : 0 }; $f(49999))"
161161
))
162-
.maxDepth(Property.ofValue(5000))
162+
.maxDepth(Property.ofValue(50000))
163163
.build();
164164

165165
assertThatThrownBy(() -> task.run(runContext))
@@ -168,14 +168,15 @@ void shouldThrowStackOverflowWithDeepRecursionOnWindowsStack() throws Exception
168168

169169
@Test
170170
void shouldThrowStackOverflowWithDeepRecursionOnLinuxStack() throws Exception {
171-
// depth=9999 ensures overflow even on a 1 MB default thread stack (~150 bytes/frame × 9999 ≈ 1.5 MB).
171+
// Linux default stack is ~8 MB without -Xss; test JVM is pinned to 512k (see build.gradle).
172+
// depth=49999 guarantees overflow on -Xss512k regardless of JIT (49999 × min 16 bytes/frame > 512k).
172173
RunContext runContext = runContextFactory.of();
173174
TransformValue task = TransformValue.builder()
174175
.from(Property.ofValue("{}"))
175176
.expression(Property.ofValue(
176-
"($f := function($n) { $n > 0 ? $f($n - 1) : 0 }; $f(9999))"
177+
"($f := function($n) { $n > 0 ? $f($n - 1) : 0 }; $f(49999))"
177178
))
178-
.maxDepth(Property.ofValue(10000))
179+
.maxDepth(Property.ofValue(50000))
179180
.build();
180181

181182
assertThatThrownBy(() -> task.run(runContext))

0 commit comments

Comments
 (0)