Almost there...
git-svn-id: svn://chrome-svn/chromeos/trunk@24 06c00378-0e64-4dae-be16-12b19f9950a1
diff --git a/mock_http_fetcher.cc b/mock_http_fetcher.cc
new file mode 100644
index 0000000..0c4209a
--- /dev/null
+++ b/mock_http_fetcher.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "glog/logging.h"
+#include "update_engine/mock_http_fetcher.h"
+
+// This is a mac implementation of HttpFetcher which is useful for testing.
+
+namespace chromeos_update_engine {
+
+MockHttpFetcher::~MockHttpFetcher() {
+ CHECK(!timeout_source_) << "Call TerminateTransfer() before dtor.";
+}
+
+void MockHttpFetcher::BeginTransfer(const std::string& url) {
+ if (sent_size_ < data_.size())
+ SendData(true);
+}
+
+// Returns false on one condition: If timeout_source_ was already set
+// and it needs to be deleted by the caller. If timeout_source_ is NULL
+// when this function is called, this function will always return true.
+bool MockHttpFetcher::SendData(bool skip_delivery) {
+ CHECK_LT(sent_size_, data_.size());
+ if (!skip_delivery) {
+ const size_t chunk_size = min(kMockHttpFetcherChunkSize,
+ data_.size() - sent_size_);
+ CHECK(delegate_);
+ delegate_->ReceivedBytes(this, &data_[sent_size_], chunk_size);
+ sent_size_ += chunk_size;
+ CHECK_LE(sent_size_, data_.size());
+ if (sent_size_ == data_.size()) {
+ // We've sent all the data. notify of success
+ delegate_->TransferComplete(this, true);
+ }
+ }
+
+ if (paused_) {
+ // If we're paused, we should return true if timeout_source_ is set,
+ // since we need the caller to delete it.
+ return timeout_source_;
+ }
+
+ if (timeout_source_) {
+ // we still need a timeout if there's more data to send
+ return sent_size_ < data_.size();
+ } else if (sent_size_ < data_.size()) {
+ // we don't have a timeout source and we need one
+ timeout_source_ = g_timeout_source_new(10);
+ CHECK(timeout_source_);
+ g_source_set_callback(timeout_source_, StaticTimeoutCallback, this,
+ NULL);
+ timout_tag_ = g_source_attach(timeout_source_, NULL);
+ }
+ return true;
+}
+
+bool MockHttpFetcher::TimeoutCallback() {
+ CHECK(!paused_);
+ bool ret = SendData(false);
+ if (false == ret) {
+ timeout_source_ = NULL;
+ }
+ return ret;
+}
+
+// If the transfer is in progress, aborts the transfer early.
+// The transfer cannot be resumed.
+void MockHttpFetcher::TerminateTransfer() {
+ sent_size_ = data_.size();
+ // kill any timeout
+ if (timeout_source_) {
+ g_source_remove(timout_tag_);
+ g_source_destroy(timeout_source_);
+ timeout_source_ = NULL;
+ }
+}
+
+void MockHttpFetcher::Pause() {
+ CHECK(!paused_);
+ paused_ = true;
+ if (timeout_source_) {
+ g_source_remove(timout_tag_);
+ g_source_destroy(timeout_source_);
+ timeout_source_ = NULL;
+ }
+
+}
+
+void MockHttpFetcher::Unpause() {
+ CHECK(paused_) << "You must pause before unpause.";
+ paused_ = false;
+ if (sent_size_ < data_.size()) {
+ SendData(false);
+ }
+}
+
+} // namespace chromeos_update_engine