1 // 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 // 16 17 #ifndef UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ 18 #define UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ 19 20 #include <map> 21 #include <string> 22 #include <vector> 23 24 #include <base/logging.h> 25 #include <brillo/message_loops/message_loop.h> 26 27 #include "update_engine/common/http_fetcher.h" 28 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 34 namespace 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. 39 static constexpr size_t kMockHttpFetcherChunkSize(65536); 40 41 class MockHttpFetcher : public HttpFetcher { 42 public: 43 // The data passed in here is copied and then passed to the delegate after 44 // the transfer begins. MockHttpFetcher(const uint8_t * data,size_t size)45 MockHttpFetcher(const uint8_t* data, size_t size) 46 : HttpFetcher(), 47 sent_offset_(0), 48 timeout_id_(brillo::MessageLoop::kTaskIdNull), 49 paused_(false), 50 fail_transfer_(false), 51 never_use_(false) { 52 data_.insert(data_.end(), data, data + size); 53 } 54 55 // Constructor overload for string data. MockHttpFetcher(const char * data,size_t size)56 MockHttpFetcher(const char* data, size_t size) 57 : MockHttpFetcher(reinterpret_cast<const uint8_t*>(data), size) {} 58 59 // Cleans up all internal state. Does not notify delegate 60 ~MockHttpFetcher() override; 61 62 // Ignores this. SetOffset(off_t offset)63 void SetOffset(off_t offset) override { 64 sent_offset_ = offset; 65 if (delegate_) 66 delegate_->SeekToOffset(offset); 67 } 68 69 // Do nothing. SetLength(size_t length)70 void SetLength(size_t length) override {} UnsetLength()71 void UnsetLength() override {} set_low_speed_limit(int low_speed_bps,int low_speed_sec)72 void set_low_speed_limit(int low_speed_bps, int low_speed_sec) override {} set_connect_timeout(int connect_timeout_seconds)73 void set_connect_timeout(int connect_timeout_seconds) override {} set_max_retry_count(int max_retry_count)74 void set_max_retry_count(int max_retry_count) override {} 75 76 // No bytes were downloaded in the mock class. GetBytesDownloaded()77 size_t GetBytesDownloaded() override { return bytes_sent_; } 78 79 // Begins the transfer if it hasn't already begun. 80 void BeginTransfer(const std::string& url) override; 81 82 // If the transfer is in progress, aborts the transfer early. 83 // The transfer cannot be resumed. 84 void TerminateTransfer() override; 85 86 void SetHeader(const std::string& header_name, 87 const std::string& header_value) override; 88 GetHeader(const std::string & header_name,std::string * header_value)89 bool GetHeader(const std::string& header_name, 90 std::string* header_value) const override { 91 header_value->clear(); 92 return false; 93 } 94 95 // Return the value of the header |header_name| or the empty string if not 96 // set. 97 std::string GetHeader(const std::string& header_name) const; 98 99 // Suspend the mock transfer. 100 void Pause() override; 101 102 // Resume the mock transfer. 103 void Unpause() override; 104 105 // Fail the transfer. This simulates a network failure. 106 void FailTransfer(int http_response_code); 107 108 // If set to true, this will EXPECT fail on BeginTransfer set_never_use(bool never_use)109 void set_never_use(bool never_use) { never_use_ = never_use; } 110 post_data()111 const brillo::Blob& post_data() const { return post_data_; } 112 set_delay(bool delay)113 void set_delay(bool delay) { delay_ = delay; } 114 115 private: 116 // Sends data to the delegate and sets up a timeout callback if needed. There 117 // must be a delegate. If |skip_delivery| is true, no bytes will be delivered, 118 // but the callbacks still be set if needed. 119 void SendData(bool skip_delivery); 120 121 // Callback for when our message loop timeout expires. 122 void TimeoutCallback(); 123 124 // Sets the HTTP response code and signals to the delegate that the transfer 125 // is complete. 126 void SignalTransferComplete(); 127 128 // A full copy of the data we'll return to the delegate 129 brillo::Blob data_; 130 131 // The current offset, marks the first byte that will be sent next 132 size_t sent_offset_{0}; 133 134 // Total number of bytes transferred 135 size_t bytes_sent_{0}; 136 137 // The extra headers set. 138 std::map<std::string, std::string> extra_headers_; 139 140 // The TaskId of the timeout callback. After each chunk of data sent, we 141 // time out for 0s just to make sure that run loop services other clients. 142 brillo::MessageLoop::TaskId timeout_id_; 143 144 // True iff the fetcher is paused. 145 bool paused_{false}; 146 147 // Set to true if the transfer should fail. 148 bool fail_transfer_{false}; 149 150 // Set to true if BeginTransfer should EXPECT fail. 151 bool never_use_{false}; 152 153 // Whether it should wait for 10ms before sending data to delegates 154 bool delay_{true}; 155 156 DISALLOW_COPY_AND_ASSIGN(MockHttpFetcher); 157 }; 158 159 } // namespace chromeos_update_engine 160 161 #endif // UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ 162