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 20fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex 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 91fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo void SetHeader(const std::string& header_name, 92fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo const std::string& header_value) override; 93fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo 9414ad88ea53bd89f9c6e477e28745c4506c2f0f81Alex Deymo // Return the value of the header |header_name| or the empty string if not 9514ad88ea53bd89f9c6e477e28745c4506c2f0f81Alex Deymo // set. 9614ad88ea53bd89f9c6e477e28745c4506c2f0f81Alex Deymo std::string GetHeader(const std::string& header_name) const; 9714ad88ea53bd89f9c6e477e28745c4506c2f0f81Alex Deymo 9849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Suspend the mock transfer. 99610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void Pause() override; 10049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 10149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Resume the mock transfer. 102610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo void Unpause() override; 10349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 10449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Fail the transfer. This simulates a network failure. 105edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov void FailTransfer(int http_response_code); 10649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 107173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes // If set to true, this will EXPECT fail on BeginTransfer 108173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes void set_never_use(bool never_use) { never_use_ = never_use; } 109173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes 1103f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko const brillo::Blob& post_data() const { 11149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com return post_data_; 11249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com } 113c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com 11449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com private: 11560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo // Sends data to the delegate and sets up a timeout callback if needed. 11649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // There must be a delegate and there must be data to send. If there is 11749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // already a timeout callback, and it should be deleted by the caller, 11849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // this will return false; otherwise true is returned. 11949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // If skip_delivery is true, no bytes will be delivered, but the callbacks 120072359ca138504065e1e0c1189eb38c09576d324Alex Vakulenko // still be set if needed. 12149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com bool SendData(bool skip_delivery); 12249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 12360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo // Callback for when our message loop timeout expires. 12460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo void TimeoutCallback(); 12549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 126edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov // Sets the HTTP response code and signals to the delegate that the transfer 127edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov // is complete. 128edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov void SignalTransferComplete(); 129edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov 13049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // A full copy of the data we'll return to the delegate 1313f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob data_; 13249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 13349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // The number of bytes we've sent so far 13449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com size_t sent_size_; 13549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 136fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo // The extra headers set. 137fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo std::map<std::string, std::string> extra_headers_; 138fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo 13960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo // The TaskId of the timeout callback. After each chunk of data sent, we 14049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // time out for 0s just to make sure that run loop services other clients. 1413f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::MessageLoop::TaskId timeout_id_; 14249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 14349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // True iff the fetcher is paused. 14449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com bool paused_; 14549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 146edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov // Set to true if the transfer should fail. 147edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov bool fail_transfer_; 148edc522e7e5c0c14c3f8a55fd2a0d23d8a6032917Darin Petkov 149173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes // Set to true if BeginTransfer should EXPECT fail. 150173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes bool never_use_; 151173e63c7e21ea7a6fdda0509c6184d79e146e4c3Andrew de los Reyes 15249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com DISALLOW_COPY_AND_ASSIGN(MockHttpFetcher); 15349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}; 15449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 15549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com} // namespace chromeos_update_engine 15649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 15739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif // UPDATE_ENGINE_COMMON_MOCK_HTTP_FETCHER_H_ 158