Skip to content

Commit 68c30b3

Browse files
authored
Updates for cedar#725 (#253)
Signed-off-by: Kesha Hietala <[email protected]>
1 parent a74d230 commit 68c30b3

File tree

4 files changed

+55
-39
lines changed

4 files changed

+55
-39
lines changed

cedar-drt/fuzz/src/lib.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use cedar_policy_core::extensions::Extensions;
3131
pub use cedar_policy_validator::{ValidationErrorKind, ValidationMode, Validator, ValidatorSchema};
3232
pub use cedar_testing::cedar_test_impl::{
3333
time_function, CedarTestImplementation, ErrorComparisonMode, TestResult,
34+
ValidationComparisonMode,
3435
};
3536
use libfuzzer_sys::arbitrary::{self, Unstructured};
3637
use log::info;
@@ -177,37 +178,27 @@ pub fn run_val_test(
177178

178179
let definitional_res = custom_impl.validate(&schema, policies, mode);
179180

180-
// If `cedar-policy` does not return an error, then the spec should not return an error.
181-
// This implies type soundness of the `cedar-policy` validator since type soundness of the
182-
// spec is formally proven.
183-
//
184-
// In particular, we have proven that if the spec validator does not return an error (B),
185-
// then there are no authorization-time errors modulo some restrictions (C). So (B) ==> (C).
186-
// DRT checks that if the `cedar-policy` validator does not return an error (A), then neither
187-
// does the spec validator (B). So (A) ==> (B). By transitivity then, (A) ==> (C).
188-
189-
if rust_res.validation_passed() {
190-
match definitional_res {
191-
TestResult::Failure(err) => {
192-
// TODO(#175): For now, ignore cases where the Lean code returned an error due to
193-
// an unknown extension function.
194-
if !err.contains("jsonToExtFun: unknown extension function") {
195-
panic!(
196-
"Unexpected error\nPolicies:\n{}\nSchema:\n{:?}\nError: {err}",
197-
&policies, schema
198-
);
199-
}
181+
match definitional_res {
182+
TestResult::Failure(err) => {
183+
// TODO(#175): For now, ignore cases where the Lean code returned an error due to
184+
// an unknown extension function.
185+
if !err.contains("jsonToExtFun: unknown extension function") {
186+
panic!(
187+
"Unexpected error\nPolicies:\n{}\nSchema:\n{:?}\nError: {err}",
188+
&policies, schema
189+
);
200190
}
201-
TestResult::Success(definitional_res) => {
202-
// Even if the Rust validator succeeds, the definitional validator may
203-
// return "impossiblePolicy" due to greater precision. In this case, the
204-
// input policy is well-typed, although it is guaranteed to always evaluate
205-
// to false.
206-
if definitional_res.errors == vec!["impossiblePolicy".to_string()] {
207-
return;
208-
}
209-
210-
// But the definitional validator should not return any other error.
191+
}
192+
TestResult::Success(definitional_res) => {
193+
if rust_res.validation_passed() {
194+
// If `cedar-policy` does not return an error, then the spec should not return an error.
195+
// This implies type soundness of the `cedar-policy` validator since type soundness of the
196+
// spec is formally proven.
197+
//
198+
// In particular, we have proven that if the spec validator does not return an error (B),
199+
// then there are no authorization-time errors modulo some restrictions (C). So (B) ==> (C).
200+
// DRT checks that if the `cedar-policy` validator does not return an error (A), then neither
201+
// does the spec validator (B). So (A) ==> (B). By transitivity then, (A) ==> (C).
211202
assert!(
212203
definitional_res.validation_passed(),
213204
"Mismatch for Policies:\n{}\nSchema:\n{:?}\ncedar-policy response: {:?}\nTest engine response: {:?}\n",
@@ -216,10 +207,22 @@ pub fn run_val_test(
216207
rust_res,
217208
definitional_res,
218209
);
219-
220-
// TODO(#69): We currently don't check for a relationship between validation errors.
221-
// E.g., the error reported by the definitional validator should be in the list
222-
// of errors reported by the production validator, but we don't check this.
210+
} else {
211+
// If `cedar-policy` returns an error, then only check the spec response
212+
// if the validation comparison mode is `AgreeOnAll`.
213+
match custom_impl.validation_comparison_mode() {
214+
ValidationComparisonMode::AgreeOnAll => {
215+
assert!(
216+
!definitional_res.validation_passed(),
217+
"Mismatch for Policies:\n{}\nSchema:\n{:?}\ncedar-policy response: {:?}\nTest engine response: {:?}\n",
218+
&policies,
219+
schema,
220+
rust_res,
221+
definitional_res,
222+
);
223+
}
224+
ValidationComparisonMode::AgreeOnValid => {} // ignore
225+
};
223226
}
224227
}
225228
}

cedar-drt/src/lean_impl.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,25 @@ impl CedarTestImplementation for LeanDefinitionalEngine {
333333
ValidationMode::Strict,
334334
"Lean definitional validator only supports `Strict` mode"
335335
);
336-
self.validate(schema, policies)
336+
let result = self.validate(schema, policies);
337+
result.map(|res| {
338+
// `impossiblePolicy` is considered a warning rather than an error,
339+
// so it's safe to drop here (although this means it can't be used
340+
// for differential testing, see #254)
341+
let errors = res
342+
.errors
343+
.into_iter()
344+
.filter(|x| x != "impossiblePolicy")
345+
.collect();
346+
TestValidationResult { errors, ..res }
347+
})
337348
}
338349

339350
fn error_comparison_mode(&self) -> ErrorComparisonMode {
340351
ErrorComparisonMode::PolicyIds
341352
}
353+
354+
fn validation_comparison_mode(&self) -> ValidationComparisonMode {
355+
ValidationComparisonMode::AgreeOnValid
356+
}
342357
}

cedar-drt/tests/integration_tests.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,5 @@ fn run_corpus_tests(custom_impl: &impl CedarTestImplementation) {
9797
fn integration_tests_on_def_impl() {
9898
let lean_def_impl = LeanDefinitionalEngine::new();
9999
run_integration_tests(&lean_def_impl);
100-
101-
// This test may fail due to differences in precision between the Rust & Lean validators (#226)
102-
// run_corpus_tests(&lean_def_impl);
100+
run_corpus_tests(&lean_def_impl);
103101
}

0 commit comments

Comments
 (0)