use std::path::PathBuf;
use tempfile::TempDir;
use test_utils::{dir_url, read_to_end, test_data, DATA_1, DATA_2};
use tough::{Repository, RepositoryLoader, TargetName};
use url::Url;
mod test_utils;
struct RepoPaths {
root_path: PathBuf,
metadata_base_url: Url,
targets_base_url: Url,
}
impl RepoPaths {
fn new() -> Self {
let base = test_data().join("tuf-reference-impl");
RepoPaths {
root_path: base.join("metadata").join("1.root.json"),
metadata_base_url: dir_url(base.join("metadata")),
targets_base_url: dir_url(base.join("targets")),
}
}
async fn root(&self) -> Vec<u8> {
tokio::fs::read(&self.root_path).await.unwrap()
}
}
async fn load_tuf_reference_impl(paths: &RepoPaths) -> Repository {
RepositoryLoader::new(
&paths.root().await,
paths.metadata_base_url.clone(),
paths.targets_base_url.clone(),
)
.load()
.await
.unwrap()
}
#[tokio::test]
async fn test_repo_cache_all_targets() {
let repo_paths = RepoPaths::new();
let repo = load_tuf_reference_impl(&repo_paths).await;
let destination = TempDir::new().unwrap();
let metadata_destination = destination.as_ref().join("metadata");
let targets_destination = destination.as_ref().join("targets");
repo.cache(
&metadata_destination,
&targets_destination,
None::<&[&str]>,
true,
)
.await
.unwrap();
let copied_repo = RepositoryLoader::new(
&repo_paths.root().await,
dir_url(&metadata_destination),
dir_url(&targets_destination),
)
.load()
.await
.unwrap();
let file1 = TargetName::new("file1.txt").unwrap();
let file_data = read_to_end(copied_repo.read_target(&file1).await.unwrap().unwrap()).await;
assert_eq!(31, file_data.len());
let file2 = TargetName::new("file2.txt").unwrap();
let file_data = read_to_end(copied_repo.read_target(&file2).await.unwrap().unwrap()).await;
assert_eq!(39, file_data.len());
}
#[tokio::test]
async fn test_repo_cache_list_of_two_targets() {
let repo_paths = RepoPaths::new();
let repo = load_tuf_reference_impl(&repo_paths).await;
let destination = TempDir::new().unwrap();
let metadata_destination = destination.as_ref().join("metadata");
let targets_destination = destination.as_ref().join("targets");
let targets_subset = vec!["file1.txt".to_string(), "file2.txt".to_string()];
repo.cache(
&metadata_destination,
&targets_destination,
Some(&targets_subset),
true,
)
.await
.unwrap();
let copied_repo = RepositoryLoader::new(
&repo_paths.root().await,
dir_url(&metadata_destination),
dir_url(&targets_destination),
)
.load()
.await
.unwrap();
let file1 = TargetName::new("file1.txt").unwrap();
let file_data = read_to_end(copied_repo.read_target(&file1).await.unwrap().unwrap()).await;
assert_eq!(31, file_data.len());
let file2 = TargetName::new("file2.txt").unwrap();
let file_data = read_to_end(copied_repo.read_target(&file2).await.unwrap().unwrap()).await;
assert_eq!(39, file_data.len());
}
#[tokio::test]
async fn test_repo_cache_some() {
let repo_paths = RepoPaths::new();
let repo = load_tuf_reference_impl(&repo_paths).await;
let destination = TempDir::new().unwrap();
let metadata_destination = destination.as_ref().join("metadata");
let targets_destination = destination.as_ref().join("targets");
let targets_subset = vec!["file2.txt".to_string()];
repo.cache(
&metadata_destination,
&targets_destination,
Some(&targets_subset),
true,
)
.await
.unwrap();
let copied_repo = RepositoryLoader::new(
&repo_paths.root().await,
dir_url(&metadata_destination),
dir_url(&targets_destination),
)
.load()
.await
.unwrap();
let file1 = TargetName::new("file1.txt").unwrap();
let read_target_result = copied_repo.read_target(&file1).await;
assert!(read_target_result.is_err());
let file2 = TargetName::new("file2.txt").unwrap();
let file_data = read_to_end(copied_repo.read_target(&file2).await.unwrap().unwrap()).await;
assert_eq!(39, file_data.len());
}
#[tokio::test]
async fn test_repo_cache_metadata() {
let repo_paths = RepoPaths::new();
let repo = load_tuf_reference_impl(&repo_paths).await;
let destination = TempDir::new().unwrap();
let metadata_destination = destination.as_ref().join("metadata");
repo.cache_metadata(&metadata_destination, true)
.await
.unwrap();
let targets_destination = destination.as_ref().join("targets");
let copied_repo = RepositoryLoader::new(
&repo_paths.root().await,
dir_url(&metadata_destination),
dir_url(targets_destination),
)
.load()
.await
.unwrap();
for (target_name, _) in copied_repo.targets().signed.targets_map() {
assert!(copied_repo.read_target(&target_name).await.is_err())
}
let read_delegated_role_option = copied_repo.delegated_role("role1");
assert!(read_delegated_role_option.is_some());
assert!(metadata_destination.join("1.root.json").exists());
}
#[tokio::test]
async fn test_repo_cache_metadata_no_root_chain() {
let repo_paths = RepoPaths::new();
let repo = load_tuf_reference_impl(&repo_paths).await;
let destination = TempDir::new().unwrap();
let metadata_destination = destination.as_ref().join("metadata");
repo.cache_metadata(&metadata_destination, false)
.await
.unwrap();
assert!(!metadata_destination.join("1.root.json").exists());
}
#[tokio::test]
async fn test_repo_cache_consistent_snapshots() {
let repo_name = "consistent-snapshots";
let metadata_dir = test_data().join(repo_name).join("metadata");
let targets_dir = test_data().join(repo_name).join("targets");
let root = metadata_dir.join("1.root.json");
let repo = RepositoryLoader::new(
&tokio::fs::read(&root).await.unwrap(),
dir_url(metadata_dir),
dir_url(targets_dir),
)
.load()
.await
.unwrap();
let destination = TempDir::new().unwrap();
let metadata_destination = destination.as_ref().join("metadata");
let targets_destination = destination.as_ref().join("targets");
repo.cache(
&metadata_destination,
&targets_destination,
Option::<&[&str]>::None,
true,
)
.await
.unwrap();
let copied_repo = RepositoryLoader::new(
&tokio::fs::read(&root).await.unwrap(),
dir_url(&metadata_destination),
dir_url(&targets_destination),
)
.load()
.await
.unwrap();
let data1 = String::from_utf8(
read_to_end(
copied_repo
.read_target(&TargetName::new("data1.txt").unwrap())
.await
.unwrap()
.unwrap(),
)
.await,
)
.unwrap();
assert_eq!(data1, DATA_1);
let data2 = String::from_utf8(
read_to_end(
copied_repo
.read_target(&TargetName::new("data2.txt").unwrap())
.await
.unwrap()
.unwrap(),
)
.await,
)
.unwrap();
assert_eq!(data2, DATA_2);
let expected_filepath = targets_destination
.join("5aa1d2b3bea034a0f9d0b27a1bc72919b3145a2b092b72ac0415a05e07e2bdd1.data1.txt");
assert!(expected_filepath.is_file())
}