use agpm_cli::cache::Cache;
use agpm_cli::git::command_builder::GitCommand;
use agpm_cli::installer::{ResourceFilter, install_resources};
use agpm_cli::manifest::{DetailedDependency, Manifest, ResourceDependency};
use agpm_cli::resolver::DependencyResolver;
use agpm_cli::test_utils::init_test_logging;
use agpm_cli::utils::progress::MultiPhaseProgress;
use anyhow::Result;
use std::sync::Arc;
use tempfile::TempDir;
use tokio::fs;
use tracing::debug;
use crate::common::{ManifestBuilder, TestProject};
#[tokio::test]
async fn test_heavy_stress_500_dependencies() -> Result<()> {
init_test_logging(None);
debug!("Starting test_heavy_stress_500_dependencies");
let temp_dir = TempDir::new()?;
let project_dir = temp_dir.path().join("project");
fs::create_dir_all(&project_dir).await?;
let mut repo_urls = Vec::new();
for repo_num in 0..5 {
let repo_dir = temp_dir.path().join(format!("repo_{}", repo_num));
fs::create_dir_all(&repo_dir).await?;
setup_large_test_repository(&repo_dir, 100).await?;
repo_urls.push(format!("file://{}", repo_dir.display()));
}
let cache = Cache::with_dir(temp_dir.path().join("cache"))?;
let mut manifest = Manifest::new();
for (repo_idx, repo_url) in repo_urls.iter().enumerate() {
manifest.sources.insert(format!("repo_{}", repo_idx), repo_url.clone());
}
let mut total_agents = 0;
for (repo_idx, _) in repo_urls.iter().enumerate() {
for i in 0..100 {
manifest.agents.insert(
format!("repo{}_agent_{:03}", repo_idx, i),
ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some(format!("repo_{}", repo_idx)),
path: format!("agents/agent_{:03}.md", i),
version: Some(
if i % 3 == 0 {
"v1.0.0"
} else {
"v2.0.0"
}
.to_string(),
),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: Some(format!("repo{}_agent_{:03}.md", repo_idx, i)),
dependencies: None,
tool: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
})),
);
total_agents += 1;
}
}
let mut resolver = DependencyResolver::with_cache(manifest.clone(), cache.clone()).await?;
let lockfile = resolver.resolve().await?;
let progress = Arc::new(MultiPhaseProgress::new(false));
println!("🚀 Starting heavy stress test with {} agents", total_agents);
debug!("Starting parallel installation of {} agents", total_agents);
let start = std::time::Instant::now();
let results = install_resources(
ResourceFilter::All,
&Arc::new(lockfile),
&manifest,
&project_dir,
cache.clone(),
false,
None,
Some(progress),
false, None, false, None, )
.await?;
let duration = start.elapsed();
debug!("Installation completed in {:?}", duration);
assert_eq!(results.installed_count, total_agents);
println!("✅ Successfully installed {} agents in {:?}", total_agents, duration);
println!(" Average: {:?} per agent", duration / total_agents as u32);
println!(" Rate: {:.1} agents/second", total_agents as f64 / duration.as_secs_f64());
for repo_idx in 0..5 {
for i in (0..100).step_by(10) {
let path =
project_dir.join(format!(".claude/agents/agpm/repo{}_agent_{:03}.md", repo_idx, i));
assert!(path.exists(), "Agent from repo {} #{} should exist", repo_idx, i);
}
}
println!("500 agents installed in {:?}", duration);
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
Ok(())
}
async fn setup_large_test_repository(path: &std::path::PathBuf, num_files: usize) -> Result<()> {
GitCommand::init().current_dir(path).execute_success().await?;
GitCommand::new().args(["checkout", "-b", "main"]).current_dir(path).execute_success().await?;
GitCommand::new()
.args(["config", "user.email", "test@example.com"])
.current_dir(path)
.execute_success()
.await?;
GitCommand::new()
.args(["config", "user.name", "Test User"])
.current_dir(path)
.execute_success()
.await?;
let agents_dir = path.join("agents");
fs::create_dir_all(&agents_dir).await?;
for i in 0..num_files {
let agent_path = agents_dir.join(format!("agent_{:03}.md", i));
let content = format!(
"# Agent {}
\
This is test agent number {}.
\
## Features
\
- Feature 1 with detailed description
\
- Feature 2 with implementation notes
\
- Feature 3 with examples
\
## Configuration
\
```json
\
{{
\
\"id\": {},
\
\"enabled\": true,
\
\"priority\": {}
\
}}
\
```
",
i,
i,
i,
i % 10
);
fs::write(&agent_path, content).await?;
}
GitCommand::add(".").current_dir(path).execute_success().await?;
GitCommand::commit("Initial commit with all agents")
.current_dir(path)
.execute_success()
.await?;
GitCommand::new().args(["tag", "v1.0.0"]).current_dir(path).execute_success().await?;
for i in 0..5 {
let agent_path = agents_dir.join(format!("agent_{:03}.md", i));
let content = fs::read_to_string(&agent_path).await?;
fs::write(
&agent_path,
format!(
"{}
## Updated in v2.0.0
",
content
),
)
.await?;
}
GitCommand::add(".").current_dir(path).execute_success().await?;
GitCommand::commit("Update for v2.0.0").current_dir(path).execute_success().await?;
GitCommand::new().args(["tag", "v2.0.0"]).current_dir(path).execute_success().await?;
for i in 5..10 {
let agent_path = agents_dir.join(format!("agent_{:03}.md", i));
let content = fs::read_to_string(&agent_path).await?;
fs::write(
&agent_path,
format!(
"{}
## Updated in v3.0.0
",
content
),
)
.await?;
}
GitCommand::add(".").current_dir(path).execute_success().await?;
GitCommand::commit("Update for v3.0.0").current_dir(path).execute_success().await?;
GitCommand::new().args(["tag", "v3.0.0"]).current_dir(path).execute_success().await?;
Ok(())
}
#[tokio::test]
async fn test_heavy_stress_500_updates() -> Result<()> {
init_test_logging(None);
debug!("Starting test_heavy_stress_500_updates");
let temp_dir = TempDir::new()?;
let project_dir = temp_dir.path().join("project");
fs::create_dir_all(&project_dir).await?;
let mut repo_urls = Vec::new();
for repo_num in 0..5 {
let repo_dir = temp_dir.path().join(format!("repo_{}", repo_num));
fs::create_dir_all(&repo_dir).await?;
setup_large_test_repository(&repo_dir, 100).await?;
repo_urls.push(format!("file://{}", repo_dir.display()));
}
let cache = Cache::with_dir(temp_dir.path().join("cache"))?;
let mut manifest_v1 = Manifest::new();
for (repo_idx, repo_url) in repo_urls.iter().enumerate() {
manifest_v1.sources.insert(format!("repo_{}", repo_idx), repo_url.clone());
}
let mut total_agents = 0;
for (repo_idx, _) in repo_urls.iter().enumerate() {
for i in 0..100 {
manifest_v1.agents.insert(
format!("repo{}_agent_{:03}", repo_idx, i),
ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some(format!("repo_{}", repo_idx)),
path: format!("agents/agent_{:03}.md", i),
version: Some("v1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: Some(format!("repo{}_agent_{:03}.md", repo_idx, i)),
dependencies: None,
tool: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
})),
);
total_agents += 1;
}
}
let mut resolver_v1 =
DependencyResolver::with_cache(manifest_v1.clone(), cache.clone()).await?;
let lockfile_v1 = resolver_v1.resolve().await?;
let progress = Arc::new(MultiPhaseProgress::new(false));
println!("📦 Installing initial version (v1.0.0) of {} agents", total_agents);
let start_install = std::time::Instant::now();
let results = install_resources(
ResourceFilter::All,
&Arc::new(lockfile_v1),
&manifest_v1,
&project_dir,
cache.clone(),
false,
None,
Some(progress),
false, None, false, None, )
.await?;
assert_eq!(results.installed_count, total_agents);
let install_duration = start_install.elapsed();
println!(" Initial install took {:?}", install_duration);
let mut manifest_v2 = Manifest::new();
for (repo_idx, repo_url) in repo_urls.iter().enumerate() {
manifest_v2.sources.insert(format!("repo_{}", repo_idx), repo_url.clone());
}
for (repo_idx, _) in repo_urls.iter().enumerate() {
for i in 0..100 {
manifest_v2.agents.insert(
format!("repo{}_agent_{:03}", repo_idx, i),
ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some(format!("repo_{}", repo_idx)),
path: format!("agents/agent_{:03}.md", i),
version: Some("v2.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: Some(format!("repo{}_agent_{:03}.md", repo_idx, i)),
dependencies: None,
tool: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
})),
);
}
}
let mut resolver_v2 =
DependencyResolver::with_cache(manifest_v2.clone(), cache.clone()).await?;
let lockfile_v2 = resolver_v2.resolve().await?;
let progress2 = Arc::new(MultiPhaseProgress::new(false));
println!("🔄 Updating all {} agents to v2.0.0", total_agents);
let start_update = std::time::Instant::now();
let results = install_resources(
ResourceFilter::All,
&Arc::new(lockfile_v2),
&manifest_v2,
&project_dir,
cache.clone(),
false,
None,
Some(progress2),
false, None, false, None, )
.await?;
let update_duration = start_update.elapsed();
assert_eq!(
results.installed_count, 500,
"Should process all 500 agents (25 with content changes)"
);
println!("✅ Successfully updated {} agents to v2.0.0 in {:?}", total_agents, update_duration);
println!(" Average: {:?} per agent", update_duration / results.installed_count as u32);
println!(
" Rate: {:.1} agents/second",
results.installed_count as f64 / update_duration.as_secs_f64()
);
for repo_idx in 0..5 {
for i in (0..5).step_by(1) {
let path =
project_dir.join(format!(".claude/agents/agpm/repo{}_agent_{:03}.md", repo_idx, i));
assert!(path.exists(), "Updated agent from repo {} #{} should exist", repo_idx, i);
let content = fs::read_to_string(&path).await?;
assert!(
content.contains("Updated in v2.0.0"),
"Agent repo {} #{} should have v2.0.0 content",
repo_idx,
i
);
}
}
println!("500 agent updates completed in {:?}", update_duration);
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
Ok(())
}
#[tokio::test]
async fn test_mixed_repos_file_and_https() -> Result<()> {
init_test_logging(None);
debug!("Starting test_mixed_repos_file_and_https");
let project = TestProject::new().await?;
let mut local_urls = Vec::new();
for repo_num in 0..2 {
let repo = project.create_source_repo(&format!("local_repo_{}", repo_num)).await?;
for i in 0..50 {
repo.add_resource(
"agents",
&format!("agent_{:03}", i),
&format!("# Agent {}\n\nTest agent", i),
)
.await?;
}
repo.commit_all("Initial commit")?;
repo.tag_version("v1.0.0")?;
local_urls.push(repo.bare_file_url(project.sources_path()).await?);
}
let community_agents = [
(
"community_agent_0",
"agents/awesome-claude-code-subagents/categories/01-core-development/api-designer.md",
),
(
"community_agent_1",
"agents/awesome-claude-code-subagents/categories/01-core-development/backend-developer.md",
),
(
"community_agent_2",
"agents/awesome-claude-code-subagents/categories/01-core-development/frontend-developer.md",
),
(
"community_agent_3",
"agents/awesome-claude-code-subagents/categories/02-language-specialists/python-pro.md",
),
(
"community_agent_4",
"agents/awesome-claude-code-subagents/categories/02-language-specialists/rust-engineer.md",
),
(
"community_agent_5",
"agents/awesome-claude-code-subagents/categories/02-language-specialists/javascript-pro.md",
),
(
"community_agent_6",
"agents/awesome-claude-code-subagents/categories/03-infrastructure/database-administrator.md",
),
(
"community_agent_7",
"agents/awesome-claude-code-subagents/categories/04-quality-security/code-reviewer.md",
),
(
"community_agent_8",
"agents/awesome-claude-code-subagents/categories/04-quality-security/test-automator.md",
),
(
"community_agent_9",
"agents/awesome-claude-code-subagents/categories/04-quality-security/security-auditor.md",
),
];
let mut builder = ManifestBuilder::new()
.add_source("local_repo_0", &local_urls[0])
.add_source("local_repo_1", &local_urls[1])
.add_source("community", "https://github.com/aig787/agpm-community.git");
for repo_idx in 0..2 {
for i in 0..50 {
let name = format!("local_repo{}_agent_{:03}", repo_idx, i);
let source = format!("local_repo_{}", repo_idx);
let path = format!("agents/agent_{:03}.md", i);
let filename = format!("{}.md", name);
builder = builder.add_agent(&name, |d| {
d.source(&source).path(&path).version("v1.0.0").filename(&filename)
});
}
}
for (name, path) in community_agents.iter() {
let filename = format!("{}.md", name);
builder = builder.add_agent(name, |d| {
d.source("community").path(path).version("main").filename(&filename)
});
}
let manifest = builder.build();
project.write_manifest(&manifest).await?;
let total_resources = 100 + community_agents.len();
println!(
"🌐 Starting mixed repository test: {} local agents + {} community agents",
100,
community_agents.len()
);
let start = std::time::Instant::now();
let result = project.run_agpm(&["install"])?;
result.assert_success();
let duration = start.elapsed();
println!("✅ Successfully installed {} resources in {:?}", total_resources, duration);
println!(" Local file:// repos: 100 agents");
println!(" Remote https:// repo: {} agents", community_agents.len());
println!(" Average: {:?} per resource", duration / total_resources as u32);
for repo_idx in 0..2 {
for i in (0..50).step_by(10) {
let path = project
.project_path()
.join(format!(".claude/agents/agpm/local_repo{}_agent_{:03}.md", repo_idx, i));
assert!(path.exists(), "Local agent from repo {} #{} should exist", repo_idx, i);
}
}
for (name, _) in community_agents.iter() {
let path = project.project_path().join(format!(".claude/agents/agpm/{}.md", name));
assert!(path.exists(), "Community agent '{}' should exist", name);
}
Ok(())
}
#[tokio::test]
async fn test_community_repo_parallel_checkout_performance() -> Result<()> {
init_test_logging(None);
debug!("Starting test_community_repo_parallel_checkout_performance");
let project = TestProject::new().await?;
let community_agents = [
(
"api-designer",
"agents/awesome-claude-code-subagents/categories/01-core-development/api-designer.md",
),
(
"backend-developer",
"agents/awesome-claude-code-subagents/categories/01-core-development/backend-developer.md",
),
(
"frontend-developer",
"agents/awesome-claude-code-subagents/categories/01-core-development/frontend-developer.md",
),
(
"python-pro",
"agents/awesome-claude-code-subagents/categories/02-language-specialists/python-pro.md",
),
(
"rust-engineer",
"agents/awesome-claude-code-subagents/categories/02-language-specialists/rust-engineer.md",
),
(
"javascript-pro",
"agents/awesome-claude-code-subagents/categories/02-language-specialists/javascript-pro.md",
),
(
"database-administrator",
"agents/awesome-claude-code-subagents/categories/03-infrastructure/database-administrator.md",
),
(
"code-reviewer",
"agents/awesome-claude-code-subagents/categories/04-quality-security/code-reviewer.md",
),
(
"test-automator",
"agents/awesome-claude-code-subagents/categories/04-quality-security/test-automator.md",
),
(
"security-auditor",
"agents/awesome-claude-code-subagents/categories/04-quality-security/security-auditor.md",
),
(
"devops-engineer",
"agents/awesome-claude-code-subagents/categories/03-infrastructure/devops-engineer.md",
),
(
"cloud-architect",
"agents/awesome-claude-code-subagents/categories/03-infrastructure/cloud-architect.md",
),
(
"documentation-engineer",
"agents/awesome-claude-code-subagents/categories/06-developer-experience/documentation-engineer.md",
),
(
"ml-engineer",
"agents/awesome-claude-code-subagents/categories/05-data-ai/ml-engineer.md",
),
(
"multi-agent-coordinator",
"agents/awesome-claude-code-subagents/categories/09-meta-orchestration/multi-agent-coordinator.md",
),
];
let mut builder = ManifestBuilder::new()
.add_source("community", "https://github.com/aig787/agpm-community.git");
for (name, path) in community_agents.iter() {
builder = builder.add_agent(name, |d| d.source("community").path(path).version("main"));
}
let manifest = builder.build();
project.write_manifest(&manifest).await?;
let total_agents = community_agents.len();
println!("📦 Testing parallel checkout from agpm-community repository");
println!(" Repository: https://github.com/aig787/agpm-community.git");
println!(" Agents: {}", total_agents);
let start = std::time::Instant::now();
let result = project.run_agpm(&["install"])?;
result.assert_success();
let duration = start.elapsed();
println!("✅ Successfully installed {} community agents in {:?}", total_agents, duration);
println!(" Average: {:?} per agent", duration / total_agents as u32);
println!(" Rate: {:.1} agents/second", total_agents as f64 / duration.as_secs_f64());
for (name, _) in community_agents.iter() {
let path = project.project_path().join(format!(".claude/agents/agpm/{}.md", name));
assert!(path.exists(), "Community agent '{}' should exist", name);
let content = fs::read_to_string(&path).await?;
assert!(!content.is_empty(), "Community agent '{}' should have content", name);
assert!(
content.contains("# ") || content.contains("## "),
"Community agent '{}' should look like a valid markdown file",
name
);
}
println!("{} community agents installed in {:?}", total_agents, duration);
Ok(())
}
#[tokio::test]
async fn test_community_repo_500_dependencies() -> Result<()> {
init_test_logging(None);
debug!("Starting test_community_repo_500_dependencies");
let project = TestProject::new().await?;
let community_agents = [
(
"api-designer",
"agents/awesome-claude-code-subagents/categories/01-core-development/api-designer.md",
),
(
"backend-developer",
"agents/awesome-claude-code-subagents/categories/01-core-development/backend-developer.md",
),
(
"frontend-developer",
"agents/awesome-claude-code-subagents/categories/01-core-development/frontend-developer.md",
),
(
"python-pro",
"agents/awesome-claude-code-subagents/categories/02-language-specialists/python-pro.md",
),
(
"rust-engineer",
"agents/awesome-claude-code-subagents/categories/02-language-specialists/rust-engineer.md",
),
(
"javascript-pro",
"agents/awesome-claude-code-subagents/categories/02-language-specialists/javascript-pro.md",
),
(
"database-administrator",
"agents/awesome-claude-code-subagents/categories/03-infrastructure/database-administrator.md",
),
(
"code-reviewer",
"agents/awesome-claude-code-subagents/categories/04-quality-security/code-reviewer.md",
),
(
"test-automator",
"agents/awesome-claude-code-subagents/categories/04-quality-security/test-automator.md",
),
(
"security-auditor",
"agents/awesome-claude-code-subagents/categories/04-quality-security/security-auditor.md",
),
(
"devops-engineer",
"agents/awesome-claude-code-subagents/categories/03-infrastructure/devops-engineer.md",
),
(
"cloud-architect",
"agents/awesome-claude-code-subagents/categories/03-infrastructure/cloud-architect.md",
),
(
"documentation-engineer",
"agents/awesome-claude-code-subagents/categories/06-developer-experience/documentation-engineer.md",
),
(
"ml-engineer",
"agents/awesome-claude-code-subagents/categories/05-data-ai/ml-engineer.md",
),
(
"multi-agent-coordinator",
"agents/awesome-claude-code-subagents/categories/09-meta-orchestration/multi-agent-coordinator.md",
),
];
let mut builder = ManifestBuilder::new()
.add_source("community", "https://github.com/aig787/agpm-community.git");
for i in 0..500 {
let agent_index = i % community_agents.len();
let (agent_name_base, agent_path) = community_agents[agent_index];
let unique_agent_name = format!("{}-{:03}", agent_name_base, i);
let unique_filename = format!("{}-{:03}.md", agent_name_base, i);
builder = builder.add_agent(&unique_agent_name, |d| {
d.source("community").path(agent_path).version("main").filename(&unique_filename)
});
}
let manifest = builder.build();
project.write_manifest(&manifest).await?;
let start = std::time::Instant::now();
let result = project.run_agpm(&["install"])?;
result.assert_success();
let duration = start.elapsed();
println!("Installed 500 community dependencies in {:?}", duration);
let agents_dir = project.project_path().join(".claude/agents/agpm");
assert!(agents_dir.exists(), "Agents directory should exist");
let mut agent_files = tokio::fs::read_dir(&agents_dir).await?;
let mut count = 0;
while let Some(entry) = agent_files.next_entry().await? {
if entry.file_name().to_string_lossy().ends_with(".md") {
count += 1;
}
}
assert_eq!(count, 500, "Should have installed exactly 500 agent files");
for i in [0, 100, 250, 499] {
let agent_name_base = community_agents[i % community_agents.len()].0;
let unique_filename = format!("{}-{:03}.md", agent_name_base, i);
let agent_path = agents_dir.join(&unique_filename);
assert!(agent_path.exists(), "Agent {} should exist", unique_filename);
let content = tokio::fs::read_to_string(&agent_path).await?;
assert!(!content.is_empty(), "Agent {} should have content", unique_filename);
assert!(
content.contains("# ") || content.contains("## "),
"Agent '{}' should look like a valid markdown file",
unique_filename
);
}
println!("500 community dependencies installed in {:?}", duration);
Ok(())
}
#[tokio::test]
async fn test_stress_trust_lockfile_checksums_mode() -> Result<()> {
init_test_logging(None);
debug!("Starting test_stress_trust_lockfile_checksums_mode");
let temp_dir = TempDir::new()?;
let project_dir = temp_dir.path().join("project");
fs::create_dir_all(&project_dir).await?;
let repo_dir = temp_dir.path().join("repo");
fs::create_dir_all(&repo_dir).await?;
setup_large_test_repository(&repo_dir, 50).await?;
let repo_url = format!("file://{}", repo_dir.display());
let cache = Cache::with_dir(temp_dir.path().join("cache"))?;
let mut manifest = Manifest::new();
manifest.sources.insert("repo".to_string(), repo_url);
for i in 0..50 {
manifest.agents.insert(
format!("agent_{:03}", i),
ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("repo".to_string()),
path: format!("agents/agent_{:03}.md", i),
version: Some("v1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: Some(format!("agent_{:03}.md", i)),
dependencies: None,
tool: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
})),
);
}
let mut resolver = DependencyResolver::with_cache(manifest.clone(), cache.clone()).await?;
let lockfile = resolver.resolve().await?;
let lockfile_arc = Arc::new(lockfile);
println!("🔒 Installing with checksum verification (trust=false)");
let start_untrusted = std::time::Instant::now();
let progress1 = Arc::new(MultiPhaseProgress::new(false));
let results_untrusted = install_resources(
ResourceFilter::All,
&lockfile_arc,
&manifest,
&project_dir,
cache.clone(),
false,
None,
Some(progress1),
false, None, false, None, )
.await?;
let duration_untrusted = start_untrusted.elapsed();
assert_eq!(results_untrusted.installed_count, 50);
println!(" Untrusted mode: {:?}", duration_untrusted);
let agents_dir = project_dir.join(".claude/agents/agpm");
if agents_dir.exists() {
tokio::fs::remove_dir_all(&agents_dir).await?;
}
println!("✅ Installing with trusted checksums (trust=true)");
let start_trusted = std::time::Instant::now();
let progress2 = Arc::new(MultiPhaseProgress::new(false));
let results_trusted = install_resources(
ResourceFilter::All,
&lockfile_arc,
&manifest,
&project_dir,
cache.clone(),
false,
None,
Some(progress2),
false, None, true, None, )
.await?;
let duration_trusted = start_trusted.elapsed();
assert_eq!(results_trusted.installed_count, 50);
println!(" Trusted mode: {:?}", duration_trusted);
assert!(agents_dir.exists(), "Agents directory should exist");
let mut agent_count = 0;
let mut entries = tokio::fs::read_dir(&agents_dir).await?;
while let Some(entry) = entries.next_entry().await? {
if entry.file_name().to_string_lossy().ends_with(".md") {
agent_count += 1;
}
}
assert_eq!(agent_count, 50, "Should have installed 50 agents");
println!(
"📊 Performance comparison: untrusted={:?}, trusted={:?}",
duration_untrusted, duration_trusted
);
Ok(())
}