1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "google_apis/gcm/engine/gcm_request_test_base.h"
#include <cmath>
#include "base/strings/string_tokenizer.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/network/test/test_url_loader_factory.h"
#include "services/network/test/test_utils.h"
namespace {
// Backoff policy for testing registration request.
const net::BackoffEntry::Policy kDefaultBackoffPolicy = {
// Number of initial errors (in sequence) to ignore before applying
// exponential back-off rules.
0,
// Initial delay for exponential back-off in ms.
15000, // 15 seconds.
// Factor by which the waiting time will be multiplied.
2,
// Fuzzing percentage. ex: 10% will spread requests randomly
// between 90%-100% of the calculated time.
0.5, // 50%.
// Maximum amount of time we are willing to delay our request in ms.
1000 * 60 * 5, // 5 minutes.
// Time to keep an entry from being discarded even when it
// has no significant state, -1 to never discard.
-1,
// Don't use initial delay unless the last request was an error.
false,
};
const network::TestURLLoaderFactory::PendingRequest* PendingForURL(
network::TestURLLoaderFactory* factory,
const std::string& url) {
GURL gurl(url);
std::vector<network::TestURLLoaderFactory::PendingRequest>* pending =
factory->pending_requests();
for (const auto& pending_request : *pending) {
if (pending_request.request.url == gurl)
return &pending_request;
}
return nullptr;
}
} // namespace
namespace gcm {
GCMRequestTestBase::GCMRequestTestBase()
: shared_factory_(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_)),
retry_count_(0) {}
GCMRequestTestBase::~GCMRequestTestBase() {
}
const net::BackoffEntry::Policy& GCMRequestTestBase::GetBackoffPolicy() const {
return kDefaultBackoffPolicy;
}
void GCMRequestTestBase::OnAboutToCompleteFetch() {}
void GCMRequestTestBase::SetResponseForURLAndComplete(
const std::string& url,
net::HttpStatusCode status_code,
const std::string& response_body,
int net_error_code) {
if (retry_count_++)
FastForwardToTriggerNextRetry();
OnAboutToCompleteFetch();
EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest(
GURL(url), network::URLLoaderCompletionStatus(net_error_code),
network::CreateURLResponseHead(status_code), response_body));
}
const net::HttpRequestHeaders* GCMRequestTestBase::GetExtraHeadersForURL(
const std::string& url) {
const network::TestURLLoaderFactory::PendingRequest* pending_request =
PendingForURL(&test_url_loader_factory_, url);
return pending_request ? &pending_request->request.headers : nullptr;
}
bool GCMRequestTestBase::GetUploadDataForURL(const std::string& url,
std::string* data_out) {
const network::TestURLLoaderFactory::PendingRequest* pending_request =
PendingForURL(&test_url_loader_factory_, url);
if (!pending_request)
return false;
*data_out = network::GetUploadData(pending_request->request);
return true;
}
void GCMRequestTestBase::VerifyFetcherUploadDataForURL(
const std::string& url,
std::map<std::string, std::string>* expected_pairs) {
std::string upload_data;
ASSERT_TRUE(GetUploadDataForURL(url, &upload_data));
// Verify data was formatted properly.
base::StringTokenizer data_tokenizer(upload_data, "&=");
while (data_tokenizer.GetNext()) {
auto iter = expected_pairs->find(data_tokenizer.token());
ASSERT_TRUE(iter != expected_pairs->end()) << data_tokenizer.token();
ASSERT_TRUE(data_tokenizer.GetNext()) << data_tokenizer.token();
ASSERT_EQ(iter->second, data_tokenizer.token());
// Ensure that none of the keys appears twice.
expected_pairs->erase(iter);
}
ASSERT_EQ(0UL, expected_pairs->size());
}
void GCMRequestTestBase::FastForwardToTriggerNextRetry() {
// Here we compute the maximum delay time by skipping the jitter fluctuation
// that only affects in the negative way.
int next_retry_delay_ms = kDefaultBackoffPolicy.initial_delay_ms;
next_retry_delay_ms *=
pow(kDefaultBackoffPolicy.multiply_factor, retry_count_);
task_environment_.FastForwardBy(base::Milliseconds(next_retry_delay_ms));
}
} // namespace gcm
|