mod test_utils;
#[cfg(feature = "http")]
mod http_happy {
use crate::test_utils::{read_to_end, test_data};
use httptest::{matchers::*, responders::*, Expectation, Server};
use std::str::FromStr;
use tough::{DefaultTransport, HttpTransport, RepositoryLoader, TargetName, Transport};
use url::Url;
async fn create_successful_get(relative_path: &str) -> httptest::Expectation {
let repo_dir = test_data().join("tuf-reference-impl");
let file_bytes = tokio::fs::read(repo_dir.join(relative_path)).await.unwrap();
Expectation::matching(request::method_path("GET", format!("/{}", relative_path)))
.times(1)
.respond_with(
status_code(200)
.append_header("content-type", "application/octet-stream")
.body(file_bytes),
)
}
fn create_unsuccessful_get(relative_path: &str) -> httptest::Expectation {
Expectation::matching(request::method_path("GET", format!("/{}", relative_path)))
.times(1)
.respond_with(status_code(403))
}
#[tokio::test]
async fn test_http_transport_happy_case() {
run_http_test(HttpTransport::default()).await;
}
#[tokio::test]
async fn test_http_default_transport() {
run_http_test(DefaultTransport::default()).await;
}
async fn run_http_test<T: Transport + Send + Sync + 'static>(transport: T) {
let server = Server::run();
let repo_dir = test_data().join("tuf-reference-impl");
server.expect(create_successful_get("metadata/timestamp.json").await);
server.expect(create_successful_get("metadata/snapshot.json").await);
server.expect(create_successful_get("metadata/targets.json").await);
server.expect(create_successful_get("metadata/role1.json").await);
server.expect(create_successful_get("metadata/role2.json").await);
server.expect(create_successful_get("targets/file1.txt").await);
server.expect(create_successful_get("targets/file2.txt").await);
server.expect(create_unsuccessful_get("metadata/2.root.json"));
let metadata_base_url = Url::from_str(server.url_str("/metadata").as_str()).unwrap();
let targets_base_url = Url::from_str(server.url_str("/targets").as_str()).unwrap();
let repo = RepositoryLoader::new(
&tokio::fs::read(repo_dir.join("metadata").join("1.root.json"))
.await
.unwrap(),
metadata_base_url,
targets_base_url,
)
.transport(transport)
.load()
.await
.unwrap();
let file1 = TargetName::new("file1.txt").unwrap();
assert_eq!(
read_to_end(repo.read_target(&file1).await.unwrap().unwrap()).await,
&b"This is an example target file."[..]
);
let file2 = TargetName::new("file2.txt").unwrap();
assert_eq!(
read_to_end(repo.read_target(&file2).await.unwrap().unwrap()).await,
&b"This is an another example target file."[..]
);
assert_eq!(
repo.targets()
.signed
.targets
.get(&file1)
.unwrap()
.custom
.get("file_permissions")
.unwrap(),
"0644"
);
}
}
#[cfg(feature = "http")]
#[cfg(feature = "integ")]
mod http_integ {
use crate::test_utils::test_data;
use failure_server::IntegServers;
use std::path::PathBuf;
use tough::{HttpTransportBuilder, RepositoryLoader};
use url::Url;
pub fn tuf_reference_impl() -> PathBuf {
test_data().join("tuf-reference-impl")
}
pub fn tuf_reference_impl_metadata() -> PathBuf {
tuf_reference_impl().join("metadata")
}
pub fn tuf_reference_impl_root_json() -> PathBuf {
tuf_reference_impl_metadata().join("1.root.json")
}
#[tokio::test]
async fn test_retries() {
let tuf_reference_path = tuf_reference_impl();
let mut integ_servers = IntegServers::new(tuf_reference_path).unwrap();
integ_servers
.run()
.await
.expect("Failed to run integration test HTTP servers");
for i in 0..5 {
let transport = HttpTransportBuilder::new()
.tries(200)
.initial_backoff(std::time::Duration::from_nanos(100))
.max_backoff(std::time::Duration::from_millis(1))
.build();
let root_path = tuf_reference_impl_root_json();
RepositoryLoader::new(
&tokio::fs::read(&root_path).await.unwrap(),
Url::parse("http://localhost:10102/metadata").unwrap(),
Url::parse("http://localhost:10102/targets").unwrap(),
)
.transport(transport)
.load()
.await
.unwrap();
println!("{}:{} SUCCESSFULLY LOADED THE REPO {}", file!(), line!(), i,);
}
integ_servers
.teardown()
.expect("failed to stop HTTP servers");
}
}