blob: ea5b83da961ff188a541dce80fbc7f6c123148a8 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2009 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
rspangler@google.com49fdf182009-10-10 00:57:34 +000016
Alex Deymo39910dc2015-11-09 17:04:30 -080017#ifndef UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_
18#define UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_
rspangler@google.com49fdf182009-10-10 00:57:34 +000019
Alex Deymofdd6dec2016-03-03 22:35:43 -080020#include <map>
Alex Vakulenkod2779df2014-06-16 13:19:00 -070021#include <string>
rspangler@google.com49fdf182009-10-10 00:57:34 +000022#include <vector>
Andrew de los Reyes45168102010-11-22 11:13:50 -080023
24#include <base/logging.h>
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070025#include <brillo/message_loops/message_loop.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080026
Alex Deymo39910dc2015-11-09 17:04:30 -080027#include "update_engine/common/http_fetcher.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000028
29// This is a mock implementation of HttpFetcher which is useful for testing.
30// All data must be passed into the ctor. When started, MockHttpFetcher will
31// deliver the data in chunks of size kMockHttpFetcherChunkSize. To simulate
32// a network failure, you can call FailTransfer().
33
34namespace chromeos_update_engine {
35
36// MockHttpFetcher will send a chunk of data down in each call to BeginTransfer
37// and Unpause. For the other chunks of data, a callback is put on the run
38// loop and when that's called, another chunk is sent down.
39const size_t kMockHttpFetcherChunkSize(65536);
40
41class MockHttpFetcher : public HttpFetcher {
42 public:
43 // The data passed in here is copied and then passed to the delegate after
44 // the transfer begins.
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080045 MockHttpFetcher(const uint8_t* data,
Andrew de los Reyes45168102010-11-22 11:13:50 -080046 size_t size,
47 ProxyResolver* proxy_resolver)
Alex Deymoc1c17b42015-11-23 03:53:15 -030048 : HttpFetcher(proxy_resolver),
Kelvin Zhang9dd93052020-07-21 17:31:19 -040049 sent_offset_(0),
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070050 timeout_id_(brillo::MessageLoop::kTaskIdNull),
Darin Petkovedc522e2010-11-05 09:35:17 -070051 paused_(false),
Andrew de los Reyes173e63c2011-04-04 17:19:57 -070052 fail_transfer_(false),
Alex Deymof6ee0162015-07-31 12:35:22 -070053 never_use_(false) {
rspangler@google.com49fdf182009-10-10 00:57:34 +000054 data_.insert(data_.end(), data, data + size);
rspangler@google.com49fdf182009-10-10 00:57:34 +000055 }
56
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080057 // Constructor overload for string data.
58 MockHttpFetcher(const char* data, size_t size, ProxyResolver* proxy_resolver)
Amin Hassanib2689592019-01-13 17:04:28 -080059 : MockHttpFetcher(
60 reinterpret_cast<const uint8_t*>(data), size, proxy_resolver) {}
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080061
rspangler@google.com49fdf182009-10-10 00:57:34 +000062 // Cleans up all internal state. Does not notify delegate
Alex Deymo610277e2014-11-11 21:18:11 -080063 ~MockHttpFetcher() override;
rspangler@google.com49fdf182009-10-10 00:57:34 +000064
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070065 // Ignores this.
Alex Deymo610277e2014-11-11 21:18:11 -080066 void SetOffset(off_t offset) override {
Kelvin Zhang9dd93052020-07-21 17:31:19 -040067 sent_offset_ = offset;
Andrew de los Reyes34e41a12010-10-26 20:07:58 -070068 if (delegate_)
69 delegate_->SeekToOffset(offset);
70 }
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070071
Gilad Arnolde4ad2502011-12-29 17:08:54 -080072 // Do nothing.
Alex Deymo610277e2014-11-11 21:18:11 -080073 void SetLength(size_t length) override {}
74 void UnsetLength() override {}
75 void set_low_speed_limit(int low_speed_bps, int low_speed_sec) override {}
76 void set_connect_timeout(int connect_timeout_seconds) override {}
77 void set_max_retry_count(int max_retry_count) override {}
Gilad Arnolde4ad2502011-12-29 17:08:54 -080078
Tianjiee283ce42020-07-29 11:37:51 -070079 // No bytes were downloaded in the mock class.
Kelvin Zhang9dd93052020-07-21 17:31:19 -040080 size_t GetBytesDownloaded() override { return bytes_sent_; }
Gilad Arnold48085ba2011-11-16 09:36:08 -080081
rspangler@google.com49fdf182009-10-10 00:57:34 +000082 // Begins the transfer if it hasn't already begun.
Alex Deymo610277e2014-11-11 21:18:11 -080083 void BeginTransfer(const std::string& url) override;
rspangler@google.com49fdf182009-10-10 00:57:34 +000084
85 // If the transfer is in progress, aborts the transfer early.
86 // The transfer cannot be resumed.
Alex Deymo610277e2014-11-11 21:18:11 -080087 void TerminateTransfer() override;
rspangler@google.com49fdf182009-10-10 00:57:34 +000088
Alex Deymofdd6dec2016-03-03 22:35:43 -080089 void SetHeader(const std::string& header_name,
90 const std::string& header_value) override;
91
Jae Hoon Kim0ae8fe12019-06-26 14:32:50 -070092 bool GetHeader(const std::string& header_name,
93 std::string* header_value) const override {
94 header_value->clear();
95 return false;
96 }
97
Alex Deymo14ad88e2016-06-29 12:30:14 -070098 // Return the value of the header |header_name| or the empty string if not
99 // set.
100 std::string GetHeader(const std::string& header_name) const;
101
rspangler@google.com49fdf182009-10-10 00:57:34 +0000102 // Suspend the mock transfer.
Alex Deymo610277e2014-11-11 21:18:11 -0800103 void Pause() override;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000104
105 // Resume the mock transfer.
Alex Deymo610277e2014-11-11 21:18:11 -0800106 void Unpause() override;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000107
108 // Fail the transfer. This simulates a network failure.
Darin Petkovedc522e2010-11-05 09:35:17 -0700109 void FailTransfer(int http_response_code);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000110
Andrew de los Reyes173e63c2011-04-04 17:19:57 -0700111 // If set to true, this will EXPECT fail on BeginTransfer
112 void set_never_use(bool never_use) { never_use_ = never_use; }
113
Amin Hassanib2689592019-01-13 17:04:28 -0800114 const brillo::Blob& post_data() const { return post_data_; }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000115
Kelvin Zhang9dd93052020-07-21 17:31:19 -0400116 void set_delay(bool delay) { delay_ = delay; }
117
rspangler@google.com49fdf182009-10-10 00:57:34 +0000118 private:
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700119 // Sends data to the delegate and sets up a timeout callback if needed. There
120 // must be a delegate. If |skip_delivery| is true, no bytes will be delivered,
121 // but the callbacks still be set if needed.
122 void SendData(bool skip_delivery);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000123
Alex Deymo60ca1a72015-06-18 18:19:15 -0700124 // Callback for when our message loop timeout expires.
125 void TimeoutCallback();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000126
Darin Petkovedc522e2010-11-05 09:35:17 -0700127 // Sets the HTTP response code and signals to the delegate that the transfer
128 // is complete.
129 void SignalTransferComplete();
130
rspangler@google.com49fdf182009-10-10 00:57:34 +0000131 // A full copy of the data we'll return to the delegate
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700132 brillo::Blob data_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000133
Kelvin Zhang9dd93052020-07-21 17:31:19 -0400134 // The current offset, marks the first byte that will be sent next
Kelvin Zhangf693d8d2020-08-04 10:17:50 -0400135 size_t sent_offset_{0};
Kelvin Zhang9dd93052020-07-21 17:31:19 -0400136
137 // Total number of bytes transferred
Kelvin Zhangf693d8d2020-08-04 10:17:50 -0400138 size_t bytes_sent_{0};
rspangler@google.com49fdf182009-10-10 00:57:34 +0000139
Alex Deymofdd6dec2016-03-03 22:35:43 -0800140 // The extra headers set.
141 std::map<std::string, std::string> extra_headers_;
142
Alex Deymo60ca1a72015-06-18 18:19:15 -0700143 // The TaskId of the timeout callback. After each chunk of data sent, we
rspangler@google.com49fdf182009-10-10 00:57:34 +0000144 // time out for 0s just to make sure that run loop services other clients.
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700145 brillo::MessageLoop::TaskId timeout_id_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000146
147 // True iff the fetcher is paused.
Kelvin Zhangf693d8d2020-08-04 10:17:50 -0400148 bool paused_{false};
rspangler@google.com49fdf182009-10-10 00:57:34 +0000149
Darin Petkovedc522e2010-11-05 09:35:17 -0700150 // Set to true if the transfer should fail.
Kelvin Zhangf693d8d2020-08-04 10:17:50 -0400151 bool fail_transfer_{false};
Darin Petkovedc522e2010-11-05 09:35:17 -0700152
Andrew de los Reyes173e63c2011-04-04 17:19:57 -0700153 // Set to true if BeginTransfer should EXPECT fail.
Kelvin Zhangf693d8d2020-08-04 10:17:50 -0400154 bool never_use_{false};
Andrew de los Reyes173e63c2011-04-04 17:19:57 -0700155
Kelvin Zhang9dd93052020-07-21 17:31:19 -0400156 // Whether it should wait for 10ms before sending data to delegates
157 bool delay_{true};
158
rspangler@google.com49fdf182009-10-10 00:57:34 +0000159 DISALLOW_COPY_AND_ASSIGN(MockHttpFetcher);
160};
161
162} // namespace chromeos_update_engine
163
Alex Deymo39910dc2015-11-09 17:04:30 -0800164#endif // UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_