use anyhow::Result;
use std::time::Duration;
use tokio::fs;
use tokio::time::Instant;
use crate::common::{ManifestBuilder, TestProject};
#[tokio::test]
async fn test_instance_cache_reuse() -> Result<()> {
let project = TestProject::new().await?;
let source_repo = project.create_source_repo("official").await?;
source_repo.add_resource("agents", "agent-1", "# Agent 1\n\nTest agent 1").await?;
source_repo.add_resource("agents", "agent-2", "# Agent 2\n\nTest agent 2").await?;
source_repo.add_resource("agents", "agent-3", "# Agent 3\n\nTest agent 3").await?;
source_repo.commit_all("Add test agents")?;
source_repo.tag_version("v1.0.0")?;
let source_url = source_repo.bare_file_url(project.sources_path()).await?;
let manifest_content = ManifestBuilder::new()
.add_source("official", &source_url)
.add_standard_agent("agent1", "official", "agents/agent-1.md")
.add_standard_agent("agent2", "official", "agents/agent-2.md")
.add_standard_agent("agent3", "official", "agents/agent-3.md")
.build();
project.write_manifest(&manifest_content).await?;
let start = Instant::now();
let output = project.run_agpm(&["install"])?;
output.assert_success();
let first_duration = start.elapsed();
fs::remove_dir_all(project.project_path().join(".claude")).await?;
let start = Instant::now();
let output = project.run_agpm(&["install"])?;
output.assert_success();
let second_duration = start.elapsed();
assert!(
second_duration <= first_duration + Duration::from_millis(500),
"Second install should reuse cache and be comparable in speed. First: {:?}, Second: {:?}",
first_duration,
second_duration
);
assert!(project.project_path().join(".claude/agents/agpm/agent-1.md").exists());
assert!(project.project_path().join(".claude/agents/agpm/agent-2.md").exists());
assert!(project.project_path().join(".claude/agents/agpm/agent-3.md").exists());
Ok(())
}
#[tokio::test]
async fn test_fetch_caching_prevents_redundancy() -> Result<()> {
let project = TestProject::new().await?;
let source_repo = project.create_source_repo("official").await?;
source_repo
.add_resource("agents", "fetch-agent-1", "# Fetch Agent 1\n\nTest fetch agent 1")
.await?;
source_repo
.add_resource("agents", "fetch-agent-2", "# Fetch Agent 2\n\nTest fetch agent 2")
.await?;
source_repo
.add_resource("snippets", "fetch-snippet-1", "# Fetch Snippet 1\n\nTest fetch snippet 1")
.await?;
source_repo.commit_all("Add test resources")?;
source_repo.tag_version("v1.0.0")?;
let source_url = source_repo.bare_file_url(project.sources_path()).await?;
let manifest_content = ManifestBuilder::new()
.add_source("official", &source_url)
.add_standard_agent("agent1", "official", "agents/fetch-agent-1.md")
.add_standard_agent("agent2", "official", "agents/fetch-agent-2.md")
.add_standard_snippet("snippet1", "official", "snippets/fetch-snippet-1.md")
.build();
project.write_manifest(&manifest_content).await?;
let start = Instant::now();
let output = project.run_agpm(&["install", "--verbose"])?;
output.assert_success();
let duration = start.elapsed();
assert!(
duration < Duration::from_secs(30),
"Install with fetch caching should complete in under 30 seconds, took {:?}",
duration
);
assert!(project.project_path().join(".claude/agents/agpm/fetch-agent-1.md").exists());
assert!(project.project_path().join(".claude/agents/agpm/fetch-agent-2.md").exists());
assert!(project.project_path().join(".agpm/snippets/fetch-snippet-1.md").exists());
drop(source_repo);
Ok(())
}
#[tokio::test]
async fn test_cache_high_concurrency() -> Result<()> {
let project = TestProject::new().await?;
let source_repo = project.create_source_repo("official").await?;
for i in 0..20 {
source_repo
.add_resource(
"agents",
&format!("concurrent-agent-{:02}", i),
&format!("# Concurrent Agent {:02}\n\nTest concurrent agent {}", i, i),
)
.await?;
}
source_repo.commit_all("Add concurrent test agents")?;
source_repo.tag_version("v1.0.0")?;
let source_url = source_repo.bare_file_url(project.sources_path()).await?;
let mut builder = ManifestBuilder::new().add_source("official", &source_url);
for i in 0..20 {
let name = format!("agent{:02}", i);
let path = format!("agents/concurrent-agent-{:02}.md", i);
builder = builder.add_standard_agent(&name, "official", &path);
}
let manifest_content = builder.build();
project.write_manifest(&manifest_content).await?;
let start = Instant::now();
let output = project.run_agpm(&["install"])?;
output.assert_success();
let duration = start.elapsed();
println!("High concurrency install took: {:?}", duration);
for i in 0..20 {
let agent_path = project
.project_path()
.join(format!(".claude/agents/agpm/concurrent-agent-{:02}.md", i));
assert!(agent_path.exists(), "Agent {} should be installed", i);
}
Ok(())
}
#[tokio::test]
async fn test_cache_persistence() -> Result<()> {
let project = TestProject::new().await?;
let source_repo = project.create_source_repo("official").await?;
source_repo
.add_resource("agents", "persistent-agent", "# Persistent Agent\n\nTest persistent agent")
.await?;
source_repo
.add_resource(
"snippets",
"persistent-snippet",
"# Persistent Snippet\n\nTest persistent snippet",
)
.await?;
source_repo.commit_all("Add persistent test resources")?;
source_repo.tag_version("v1.0.0")?;
let source_url = source_repo.bare_file_url(project.sources_path()).await?;
let manifest_content = ManifestBuilder::new()
.add_source("official", &source_url)
.add_standard_agent("agent", "official", "agents/persistent-agent.md")
.add_standard_snippet("snippet", "official", "snippets/persistent-snippet.md")
.build();
project.write_manifest(&manifest_content).await?;
let output = project.run_agpm(&["install"])?;
output.assert_success();
let output = project.run_agpm(&["update"])?;
output.assert_success();
let output = project.run_agpm(&["list"])?;
output.assert_success();
assert!(project.project_path().join(".claude/agents/agpm/persistent-agent.md").exists());
assert!(project.project_path().join(".agpm/snippets/persistent-snippet.md").exists());
Ok(())
}