1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2009 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#ifndef UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ 1839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#define UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ 1949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 206f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo#include <map> 21d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko#include <string> 2249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <vector> 234516810fe41a39c0c55d2095679898787259ae38Andrew de los Reyes 244516810fe41a39c0c55d2095679898787259ae38Andrew de los Reyes#include <base/logging.h> 253f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/message_loops/message_loop.h> 264516810fe41a39c0c55d2095679898787259ae38Andrew de los Reyes 2739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/http_fetcher.h" 2849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 2949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// This is a mock implementation of HttpFetcher which is useful for testing. 3049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// All data must be passed into the ctor. When started, MockHttpFetcher will 3149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// deliver the data in chunks of size kMockHttpFetcherChunkSize. To simulate 3249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// a network failure, you can call FailTransfer(). 3349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 3449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine { 3549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 3649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// MockHttpFetcher will send a chunk of data down in each call to BeginTransfer 3749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// and Unpause. For the other chunks of data, a callback is put on the run 3849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// loop and when that's called, another chunk is sent down. 3949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comconst size_t kMockHttpFetcherChunkSize(65536); 4049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 4149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass MockHttpFetcher : public HttpFetcher { 4249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public: 4349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // The data passed in here is copied and then passed to the delegate after 4449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // the transfer begins. 45f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko MockHttpFetcher(const uint8_t* data, 464516810fe41a39c0c55d2095679898787259ae38Andrew de los Reyes size_t size, 474516810fe41a39c0c55d2095679898787259ae38Andrew de los Reyes ProxyResolver* proxy_resolver) 48c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo : HttpFetcher(proxy_resolver), 494516810fe41a39c0c55d2095679898787259ae38Andrew de los Reyes sent_size_(0), 503f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko timeout_id_(brillo::MessageLoop::kTaskIdNull), 51edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov paused_(false), 52173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes fail_transfer_(false), 53f6ee0163504eaf1a7cc136ba2c075d77ae2b4dd5Alex Deymo never_use_(false) { 5449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com data_.insert(data_.end(), data, data + size); 5549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com } 5649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 57f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko // Constructor overload for string data. 58f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko MockHttpFetcher(const char* data, size_t size, ProxyResolver* proxy_resolver) 59f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko : MockHttpFetcher(reinterpret_cast<const uint8_t*>(data), size, 60f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko proxy_resolver) {} 61f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko 6249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Cleans up all internal state. Does not notify delegate 63610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo ~MockHttpFetcher() override; 6449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 653fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes // Ignores this. 66610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void SetOffset(off_t offset) override { 6734e41a1b50ccd06f5b3dad7a1ab1d467c7e8e00eAndrew de los Reyes sent_size_ = offset; 6834e41a1b50ccd06f5b3dad7a1ab1d467c7e8e00eAndrew de los Reyes if (delegate_) 6934e41a1b50ccd06f5b3dad7a1ab1d467c7e8e00eAndrew de los Reyes delegate_->SeekToOffset(offset); 7034e41a1b50ccd06f5b3dad7a1ab1d467c7e8e00eAndrew de los Reyes } 713fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes 72e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold // Do nothing. 73610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void SetLength(size_t length) override {} 74610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void UnsetLength() override {} 75610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void set_low_speed_limit(int low_speed_bps, int low_speed_sec) override {} 76610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void set_connect_timeout(int connect_timeout_seconds) override {} 77610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void set_max_retry_count(int max_retry_count) override {} 78e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold 7948085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold // Dummy: no bytes were downloaded. 80610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo size_t GetBytesDownloaded() override { 8148085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold return sent_size_; 8248085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold } 8348085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold 8449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Begins the transfer if it hasn't already begun. 85610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void BeginTransfer(const std::string& url) override; 8649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 8749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // If the transfer is in progress, aborts the transfer early. 8849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // The transfer cannot be resumed. 89610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void TerminateTransfer() override; 9049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 916f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo void SetHeader(const std::string& header_name, 926f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo const std::string& header_value) override; 936f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo 9449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Suspend the mock transfer. 95610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void Pause() override; 9649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 9749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Resume the mock transfer. 98610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void Unpause() override; 9949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 10049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Fail the transfer. This simulates a network failure. 101edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov void FailTransfer(int http_response_code); 10249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 103173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes // If set to true, this will EXPECT fail on BeginTransfer 104173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes void set_never_use(bool never_use) { never_use_ = never_use; } 105173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes 1063f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko const brillo::Blob& post_data() const { 10749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com return post_data_; 10849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com } 109c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 11049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com private: 11160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo // Sends data to the delegate and sets up a timeout callback if needed. 11249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // There must be a delegate and there must be data to send. If there is 11349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // already a timeout callback, and it should be deleted by the caller, 11449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // this will return false; otherwise true is returned. 11549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // If skip_delivery is true, no bytes will be delivered, but the callbacks 116072359ca138504065e1e0c1189eb38c09576d324Alex Vakulenko // still be set if needed. 11749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com bool SendData(bool skip_delivery); 11849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 11960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo // Callback for when our message loop timeout expires. 12060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo void TimeoutCallback(); 12149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 122edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov // Sets the HTTP response code and signals to the delegate that the transfer 123edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov // is complete. 124edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov void SignalTransferComplete(); 125edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov 12649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // A full copy of the data we'll return to the delegate 1273f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob data_; 12849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 12949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // The number of bytes we've sent so far 13049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com size_t sent_size_; 13149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 1326f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo // The extra headers set. 1336f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo std::map<std::string, std::string> extra_headers_; 1346f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo 13560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo // The TaskId of the timeout callback. After each chunk of data sent, we 13649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // time out for 0s just to make sure that run loop services other clients. 1373f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::MessageLoop::TaskId timeout_id_; 13849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 13949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // True iff the fetcher is paused. 14049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com bool paused_; 14149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 142edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov // Set to true if the transfer should fail. 143edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov bool fail_transfer_; 144edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov 145173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes // Set to true if BeginTransfer should EXPECT fail. 146173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes bool never_use_; 147173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes 14849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com DISALLOW_COPY_AND_ASSIGN(MockHttpFetcher); 14949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}; 15049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 15149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com} // namespace chromeos_update_engine 15249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 15339910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif // UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ 154