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( 60 reinterpret_cast<const uint8_t*>(data), size, 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 { return sent_size_; } 81 82 // Begins the transfer if it hasn't already begun. 83 void BeginTransfer(const std::string& url) override; 84 85 // If the transfer is in progress, aborts the transfer early. 86 // The transfer cannot be resumed. 87 void TerminateTransfer() override; 88 89 void SetHeader(const std::string& header_name, 90 const std::string& header_value) override; 91 92 // Return the value of the header |header_name| or the empty string if not 93 // set. 94 std::string GetHeader(const std::string& header_name) const; 95 96 // Suspend the mock transfer. 97 void Pause() override; 98 99 // Resume the mock transfer. 100 void Unpause() override; 101 102 // Fail the transfer. This simulates a network failure. 103 void FailTransfer(int http_response_code); 104 105 // If set to true, this will EXPECT fail on BeginTransfer set_never_use(bool never_use)106 void set_never_use(bool never_use) { never_use_ = never_use; } 107 post_data()108 const brillo::Blob& post_data() const { return post_data_; } 109 110 private: 111 // Sends data to the delegate and sets up a timeout callback if needed. There 112 // must be a delegate. If |skip_delivery| is true, no bytes will be delivered, 113 // but the callbacks still be set if needed. 114 void SendData(bool skip_delivery); 115 116 // Callback for when our message loop timeout expires. 117 void TimeoutCallback(); 118 119 // Sets the HTTP response code and signals to the delegate that the transfer 120 // is complete. 121 void SignalTransferComplete(); 122 123 // A full copy of the data we'll return to the delegate 124 brillo::Blob data_; 125 126 // The number of bytes we've sent so far 127 size_t sent_size_; 128 129 // The extra headers set. 130 std::map<std::string, std::string> extra_headers_; 131 132 // The TaskId of the timeout callback. After each chunk of data sent, we 133 // time out for 0s just to make sure that run loop services other clients. 134 brillo::MessageLoop::TaskId timeout_id_; 135 136 // True iff the fetcher is paused. 137 bool paused_; 138 139 // Set to true if the transfer should fail. 140 bool fail_transfer_; 141 142 // Set to true if BeginTransfer should EXPECT fail. 143 bool never_use_; 144 145 DISALLOW_COPY_AND_ASSIGN(MockHttpFetcher); 146 }; 147 148 } // namespace chromeos_update_engine 149 150 #endif // UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ 151