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 const 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,ProxyResolver * proxy_resolver)45 MockHttpFetcher(const uint8_t* data, 46 size_t size, 47 ProxyResolver* proxy_resolver) 48 : HttpFetcher(proxy_resolver), 49 sent_size_(0), 50 timeout_id_(brillo::MessageLoop::kTaskIdNull), 51 paused_(false), 52 fail_transfer_(false), 53 never_use_(false) { 54 data_.insert(data_.end(), data, data + size); 55 } 56 57 // Constructor overload for string data. MockHttpFetcher(const char * data,size_t size,ProxyResolver * proxy_resolver)58 MockHttpFetcher(const char* data, size_t size, ProxyResolver* proxy_resolver) 59 : MockHttpFetcher(reinterpret_cast<const uint8_t*>(data), size, 60 proxy_resolver) {} 61 62 // Cleans up all internal state. Does not notify delegate 63 ~MockHttpFetcher() override; 64 65 // Ignores this. SetOffset(off_t offset)66 void SetOffset(off_t offset) override { 67 sent_size_ = offset; 68 if (delegate_) 69 delegate_->SeekToOffset(offset); 70 } 71 72 // Do nothing. SetLength(size_t length)73 void SetLength(size_t length) override {} UnsetLength()74 void UnsetLength() override {} set_low_speed_limit(int low_speed_bps,int low_speed_sec)75 void set_low_speed_limit(int low_speed_bps, int low_speed_sec) override {} set_connect_timeout(int connect_timeout_seconds)76 void set_connect_timeout(int connect_timeout_seconds) override {} set_max_retry_count(int max_retry_count)77 void set_max_retry_count(int max_retry_count) override {} 78 79 // Dummy: no bytes were downloaded. GetBytesDownloaded()80 size_t GetBytesDownloaded() override { 81 return sent_size_; 82 } 83 84 // Begins the transfer if it hasn't already begun. 85 void BeginTransfer(const std::string& url) override; 86 87 // If the transfer is in progress, aborts the transfer early. 88 // The transfer cannot be resumed. 89 void TerminateTransfer() override; 90 91 void SetHeader(const std::string& header_name, 92 const std::string& header_value) override; 93 94 // Suspend the mock transfer. 95 void Pause() override; 96 97 // Resume the mock transfer. 98 void Unpause() override; 99 100 // Fail the transfer. This simulates a network failure. 101 void FailTransfer(int http_response_code); 102 103 // If set to true, this will EXPECT fail on BeginTransfer set_never_use(bool never_use)104 void set_never_use(bool never_use) { never_use_ = never_use; } 105 post_data()106 const brillo::Blob& post_data() const { 107 return post_data_; 108 } 109 110 private: 111 // Sends data to the delegate and sets up a timeout callback if needed. 112 // There must be a delegate and there must be data to send. If there is 113 // already a timeout callback, and it should be deleted by the caller, 114 // this will return false; otherwise true is returned. 115 // If skip_delivery is true, no bytes will be delivered, but the callbacks 116 // still be set if needed. 117 bool SendData(bool skip_delivery); 118 119 // Callback for when our message loop timeout expires. 120 void TimeoutCallback(); 121 122 // Sets the HTTP response code and signals to the delegate that the transfer 123 // is complete. 124 void SignalTransferComplete(); 125 126 // A full copy of the data we'll return to the delegate 127 brillo::Blob data_; 128 129 // The number of bytes we've sent so far 130 size_t sent_size_; 131 132 // The extra headers set. 133 std::map<std::string, std::string> extra_headers_; 134 135 // The TaskId of the timeout callback. After each chunk of data sent, we 136 // time out for 0s just to make sure that run loop services other clients. 137 brillo::MessageLoop::TaskId timeout_id_; 138 139 // True iff the fetcher is paused. 140 bool paused_; 141 142 // Set to true if the transfer should fail. 143 bool fail_transfer_; 144 145 // Set to true if BeginTransfer should EXPECT fail. 146 bool never_use_; 147 148 DISALLOW_COPY_AND_ASSIGN(MockHttpFetcher); 149 }; 150 151 } // namespace chromeos_update_engine 152 153 #endif // UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ 154