// file: crates/ksp-job-api/tests/security_hardening.rs // version: 1 //! Adversarial lifecycle, cancellation and redaction canaries. const HOSTILE_MARKER: &str = "JOB-IDENTITY-SECRET-CANARY"; #[test] fn pre_002_job_id_and_lifecycle_debug_redact_caller_identity() { let id = ksp_job_api::JobId::new(HOSTILE_MARKER); let kind = ksp_job_api::JobKindCode::new("backfill_raw"); assert!(id.is_ok()); assert!(kind.is_ok()); let id = match id { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let kind = match kind { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; assert_eq!(std::format!("{id:?}"), "JobId(..)"); let lifecycle = ksp_job_api::JobLifecycle::new(id, kind); let debug = std::format!("{lifecycle:?}"); assert!(debug.contains("JobLifecycle")); assert!(debug.contains("backfill_raw")); assert!(debug.contains("Created")); assert!(!debug.contains(HOSTILE_MARKER)); return; } #[test] fn pre_002_terminal_states_are_immutable_under_all_public_mutators() { let id = ksp_job_api::JobId::new("terminal-job"); let kind = ksp_job_api::JobKindCode::new("test_job"); assert!(id.is_ok()); assert!(kind.is_ok()); let id = match id { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let kind = match kind { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let mut lifecycle = ksp_job_api::JobLifecycle::new(id, kind); assert!(lifecycle.start().is_ok()); assert!(lifecycle.complete(ksp_job_api::JobCompletion::Complete).is_ok()); assert!(lifecycle.start().is_err()); assert!(lifecycle.mark_cancelling().is_err()); assert!(lifecycle.complete(ksp_job_api::JobCompletion::Partial).is_err()); assert!(lifecycle.mark_cancelled().is_err()); assert!(lifecycle.fail().is_err()); assert_eq!(lifecycle.state(), ksp_job_api::JobState::Completed(ksp_job_api::JobCompletion::Complete)); return; } #[test] fn pre_002_cancellation_token_is_send_sync_and_cross_thread_visible() { fn require_send_sync() {} require_send_sync::(); let token = ksp_job_api::JobCancellationToken::new(); let worker_token = token.clone(); let thread = std::thread::spawn(move || return worker_token.cancel()); let request = match thread.join() { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; assert!(request); assert!(token.is_cancellation_requested()); return; }