#![cfg(feature = "s3")]
extern crate rusoto;
extern crate time;
extern crate hyper;
extern crate env_logger;
extern crate log;
use hyper::Client;
use std::fs::File;
use std::io::Read;
use time::get_time;
use rusoto::{DefaultCredentialsProvider, Region};
use rusoto::s3::{S3Client, HeadObjectRequest, CopyObjectRequest, GetObjectRequest, PutObjectRequest,
DeleteObjectRequest, PutBucketCorsRequest, CORSConfiguration, CORSRule,
CreateBucketRequest, DeleteBucketRequest, CreateMultipartUploadRequest,
UploadPartRequest, CompleteMultipartUploadRequest, CompletedMultipartUpload,
CompletedPart, CompletedPartList};
use rusoto::default_tls_client;
type TestClient = S3Client<DefaultCredentialsProvider, Client>;
#[test]
fn test_all_the_things() {
let _ = env_logger::init();
let client = S3Client::new(default_tls_client().unwrap(),
DefaultCredentialsProvider::new().unwrap(),
Region::UsEast1);
let test_bucket = format!("rusoto_test_bucket_{}", get_time().sec);
let filename = format!("test_file_{}", get_time().sec);
let binary_filename = format!("test_file_b{}", get_time().sec);
let multipart_filename = format!("test_multipart_file_{}", get_time().sec);
test_list_buckets(&client);
test_create_bucket(&client, &test_bucket);
test_multipart_upload(&client, &test_bucket, &multipart_filename);
test_put_bucket_cors(&client, &test_bucket);
test_put_object_with_filename(&client,
&test_bucket,
&filename,
&"tests/sample-data/no_credentials");
test_head_object(&client, &test_bucket, &filename);
test_get_object(&client, &test_bucket, &filename);
test_get_object_range(&client, &test_bucket, &filename);
test_copy_object(&client, &test_bucket, &filename);
test_delete_object(&client, &test_bucket, &filename);
test_put_object_with_filename(&client,
&test_bucket,
&binary_filename,
&"tests/sample-data/binary-file");
test_get_object(&client, &test_bucket, &binary_filename);
test_delete_object(&client, &test_bucket, &binary_filename);
test_delete_bucket(&client, &test_bucket);
}
fn test_multipart_upload(client: &TestClient, bucket: &str, filename: &str) {
let create_multipart_req = CreateMultipartUploadRequest {
bucket: bucket.to_owned(),
key: filename.to_owned(),
..Default::default()
};
let response = client.create_multipart_upload(&create_multipart_req).unwrap();
println!("{:#?}", response);
let upload_id = response.upload_id.unwrap();
let create_upload_part = |body: Vec<u8>, part_number: i32| -> UploadPartRequest {
UploadPartRequest {
body: Some(body),
bucket: bucket.to_owned(),
key: filename.to_owned(),
upload_id: upload_id.to_owned(),
part_number: part_number,
..Default::default()
}
};
let part_req1 = create_upload_part(vec!['a' as u8; 1024 * 1024 * 5], 1);
let part_req2 = create_upload_part("foo".as_bytes().to_vec(), 2);
let mut completed_parts = CompletedPartList::new();
for req in [part_req1, part_req2].into_iter() {
let response = client.upload_part(&req).unwrap();
println!("{:#?}", response);
completed_parts.push(CompletedPart {
e_tag: response.e_tag.clone(),
part_number: Some(req.part_number),
});
}
let completed_upload = CompletedMultipartUpload { parts: Some(completed_parts) };
let complete_req = CompleteMultipartUploadRequest {
bucket: bucket.to_owned(),
key: filename.to_owned(),
upload_id: upload_id.to_owned(),
multipart_upload: Some(completed_upload),
..Default::default()
};
let response = client.complete_multipart_upload(&complete_req).unwrap();
println!("{:#?}", response);
test_delete_object(client, bucket, filename);
}
fn test_create_bucket(client: &TestClient, bucket: &str) {
let create_bucket_req = CreateBucketRequest { bucket: bucket.to_owned(), ..Default::default() };
let result = client.create_bucket(&create_bucket_req).unwrap();
println!("{:#?}", result);
}
fn test_delete_bucket(client: &TestClient, bucket: &str) {
let delete_bucket_req = DeleteBucketRequest { bucket: bucket.to_owned(), ..Default::default() };
let result = client.delete_bucket(&delete_bucket_req).unwrap();
println!("{:#?}", result);
}
fn test_put_object_with_filename(client: &TestClient,
bucket: &str,
dest_filename: &str,
local_filename: &str) {
let mut f = File::open(local_filename).unwrap();
let mut contents: Vec<u8> = Vec::new();
match f.read_to_end(&mut contents) {
Err(why) => panic!("Error opening file to send to S3: {}", why),
Ok(_) => {
let req = PutObjectRequest {
bucket: bucket.to_owned(),
key: dest_filename.to_owned(),
body: Some(contents),
..Default::default()
};
let result = client.put_object(&req);
println!("{:#?}", result);
}
}
}
fn test_head_object(client: &TestClient, bucket: &str, filename: &str) {
let head_req = HeadObjectRequest {
bucket: bucket.to_owned(),
key: filename.to_owned(),
..Default::default()
};
let result = client.head_object(&head_req).unwrap();
println!("{:#?}", result);
}
fn test_get_object(client: &TestClient, bucket: &str, filename: &str) {
let get_req = GetObjectRequest {
bucket: bucket.to_owned(),
key: filename.to_owned(),
..Default::default()
};
let result = client.get_object(&get_req).unwrap();
println!("get object result: {:#?}", result);
assert!(result.body.unwrap().len() > 0);
}
fn test_get_object_range(client: &TestClient, bucket: &str, filename: &str) {
let get_req = GetObjectRequest {
bucket: bucket.to_owned(),
key: filename.to_owned(),
range: Some("bytes=0-1".to_owned()),
..Default::default()
};
let result = client.get_object(&get_req).unwrap();
println!("\nget object range result: {:#?}", result);
assert_eq!(result.content_length.unwrap(), 2);
}
fn test_copy_object(client: &TestClient, bucket: &str, filename: &str) {
let req = CopyObjectRequest {
bucket: bucket.to_owned(),
key: filename.to_owned(),
copy_source: format!("{}/{}", bucket, filename),
cache_control: Some("max-age=123".to_owned()),
content_type: Some("application/json".to_owned()),
metadata_directive: Some("REPLACE".to_owned()),
..Default::default()
};
let result = client.copy_object(&req).unwrap();
println!("{:#?}", result);
}
fn test_delete_object(client: &TestClient, bucket: &str, filename: &str) {
let del_req = DeleteObjectRequest {
bucket: bucket.to_owned(),
key: filename.to_owned(),
..Default::default()
};
let result = client.delete_object(&del_req).unwrap();
println!("{:#?}", result);
}
fn test_list_buckets(client: &TestClient) {
let result = client.list_buckets().unwrap();
println!("{:#?}", result);
}
fn test_put_bucket_cors(client: &TestClient, bucket: &str) {
let cors_rules =
vec![CORSRule {
allowed_methods: vec!["PUT".to_owned(), "POST".to_owned(), "DELETE".to_owned()],
allowed_origins: vec!["http://www.example.com".to_owned()],
allowed_headers: Some(vec!["*".to_owned()]),
max_age_seconds: Some(3000),
expose_headers: Some(vec!["x-amz-server-side-encryption".to_owned()]),
..Default::default()
}];
let cors_configuration = CORSConfiguration { cors_rules: cors_rules };
let req = PutBucketCorsRequest {
bucket: bucket.to_owned(),
cors_configuration: cors_configuration,
..Default::default()
};
let result = client.put_bucket_cors(&req).unwrap();
println!("{:#?}", result);
}