|
| 1 | +//! Integration tests for pipeline artifact persistence. |
| 2 | +
|
| 3 | +#[test] |
| 4 | +fn test_artifact_store_lifecycle() { |
| 5 | + let tmp = tempfile::tempdir().unwrap(); |
| 6 | + let store = noricum_core::artifacts::ArtifactStore::new(tmp.path(), "lifecycle_test").unwrap(); |
| 7 | + |
| 8 | + // Simulate a full pipeline artifact trail |
| 9 | + store.save_c_source("int add(int a, int b) { return a + b; }").unwrap(); |
| 10 | + store.save_analysis(r#"{"difficulty":"easy","patterns":["arithmetic"]}"#).unwrap(); |
| 11 | + store.save_c2rust("unsafe fn add() {}").unwrap(); |
| 12 | + store.save_translation_final("fn add(a: i32, b: i32) -> i32 { a + b }").unwrap(); |
| 13 | + store.save_initial_validation(r#"{"compiles":true,"idiomatic_score":90}"#).unwrap(); |
| 14 | + store.save_final_output("fn add(a: i32, b: i32) -> i32 { a + b }").unwrap(); |
| 15 | + store.save_manifest(r#"{"name":"add","state":"Validated"}"#).unwrap(); |
| 16 | + |
| 17 | + // Verify directory structure |
| 18 | + let dir = store.run_dir(); |
| 19 | + assert!(dir.join("00-c-source.c").exists()); |
| 20 | + assert!(dir.join("01-analysis.json").exists()); |
| 21 | + assert!(dir.join("02-c2rust.rs").exists()); |
| 22 | + assert!(dir.join("03-translation/final.rs").exists()); |
| 23 | + assert!(dir.join("04-validation-initial.json").exists()); |
| 24 | + assert!(dir.join("06-final.rs").exists()); |
| 25 | + assert!(dir.join("manifest.json").exists()); |
| 26 | + |
| 27 | + // Verify content round-trip |
| 28 | + let c_source = std::fs::read_to_string(dir.join("00-c-source.c")).unwrap(); |
| 29 | + assert_eq!(c_source, "int add(int a, int b) { return a + b; }"); |
| 30 | + let manifest = std::fs::read_to_string(dir.join("manifest.json")).unwrap(); |
| 31 | + assert!(manifest.contains("Validated")); |
| 32 | +} |
| 33 | + |
| 34 | +#[test] |
| 35 | +fn test_artifact_store_repair_loop_simulation() { |
| 36 | + let tmp = tempfile::tempdir().unwrap(); |
| 37 | + let store = noricum_core::artifacts::ArtifactStore::new(tmp.path(), "repair_test").unwrap(); |
| 38 | + |
| 39 | + store.save_c_source("int complex() { /* ... */ }").unwrap(); |
| 40 | + store.save_translation_final("fn complex() { todo!() }").unwrap(); |
| 41 | + store.save_initial_validation(r#"{"compiles":false}"#).unwrap(); |
| 42 | + |
| 43 | + // Simulate 3 repair iterations |
| 44 | + store.save_repair_iteration(1, "fn complex() { /* attempt 1 */ }", r#"{"compiles":false}"#).unwrap(); |
| 45 | + store.save_repair_rejected(2, "unsafe fn complex() {}").unwrap(); |
| 46 | + store.save_repair_iteration(3, "fn complex() -> i32 { 42 }", r#"{"compiles":true,"idiomatic_score":75}"#).unwrap(); |
| 47 | + store.save_best_version("fn complex() -> i32 { 42 }", 75, 0, true).unwrap(); |
| 48 | + store.save_final_output("fn complex() -> i32 { 42 }").unwrap(); |
| 49 | + |
| 50 | + // All artifacts should exist |
| 51 | + let dir = store.run_dir(); |
| 52 | + assert!(dir.join("05-repair/iter-01.rs").exists()); |
| 53 | + assert!(dir.join("05-repair/iter-01-validation.json").exists()); |
| 54 | + assert!(dir.join("05-repair/iter-02-rejected.rs").exists()); |
| 55 | + assert!(dir.join("05-repair/iter-03.rs").exists()); |
| 56 | + assert!(dir.join("05-repair/iter-03-validation.json").exists()); |
| 57 | + assert!(dir.join("05-repair/best-version.rs").exists()); |
| 58 | + assert!(dir.join("05-repair/best-version-meta.json").exists()); |
| 59 | + assert!(dir.join("06-final.rs").exists()); |
| 60 | + |
| 61 | + // Verify best-version meta |
| 62 | + let meta = std::fs::read_to_string(dir.join("05-repair/best-version-meta.json")).unwrap(); |
| 63 | + assert!(meta.contains("\"score\":75")); |
| 64 | +} |
| 65 | + |
| 66 | +#[test] |
| 67 | +fn test_artifact_store_chunked_translation_simulation() { |
| 68 | + let tmp = tempfile::tempdir().unwrap(); |
| 69 | + let store = noricum_core::artifacts::ArtifactStore::new(tmp.path(), "chunked_test").unwrap(); |
| 70 | + |
| 71 | + store.save_c_source("/* 2000 LOC C file */").unwrap(); |
| 72 | + store.save_agreed_signatures("fn parse() -> Result<(), Error>;\nfn lex() -> Vec<Token>;").unwrap(); |
| 73 | + store.save_foundation("struct Token { kind: TokenKind, span: Span }").unwrap(); |
| 74 | + store.save_translation_chunk(0, "struct Token { kind: TokenKind, span: Span }").unwrap(); |
| 75 | + store.save_translation_chunk(1, "fn lex() -> Vec<Token> { vec![] }").unwrap(); |
| 76 | + store.save_translation_chunk(2, "fn parse() -> Result<(), Error> { Ok(()) }").unwrap(); |
| 77 | + store.save_translation_final("// combined output").unwrap(); |
| 78 | + |
| 79 | + let dir = store.run_dir(); |
| 80 | + assert!(dir.join("03-translation/agreed-signatures.rs").exists()); |
| 81 | + assert!(dir.join("03-translation/foundation.rs").exists()); |
| 82 | + assert!(dir.join("03-translation/chunk-00.rs").exists()); |
| 83 | + assert!(dir.join("03-translation/chunk-01.rs").exists()); |
| 84 | + assert!(dir.join("03-translation/chunk-02.rs").exists()); |
| 85 | + assert!(dir.join("03-translation/final.rs").exists()); |
| 86 | +} |
| 87 | + |
| 88 | +#[test] |
| 89 | +fn test_artifact_store_modular_migration_simulation() { |
| 90 | + let tmp = tempfile::tempdir().unwrap(); |
| 91 | + let store = noricum_core::artifacts::ArtifactStore::new(tmp.path(), "modular_test").unwrap(); |
| 92 | + |
| 93 | + store.save_translation_module("parser", "fn parse() {}").unwrap(); |
| 94 | + store.save_translation_module("lexer", "fn lex() {}").unwrap(); |
| 95 | + store.save_translation_module("eval", "fn eval() {}").unwrap(); |
| 96 | + |
| 97 | + let dir = store.run_dir(); |
| 98 | + assert!(dir.join("03-translation/module-parser.rs").exists()); |
| 99 | + assert!(dir.join("03-translation/module-lexer.rs").exists()); |
| 100 | + assert!(dir.join("03-translation/module-eval.rs").exists()); |
| 101 | +} |
| 102 | + |
| 103 | +#[test] |
| 104 | +fn test_artifact_store_retranslation_artifacts() { |
| 105 | + let tmp = tempfile::tempdir().unwrap(); |
| 106 | + let store = noricum_core::artifacts::ArtifactStore::new(tmp.path(), "retrans_test").unwrap(); |
| 107 | + |
| 108 | + store.save_retranslation("stub", "fn foo() { /* retranslated from stub */ }").unwrap(); |
| 109 | + store.save_retranslation("unsafe", "fn bar() { /* retranslated to remove unsafe */ }").unwrap(); |
| 110 | + store.save_retranslation_stall("fn baz() { /* stall retranslation */ }").unwrap(); |
| 111 | + |
| 112 | + let dir = store.run_dir(); |
| 113 | + assert!(dir.join("03-translation/retranslation-stub.rs").exists()); |
| 114 | + assert!(dir.join("03-translation/retranslation-unsafe.rs").exists()); |
| 115 | + assert!(dir.join("05-repair/retranslation-stall.rs").exists()); |
| 116 | + |
| 117 | + let stall = std::fs::read_to_string(dir.join("05-repair/retranslation-stall.rs")).unwrap(); |
| 118 | + assert!(stall.contains("stall retranslation")); |
| 119 | +} |
0 commit comments