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