| Index: components/data_usage/core/data_use_aggregator_unittest.cc
|
| diff --git a/components/data_usage/core/data_use_aggregator_unittest.cc b/components/data_usage/core/data_use_aggregator_unittest.cc
|
| index f0d5f44d67e5288ed7ac72a2242d239983da0c50..325065ca11717edb13f5c825b2408155e26d4895 100644
|
| --- a/components/data_usage/core/data_use_aggregator_unittest.cc
|
| +++ b/components/data_usage/core/data_use_aggregator_unittest.cc
|
| @@ -15,6 +15,7 @@
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/time/time.h"
|
| #include "components/data_usage/core/data_use.h"
|
| +#include "components/data_usage/core/data_use_amortizer.h"
|
| #include "components/data_usage/core/data_use_annotator.h"
|
| #include "net/base/load_timing_info.h"
|
| #include "net/base/network_change_notifier.h"
|
| @@ -38,8 +39,9 @@ base::TimeTicks GetRequestStart(const net::URLRequest& request) {
|
| // Test class that can set the network operator's MCCMNC.
|
| class TestDataUseAggregator : public DataUseAggregator {
|
| public:
|
| - TestDataUseAggregator(scoped_ptr<DataUseAnnotator> annotator)
|
| - : DataUseAggregator(annotator.Pass()) {}
|
| + TestDataUseAggregator(scoped_ptr<DataUseAnnotator> annotator,
|
| + scoped_ptr<DataUseAmortizer> amortizer)
|
| + : DataUseAggregator(annotator.Pass(), amortizer.Pass()) {}
|
|
|
| ~TestDataUseAggregator() override {}
|
|
|
| @@ -102,6 +104,25 @@ class FakeDataUseAnnotator : public DataUseAnnotator {
|
| DISALLOW_COPY_AND_ASSIGN(FakeDataUseAnnotator);
|
| };
|
|
|
| +// Test DataUseAmortizer that doubles the bytes of all DataUse objects it sees.
|
| +class DoublingAmortizer : public DataUseAmortizer {
|
| + public:
|
| + DoublingAmortizer() {}
|
| + ~DoublingAmortizer() override {}
|
| +
|
| + void AmortizeDataUse(scoped_ptr<DataUse> data_use,
|
| + const AmortizationCompleteCallback& callback) override {
|
| + data_use->tx_bytes *= 2;
|
| + data_use->rx_bytes *= 2;
|
| + callback.Run(data_use.Pass());
|
| + }
|
| +
|
| + void OnExtraBytes(int64_t extra_tx_bytes, int64_t extra_rx_bytes) override {}
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(DoublingAmortizer);
|
| +};
|
| +
|
| // A network delegate that reports all received and sent network bytes to a
|
| // DataUseAggregator.
|
| class ReportingNetworkDelegate : public net::NetworkDelegateImpl {
|
| @@ -124,6 +145,9 @@ class ReportingNetworkDelegate : public net::NetworkDelegateImpl {
|
|
|
| typedef std::map<const net::URLRequest*, DataUseContext> DataUseContextMap;
|
|
|
| + // Constructs a ReportingNetworkDelegate. |fake_data_use_annotator| can be
|
| + // NULL, indicating that no annotator is in use and no requests should be
|
| + // annotated with tab IDs.
|
| ReportingNetworkDelegate(
|
| TestDataUseAggregator* data_use_aggregator,
|
| FakeDataUseAnnotator* fake_data_use_annotator,
|
| @@ -147,7 +171,8 @@ class ReportingNetworkDelegate : public net::NetworkDelegateImpl {
|
| ? DataUseContext()
|
| : data_use_context_it->second;
|
|
|
| - fake_data_use_annotator_->set_tab_id(data_use_context.tab_id);
|
| + if (fake_data_use_annotator_)
|
| + fake_data_use_annotator_->set_tab_id(data_use_context.tab_id);
|
|
|
| if (test_network_change_notifier_->GetCurrentConnectionType() !=
|
| data_use_context.connection_type) {
|
| @@ -211,23 +236,37 @@ class TestObserver : public DataUseAggregator::Observer {
|
|
|
| class DataUseAggregatorTest : public testing::Test {
|
| public:
|
| - DataUseAggregatorTest()
|
| - : fake_data_use_annotator_(new FakeDataUseAnnotator()),
|
| - data_use_aggregator_(
|
| - scoped_ptr<DataUseAnnotator>(fake_data_use_annotator_)),
|
| - test_network_change_notifier_(&data_use_aggregator_),
|
| - reporting_network_delegate_(&data_use_aggregator_,
|
| - fake_data_use_annotator_,
|
| - &test_network_change_notifier_),
|
| - context_(true),
|
| - test_observer_(&data_use_aggregator_) {
|
| - context_.set_client_socket_factory(&mock_socket_factory_);
|
| - context_.set_network_delegate(&reporting_network_delegate_);
|
| - context_.Init();
|
| - }
|
| -
|
| + DataUseAggregatorTest() {}
|
| ~DataUseAggregatorTest() override {}
|
|
|
| + void Initialize(scoped_ptr<FakeDataUseAnnotator> annotator,
|
| + scoped_ptr<DataUseAmortizer> amortizer) {
|
| + // Destroy objects that have dependencies on other objects here in the
|
| + // reverse order that they are created.
|
| + context_.reset();
|
| + reporting_network_delegate_.reset();
|
| + mock_socket_factory_.reset();
|
| + test_network_change_notifier_.reset();
|
| + test_observer_.reset();
|
| +
|
| + // Initialize testing objects.
|
| + FakeDataUseAnnotator* fake_data_use_annotator = annotator.get();
|
| + data_use_aggregator_.reset(
|
| + new TestDataUseAggregator(annotator.Pass(), amortizer.Pass()));
|
| + test_observer_.reset(new TestObserver(data_use_aggregator_.get()));
|
| + test_network_change_notifier_.reset(
|
| + new TestNetworkChangeNotifier(data_use_aggregator_.get()));
|
| + mock_socket_factory_.reset(new net::MockClientSocketFactory());
|
| + reporting_network_delegate_.reset(new ReportingNetworkDelegate(
|
| + data_use_aggregator_.get(), fake_data_use_annotator,
|
| + test_network_change_notifier_.get()));
|
| +
|
| + context_.reset(new net::TestURLRequestContext(true));
|
| + context_->set_client_socket_factory(mock_socket_factory_.get());
|
| + context_->set_network_delegate(reporting_network_delegate_.get());
|
| + context_->Init();
|
| + }
|
| +
|
| scoped_ptr<net::URLRequest> ExecuteRequest(
|
| const GURL& url,
|
| const GURL& first_party_for_cookies,
|
| @@ -239,18 +278,18 @@ class DataUseAggregatorTest : public testing::Test {
|
| net::MockRead(net::SYNCHRONOUS, net::OK),
|
| };
|
| net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0);
|
| - mock_socket_factory_.AddSocketDataProvider(&socket);
|
| + mock_socket_factory_->AddSocketDataProvider(&socket);
|
|
|
| net::TestDelegate delegate;
|
| scoped_ptr<net::URLRequest> request =
|
| - context_.CreateRequest(url, net::IDLE, &delegate);
|
| + context_->CreateRequest(url, net::IDLE, &delegate);
|
| request->set_first_party_for_cookies(first_party_for_cookies);
|
|
|
| ReportingNetworkDelegate::DataUseContextMap data_use_context_map;
|
| data_use_context_map[request.get()] =
|
| ReportingNetworkDelegate::DataUseContext(tab_id, connection_type,
|
| mcc_mnc);
|
| - reporting_network_delegate_.set_data_use_context_map(data_use_context_map);
|
| + reporting_network_delegate_->set_data_use_context_map(data_use_context_map);
|
|
|
| request->Start();
|
| loop_.RunUntilIdle();
|
| @@ -259,179 +298,132 @@ class DataUseAggregatorTest : public testing::Test {
|
| }
|
|
|
| ReportingNetworkDelegate* reporting_network_delegate() {
|
| - return &reporting_network_delegate_;
|
| + return reporting_network_delegate_.get();
|
| }
|
|
|
| - DataUseAggregator* data_use_aggregator() { return &data_use_aggregator_; }
|
| + DataUseAggregator* data_use_aggregator() {
|
| + return data_use_aggregator_.get();
|
| + }
|
|
|
| net::MockClientSocketFactory* mock_socket_factory() {
|
| - return &mock_socket_factory_;
|
| + return mock_socket_factory_.get();
|
| }
|
|
|
| - net::TestURLRequestContext* context() { return &context_; }
|
| + net::TestURLRequestContext* context() { return context_.get(); }
|
|
|
| - TestObserver* test_observer() { return &test_observer_; }
|
| + TestObserver* test_observer() { return test_observer_.get(); }
|
|
|
| private:
|
| base::MessageLoopForIO loop_;
|
| - // Weak, owned by |data_use_aggregator_|.
|
| - FakeDataUseAnnotator* fake_data_use_annotator_;
|
| - TestDataUseAggregator data_use_aggregator_;
|
| - TestNetworkChangeNotifier test_network_change_notifier_;
|
| - net::MockClientSocketFactory mock_socket_factory_;
|
| - ReportingNetworkDelegate reporting_network_delegate_;
|
| - net::TestURLRequestContext context_;
|
| - TestObserver test_observer_;
|
| + scoped_ptr<TestDataUseAggregator> data_use_aggregator_;
|
| + scoped_ptr<TestObserver> test_observer_;
|
| + scoped_ptr<TestNetworkChangeNotifier> test_network_change_notifier_;
|
| + scoped_ptr<net::MockClientSocketFactory> mock_socket_factory_;
|
| + scoped_ptr<ReportingNetworkDelegate> reporting_network_delegate_;
|
| + scoped_ptr<net::TestURLRequestContext> context_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(DataUseAggregatorTest);
|
| };
|
|
|
| TEST_F(DataUseAggregatorTest, ReportDataUse) {
|
| - const int32_t kFooTabId = 10;
|
| - const net::NetworkChangeNotifier::ConnectionType kFooConnectionType =
|
| - net::NetworkChangeNotifier::CONNECTION_2G;
|
| - const std::string kFooMccMnc = "foo_mcc_mnc";
|
| - scoped_ptr<net::URLRequest> foo_request =
|
| - ExecuteRequest(GURL("http://foo.com"), GURL("http://foofirstparty.com"),
|
| - kFooTabId, kFooConnectionType, kFooMccMnc);
|
| -
|
| - const int32_t kBarTabId = 20;
|
| - const net::NetworkChangeNotifier::ConnectionType kBarConnectionType =
|
| - net::NetworkChangeNotifier::CONNECTION_WIFI;
|
| - const std::string kBarMccMnc = "bar_mcc_mnc";
|
| - scoped_ptr<net::URLRequest> bar_request =
|
| - ExecuteRequest(GURL("http://bar.com"), GURL("http://barfirstparty.com"),
|
| - kBarTabId, kBarConnectionType, kBarMccMnc);
|
| -
|
| - auto data_use_it = test_observer()->observed_data_use().begin();
|
| -
|
| - // First, the |foo_request| data use should have happened.
|
| - int64_t observed_foo_tx_bytes = 0, observed_foo_rx_bytes = 0;
|
| - while (data_use_it != test_observer()->observed_data_use().end() &&
|
| - data_use_it->url == GURL("http://foo.com")) {
|
| - EXPECT_EQ(GetRequestStart(*foo_request), data_use_it->request_start);
|
| - EXPECT_EQ(GURL("http://foofirstparty.com"),
|
| - data_use_it->first_party_for_cookies);
|
| - EXPECT_EQ(kFooTabId, data_use_it->tab_id);
|
| - EXPECT_EQ(kFooConnectionType, data_use_it->connection_type);
|
| - EXPECT_EQ(kFooMccMnc, data_use_it->mcc_mnc);
|
| -
|
| - observed_foo_tx_bytes += data_use_it->tx_bytes;
|
| - observed_foo_rx_bytes += data_use_it->rx_bytes;
|
| - ++data_use_it;
|
| - }
|
| - EXPECT_EQ(foo_request->GetTotalSentBytes(), observed_foo_tx_bytes);
|
| - EXPECT_EQ(foo_request->GetTotalReceivedBytes(), observed_foo_rx_bytes);
|
| -
|
| - // Then, the |bar_request| data use should have happened.
|
| - int64_t observed_bar_tx_bytes = 0, observed_bar_rx_bytes = 0;
|
| - while (data_use_it != test_observer()->observed_data_use().end()) {
|
| - EXPECT_EQ(GURL("http://bar.com"), data_use_it->url);
|
| - EXPECT_EQ(GetRequestStart(*bar_request), data_use_it->request_start);
|
| - EXPECT_EQ(GURL("http://barfirstparty.com"),
|
| - data_use_it->first_party_for_cookies);
|
| - EXPECT_EQ(kBarTabId, data_use_it->tab_id);
|
| - EXPECT_EQ(kBarConnectionType, data_use_it->connection_type);
|
| - EXPECT_EQ(kBarMccMnc, data_use_it->mcc_mnc);
|
| -
|
| - observed_bar_tx_bytes += data_use_it->tx_bytes;
|
| - observed_bar_rx_bytes += data_use_it->rx_bytes;
|
| - ++data_use_it;
|
| - }
|
| - EXPECT_EQ(bar_request->GetTotalSentBytes(), observed_bar_tx_bytes);
|
| - EXPECT_EQ(bar_request->GetTotalReceivedBytes(), observed_bar_rx_bytes);
|
| -}
|
| -
|
| -TEST_F(DataUseAggregatorTest, ReportCombinedDataUse) {
|
| - // Set up the |foo_request|.
|
| - net::MockRead foo_reads[] = {
|
| - net::MockRead(net::SYNCHRONOUS, "HTTP/1.1 200 OK\r\n\r\n"),
|
| - net::MockRead(net::SYNCHRONOUS, "hello world"),
|
| - net::MockRead(net::SYNCHRONOUS, net::OK),
|
| - };
|
| - net::StaticSocketDataProvider foo_socket(foo_reads, arraysize(foo_reads),
|
| - nullptr, 0);
|
| - mock_socket_factory()->AddSocketDataProvider(&foo_socket);
|
| -
|
| - net::TestDelegate foo_delegate;
|
| - scoped_ptr<net::URLRequest> foo_request = context()->CreateRequest(
|
| - GURL("http://foo.com"), net::IDLE, &foo_delegate);
|
| - foo_request->set_first_party_for_cookies(GURL("http://foofirstparty.com"));
|
| -
|
| - // Set up the |bar_request|.
|
| - net::MockRead bar_reads[] = {
|
| - net::MockRead(net::SYNCHRONOUS, "HTTP/1.1 200 OK\r\n\r\n"),
|
| - net::MockRead(net::SYNCHRONOUS, "hello world"),
|
| - net::MockRead(net::SYNCHRONOUS, net::OK),
|
| + const struct {
|
| + bool use_annotator;
|
| + bool use_amortizer;
|
| + bool expect_tab_ids;
|
| + int64_t expected_amortization_multiple;
|
| + } kTestCases[] = {
|
| + {false, false, false, 1},
|
| + {false, true, false, 2},
|
| + {true, false, true, 1},
|
| + {true, true, true, 2},
|
| };
|
| - net::StaticSocketDataProvider bar_socket(bar_reads, arraysize(bar_reads),
|
| - nullptr, 0);
|
| - mock_socket_factory()->AddSocketDataProvider(&bar_socket);
|
| -
|
| - net::TestDelegate bar_delegate;
|
| - scoped_ptr<net::URLRequest> bar_request = context()->CreateRequest(
|
| - GURL("http://bar.com"), net::IDLE, &bar_delegate);
|
| - bar_request->set_first_party_for_cookies(GURL("http://barfirstparty.com"));
|
| -
|
| - // Set up the network delegate to assign tab IDs and connection types for each
|
| - // request.
|
| - const int32_t kFooTabId = 10;
|
| - const net::NetworkChangeNotifier::ConnectionType kFooConnectionType =
|
| - net::NetworkChangeNotifier::CONNECTION_2G;
|
| - const std::string kFooMccMnc = "foo_mcc_mnc";
|
| - const int32_t kBarTabId = 20;
|
| - const net::NetworkChangeNotifier::ConnectionType kBarConnectionType =
|
| - net::NetworkChangeNotifier::CONNECTION_WIFI;
|
| - const std::string kBarMccMnc = "bar_mcc_mnc";
|
| -
|
| - ReportingNetworkDelegate::DataUseContextMap data_use_context_map;
|
| - data_use_context_map[foo_request.get()] =
|
| - ReportingNetworkDelegate::DataUseContext(kFooTabId, kFooConnectionType,
|
| - kFooMccMnc);
|
| - data_use_context_map[bar_request.get()] =
|
| - ReportingNetworkDelegate::DataUseContext(kBarTabId, kBarConnectionType,
|
| - kBarMccMnc);
|
| - reporting_network_delegate()->set_data_use_context_map(data_use_context_map);
|
| -
|
| - // Run the requests.
|
| - foo_request->Start();
|
| - bar_request->Start();
|
| - base::MessageLoop::current()->RunUntilIdle();
|
|
|
| - // The observer should have been notified once with a DataUse element for each
|
| - // request.
|
| - EXPECT_EQ(1, test_observer()->on_data_use_called_count());
|
| - EXPECT_EQ(static_cast<size_t>(2),
|
| - test_observer()->observed_data_use().size());
|
| -
|
| - // All of the |foo_request| DataUse should have been combined into a single
|
| - // DataUse element.
|
| - const DataUse& foo_data_use = test_observer()->observed_data_use().front();
|
| - EXPECT_EQ(GURL("http://foo.com"), foo_data_use.url);
|
| - EXPECT_EQ(GetRequestStart(*foo_request), foo_data_use.request_start);
|
| - EXPECT_EQ(GURL("http://foofirstparty.com"),
|
| - foo_data_use.first_party_for_cookies);
|
| - EXPECT_EQ(kFooTabId, foo_data_use.tab_id);
|
| - EXPECT_EQ(kFooConnectionType, foo_data_use.connection_type);
|
| - EXPECT_EQ(kFooMccMnc, foo_data_use.mcc_mnc);
|
| - EXPECT_EQ(foo_request->GetTotalSentBytes(), foo_data_use.tx_bytes);
|
| - EXPECT_EQ(foo_request->GetTotalReceivedBytes(), foo_data_use.rx_bytes);
|
| -
|
| - // All of the |bar_request| DataUse should have been combined into a single
|
| - // DataUse element.
|
| - const DataUse& bar_data_use = test_observer()->observed_data_use().back();
|
| - EXPECT_EQ(GURL("http://bar.com"), bar_data_use.url);
|
| - EXPECT_EQ(GetRequestStart(*bar_request), bar_data_use.request_start);
|
| - EXPECT_EQ(GURL("http://barfirstparty.com"),
|
| - bar_data_use.first_party_for_cookies);
|
| - EXPECT_EQ(kBarTabId, bar_data_use.tab_id);
|
| - EXPECT_EQ(kBarConnectionType, bar_data_use.connection_type);
|
| - EXPECT_EQ(kBarMccMnc, bar_data_use.mcc_mnc);
|
| - EXPECT_EQ(bar_request->GetTotalSentBytes(), bar_data_use.tx_bytes);
|
| - EXPECT_EQ(bar_request->GetTotalReceivedBytes(), bar_data_use.rx_bytes);
|
| + for (const auto& test_case : kTestCases) {
|
| + scoped_ptr<FakeDataUseAnnotator> annotator(
|
| + test_case.use_annotator ? new FakeDataUseAnnotator() : nullptr);
|
| + scoped_ptr<DataUseAmortizer> amortizer(
|
| + test_case.use_amortizer ? new DoublingAmortizer() : nullptr);
|
| +
|
| + Initialize(annotator.Pass(), amortizer.Pass());
|
| +
|
| + const int32_t kFooTabId = 10;
|
| + const net::NetworkChangeNotifier::ConnectionType kFooConnectionType =
|
| + net::NetworkChangeNotifier::CONNECTION_2G;
|
| + const std::string kFooMccMnc = "foo_mcc_mnc";
|
| + scoped_ptr<net::URLRequest> foo_request =
|
| + ExecuteRequest(GURL("http://foo.com"), GURL("http://foofirstparty.com"),
|
| + kFooTabId, kFooConnectionType, kFooMccMnc);
|
| +
|
| + const int32_t kBarTabId = 20;
|
| + const net::NetworkChangeNotifier::ConnectionType kBarConnectionType =
|
| + net::NetworkChangeNotifier::CONNECTION_WIFI;
|
| + const std::string kBarMccMnc = "bar_mcc_mnc";
|
| + scoped_ptr<net::URLRequest> bar_request =
|
| + ExecuteRequest(GURL("http://bar.com"), GURL("http://barfirstparty.com"),
|
| + kBarTabId, kBarConnectionType, kBarMccMnc);
|
| +
|
| + auto data_use_it = test_observer()->observed_data_use().begin();
|
| +
|
| + // First, the |foo_request| data use should have happened.
|
| + int64_t observed_foo_tx_bytes = 0, observed_foo_rx_bytes = 0;
|
| + while (data_use_it != test_observer()->observed_data_use().end() &&
|
| + data_use_it->url == GURL("http://foo.com")) {
|
| + EXPECT_EQ(GetRequestStart(*foo_request), data_use_it->request_start);
|
| + EXPECT_EQ(GURL("http://foofirstparty.com"),
|
| + data_use_it->first_party_for_cookies);
|
| +
|
| + if (test_case.expect_tab_ids)
|
| + EXPECT_EQ(kFooTabId, data_use_it->tab_id);
|
| + else
|
| + EXPECT_EQ(-1, data_use_it->tab_id);
|
| +
|
| + EXPECT_EQ(kFooConnectionType, data_use_it->connection_type);
|
| + EXPECT_EQ(kFooMccMnc, data_use_it->mcc_mnc);
|
| +
|
| + observed_foo_tx_bytes += data_use_it->tx_bytes;
|
| + observed_foo_rx_bytes += data_use_it->rx_bytes;
|
| + ++data_use_it;
|
| + }
|
| + EXPECT_EQ(foo_request->GetTotalSentBytes() *
|
| + test_case.expected_amortization_multiple,
|
| + observed_foo_tx_bytes);
|
| + EXPECT_EQ(foo_request->GetTotalReceivedBytes() *
|
| + test_case.expected_amortization_multiple,
|
| + observed_foo_rx_bytes);
|
| +
|
| + // Then, the |bar_request| data use should have happened.
|
| + int64_t observed_bar_tx_bytes = 0, observed_bar_rx_bytes = 0;
|
| + while (data_use_it != test_observer()->observed_data_use().end()) {
|
| + EXPECT_EQ(GURL("http://bar.com"), data_use_it->url);
|
| + EXPECT_EQ(GetRequestStart(*bar_request), data_use_it->request_start);
|
| + EXPECT_EQ(GURL("http://barfirstparty.com"),
|
| + data_use_it->first_party_for_cookies);
|
| +
|
| + if (test_case.expect_tab_ids)
|
| + EXPECT_EQ(kBarTabId, data_use_it->tab_id);
|
| + else
|
| + EXPECT_EQ(-1, data_use_it->tab_id);
|
| +
|
| + EXPECT_EQ(kBarConnectionType, data_use_it->connection_type);
|
| + EXPECT_EQ(kBarMccMnc, data_use_it->mcc_mnc);
|
| +
|
| + observed_bar_tx_bytes += data_use_it->tx_bytes;
|
| + observed_bar_rx_bytes += data_use_it->rx_bytes;
|
| + ++data_use_it;
|
| + }
|
| + EXPECT_EQ(bar_request->GetTotalSentBytes() *
|
| + test_case.expected_amortization_multiple,
|
| + observed_bar_tx_bytes);
|
| + EXPECT_EQ(bar_request->GetTotalReceivedBytes() *
|
| + test_case.expected_amortization_multiple,
|
| + observed_bar_rx_bytes);
|
| + }
|
| }
|
|
|
| TEST_F(DataUseAggregatorTest, ReportOffTheRecordDataUse) {
|
| + Initialize(scoped_ptr<FakeDataUseAnnotator>(new FakeDataUseAnnotator()),
|
| + scoped_ptr<DataUseAmortizer>(new DoublingAmortizer()));
|
| +
|
| // Off the record data use should not be reported to observers.
|
| data_use_aggregator()->ReportOffTheRecordDataUse(1000, 1000);
|
| base::MessageLoop::current()->RunUntilIdle();
|
|
|