Add unit test for fallback route of manifest cache
Test: Run atest
Change-Id: Icc6a2c809c571c3ad8e16a863c37afd8d4042ed6
diff --git a/common/action_pipe.h b/common/action_pipe.h
index 0c98ee1..4c56812 100644
--- a/common/action_pipe.h
+++ b/common/action_pipe.h
@@ -79,6 +79,8 @@
private:
ObjectType contents_;
+ // Give unit test access
+ friend class DownloadActionTest;
// The ctor is private. This is because this class should construct itself
// via the static Bond() method.
diff --git a/common/action_processor.h b/common/action_processor.h
index 735a106..ad98cc9 100644
--- a/common/action_processor.h
+++ b/common/action_processor.h
@@ -89,7 +89,7 @@
// But this call deletes the action if there no other object has a reference
// to it, so in that case, the caller should not try to access any of its
// member variables after this call.
- void ActionComplete(AbstractAction* actionptr, ErrorCode code);
+ virtual void ActionComplete(AbstractAction* actionptr, ErrorCode code);
private:
FRIEND_TEST(ActionProcessorTest, ChainActionsTest);
diff --git a/common/mock_action_processor.h b/common/mock_action_processor.h
index 4c62109..9785776 100644
--- a/common/mock_action_processor.h
+++ b/common/mock_action_processor.h
@@ -32,6 +32,8 @@
MOCK_METHOD0(StartProcessing, void());
MOCK_METHOD1(EnqueueAction, void(AbstractAction* action));
+ MOCK_METHOD2(ActionComplete, void(AbstractAction*, ErrorCode));
+
// This is a legacy workaround described in:
// https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#legacy-workarounds-for-move-only-types-legacymoveonly
void EnqueueAction(std::unique_ptr<AbstractAction> action) override {
diff --git a/common/mock_http_fetcher.cc b/common/mock_http_fetcher.cc
index 10e3b9e..1b3cd7d 100644
--- a/common/mock_http_fetcher.cc
+++ b/common/mock_http_fetcher.cc
@@ -22,6 +22,7 @@
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/time/time.h>
+#include <brillo/message_loops/message_loop.h>
#include <gtest/gtest.h>
// This is a mock implementation of HttpFetcher which is useful for testing.
@@ -43,12 +44,12 @@
SignalTransferComplete();
return;
}
- if (sent_size_ < data_.size())
+ if (sent_offset_ < data_.size())
SendData(true);
}
void MockHttpFetcher::SendData(bool skip_delivery) {
- if (fail_transfer_ || sent_size_ == data_.size()) {
+ if (fail_transfer_ || sent_offset_ == data_.size()) {
SignalTransferComplete();
return;
}
@@ -60,19 +61,22 @@
// Setup timeout callback even if the transfer is about to be completed in
// order to get a call to |TransferComplete|.
- if (timeout_id_ == MessageLoop::kTaskIdNull) {
+ if (timeout_id_ == MessageLoop::kTaskIdNull && delay_) {
+ CHECK(MessageLoop::current());
timeout_id_ = MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&MockHttpFetcher::TimeoutCallback, base::Unretained(this)),
base::TimeDelta::FromMilliseconds(10));
}
- if (!skip_delivery) {
+ if (!skip_delivery || !delay_) {
const size_t chunk_size =
- min(kMockHttpFetcherChunkSize, data_.size() - sent_size_);
- sent_size_ += chunk_size;
+ min(kMockHttpFetcherChunkSize, data_.size() - sent_offset_);
+ sent_offset_ += chunk_size;
+ bytes_sent_ += chunk_size;
CHECK(delegate_);
- delegate_->ReceivedBytes(this, &data_[sent_size_ - chunk_size], chunk_size);
+ delegate_->ReceivedBytes(
+ this, &data_[sent_offset_ - chunk_size], chunk_size);
}
// We may get terminated and deleted right after |ReceivedBytes| call, so we
// should not access any class member variable after this call.
@@ -81,7 +85,7 @@
void MockHttpFetcher::TimeoutCallback() {
CHECK(!paused_);
timeout_id_ = MessageLoop::kTaskIdNull;
- CHECK_LE(sent_size_, data_.size());
+ CHECK_LE(sent_offset_, data_.size());
// Same here, we should not access any member variable after this call.
SendData(false);
}
@@ -90,10 +94,15 @@
// The transfer cannot be resumed.
void MockHttpFetcher::TerminateTransfer() {
LOG(INFO) << "Terminating transfer.";
- // Kill any timeout, it is ok to call with kTaskIdNull.
- MessageLoop::current()->CancelTask(timeout_id_);
- timeout_id_ = MessageLoop::kTaskIdNull;
- delegate_->TransferTerminated(this);
+ // During testing, MessageLoop may or may not be available.
+ // So don't call CancelTask() unless necessary.
+ if (timeout_id_ != MessageLoop::kTaskIdNull) {
+ MessageLoop::current()->CancelTask(timeout_id_);
+ timeout_id_ = MessageLoop::kTaskIdNull;
+ }
+ if (delegate_) {
+ delegate_->TransferTerminated(this);
+ }
}
void MockHttpFetcher::SetHeader(const std::string& header_name,
diff --git a/common/mock_http_fetcher.h b/common/mock_http_fetcher.h
index dec81b0..b082bbd 100644
--- a/common/mock_http_fetcher.h
+++ b/common/mock_http_fetcher.h
@@ -46,7 +46,7 @@
size_t size,
ProxyResolver* proxy_resolver)
: HttpFetcher(proxy_resolver),
- sent_size_(0),
+ sent_offset_(0),
timeout_id_(brillo::MessageLoop::kTaskIdNull),
paused_(false),
fail_transfer_(false),
@@ -64,7 +64,7 @@
// Ignores this.
void SetOffset(off_t offset) override {
- sent_size_ = offset;
+ sent_offset_ = offset;
if (delegate_)
delegate_->SeekToOffset(offset);
}
@@ -77,7 +77,7 @@
void set_max_retry_count(int max_retry_count) override {}
// No bytes were downloaded in the mock class.
- size_t GetBytesDownloaded() override { return sent_size_; }
+ size_t GetBytesDownloaded() override { return bytes_sent_; }
// Begins the transfer if it hasn't already begun.
void BeginTransfer(const std::string& url) override;
@@ -113,6 +113,8 @@
const brillo::Blob& post_data() const { return post_data_; }
+ void set_delay(bool delay) { delay_ = delay; }
+
private:
// Sends data to the delegate and sets up a timeout callback if needed. There
// must be a delegate. If |skip_delivery| is true, no bytes will be delivered,
@@ -129,8 +131,11 @@
// A full copy of the data we'll return to the delegate
brillo::Blob data_;
- // The number of bytes we've sent so far
- size_t sent_size_;
+ // The current offset, marks the first byte that will be sent next
+ size_t sent_offset_;
+
+ // Total number of bytes transferred
+ size_t bytes_sent_;
// The extra headers set.
std::map<std::string, std::string> extra_headers_;
@@ -148,6 +153,9 @@
// Set to true if BeginTransfer should EXPECT fail.
bool never_use_;
+ // Whether it should wait for 10ms before sending data to delegates
+ bool delay_{true};
+
DISALLOW_COPY_AND_ASSIGN(MockHttpFetcher);
};