use crate::{
progress::{TestCreateProgressCallback, TestExtractProgressCallback},
Result,
};
use aws_config::meta::region::RegionProviderChain;
use aws_types::region::Region;
use ssstar::{Config, CreateArchiveJobBuilder, TargetArchive};
use ssstar_testing::test_data;
use url::Url;
const TEST_BUCKET: &str = dotenv!("TEST_S3_BUCKET");
const TEST_BUCKET_REGION: &str = dotenv!("TEST_S3_BUCKET_REGION");
async fn create_s3_client() -> Result<aws_sdk_s3::Client> {
let region_provider = RegionProviderChain::first_try(Region::new(TEST_BUCKET_REGION));
let aws_config_builder = aws_config::from_env().region(region_provider);
let aws_config = aws_config_builder.load().await;
let s3_config_builder = aws_sdk_s3::config::Builder::from(&aws_config);
Ok(aws_sdk_s3::Client::from_conf(s3_config_builder.build()))
}
async fn run_test(test_data: Vec<test_data::TestObject>) -> Result<()> {
let client = create_s3_client().await?;
let (prefix, test_data) = test_data::prepend_unique_prefix(test_data);
let test_data = test_data::make_test_data(&client, TEST_BUCKET, test_data).await?;
let archive_url: Url = format!("s3://{TEST_BUCKET}/{prefix}test.tar").parse()?;
let target_archive = TargetArchive::ObjectStorage(archive_url.clone());
let mut builder = CreateArchiveJobBuilder::new(Config::default(), target_archive);
builder
.add_input(&format!("s3://{TEST_BUCKET}/{prefix}**").parse()?)
.await?;
let job = builder.build().await?;
let progress = TestCreateProgressCallback::new();
job.run(futures::future::pending(), progress.clone())
.await?;
progress.sanity_check_updates();
let archive_key = archive_url.path().strip_prefix('/').unwrap();
let object = client
.head_object()
.bucket(TEST_BUCKET)
.key(archive_key)
.checksum_mode(aws_sdk_s3::types::ChecksumMode::Enabled)
.send()
.await?;
assert!(object.checksum_sha256().is_some());
let source_archive = ssstar::SourceArchive::ObjectStorage(archive_url);
let restore_prefix = format!("restore-{prefix}");
let builder = ssstar::ExtractArchiveJobBuilder::new(
Config::default(),
source_archive,
format!("s3://{TEST_BUCKET}/{restore_prefix}").parse()?,
)
.await?;
let job = builder.build().await?;
let progress = TestExtractProgressCallback::new();
job.run(futures::future::pending(), progress.clone())
.await?;
progress.sanity_check_updates();
test_data::validate_test_data_in_s3(
&client,
&test_data,
TEST_BUCKET,
&restore_prefix,
test_data
.keys()
.map(|key| key.to_string())
.collect::<Vec<_>>(),
)
.await?;
Ok(())
}
#[test]
#[ignore = "Run explicitly with --ignored if you're sure you have setup S3 access correctly"]
fn small_objects_archive_in_bucket() -> Result<()> {
ssstar_testing::logging::test_with_logging(async move {
let test_data = vec![
test_data::TestObject::new("test1", "1KiB"),
test_data::TestObject::new("test2", "1KiB"),
test_data::TestObject::new("foo/test3", "1KiB"),
];
run_test(test_data).await
})
}
#[test]
#[ignore = "Run explicitly with --ignored if you're sure you have setup S3 access correctly"]
fn small_objects_multipart_archive_in_bucket() -> Result<()> {
ssstar_testing::logging::test_with_logging(async move {
let test_data = vec![
test_data::TestObject::new("test1", "1MiB"),
test_data::TestObject::new("test2", "2MiB"),
test_data::TestObject::new("foo/test1", "2MiB"),
test_data::TestObject::new("foo/test2", "2MiB"),
test_data::TestObject::new("bar/test1", "2MiB"),
];
run_test(test_data).await
})
}
#[test]
#[ignore = "Run explicitly with --ignored if you're sure you have setup S3 access correctly"]
fn multipart_objects_multipart_archive_in_bucket() -> Result<()> {
ssstar_testing::logging::test_with_logging(async move {
let test_data = vec![
test_data::TestObject::new("test1", "1MiB"),
test_data::TestObject::new("test2", "9MiB"),
test_data::TestObject::new("foo/test1", "8MiB"),
test_data::TestObject::new("foo/test2", "9MiB"),
test_data::TestObject::new("bar/test1", "10"),
];
run_test(test_data).await
})
}