blob: f0990fb3873df4aeea9cff2158642a4fb34d7db6 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
cobalt_sw_delivery_registry as metrics,
fidl_fuchsia_pkg_ext::RepositoryConfigBuilder,
fuchsia_async as fasync,
fuchsia_pkg_testing::{serve::responder, PackageBuilder, RepositoryBuilder},
fuchsia_zircon::Status,
lib::{TestEnvBuilder, EMPTY_REPO_PATH},
std::{sync::Arc, time::Duration},
};
#[fasync::run_singlethreaded(test)]
async fn resolve_disallow_local_mirror_fails() {
let pkg = PackageBuilder::new("test")
.add_resource_at("test_file", "hi there".as_bytes())
.build()
.await
.unwrap();
let repo = Arc::new(
RepositoryBuilder::from_template_dir(EMPTY_REPO_PATH)
.add_package(&pkg)
.build()
.await
.unwrap(),
);
// Local mirror defaults not being enabled.
let env = TestEnvBuilder::new()
.local_mirror_repo(&repo, "fuchsia-pkg://test".parse().unwrap())
.build()
.await;
let repo_config = repo.make_repo_config("fuchsia-pkg://test".parse().unwrap(), None, true);
env.proxies.repo_manager.add(repo_config.into()).await.unwrap().unwrap();
let pkg_url = format!("fuchsia-pkg://test/{}", pkg.name());
let result = env.resolve_package(&pkg_url).await;
assert_eq!(result.unwrap_err(), Status::INTERNAL);
env.stop().await;
}
#[fasync::run_singlethreaded(test)]
async fn resolve_local_and_remote_mirrors_fails() {
let pkg = PackageBuilder::new("test")
.add_resource_at("test_file", "hi there".as_bytes())
.build()
.await
.unwrap();
let repo = Arc::new(
RepositoryBuilder::from_template_dir(EMPTY_REPO_PATH)
.add_package(&pkg)
.build()
.await
.unwrap(),
);
let env = TestEnvBuilder::new()
.allow_local_mirror()
.local_mirror_repo(&repo, "fuchsia-pkg://test".parse().unwrap())
.build()
.await;
let server = repo.server().start().expect("Starting server succeeds");
let repo_config = server.make_repo_config("fuchsia-pkg://test".parse().unwrap());
let repo_config = RepositoryConfigBuilder::from(repo_config).use_local_mirror(true).build();
env.proxies.repo_manager.add(repo_config.into()).await.unwrap().unwrap();
let pkg_url = format!("fuchsia-pkg://test/{}", pkg.name());
let result = env.resolve_package(&pkg_url).await;
assert_eq!(result.unwrap_err(), Status::INTERNAL);
env.stop().await;
}
#[fasync::run_singlethreaded(test)]
async fn create_tuf_client_timeout() {
let repo =
Arc::new(RepositoryBuilder::from_template_dir(EMPTY_REPO_PATH).build().await.unwrap());
let env = TestEnvBuilder::new().tuf_metadata_timeout(Duration::from_secs(0)).build().await;
let server = repo
.server()
.response_overrider(responder::ForPath::new("/1.root.json", responder::Hang))
.start()
.expect("Starting server succeeds");
let repo_config = server.make_repo_config("fuchsia-pkg://test".parse().unwrap());
env.proxies.repo_manager.add(repo_config.into()).await.unwrap().unwrap();
// The package does not need to exist in the repository, because the resolve will fail before
// it obtains metadata.
let result = env.resolve_package("fuchsia-pkg://test/missing-package").await;
assert_eq!(result.unwrap_err(), Status::INTERNAL);
env.assert_count_events(
metrics::CREATE_TUF_CLIENT_METRIC_ID,
vec![metrics::CreateTufClientMetricDimensionResult::DeadlineExceeded],
)
.await;
env.stop().await;
}
#[fasync::run_singlethreaded(test)]
async fn update_tuf_client_timeout() {
let repo =
Arc::new(RepositoryBuilder::from_template_dir(EMPTY_REPO_PATH).build().await.unwrap());
// pkg-resolver uses this timeout when creating and updating tuf metadata, so since this test
// hangs the update, the timeout needs to be long enough for the create to succeed.
// TODO(fxbug.dev/66946) have separate tuf client create and update timeout durations.
let env = TestEnvBuilder::new().tuf_metadata_timeout(Duration::from_secs(10)).build().await;
// pkg-resolver uses tuf::client::Client::with_trusted_root_keys to create its TUF client.
// That method will only retrieve the specified version of the root metadata (1 for these
// tests), with the rest of the metadata being retrieved during the first update. This means
// that hanging all attempts for timestamp.json metadata will allow tuf client creation to
// succeed but still fail tuf client update.
let server = repo
.server()
.response_overrider(responder::ForPath::new("/timestamp.json", responder::Hang))
.start()
.expect("Starting server succeeds");
let repo_config = server.make_repo_config("fuchsia-pkg://test".parse().unwrap());
env.proxies.repo_manager.add(repo_config.into()).await.unwrap().unwrap();
// The package does not need to exist in the repository, because the resolve will fail before
// it obtains metadata.
let result = env.resolve_package("fuchsia-pkg://test/missing-package").await;
// The resolve will still fail, even though pkg-resolver normally ignores failed tuf updates,
// see fxbug.dev/43646, because the tuf client actually downloads most of the metadata during
// the first update, not during creation.
assert_eq!(result.unwrap_err(), Status::INTERNAL);
env.assert_count_events(
metrics::UPDATE_TUF_CLIENT_METRIC_ID,
vec![metrics::UpdateTufClientMetricDimensionResult::DeadlineExceeded],
)
.await;
env.stop().await;
}
#[fasync::run_singlethreaded(test)]
async fn download_blob_header_timeout() {
let pkg = PackageBuilder::new("test").build().await.unwrap();
let repo = Arc::new(
RepositoryBuilder::from_template_dir(EMPTY_REPO_PATH)
.add_package(&pkg)
.build()
.await
.unwrap(),
);
let env =
TestEnvBuilder::new().blob_network_header_timeout(Duration::from_secs(0)).build().await;
let server = repo
.server()
.response_overrider(responder::ForPathPrefix::new("/blobs/", responder::Hang))
.start()
.expect("Starting server succeeds");
let repo_config = server.make_repo_config("fuchsia-pkg://test".parse().unwrap());
env.proxies.repo_manager.add(repo_config.into()).await.unwrap().unwrap();
let result = env.resolve_package("fuchsia-pkg://test/test").await;
assert_eq!(result.unwrap_err(), Status::UNAVAILABLE);
env.assert_count_events(
metrics::FETCH_BLOB_METRIC_ID,
vec![
(
metrics::FetchBlobMetricDimensionResult::BlobHeaderDeadlineExceeded,
metrics::FetchBlobMetricDimensionResumed::False
);
2
],
)
.await;
env.stop().await;
}
#[fasync::run_singlethreaded(test)]
async fn download_blob_body_timeout() {
let pkg = PackageBuilder::new("test").build().await.unwrap();
let repo = Arc::new(
RepositoryBuilder::from_template_dir(EMPTY_REPO_PATH)
.add_package(&pkg)
.build()
.await
.unwrap(),
);
let env = TestEnvBuilder::new().blob_network_body_timeout(Duration::from_secs(0)).build().await;
let server = repo
.server()
.response_overrider(responder::ForPathPrefix::new("/blobs/", responder::HangBody))
.start()
.expect("Starting server succeeds");
let repo_config = server.make_repo_config("fuchsia-pkg://test".parse().unwrap());
env.proxies.repo_manager.add(repo_config.into()).await.unwrap().unwrap();
let result = env.resolve_package("fuchsia-pkg://test/test").await;
assert_eq!(result.unwrap_err(), Status::UNAVAILABLE);
env.assert_count_events(
metrics::FETCH_BLOB_METRIC_ID,
vec![
(
metrics::FetchBlobMetricDimensionResult::BlobBodyDeadlineExceeded,
metrics::FetchBlobMetricDimensionResumed::False
);
2
],
)
.await;
env.stop().await;
}