use codeowners_validation::parser::parse_codeowners_file;
use codeowners_validation::validators::duplicate_patterns::validate_duplicates;
use codeowners_validation::validators::exists::validate_directory;
use std::time::Instant;
#[test]
#[ignore] fn ci_environment_constraints() {
println!("\n=== CI Environment Simulation ===");
println!("Testing with CI constraints:");
println!("- Memory limit: 500MB");
println!("- Time limit: 60 seconds");
println!("- Large repository simulation");
const CI_MEMORY_LIMIT_MB: f64 = 500.0;
const CI_TIME_LIMIT_SECS: u64 = 60;
let file = create_ci_test_codeowners(15_000);
let repo = create_ci_test_repo();
let baseline = memory_stats::memory_stats()
.map(|s| s.physical_mem)
.unwrap_or(0);
let start = Instant::now();
let (rules, invalid) = parse_codeowners_file(file.path().to_str().unwrap()).unwrap();
assert_eq!(
invalid.len(),
0,
"Generated file should have no invalid lines"
);
let missing = validate_directory(repo.path(), &rules).unwrap();
let duplicates = validate_duplicates(&rules);
let elapsed = start.elapsed();
let peak = memory_stats::memory_stats()
.map(|s| s.physical_mem)
.unwrap_or(0);
let memory_mb = (peak.saturating_sub(baseline)) as f64 / 1024.0 / 1024.0;
println!("\nCI Simulation Results:");
println!("- Rules processed: {}", rules.len());
println!("- Processing time: {:?}", elapsed);
println!("- Memory used: {:.2} MB", memory_mb);
println!("- Missing patterns: {}", missing.len());
println!("- Duplicate patterns: {}", duplicates.len());
assert!(
elapsed.as_secs() <= CI_TIME_LIMIT_SECS,
"CI time limit exceeded: {:?} > {}s",
elapsed,
CI_TIME_LIMIT_SECS
);
assert!(
memory_mb <= CI_MEMORY_LIMIT_MB,
"CI memory limit exceeded: {:.2} MB > {} MB",
memory_mb,
CI_MEMORY_LIMIT_MB
);
println!("\n✅ CI simulation passed - tool is probably suitable for CI environments!");
}
#[test]
#[ignore] fn github_actions_runner_test() {
println!("\n=== GitHub Actions Runner Simulation ===");
println!("Simulating github-hosted runner constraints:");
println!("- 2-core CPU");
println!("- 7 GB RAM (but we should use much less)");
println!("- Ubuntu latest");
std::env::set_var("CODEOWNERS_THREADS", "2");
let file = create_ci_test_codeowners(20_000); let repo = create_ci_test_repo();
let start = Instant::now();
let (rules, _) = parse_codeowners_file(file.path().to_str().unwrap()).unwrap();
let _ = validate_directory(repo.path(), &rules).unwrap();
let _ = validate_duplicates(&rules);
let elapsed = start.elapsed();
std::env::remove_var("CODEOWNERS_THREADS");
println!("GitHub Actions simulation completed in {:?}", elapsed);
assert!(
elapsed.as_secs() < 120, "Too slow for GitHub Actions: {:?}",
elapsed
);
println!("\n✅ GitHub Actions simulation passed!");
}
fn create_ci_test_codeowners(num_rules: usize) -> tempfile::NamedTempFile {
use std::fmt::Write as FmtWrite;
use std::io::Write;
let mut file = tempfile::NamedTempFile::new().unwrap();
let mut content = String::with_capacity(num_rules * 60);
writeln!(&mut content, "# CI Test CODEOWNERS - {} rules", num_rules).unwrap();
for i in 0..num_rules {
match i % 20 {
0..=7 => writeln!(
&mut content,
"/src/module{}/file.ts @team{}",
i % 100,
i % 10
)
.unwrap(),
8..=11 => writeln!(&mut content, "/lib/package{}/ @org/team{}", i % 50, i % 5).unwrap(),
12..=15 => writeln!(
&mut content,
"*.{} @team{}",
["yml", "json", "md", "txt"][i % 4],
i % 3
)
.unwrap(),
16..=18 => writeln!(&mut content, "**/*.test.ts @test-team").unwrap(),
_ => writeln!(&mut content, "/docs/**/*.md @docs-team").unwrap(),
}
}
file.write_all(content.as_bytes()).unwrap();
file.flush().unwrap();
file
}
fn create_ci_test_repo() -> tempfile::TempDir {
let repo = tempfile::tempdir().unwrap();
let dirs = [
"src/module1",
"src/module2",
"src/module3",
"lib/package1",
"lib/package2",
"docs/api",
"docs/guides",
"test/unit",
"test/integration",
".github/workflows",
];
for dir in &dirs {
std::fs::create_dir_all(repo.path().join(dir)).unwrap();
}
let files = [
"src/module1/file.ts",
"src/module2/file.ts",
"docs/api/README.md",
"test/unit/example.test.ts",
".github/workflows/ci.yml",
"package.json",
"README.md",
];
for file in &files {
let path = repo.path().join(file);
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).ok();
}
std::fs::write(path, "test content").unwrap();
}
repo
}