blob: abeff7a1481fa79682282633ad527c4434b69cd8 [file] [log] [blame]
rspangler@google.com49fdf182009-10-10 00:57:34 +00001// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
rspangler@google.com49fdf182009-10-10 00:57:34 +00005#include "update_engine/mock_http_fetcher.h"
adlr@google.comc98a7ed2009-12-04 18:54:03 +00006#include <algorithm>
7#include "chromeos/obsolete_logging.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +00008
9// This is a mac implementation of HttpFetcher which is useful for testing.
10
adlr@google.comc98a7ed2009-12-04 18:54:03 +000011using std::min;
12
rspangler@google.com49fdf182009-10-10 00:57:34 +000013namespace chromeos_update_engine {
14
15MockHttpFetcher::~MockHttpFetcher() {
16 CHECK(!timeout_source_) << "Call TerminateTransfer() before dtor.";
17}
18
19void MockHttpFetcher::BeginTransfer(const std::string& url) {
20 if (sent_size_ < data_.size())
21 SendData(true);
22}
23
24// Returns false on one condition: If timeout_source_ was already set
25// and it needs to be deleted by the caller. If timeout_source_ is NULL
26// when this function is called, this function will always return true.
27bool MockHttpFetcher::SendData(bool skip_delivery) {
28 CHECK_LT(sent_size_, data_.size());
29 if (!skip_delivery) {
30 const size_t chunk_size = min(kMockHttpFetcherChunkSize,
31 data_.size() - sent_size_);
32 CHECK(delegate_);
33 delegate_->ReceivedBytes(this, &data_[sent_size_], chunk_size);
34 sent_size_ += chunk_size;
35 CHECK_LE(sent_size_, data_.size());
36 if (sent_size_ == data_.size()) {
37 // We've sent all the data. notify of success
38 delegate_->TransferComplete(this, true);
39 }
40 }
41
42 if (paused_) {
43 // If we're paused, we should return true if timeout_source_ is set,
44 // since we need the caller to delete it.
45 return timeout_source_;
46 }
47
48 if (timeout_source_) {
49 // we still need a timeout if there's more data to send
50 return sent_size_ < data_.size();
51 } else if (sent_size_ < data_.size()) {
52 // we don't have a timeout source and we need one
53 timeout_source_ = g_timeout_source_new(10);
54 CHECK(timeout_source_);
55 g_source_set_callback(timeout_source_, StaticTimeoutCallback, this,
56 NULL);
57 timout_tag_ = g_source_attach(timeout_source_, NULL);
58 }
59 return true;
60}
61
62bool MockHttpFetcher::TimeoutCallback() {
63 CHECK(!paused_);
64 bool ret = SendData(false);
65 if (false == ret) {
66 timeout_source_ = NULL;
67 }
68 return ret;
69}
70
71// If the transfer is in progress, aborts the transfer early.
72// The transfer cannot be resumed.
73void MockHttpFetcher::TerminateTransfer() {
74 sent_size_ = data_.size();
75 // kill any timeout
76 if (timeout_source_) {
77 g_source_remove(timout_tag_);
78 g_source_destroy(timeout_source_);
79 timeout_source_ = NULL;
80 }
81}
82
83void MockHttpFetcher::Pause() {
84 CHECK(!paused_);
85 paused_ = true;
86 if (timeout_source_) {
87 g_source_remove(timout_tag_);
88 g_source_destroy(timeout_source_);
89 timeout_source_ = NULL;
90 }
91
92}
93
94void MockHttpFetcher::Unpause() {
95 CHECK(paused_) << "You must pause before unpause.";
96 paused_ = false;
97 if (sent_size_ < data_.size()) {
98 SendData(false);
99 }
100}
101
102} // namespace chromeos_update_engine