use std::path::{Path, PathBuf};
use std::sync::Mutex;
use super::{Engine, FLAG, answer, fixture, fixture_answering, opts};
use crate::process::fake::{Call, Reply};
use crate::testing::FLAG_PORTAL;
use crate::{Park, Recorder, RunOptions};
fn files_holding(dir: &Path, value: &str) -> Vec<PathBuf> {
let Ok(entries) = std::fs::read_dir(dir) else {
return Vec::new();
};
entries
.filter_map(Result::ok)
.flat_map(|e| {
let path = e.path();
if path.is_dir() {
files_holding(&path, value)
} else if std::fs::read(&path).is_ok_and(|b| String::from_utf8_lossy(&b).contains(value)) {
vec![path]
} else {
Vec::new()
}
})
.collect()
}
fn up_fails_saying_the_flag(engine: &Mutex<Engine>, call: &Call) -> Reply {
if call.line().contains(" up --detach ") {
let flag = call.env("CTF_FLAG_MAIN").unwrap_or_default();
return Reply::fail(1, &format!("Error response from daemon: can't place {flag} in the secret"));
}
answer(engine, call)
}
#[tokio::test]
async fn a_delivered_value_lands_in_no_file_and_no_event_through_a_whole_run() {
let f = fixture();
let lab = f.runner.open(&f.manifest, None).unwrap();
let events = Recorder::new();
lab.up(&opts(), &events).await.unwrap();
lab.status().await.unwrap();
lab.check(&opts(), &events).await.unwrap();
lab.park(Park::Shutdown, &events).await.unwrap();
lab.resume(&opts(), &events).await.unwrap();
lab.down(&RunOptions::default(), &events).await.unwrap();
assert!(f.fake.calls().iter().any(|c| c.env("CTF_FLAG_MAIN") == Some(FLAG)), "the value was delivered");
let said = serde_json::to_string(&events.events()).unwrap();
assert!(!said.contains(FLAG) && said.contains("seeding ***"), "{said}");
assert_eq!(files_holding(f.home(), FLAG), Vec::<PathBuf>::new());
}
#[tokio::test]
async fn a_failed_step_that_prints_the_value_shows_it_in_no_error_event_or_file() {
let f = fixture_answering(FLAG_PORTAL, up_fails_saying_the_flag);
let lab = f.runner.open(&f.manifest, None).unwrap();
let events = Recorder::new();
let err = lab.up(&opts(), &events).await.unwrap_err();
let (shown, debug) = (err.to_string(), format!("{err:?}"));
assert!(
!shown.contains(FLAG) && !debug.contains(FLAG) && shown.contains("can't place *** in the secret"),
"{shown}"
);
assert!(!serde_json::to_string(&events.events()).unwrap().contains(FLAG));
assert_eq!(files_holding(f.home(), FLAG), Vec::<PathBuf>::new());
}