Chromium Code Reviews| 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 |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e75c7eaabddbd90c4eb49ce137e38dad75474be7 |
| --- /dev/null |
| +++ b/components/data_usage/core/data_use_aggregator_unittest.cc |
| @@ -0,0 +1,234 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/data_usage/core/data_use_aggregator.h" |
| + |
| +#include <stdint.h> |
| + |
| +#include <vector> |
| + |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "components/data_usage/core/data_use.h" |
| +#include "net/base/network_change_notifier.h" |
| +#include "net/base/network_delegate_impl.h" |
| +#include "net/socket/socket_test_util.h" |
| +#include "net/url_request/url_request.h" |
| +#include "net/url_request/url_request_test_util.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "url/gurl.h" |
| + |
| +namespace data_usage { |
| + |
| +namespace { |
| + |
| +// Override NetworkChangeNotifier to simulate connection type changes for tests. |
| +class TestNetworkChangeNotifier : public net::NetworkChangeNotifier { |
| + public: |
| + TestNetworkChangeNotifier() |
| + : net::NetworkChangeNotifier(), |
| + connection_type_to_return_( |
| + net::NetworkChangeNotifier::CONNECTION_UNKNOWN) {} |
| + |
| + // Simulates a change of the connection type to |type|. |
| + void SimulateNetworkConnectionChange(ConnectionType type) { |
| + connection_type_to_return_ = type; |
| + } |
| + |
| + private: |
| + ConnectionType GetCurrentConnectionType() const override { |
| + return connection_type_to_return_; |
| + } |
| + |
| + // The currently simulated network connection type. |
| + ConnectionType connection_type_to_return_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TestNetworkChangeNotifier); |
| +}; |
| + |
| +// A network delegate that reports all received and sent network bytes to a |
| +// DataUseAggregator. |
| +class ReportingNetworkDelegate : public net::NetworkDelegateImpl { |
| + public: |
| + ReportingNetworkDelegate(DataUseAggregator* data_use_aggregator) |
| + : data_use_aggregator_(data_use_aggregator), tab_id_for_requests_(-1) {} |
| + |
| + ~ReportingNetworkDelegate() override {} |
| + |
| + void set_tab_id_for_requests(int32_t tab_id_for_requests) { |
| + tab_id_for_requests_ = tab_id_for_requests; |
| + } |
| + |
| + private: |
| + void OnNetworkBytesReceived(const net::URLRequest& request, |
| + int64_t bytes_received) override { |
| + data_use_aggregator_->ReportDataUse(request, tab_id_for_requests_, |
| + 0 /* tx_bytes */, bytes_received); |
| + } |
| + |
| + void OnNetworkBytesSent(const net::URLRequest& request, |
| + int64_t bytes_sent) override { |
| + data_use_aggregator_->ReportDataUse(request, tab_id_for_requests_, |
| + bytes_sent, 0 /* rx_bytes */); |
| + } |
| + |
| + DataUseAggregator* data_use_aggregator_; |
| + int32_t tab_id_for_requests_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ReportingNetworkDelegate); |
| +}; |
| + |
| +// An observer that keeps track of all the data use it observed. |
| +class TestObserver : public DataUseAggregator::Observer { |
| + public: |
| + TestObserver(DataUseAggregator* data_use_aggregator) |
|
tbansal1
2015/10/08 04:22:44
explicit
sclittle
2015/10/08 19:44:13
Done.
|
| + : data_use_aggregator_(data_use_aggregator) { |
| + data_use_aggregator_->AddObserver(this); |
| + } |
| + |
| + ~TestObserver() override { data_use_aggregator_->RemoveObserver(this); } |
| + |
| + void OnDataUse(const std::vector<DataUse>& data_use_sequence) override { |
| + observed_data_use_.insert(observed_data_use_.end(), |
| + data_use_sequence.begin(), |
| + data_use_sequence.end()); |
| + } |
| + |
| + const std::vector<DataUse>& observed_data_use() const { |
| + return observed_data_use_; |
| + } |
| + |
| + private: |
| + DataUseAggregator* data_use_aggregator_; |
| + std::vector<DataUse> observed_data_use_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TestObserver); |
| +}; |
| + |
| +class DataUseAggregatorTest : public testing::Test { |
| + public: |
| + DataUseAggregatorTest() |
| + : reporting_network_delegate_(&data_use_aggregator_), |
| + 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() override {} |
| + |
| + scoped_ptr<net::URLRequest> ExecuteRequest( |
| + const GURL& url, |
| + const GURL& first_party_for_cookies) { |
| + net::MockRead reads[] = { |
| + net::MockRead("HTTP/1.1 200 OK\r\n\r\n"), net::MockRead("hello world"), |
| + net::MockRead(net::SYNCHRONOUS, net::OK), |
| + }; |
| + net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0); |
| + mock_socket_factory_.AddSocketDataProvider(&socket); |
| + |
| + net::TestDelegate delegate; |
| + scoped_ptr<net::URLRequest> request = |
| + context_.CreateRequest(url, net::IDLE, &delegate); |
| + request->set_first_party_for_cookies(first_party_for_cookies); |
| + request->Start(); |
| + loop_.RunUntilIdle(); |
| + |
| + return request.Pass(); |
| + } |
| + |
| + void SimulateNetworkConnectionChange( |
| + net::NetworkChangeNotifier::ConnectionType connection_type) { |
| + test_network_change_notifier_.SimulateNetworkConnectionChange( |
| + connection_type); |
| + } |
| + |
| + void set_tab_id_for_requests(int32_t tab_id_for_requests) { |
| + reporting_network_delegate_.set_tab_id_for_requests(tab_id_for_requests); |
| + } |
| + |
| + DataUseAggregator* data_use_aggregator() { return &data_use_aggregator_; } |
| + |
| + const std::vector<DataUse>& observed_data_use() const { |
| + return test_observer_.observed_data_use(); |
| + } |
| + |
| + private: |
| + base::MessageLoopForIO loop_; |
| + TestNetworkChangeNotifier test_network_change_notifier_; |
| + |
| + DataUseAggregator data_use_aggregator_; |
| + net::MockClientSocketFactory mock_socket_factory_; |
| + ReportingNetworkDelegate reporting_network_delegate_; |
| + net::TestURLRequestContext context_; |
| + TestObserver test_observer_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DataUseAggregatorTest); |
| +}; |
| + |
| +TEST_F(DataUseAggregatorTest, ReportDataUse) { |
| + const net::NetworkChangeNotifier::ConnectionType kFooConnectionType = |
| + net::NetworkChangeNotifier::CONNECTION_2G; |
| + SimulateNetworkConnectionChange(kFooConnectionType); |
| + const int32_t kFooTabId = 10; |
| + set_tab_id_for_requests(kFooTabId); |
| + const scoped_ptr<net::URLRequest> foo_request = |
| + ExecuteRequest(GURL("http://foo.com"), GURL("http://foofirstparty.com")); |
| + |
| + const net::NetworkChangeNotifier::ConnectionType kBarConnectionType = |
| + net::NetworkChangeNotifier::CONNECTION_WIFI; |
| + SimulateNetworkConnectionChange(kBarConnectionType); |
| + const int32_t kBarTabId = 20; |
| + set_tab_id_for_requests(kBarTabId); |
| + scoped_ptr<net::URLRequest> bar_request = |
| + ExecuteRequest(GURL("http://bar.com"), GURL("http://barfirstparty.com")); |
| + |
| + auto data_use_it = 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 != observed_data_use().end() && |
| + data_use_it->url == GURL("http://foo.com")) { |
| + EXPECT_EQ(foo_request->request_time(), data_use_it->request_time); |
| + 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); |
| + |
| + 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 != observed_data_use().end()) { |
| + EXPECT_EQ(GURL("http://bar.com"), data_use_it->url); |
| + EXPECT_EQ(bar_request->request_time(), data_use_it->request_time); |
| + 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); |
| + |
| + 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, ReportOffTheRecordDataUse) { |
| + // Off the record data use should not be reported to observers. |
| + data_use_aggregator()->ReportOffTheRecordDataUse(1000, 1000); |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + EXPECT_EQ(static_cast<size_t>(0), observed_data_use().size()); |
|
tbansal1
2015/10/08 04:22:44
Just say 0U?
sclittle
2015/10/08 19:44:13
0U means unsigned int, but the exact size of size_
|
| +} |
| + |
| +} // namespace |
| + |
| +} // namespace data_usage |