15 #include <condition_variable> 19 #include <boost/bind.hpp> 21 #include <aws/s3/S3Client.h> 22 #include <gtest/gtest.h> 23 #include <gmock/gmock.h> 30 using ::testing::DoAll;
31 using ::testing::InvokeWithoutArgs;
32 using ::testing::IgnoreResult;
33 using ::testing::Return;
40 MOCK_METHOD3(PutObject, Model::PutObjectOutcome(
const std::string &,
const std::string &,
const std::string &));
47 std::unique_ptr<MockS3Facade>
facade;
58 num_feedback_calls = 0;
59 facade = std::make_unique<MockS3Facade>(enable_encryption);
62 {
"file1",
"location1"},
63 {
"file2",
"location2"}
71 EXPECT_EQ(callback_uploads.size(), num_feedback_calls);
72 completed_uploads = callback_uploads;
76 std::mutex & lock_during_uploading,
77 std::condition_variable & notify_is_uploading,
79 const boost::function<
void(
const std::vector<UploadDescription>&)>& callback,
80 int additional_returns = 0) {
81 auto & mock_calls = EXPECT_CALL(*facade, PutObject(_,_,_))
83 InvokeWithoutArgs([&is_uploading, ¬ify_is_uploading, &lock_during_uploading]() {
86 notify_is_uploading.notify_all();
88 std::unique_lock<std::mutex> lock(lock_during_uploading);
90 Return(successful_outcome)));
91 for (
int i = 0; i < additional_returns; ++i) {
92 mock_calls.WillOnce(Return(successful_outcome));
95 manager = std::unique_ptr<S3UploadManager>(
new S3UploadManager(std::move(facade)));
97 auto upload = [
this, &manager, callback]() {
98 return manager->UploadFiles(this->uploads,
"bucket", callback);
101 return std::async(std::launch::async, upload);
107 Aws::Client::ClientConfiguration config;
110 auto outcome = manager.
UploadFiles(uploads,
"bucket",
111 [
this](
const std::vector<UploadDescription>& callback_uploads)
112 {this->FeedbackCallback(callback_uploads);});
116 EXPECT_FALSE(outcome.IsSuccess());
121 EXPECT_CALL(*facade,PutObject(_,_,_))
123 .WillRepeatedly(Return(successful_outcome));
127 EXPECT_TRUE(completed_uploads.empty());
128 auto outcome = manager.
UploadFiles(uploads,
"bucket",
129 [
this](
const std::vector<UploadDescription>& callback_uploads)
130 {this->FeedbackCallback(callback_uploads);});
131 EXPECT_TRUE(outcome.IsSuccess());
132 EXPECT_EQ(uploads.size(), num_feedback_calls);
133 EXPECT_EQ(uploads, completed_uploads);
141 EXPECT_CALL(*facade,PutObject(_,_,_))
142 .WillOnce(Return(successful_outcome))
143 .WillOnce(Return(failed_outcome));
146 auto outcome = manager.
UploadFiles(uploads,
"bucket",
147 [
this](
const std::vector<UploadDescription>& callback_uploads)
148 {this->FeedbackCallback(callback_uploads);});
149 EXPECT_FALSE(outcome.IsSuccess());
150 EXPECT_EQ(1u, num_feedback_calls);
151 EXPECT_EQ(1u, completed_uploads.size());
152 EXPECT_EQ(uploads.at(0), completed_uploads.at(0));
158 std::unique_ptr<S3UploadManager> manager;
159 bool is_uploading =
false;
161 std::mutex pause_mutex;
163 std::condition_variable upload_cv;
165 auto feedback_callback = [
this](
const std::vector<UploadDescription> & callback_uploads) {
166 this->FeedbackCallback(callback_uploads);
172 std::future<Model::PutObjectOutcome> outcome1 = UploadFilesUntilUnlocked(manager, pause_mutex, upload_cv, is_uploading, feedback_callback, 1);
177 std::unique_lock<std::mutex> lk(cv_mutex);
178 upload_cv.wait(lk, [&is_uploading]() {
return is_uploading; });
181 EXPECT_FALSE(manager->IsAvailable());
183 Model::PutObjectOutcome outcome2 = manager->UploadFiles(uploads,
"bucket", feedback_callback);
186 EXPECT_EQ(S3Errors::INVALID_ACTION, outcome2.GetError().GetErrorType());
188 EXPECT_TRUE(completed_uploads.empty());
191 pause_mutex.unlock();
194 EXPECT_TRUE(outcome1.get().IsSuccess());
195 EXPECT_EQ(uploads, completed_uploads);
196 EXPECT_EQ(uploads.size(), num_feedback_calls);
198 EXPECT_TRUE(manager->IsAvailable());
203 std::unique_ptr<S3UploadManager> manager;
204 bool is_uploading =
false;
206 std::mutex pause_mutex;
208 std::condition_variable upload_cv;
210 auto feedback_callback = [
this](
const std::vector<UploadDescription>& callback_uploads) {
211 this->FeedbackCallback(callback_uploads);
217 std::future<Model::PutObjectOutcome> outcome = UploadFilesUntilUnlocked(manager, pause_mutex, upload_cv, is_uploading, feedback_callback);
222 std::unique_lock<std::mutex> lk(cv_mutex);
223 upload_cv.wait(lk, [&is_uploading]() {
return is_uploading; });
226 EXPECT_FALSE(manager->IsAvailable());
228 manager->CancelUpload();
231 pause_mutex.unlock();
234 EXPECT_TRUE(outcome.get().IsSuccess());
235 EXPECT_EQ(1u, num_feedback_calls);
236 EXPECT_EQ(1u, completed_uploads.size());
237 EXPECT_EQ(uploads.at(0), completed_uploads.at(0));
239 EXPECT_TRUE(manager->IsAvailable());
std::vector< UploadDescription > uploads
virtual bool IsAvailable() const
std::unique_ptr< MockS3Facade > facade
TEST_F(S3UploadManagerTest, TestClientConfigConstructor)
virtual Model::PutObjectOutcome UploadFiles(const std::vector< UploadDescription > &upload_descriptions, const std::string &bucket, const boost::function< void(const std::vector< UploadDescription > &)> &feedback_callback)
Model::PutObjectOutcome successful_outcome
MockS3Facade(const bool enable_encryption)
std::size_t num_feedback_calls
std::vector< UploadDescription > completed_uploads
void FeedbackCallback(const std::vector< UploadDescription > &callback_uploads)
std::future< Model::PutObjectOutcome > UploadFilesUntilUnlocked(std::unique_ptr< S3UploadManager > &manager, std::mutex &lock_during_uploading, std::condition_variable ¬ify_is_uploading, bool &is_uploading, const boost::function< void(const std::vector< UploadDescription > &)> &callback, int additional_returns=0)
Model::PutObjectOutcome failed_outcome