Skip to content

Commit d46fc08

Browse files
Fix issues found in our testing framework (#486)
- Some tests were not executed - Exceptions in interpreter where thrown instead of being wrapper in Either() - Parsing of infinite number caused unhandled exceptions. - Add new test suite to graalvm
1 parent d2d9c6b commit d46fc08

12 files changed

Lines changed: 65 additions & 51 deletions

build.mill

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,6 @@ object sjsonnet extends VersionFileModule {
202202
mvn"org.virtuslab::scala-yaml::0.3.0"
203203
)
204204

205-
val osName = System.getProperty("os.name").toLowerCase
206-
207205
def releaseMode = ReleaseMode.ReleaseFull
208206
def nativeLTO = LTO.Full
209207
def nativeMultithreading = None

sjsonnet/src/sjsonnet/Interpreter.scala

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,8 @@ class Interpreter(
155155
def evaluate(txt: String, path: Path): Either[Error, Val] = {
156156
val resolvedImport = StaticResolvedFile(txt)
157157
resolver.cache(path) = resolvedImport
158-
for {
159-
res <- resolver.parse(path, resolvedImport)(evaluator)
160-
(parsed, _) = res
161-
res0 <- handleException(evaluator.visitExpr(parsed)(ValScope.empty))
162-
res = res0 match {
158+
resolver.parse(path, resolvedImport)(evaluator) flatMap { case (expr, _) =>
159+
handleException(evaluator.visitExpr(expr)(ValScope.empty)) flatMap {
163160
case f: Val.Func =>
164161
val defaults2 = f.params.defaultExprs.clone()
165162
val tlaExpressions = collection.mutable.Set.empty[Expr]
@@ -173,18 +170,20 @@ class Interpreter(
173170
}
174171
i += 1
175172
}
176-
new Val.Func(f.pos, f.defSiteValScope, Params(f.params.names, defaults2)) {
173+
val out = new Val.Func(f.pos, f.defSiteValScope, Params(f.params.names, defaults2)) {
177174
def evalRhs(vs: ValScope, es: EvalScope, fs: FileScope, pos: Position): Val =
178175
f.evalRhs(vs, es, fs, pos)
176+
179177
override def evalDefault(expr: Expr, vs: ValScope, es: EvalScope): Val = {
180178
evaluator.visitExpr(expr)(
181179
if (tlaExpressions.exists(_ eq expr)) ValScope.empty else vs
182180
)
183181
}
184-
}.apply0(f.pos)(evaluator, TailstrictModeDisabled)
185-
case x => x
182+
}
183+
handleException(out.apply0(f.pos)(evaluator, TailstrictModeDisabled))
184+
case x => Right(x)
186185
}
187-
} yield res
186+
}
188187
}
189188

190189
def materialize[T](res: Val, visitor: upickle.core.Visitor[T, T]): Either[Error, T] = {

sjsonnet/src/sjsonnet/Parser.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,12 @@ class Parser(
9898
if (s._2.length > 1 && Character.isDigit(s._2.charAt(1)) && s._2.charAt(0) == '0') {
9999
Fail.opaque("numbers cannot start with a 0 digit")
100100
} else {
101-
Pass(Val.Num(s._1, s._2.toDouble))
101+
val v = s._2.toDouble
102+
if (v.isInfinite) {
103+
Fail.opaque("finite number required")
104+
} else {
105+
Pass(Val.Num(s._1, v))
106+
}
102107
}
103108
})
104109

sjsonnet/test/graalvm/run_test_suites.py

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,14 @@ def run_individual_test(self, jsonnet_file: str, base_name: str):
6565
with open(f"{base_name}.jsonnet.golden", 'r', encoding='utf-8') as f:
6666
golden_content = f.read()
6767

68-
normalized_output = strip_trailing_empty_lines(output.replace('Exception in thread "main" ', ''))
69-
normalized_golden_content = strip_trailing_empty_lines(golden_content.replace('Exception in thread "main" ', ''))
68+
normalized_output = output.strip()
69+
normalized_golden_content = golden_content.strip()
7070
if jsonnet_file.endswith("trace.jsonnet"):
7171
normalized_output = normalized_output.replace("true", "").strip()
7272
normalized_golden_content = normalized_golden_content.replace("true", "").strip()
7373

7474
# Compare with golden file, ignoring trailing empty lines
75-
if normalized_golden_content.startswith("java.lang.StackOverflowError") and normalized_output.startswith("java.lang.StackOverflowError"):
75+
if normalized_golden_content.startswith("""Exception in thread "main" java.lang.StackOverflowError""") and normalized_output.startswith("""Exception in thread "main" java.lang.StackOverflowError"""):
7676
return
7777
elif len(normalized_golden_content) > 10000 and normalized_golden_content != normalized_output:
7878
print(f"normalized_golden_content: {normalized_golden_content[:100]}")
@@ -92,12 +92,7 @@ def setUpClass(cls):
9292
def test_all_files(self):
9393
"""Test all files in the main test suite using subTest for each file."""
9494
# Skip list for main test suite
95-
skip_list = [
96-
# Some slight differences with how graalvm throws exceptions
97-
"error.overflow",
98-
"error.overflow2",
99-
"error.overflow3",
100-
]
95+
skip_list = []
10196

10297
# Find all .jsonnet files in the test directory
10398
jsonnet_files = glob.glob("*.jsonnet")
@@ -123,13 +118,16 @@ def setUpClass(cls):
123118

124119
def test_all_files(self):
125120
"""Test all files in the go test suite using subTest for each file."""
126-
# Skip list for go_test_suite - almost all of them due to floating point precision differences
127121
skip_list = [
122+
# GraalVM has slight difference with how it manages high precision floats
128123
"builtin_cos",
129-
"builtin_exp4",
124+
"builtin_exp4",
130125
"builtin_log3",
131126
"div3",
132-
"function_too_many_params",
127+
"std.mantissa3",
128+
"stdlib_smoke_test",
129+
130+
# These tests rely on custom native functions that are not implemented in the binary we use
133131
"native1",
134132
"native2",
135133
"native3",
@@ -139,8 +137,6 @@ def test_all_files(self):
139137
"native7",
140138
"native_error",
141139
"native_panic",
142-
"std.mantissa3",
143-
"stdlib_smoke_test"
144140
]
145141

146142
# Find all .jsonnet files in the test directory
@@ -157,6 +153,32 @@ def test_all_files(self):
157153
with self.subTest(file=base_name):
158154
self.run_individual_test(jsonnet_file, base_name)
159155

156+
class NewTestSuite(BaseGraalVMTestSuite):
157+
"""Test suite for the new jsonnet test files."""
158+
159+
@classmethod
160+
def setUpClass(cls):
161+
super(NewTestSuite, cls).setUpClass()
162+
os.chdir(os.path.join(root_dir, "sjsonnet/test/resources/new_test_suite"))
163+
164+
def test_all_files(self):
165+
"""Test all files in the main test suite using subTest for each file."""
166+
# Skip list for main test suite
167+
skip_list = []
168+
169+
# Find all .jsonnet files in the test directory
170+
jsonnet_files = glob.glob("*jvm-native.jsonnet")
171+
self.assertTrue(jsonnet_files, f"No .jsonnet files found in {os.getcwd()}")
172+
173+
for jsonnet_file in sorted(jsonnet_files):
174+
base_name = Path(jsonnet_file).stem
175+
176+
# Check if this test should be skipped
177+
if base_name in skip_list:
178+
continue
179+
180+
with self.subTest(file=base_name):
181+
self.run_individual_test(jsonnet_file, base_name)
160182

161183
if __name__ == "__main__":
162184
unittest.main(verbosity=2)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
sjsonnet.Error: Function parameter x not bound in call
2+
at .(function_too_many_params.jsonnet:1:1)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
sjsonnet.Error: Internal Error
22
at [std.nativePanic].(native_panic.jsonnet:1:26)
3-
3+
Caused by: java.lang.RuntimeException: native function panic
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
sjsonnet.Error: Function parameter b not bound in call
2-
at .(error.function_no_default_arg.jsonnet:17:1)
2+
at .(error.function_no_default_arg.jsonnet:17:1)
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
sjsonnet.Error: overflow
2-
at [BinaryOp *].(error.overflow.jsonnet:17:7)
3-
1+
sjsonnet.ParseError: Expected finite number required:17:6, found "\n"
2+
at .(error.overflow.jsonnet:17:6)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
sjsonnet.Error: numeric value is not finite
2-
at [BinaryOp &].(error.overflow3.jsonnet:17:7)
1+
sjsonnet.ParseError: Expected finite number required:17:6, found " & 0\n"
2+
at .(error.overflow3.jsonnet:17:6)
33

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
sjsonnet.Error: Function parameter name not bound in call
2-
at .(error.top_level_func.jsonnet:17:1)
2+
at .(error.top_level_func.jsonnet:17:1)

0 commit comments

Comments
 (0)