use super::*;
#[tokio::test]
async fn parallel_pipelines_isolate_egress_policy_and_http_mocks() {
let _env_guard = crate::tests::common::harn_state_lock::lock_harn_state_async().await;
let _egress_env = [
harn_vm::egress::HARN_EGRESS_ALLOW_ENV,
harn_vm::egress::HARN_EGRESS_DENY_ENV,
harn_vm::egress::HARN_EGRESS_DEFAULT_ENV,
harn_vm::egress::HARN_EGRESS_BLOCK_PRIVATE_ENV,
harn_vm::egress::HARN_EGRESS_ALLOW_LOOPBACK_ENV,
]
.map(ScopedEnvVar::unset);
let temp = TempTestDir::new();
let source = (0..32)
.map(|index| {
format!(
r#"
pipeline test_policy_{index}(harness: Harness, _task) {{
const url = "https://case-{index}.example.test/data"
harness.net.egress_policy({{default: "deny", allow: ["case-{index}.example.test"]}})
harness.testing.http_mock("GET", url, {{status: 200, body: "case-{index}", headers: {{}}}})
const response = harness.net.get(url)
assert_eq(response.body, "case-{index}")
}}
"#
)
})
.collect::<String>();
temp.write("suite/test_egress_parallel.harn", &source);
let opts = RunOptions {
parallel: true,
jobs: Some(8),
..RunOptions::new(5_000)
};
let summary = run_tests_with_options(&temp.path().join("suite"), &opts).await;
assert_eq!(
summary.failed,
0,
"parallel egress state leaked: {:?}",
summary
.results
.iter()
.filter(|result| !result.passed)
.map(|result| (&result.name, &result.error))
.collect::<Vec<_>>()
);
assert_eq!(summary.passed, 32);
}
#[tokio::test]
async fn environment_and_script_egress_policy_compose_without_failing_the_suite() {
let _env_guard = crate::tests::common::harn_state_lock::lock_harn_state_async().await;
let _allow = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_ALLOW_ENV);
let _deny = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_DENY_ENV);
let _default = ScopedEnvVar::set(harn_vm::egress::HARN_EGRESS_DEFAULT_ENV, "deny");
let _block_private = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_BLOCK_PRIVATE_ENV);
let _allow_loopback = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_ALLOW_LOOPBACK_ENV);
let temp = TempTestDir::new();
temp.write(
"suite/test_egress_environment.harn",
r#"
pipeline test_environment_one(harness: Harness, _task) {
const receipt = harness.net.egress_policy({allow: ["api.example.test"], default: "deny"})
assert(contains(to_string(receipt.sources), "environment"), "receipt names the environment")
assert(contains(to_string(receipt.sources), "stdlib"), "receipt names the script")
harness.testing.http_mock("GET", "https://api.example.test/ok", {status: 200, body: "reached"})
const response = harness.net.get("https://api.example.test/ok")
assert_eq(response.body, "reached")
}
pipeline test_environment_two(harness: Harness, _task) {
const receipt = harness.net.egress_policy({allow: ["api.example.test"], default: "deny"})
assert_eq(receipt.default, "deny")
harness.testing.http_mock("GET", "https://api.example.test/ok", {status: 200, body: "reached"})
const response = harness.net.get("https://api.example.test/ok")
assert_eq(response.body, "reached")
}
"#,
);
let opts = RunOptions {
parallel: true,
jobs: Some(2),
..RunOptions::new(5_000)
};
let summary = run_tests_with_options(&temp.path().join("suite"), &opts).await;
assert_eq!(
summary.failed,
0,
"an ambient egress policy must not fail a suite that configures its own: {:?}",
summary
.results
.iter()
.map(|result| (&result.name, &result.error))
.collect::<Vec<_>>()
);
assert_eq!(summary.passed, 2);
}
#[tokio::test]
async fn script_egress_policy_reaches_connector_behavior_without_an_environment_policy() {
let _env_guard = crate::tests::common::harn_state_lock::lock_harn_state_async().await;
let _allow = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_ALLOW_ENV);
let _deny = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_DENY_ENV);
let _default = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_DEFAULT_ENV);
let _block_private = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_BLOCK_PRIVATE_ENV);
let _allow_loopback = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_ALLOW_LOOPBACK_ENV);
let temp = TempTestDir::new();
temp.write(
"suite/test_egress_no_environment.harn",
r#"
pipeline test_script_only(harness: Harness, _task) {
const receipt = harness.net.egress_policy({allow: ["api.example.test"], default: "deny"})
assert_eq(len(receipt.sources), 1)
assert(contains(to_string(receipt.sources), "stdlib"), "only the script contributed")
harness.testing.http_mock("GET", "https://api.example.test/ok", {status: 200, body: "reached"})
const response = harness.net.get("https://api.example.test/ok")
assert_eq(response.body, "reached")
}
"#,
);
let opts = RunOptions::new(5_000);
let summary = run_tests_with_options(&temp.path().join("suite"), &opts).await;
assert_eq!(
summary.failed,
0,
"{:?}",
summary
.results
.iter()
.map(|result| (&result.name, &result.error))
.collect::<Vec<_>>()
);
assert_eq!(summary.passed, 1);
}
#[tokio::test]
async fn block_private_environment_policy_composes_with_a_connector_script_policy() {
let _env_guard = crate::tests::common::harn_state_lock::lock_harn_state_async().await;
let _allow = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_ALLOW_ENV);
let _deny = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_DENY_ENV);
let _default = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_DEFAULT_ENV);
let _block_private =
ScopedEnvVar::set(harn_vm::egress::HARN_EGRESS_BLOCK_PRIVATE_ENV, "private");
let _allow_loopback = ScopedEnvVar::unset(harn_vm::egress::HARN_EGRESS_ALLOW_LOOPBACK_ENV);
let temp = TempTestDir::new();
temp.write(
"suite/test_egress_block_private.harn",
r#"
pipeline test_connector_policy(harness: Harness, _task) {
const receipt = harness.net.egress_policy(
{allow: ["api.example.test"], default: "deny", block_private: "off"},
)
assert(contains(to_string(receipt.sources), "environment"), "receipt names the environment")
assert(contains(to_string(receipt.sources), "stdlib"), "receipt names the script")
assert_eq(receipt.block_private, "private")
assert_eq(receipt.default, "deny")
}
"#,
);
let opts = RunOptions::new(5_000);
let summary = run_tests_with_options(&temp.path().join("suite"), &opts).await;
assert_eq!(
summary.failed,
0,
"HARN_EGRESS_BLOCK_PRIVATE must not fail a connector policy suite: {:?}",
summary
.results
.iter()
.map(|result| (&result.name, &result.error))
.collect::<Vec<_>>()
);
assert_eq!(summary.passed, 1);
}