difftreelog
test reenable more upstream tests
in: master
6 files changed
tests/cpp_test_suite_golden_override/error.function_duplicate_param.jsonnet.goldendiffbeforeafterboth--- /dev/null
+++ b/tests/cpp_test_suite_golden_override/error.function_duplicate_param.jsonnet.golden
@@ -0,0 +1 @@
+static analysis errors: local is already defined in the current frame: x; do not define identity functions manually, use std.id instead
\ No newline at end of file
tests/cpp_test_suite_golden_override/error.parse.object_local_clash.jsonnet.goldendiffbeforeafterboth--- /dev/null
+++ b/tests/cpp_test_suite_golden_override/error.parse.object_local_clash.jsonnet.golden
@@ -0,0 +1 @@
+static analysis errors: local is already defined in the current frame: x; unused local: x
\ No newline at end of file
tests/go_testdata_golden_override/div3.jsonnet.goldendiffbeforeafterboth--- /dev/null
+++ b/tests/go_testdata_golden_override/div3.jsonnet.golden
@@ -0,0 +1 @@
+0.0000000000000000000000000000009999999999999999
\ No newline at end of file
tests/go_testdata_golden_override/number_leading_zero.jsonnet.goldendiffbeforeafterboth--- /dev/null
+++ b/tests/go_testdata_golden_override/number_leading_zero.jsonnet.golden
@@ -0,0 +1,3 @@
+syntax error: expected end of file, got number "42"
+ number_leading_zero.jsonnet:1:2
+ number_leading_zero.jsonnet:1:2-3: parse imported
\ No newline at end of file
tests/go_testdata_golden_override/pow6.jsonnet.goldendiffbeforeafterboth--- /dev/null
+++ b/tests/go_testdata_golden_override/pow6.jsonnet.golden
@@ -0,0 +1 @@
+179754255558440960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
\ No newline at end of file
tests/tests/cpp_test_suite.rsdiffbeforeafterboth1use std::{2 env, fs,3 io::{self, ErrorKind},4 path::{Path, PathBuf},5};67use jrsonnet_evaluator::{8 FileImportResolver, IStr, ObjValueBuilder, State, Val, apply_tla,9 gc::WithCapacityExt as _,10 manifest::JsonFormat,11 rustc_hash::FxHashMap,12 stack::limit_stack_depth,13 tla::TlaArg,14 trace::{CompactFormat, PathResolver, TraceFormat},15};16use jrsonnet_gcmodule::ObjectSpace;17use jrsonnet_stdlib::ContextInitializer;18mod common;19use common::ContextInitializer as TestContextInitializer;2021fn run(file: &Path, root: &Path) -> String {22 let mut s = State::builder();2324 let resolver = PathResolver::Relative(root.to_owned());25 let std_context = ContextInitializer::new(resolver.clone());26 // C++ test suite27 std_context.add_ext_str("var1".into(), "test".into());28 std_context29 .add_ext_code("var2", "{x:1,y:2}")30 .expect("code is valid");3132 // Golang test suite33 std_context34 .add_ext_code("codeVar", "3+3")35 .expect("code is valid");36 std_context.add_ext_str("stringVar".into(), "2 + 2".into());37 std_context38 .add_ext_code(39 "selfRecursiveVar",40 r#"[42, std.extVar("selfRecursiveVar")[0] + 1]"#,41 )42 .expect("code is valid");43 std_context44 .add_ext_code(45 "mutuallyRecursiveVar1",46 r#"[42, std.extVar("mutuallyRecursiveVar2")[0] + 1]"#,47 )48 .expect("code is valid");49 std_context50 .add_ext_code(51 "mutuallyRecursiveVar2",52 r#"[42, std.extVar("mutuallyRecursiveVar1")[0] + 1]"#,53 )54 .expect("code is valid");5556 s.context_initializer((std_context, TestContextInitializer))57 .import_resolver(FileImportResolver::default());58 let s = s.build();5960 let _entered = s.enter();6162 let trace_format = CompactFormat {63 resolver: resolver.clone(),64 max_trace: 20,65 padding: 4,66 };6768 let mut v = match s.import(file) {69 Ok(v) => v,70 Err(e) => return trace_format.format(&e).unwrap(),71 };7273 if file74 .file_name()75 .expect("file has basename")76 .to_str()77 .expect("jsonnet testsuite has ascii names")78 .starts_with("tla.")79 {80 let mut args = FxHashMap::new();81 args.insert(IStr::from("var1"), TlaArg::String("test".into()));82 args.insert(83 IStr::from("var2"),84 TlaArg::Val({85 let mut o = ObjValueBuilder::new();8687 o.field("x").value(Val::num(1));88 o.field("y").value(Val::num(2));8990 Val::Obj(o.build())91 }),92 );93 v = apply_tla(&args, v).expect("failed to apply tla");94 } else {95 v = match apply_tla(&FxHashMap::new(), v) {96 Ok(v) => v,97 Err(e) => return trace_format.format(&e).unwrap(),98 };99 }100101 match v.manifest(JsonFormat::default()) {102 Ok(v) => v,103 Err(e) => trace_format.format(&e).unwrap(),104 }105}106107fn read_file(path: &Path) -> io::Result<Option<String>> {108 match fs::read_to_string(path) {109 Ok(v) => Ok(Some(v)),110 Err(e) if e.kind() == ErrorKind::NotFound => Ok(None),111 Err(e) => Err(e),112 }113}114115const SKIPPED: &[&str] = &[116 // C++ tests:117118 // Parser fails with stack overflow. While is a bug, this is a too unusual119 // thing to run untrusted jsonnet code? Will be fixed with nom/rowan.120 "error.parse.deep_array_nesting.jsonnet",121 // Runtime, not static error in jrsonnet122 "error.parse.object_local_clash.jsonnet",123 "error.function_duplicate_param.jsonnet",124 // Too slow to throw due to how lazyness is implemented in jrsonnet125 "error.recursive_object_non_term.jsonnet",126 // In jrsonnet returns the one passed argument, works as Rust's dbg!()127 "error.trace_one_param.jsonnet",128 // In jrsonnet can display any value129 "error.trace_two_param.jsonnet",130 // Depends on unsafe handling of strings as arrays in jsonnet stdlib131 "invariant_manifest.jsonnet",132 // Little bit hard to capture trace logs in this test suite at this moment133 "trace.jsonnet",134 // Go tests:135136 // Something is wrong, go-jsonnet skips safe integer range check here137 "bitwise_or9.jsonnet",138 // Jrsonnet does not use byte strings, all utf8 is converted to bytes first139 "builtinBase64_string_high_codepoint.jsonnet",140 // Split by empty string is string characters, same as everywhere else141 "builtinSplitLimitR6.jsonnet",142 // escapeStringJson only accepts string in jrsonnet143 "builtin_escapeStringJson.jsonnet",144 // golang float formatting is inefficient and not portable145 "builtin_manifestTomlEx.jsonnet",146 "div3.jsonnet",147 "pow6.jsonnet",148 // golang escapes "e" yaml key, does it think it is float?149 "builtin_manifestYamlDoc.jsonnet",150 // multi output is a CLI part, not an interpreter.151 "multi.jsonnet",152 "multi_no_newline.jsonnet",153 "multi_no_newline_string_output.jsonnet",154 "multi_string_output.jsonnet",155 // Tested otherwise156 "native1.jsonnet",157 "native2.jsonnet",158 "native3.jsonnet",159 "native6.jsonnet",160 // Since when parser should throw an error for that?..161 "number_leading_zero.jsonnet",162 // Golang fails with max stack frames exceeded error163 "std.makeArray_recursive_evalutation_order_matters.jsonnet",164 // Tailstrict semantics is partially unspecified165 "tailstrict3.jsonnet",166 // Jrsonnet has this overload167 "number_times_string.jsonnet",168 // Jrsonnet has this overload169 "string_times_number.jsonnet",170];171172fn run_test_suite(root: PathBuf, root_override: PathBuf) -> io::Result<()> {173 dbg!(&root);174 for entry in fs::read_dir(&root).map_err(|e| io::Error::other(format!("failed to enumerate test suite dir (Note: it needs to be cloned from upstream jsonnet repo for this test): {e}")))? {175 let entry = entry?;176 if entry.path().extension().is_none_or(|e| e != "jsonnet") {177 continue;178 }179180 let _stack = if entry.path().file_stem().is_some_and(|e| e == "recursive_function" || e == "tailstrict"|| e == "tailstrict5") {181 Some(limit_stack_depth(100_000))182 } else {183 None184 };185186 if entry187 .path()188 .file_name()189 .and_then(|v| v.to_str())190 .is_some_and(|v| SKIPPED.contains(&v))191 {192 continue;193 }194195 eprintln!("test: {}", entry.path().display());196197 let result = run(&entry.path(), &root);198199 let mut golden_path = entry.path();200 golden_path.set_extension("jsonnet.golden");201202 let mut golden_path2 = entry.path();203 golden_path2.set_extension("golden");204205 let golden_override =206 root_override.join(golden_path.file_name().expect("file has basename"));207208 // .jsonnet.golden for C++ tests209 let mut golden = read_file(&golden_path)?;210 // .golden for Go tests211 if golden.is_none() && let Some(golden_path) = read_file(&golden_path2)? {212 golden = Some(golden_path);213 }214215 // Any of them can be overriden by overrides216 if let Some(golden_path) = read_file(&golden_override)? {217 golden = Some(golden_path);218 }219220 // Otherwise assume test should just not fail and return true.221 let golden = golden.unwrap_or_else(|| "true".to_owned());222223 let update_golden_path = &golden_override;224225 match (serde_json::from_str::<serde_json::Value>(&result), serde_json::from_str::<serde_json::Value>(&golden)) {226 (Err(_), Ok(_)) => panic!(227 "unexpected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",228 entry.path().display()229 ),230 (Ok(_), Err(_)) => panic!(231 "expected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",232 entry.path().display()233 ),234 (Ok(result_v), Ok(golden_v)) => {235 if result_v != golden_v {236 if env::var_os("UPDATE_GOLDEN").is_some() {237 fs::write(update_golden_path, result)?;238 } else {239 panic!(240 "Result \n{result_v:#}\n\241 and golden \n{golden_v:#}\n\242 did not match structurally\n\243 for golden {}",244 entry.path().display()245 );246 }247 }248 }249 (Err(_), Err(_)) => {250 if result != golden.trim_end() {251 if env::var_os("UPDATE_GOLDEN").is_some() {252 fs::write(update_golden_path, result)?;253 } else {254 panic!(255 "golden didn't match for {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",256 entry.path().display()257 )258 }259 }260 }261 }262 println!("done!");263 }264 Ok(())265}266267#[test]268fn upstream_test_suite() -> io::Result<()> {269 let manifest = PathBuf::from(env!("CARGO_MANIFEST_DIR"));270 if let Some(cpp_jsonnet) = std::env::var_os("CPP_JSONNET_FOR_TESTS") {271 let path = PathBuf::from(cpp_jsonnet).join("test_suite");272 let path_override = manifest.join("cpp_test_suite_golden_override");273 run_test_suite(path, path_override)?;274 } else {275 eprintln!("no cpp jsonnet available for tests");276 }277 if let Some(go_jsonnet) = std::env::var_os("GO_JSONNET_FOR_TESTS") {278 let path = PathBuf::from(go_jsonnet).join("testdata");279 let path_override = manifest.join("go_testdata_golden_override");280 run_test_suite(path, path_override)?;281 } else {282 eprintln!("no go jsonnet available for tests");283 }284285 jrsonnet_gcmodule::with_thread_object_space(ObjectSpace::leak);286287 Ok(())288}1use std::{2 env, fs,3 io::{self, ErrorKind},4 path::{Path, PathBuf},5};67use jrsonnet_evaluator::{8 FileImportResolver, IStr, ObjValueBuilder, State, Val, apply_tla,9 gc::WithCapacityExt as _,10 manifest::JsonFormat,11 rustc_hash::FxHashMap,12 stack::limit_stack_depth,13 tla::TlaArg,14 trace::{CompactFormat, PathResolver, TraceFormat},15};16use jrsonnet_gcmodule::ObjectSpace;17use jrsonnet_stdlib::ContextInitializer;18mod common;19use common::ContextInitializer as TestContextInitializer;2021fn run(file: &Path, root: &Path) -> String {22 let mut s = State::builder();2324 let resolver = PathResolver::Relative(root.to_owned());25 let std_context = ContextInitializer::new(resolver.clone());26 // C++ test suite27 std_context.add_ext_str("var1".into(), "test".into());28 std_context29 .add_ext_code("var2", "{x:1,y:2}")30 .expect("code is valid");3132 // Golang test suite33 std_context34 .add_ext_code("codeVar", "3+3")35 .expect("code is valid");36 std_context.add_ext_str("stringVar".into(), "2 + 2".into());37 std_context38 .add_ext_code(39 "selfRecursiveVar",40 r#"[42, std.extVar("selfRecursiveVar")[0] + 1]"#,41 )42 .expect("code is valid");43 std_context44 .add_ext_code(45 "mutuallyRecursiveVar1",46 r#"[42, std.extVar("mutuallyRecursiveVar2")[0] + 1]"#,47 )48 .expect("code is valid");49 std_context50 .add_ext_code(51 "mutuallyRecursiveVar2",52 r#"[42, std.extVar("mutuallyRecursiveVar1")[0] + 1]"#,53 )54 .expect("code is valid");5556 s.context_initializer((std_context, TestContextInitializer))57 .import_resolver(FileImportResolver::default());58 let s = s.build();5960 let _entered = s.enter();6162 let trace_format = CompactFormat {63 resolver: resolver.clone(),64 max_trace: 20,65 padding: 4,66 };6768 let mut v = match s.import(file) {69 Ok(v) => v,70 Err(e) => return trace_format.format(&e).unwrap(),71 };7273 if file74 .file_name()75 .expect("file has basename")76 .to_str()77 .expect("jsonnet testsuite has ascii names")78 .starts_with("tla.")79 {80 let mut args = FxHashMap::new();81 args.insert(IStr::from("var1"), TlaArg::String("test".into()));82 args.insert(83 IStr::from("var2"),84 TlaArg::Val({85 let mut o = ObjValueBuilder::new();8687 o.field("x").value(Val::num(1));88 o.field("y").value(Val::num(2));8990 Val::Obj(o.build())91 }),92 );93 v = apply_tla(&args, v).expect("failed to apply tla");94 } else {95 v = match apply_tla(&FxHashMap::new(), v) {96 Ok(v) => v,97 Err(e) => return trace_format.format(&e).unwrap(),98 };99 }100101 match v.manifest(JsonFormat::default()) {102 Ok(v) => v,103 Err(e) => trace_format.format(&e).unwrap(),104 }105}106107fn read_file(path: &Path) -> io::Result<Option<String>> {108 match fs::read_to_string(path) {109 Ok(v) => Ok(Some(v)),110 Err(e) if e.kind() == ErrorKind::NotFound => Ok(None),111 Err(e) => Err(e),112 }113}114115const SKIPPED: &[&str] = &[116 // C++ tests:117118 // Parser fails with stack overflow. While is a bug, this is a too unusual119 // thing to run untrusted jsonnet code? Will be fixed with nom/rowan.120 "error.parse.deep_array_nesting.jsonnet",121 // Too slow to throw due to how lazyness is implemented in jrsonnet122 "error.recursive_object_non_term.jsonnet",123 // In jrsonnet returns the one passed argument, works as Rust's dbg!()124 "error.trace_one_param.jsonnet",125 // In jrsonnet can display any value126 "error.trace_two_param.jsonnet",127 // Depends on unsafe handling of strings as arrays in jsonnet stdlib128 "invariant_manifest.jsonnet",129 // Little bit hard to capture trace logs in this test suite at this moment130 "trace.jsonnet",131 // Go tests:132133 // Something is wrong, go-jsonnet skips safe integer range check here134 "bitwise_or9.jsonnet",135 // Bad check: https://github.com/databricks/sjsonnet/issues/793#issuecomment-4323153709136 "builtinBase64_string_high_codepoint.jsonnet",137 // Split by empty string is string characters, same as everywhere else138 "builtinSplitLimitR6.jsonnet",139 // escapeStringJson only accepts string in jrsonnet140 "builtin_escapeStringJson.jsonnet",141 // golang float formatting is inefficient and not portable142 "builtin_manifestTomlEx.jsonnet",143 // golang escapes "e" yaml key, does it think it is float?144 "builtin_manifestYamlDoc.jsonnet",145 // multi output is a CLI part, not an interpreter.146 "multi.jsonnet",147 "multi_no_newline.jsonnet",148 "multi_no_newline_string_output.jsonnet",149 "multi_string_output.jsonnet",150 // Tested otherwise151 "native1.jsonnet",152 "native2.jsonnet",153 "native3.jsonnet",154 "native6.jsonnet",155 // Golang fails with max stack frames exceeded error156 "std.makeArray_recursive_evalutation_order_matters.jsonnet",157 // Tailstrict semantics is partially unspecified158 "tailstrict3.jsonnet",159 // Jrsonnet has this overload160 "number_times_string.jsonnet",161 // Jrsonnet has this overload162 "string_times_number.jsonnet",163];164165fn run_test_suite(root: PathBuf, root_override: PathBuf) -> io::Result<()> {166 dbg!(&root);167 for entry in fs::read_dir(&root).map_err(|e| io::Error::other(format!("failed to enumerate test suite dir (Note: it needs to be cloned from upstream jsonnet repo for this test): {e}")))? {168 let entry = entry?;169 if entry.path().extension().is_none_or(|e| e != "jsonnet") {170 continue;171 }172173 let _stack = if entry.path().file_stem().is_some_and(|e| e == "recursive_function" || e == "tailstrict"|| e == "tailstrict5") {174 Some(limit_stack_depth(100_000))175 } else {176 None177 };178179 if entry180 .path()181 .file_name()182 .and_then(|v| v.to_str())183 .is_some_and(|v| SKIPPED.contains(&v))184 {185 continue;186 }187188 eprintln!("test: {}", entry.path().display());189190 let result = run(&entry.path(), &root);191192 let mut golden_path = entry.path();193 golden_path.set_extension("jsonnet.golden");194195 let mut golden_path2 = entry.path();196 golden_path2.set_extension("golden");197198 let golden_override =199 root_override.join(golden_path.file_name().expect("file has basename"));200201 // .jsonnet.golden for C++ tests202 let mut golden = read_file(&golden_path)?;203 // .golden for Go tests204 if golden.is_none() && let Some(golden_path) = read_file(&golden_path2)? {205 golden = Some(golden_path);206 }207208 // Any of them can be overriden by overrides209 if let Some(golden_path) = read_file(&golden_override)? {210 golden = Some(golden_path);211 }212213 // Otherwise assume test should just not fail and return true.214 let golden = golden.unwrap_or_else(|| "true".to_owned());215216 let update_golden_path = &golden_override;217218 match (serde_json::from_str::<serde_json::Value>(&result), serde_json::from_str::<serde_json::Value>(&golden)) {219 (Err(_), Ok(_)) => panic!(220 "unexpected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",221 entry.path().display()222 ),223 (Ok(_), Err(_)) => panic!(224 "expected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",225 entry.path().display()226 ),227 (Ok(result_v), Ok(golden_v)) => {228 if result_v != golden_v {229 if env::var_os("UPDATE_GOLDEN").is_some() {230 fs::write(update_golden_path, result)?;231 } else {232 panic!(233 "Result \n{result_v:#}\n\234 and golden \n{golden_v:#}\n\235 did not match structurally\n\236 for golden {}",237 entry.path().display()238 );239 }240 }241 }242 (Err(_), Err(_)) => {243 if result != golden.trim_end() {244 if env::var_os("UPDATE_GOLDEN").is_some() {245 fs::write(update_golden_path, result)?;246 } else {247 panic!(248 "golden didn't match for {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",249 entry.path().display()250 )251 }252 }253 }254 }255 println!("done!");256 }257 Ok(())258}259260#[test]261fn upstream_test_suite() -> io::Result<()> {262 let manifest = PathBuf::from(env!("CARGO_MANIFEST_DIR"));263 if let Some(cpp_jsonnet) = std::env::var_os("CPP_JSONNET_FOR_TESTS") {264 let path = PathBuf::from(cpp_jsonnet).join("test_suite");265 let path_override = manifest.join("cpp_test_suite_golden_override");266 run_test_suite(path, path_override)?;267 } else {268 eprintln!("no cpp jsonnet available for tests");269 }270 if let Some(go_jsonnet) = std::env::var_os("GO_JSONNET_FOR_TESTS") {271 let path = PathBuf::from(go_jsonnet).join("testdata");272 let path_override = manifest.join("go_testdata_golden_override");273 run_test_suite(path, path_override)?;274 } else {275 eprintln!("no go jsonnet available for tests");276 }277278 jrsonnet_gcmodule::with_thread_object_space(ObjectSpace::leak);279280 Ok(())281}