// // Copyright (C) 2009 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ #define UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ #include <map> #include <string> #include <vector> #include <base/logging.h> #include <brillo/message_loops/message_loop.h> #include "update_engine/common/http_fetcher.h" // This is a mock implementation of HttpFetcher which is useful for testing. // All data must be passed into the ctor. When started, MockHttpFetcher will // deliver the data in chunks of size kMockHttpFetcherChunkSize. To simulate // a network failure, you can call FailTransfer(). namespace chromeos_update_engine { // MockHttpFetcher will send a chunk of data down in each call to BeginTransfer // and Unpause. For the other chunks of data, a callback is put on the run // loop and when that's called, another chunk is sent down. const size_t kMockHttpFetcherChunkSize(65536); class MockHttpFetcher : public HttpFetcher { public: // The data passed in here is copied and then passed to the delegate after // the transfer begins. MockHttpFetcher(const uint8_t* data, size_t size, ProxyResolver* proxy_resolver) : HttpFetcher(proxy_resolver), sent_size_(0), timeout_id_(brillo::MessageLoop::kTaskIdNull), paused_(false), fail_transfer_(false), never_use_(false) { data_.insert(data_.end(), data, data + size); } // Constructor overload for string data. MockHttpFetcher(const char* data, size_t size, ProxyResolver* proxy_resolver) : MockHttpFetcher( reinterpret_cast<const uint8_t*>(data), size, proxy_resolver) {} // Cleans up all internal state. Does not notify delegate ~MockHttpFetcher() override; // Ignores this. void SetOffset(off_t offset) override { sent_size_ = offset; if (delegate_) delegate_->SeekToOffset(offset); } // Do nothing. void SetLength(size_t length) override {} void UnsetLength() override {} void set_low_speed_limit(int low_speed_bps, int low_speed_sec) override {} void set_connect_timeout(int connect_timeout_seconds) override {} void set_max_retry_count(int max_retry_count) override {} // Dummy: no bytes were downloaded. size_t GetBytesDownloaded() override { return sent_size_; } // Begins the transfer if it hasn't already begun. void BeginTransfer(const std::string& url) override; // If the transfer is in progress, aborts the transfer early. // The transfer cannot be resumed. void TerminateTransfer() override; void SetHeader(const std::string& header_name, const std::string& header_value) override; // Return the value of the header |header_name| or the empty string if not // set. std::string GetHeader(const std::string& header_name) const; // Suspend the mock transfer. void Pause() override; // Resume the mock transfer. void Unpause() override; // Fail the transfer. This simulates a network failure. void FailTransfer(int http_response_code); // If set to true, this will EXPECT fail on BeginTransfer void set_never_use(bool never_use) { never_use_ = never_use; } const brillo::Blob& post_data() const { return post_data_; } private: // Sends data to the delegate and sets up a timeout callback if needed. There // must be a delegate. If |skip_delivery| is true, no bytes will be delivered, // but the callbacks still be set if needed. void SendData(bool skip_delivery); // Callback for when our message loop timeout expires. void TimeoutCallback(); // Sets the HTTP response code and signals to the delegate that the transfer // is complete. void SignalTransferComplete(); // A full copy of the data we'll return to the delegate brillo::Blob data_; // The number of bytes we've sent so far size_t sent_size_; // The extra headers set. std::map<std::string, std::string> extra_headers_; // The TaskId of the timeout callback. After each chunk of data sent, we // time out for 0s just to make sure that run loop services other clients. brillo::MessageLoop::TaskId timeout_id_; // True iff the fetcher is paused. bool paused_; // Set to true if the transfer should fail. bool fail_transfer_; // Set to true if BeginTransfer should EXPECT fail. bool never_use_; DISALLOW_COPY_AND_ASSIGN(MockHttpFetcher); }; } // namespace chromeos_update_engine #endif // UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_