123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- // Copyright (c) 2016 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 <memory>
- #include <string>
- #include "base/feature_list.h"
- #include "base/run_loop.h"
- #include "base/test/task_environment.h"
- #include "net/base/features.h"
- #include "net/base/net_errors.h"
- #include "net/base/schemeful_site.h"
- #include "net/base/test_completion_callback.h"
- #include "net/http/http_cache_lookup_manager.h"
- #include "net/http/http_transaction_test_util.h"
- #include "net/http/mock_http_cache.h"
- #include "net/test/gtest_util.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest-param-test.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using net::test::IsOk;
- namespace net {
- namespace {
- class MockServerPushHelper : public ServerPushDelegate::ServerPushHelper {
- public:
- explicit MockServerPushHelper(const GURL& url)
- : request_url_(url),
- network_isolation_key_(SchemefulSite(url), SchemefulSite(url)) {}
- const GURL& GetURL() const override { return request_url_; }
- NetworkIsolationKey GetNetworkIsolationKey() const override {
- return network_isolation_key_;
- }
- void set_network_isolation_key(
- const net::NetworkIsolationKey& network_isolation_key) {
- network_isolation_key_ = network_isolation_key;
- }
- MOCK_METHOD0(Cancel, void());
- private:
- const GURL request_url_;
- NetworkIsolationKey network_isolation_key_;
- };
- std::unique_ptr<MockTransaction> CreateMockTransaction(const GURL& url) {
- MockTransaction mock_trans = {
- url.spec().c_str(),
- "GET",
- base::Time(),
- "",
- LOAD_NORMAL,
- DefaultTransportInfo(),
- "HTTP/1.1 200 OK",
- "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
- "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n",
- base::Time(),
- "<html><body>Google Blah Blah</body></html>",
- {},
- TEST_MODE_NORMAL,
- nullptr,
- nullptr,
- nullptr,
- 0,
- 0,
- OK,
- };
- return std::make_unique<MockTransaction>(mock_trans);
- }
- void PopulateCacheEntry(HttpCache* cache, const GURL& request_url) {
- TestCompletionCallback callback;
- std::unique_ptr<MockTransaction> mock_trans =
- CreateMockTransaction(request_url);
- AddMockTransaction(mock_trans.get());
- MockHttpRequest request(*(mock_trans.get()));
- std::unique_ptr<HttpTransaction> trans;
- int rv = cache->CreateTransaction(DEFAULT_PRIORITY, &trans);
- EXPECT_THAT(rv, IsOk());
- ASSERT_TRUE(trans.get());
- rv = trans->Start(&request, callback.callback(), NetLogWithSource());
- base::RunLoop().RunUntilIdle();
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- ASSERT_EQ(mock_trans->start_return_code, rv);
- if (OK != rv)
- return;
- const HttpResponseInfo* response = trans->GetResponseInfo();
- ASSERT_TRUE(response);
- std::string content;
- rv = ReadTransaction(trans.get(), &content);
- EXPECT_THAT(rv, IsOk());
- std::string expected(mock_trans->data);
- EXPECT_EQ(expected, content);
- RemoveMockTransaction(mock_trans.get());
- }
- } // namespace
- TEST(HttpCacheLookupManagerTest, ServerPushMissCache) {
- base::test::TaskEnvironment task_environment;
- MockHttpCache mock_cache;
- HttpCacheLookupManager push_delegate(mock_cache.http_cache());
- GURL request_url("http://www.example.com/pushed.jpg");
- std::unique_ptr<MockServerPushHelper> push_helper =
- std::make_unique<MockServerPushHelper>(request_url);
- MockServerPushHelper* push_helper_ptr = push_helper.get();
- // Receive a server push and should not cancel the push.
- EXPECT_CALL(*push_helper_ptr, Cancel()).Times(0);
- push_delegate.OnPush(std::move(push_helper), NetLogWithSource());
- base::RunLoop().RunUntilIdle();
- // Make sure no network transaction is created.
- EXPECT_EQ(0, mock_cache.network_layer()->transaction_count());
- EXPECT_EQ(0, mock_cache.disk_cache()->open_count());
- EXPECT_EQ(0, mock_cache.disk_cache()->create_count());
- }
- TEST(HttpCacheLookupManagerTest, ServerPushDoNotCreateCacheEntry) {
- base::test::TaskEnvironment task_environment;
- MockHttpCache mock_cache;
- HttpCacheLookupManager push_delegate(mock_cache.http_cache());
- GURL request_url("http://www.example.com/pushed.jpg");
- std::unique_ptr<MockServerPushHelper> push_helper =
- std::make_unique<MockServerPushHelper>(request_url);
- MockServerPushHelper* push_helper_ptr = push_helper.get();
- // Receive a server push and should not cancel the push.
- EXPECT_CALL(*push_helper_ptr, Cancel()).Times(0);
- push_delegate.OnPush(std::move(push_helper), NetLogWithSource());
- base::RunLoop().RunUntilIdle();
- // Receive another server push for the same url.
- std::unique_ptr<MockServerPushHelper> push_helper2 =
- std::make_unique<MockServerPushHelper>(request_url);
- MockServerPushHelper* push_helper_ptr2 = push_helper2.get();
- EXPECT_CALL(*push_helper_ptr2, Cancel()).Times(0);
- push_delegate.OnPush(std::move(push_helper2), NetLogWithSource());
- base::RunLoop().RunUntilIdle();
- // Verify no network transaction is created.
- EXPECT_EQ(0, mock_cache.network_layer()->transaction_count());
- EXPECT_EQ(0, mock_cache.disk_cache()->open_count());
- // Verify no cache entry is created for server push lookup.
- EXPECT_EQ(0, mock_cache.disk_cache()->create_count());
- }
- // Parameterized by whether the network isolation key are the same for the
- // server push and corresponding cache entry.
- class HttpCacheLookupManagerTest_NetworkIsolationKey
- : public ::testing::Test,
- public ::testing::WithParamInterface<
- bool /* use_same_network_isolation_key */> {};
- TEST_P(HttpCacheLookupManagerTest_NetworkIsolationKey, ServerPushCacheStatus) {
- bool use_same_network_isolation_key = GetParam();
- bool split_cache_enabled = base::FeatureList::IsEnabled(
- net::features::kSplitCacheByNetworkIsolationKey);
- base::test::TaskEnvironment task_environment;
- MockHttpCache mock_cache;
- HttpCacheLookupManager push_delegate(mock_cache.http_cache());
- GURL request_url("http://www.example.com/pushed.jpg");
- // Populate the cache entry so that the cache lookup for server push hits.
- PopulateCacheEntry(mock_cache.http_cache(), request_url);
- EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
- EXPECT_EQ(0, mock_cache.disk_cache()->open_count());
- EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
- // Add another mock transaction since the OnPush will create a new cache
- // transaction.
- std::unique_ptr<MockTransaction> mock_trans =
- CreateMockTransaction(request_url);
- AddMockTransaction(mock_trans.get());
- std::unique_ptr<MockServerPushHelper> push_helper =
- std::make_unique<MockServerPushHelper>(request_url);
- if (!use_same_network_isolation_key) {
- SchemefulSite site(GURL("http://www.abc.com"));
- push_helper->set_network_isolation_key(
- net::NetworkIsolationKey(site, site));
- }
- MockServerPushHelper* push_helper_ptr = push_helper.get();
- int expected_cancel_times =
- use_same_network_isolation_key || !split_cache_enabled ? 1 : 0;
- EXPECT_CALL(*push_helper_ptr, Cancel()).Times(expected_cancel_times);
- push_delegate.OnPush(std::move(push_helper), NetLogWithSource());
- base::RunLoop().RunUntilIdle();
- // Make sure no new net layer transaction is created.
- EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
- int expected_open_count =
- use_same_network_isolation_key || !split_cache_enabled ? 1 : 0;
- EXPECT_EQ(expected_open_count, mock_cache.disk_cache()->open_count());
- EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
- RemoveMockTransaction(mock_trans.get());
- }
- INSTANTIATE_TEST_SUITE_P(
- All,
- HttpCacheLookupManagerTest_NetworkIsolationKey,
- ::testing::Bool());
- // Test when a server push is received while the HttpCacheLookupManager has a
- // pending lookup transaction for the same URL, the new server push will not
- // send a new lookup transaction and should not be canceled.
- TEST(HttpCacheLookupManagerTest, ServerPushPendingLookup) {
- base::test::TaskEnvironment task_environment;
- MockHttpCache mock_cache;
- HttpCacheLookupManager push_delegate(mock_cache.http_cache());
- GURL request_url("http://www.example.com/pushed.jpg");
- // Populate the cache entry so that the cache lookup for server push hits.
- PopulateCacheEntry(mock_cache.http_cache(), request_url);
- EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
- EXPECT_EQ(0, mock_cache.disk_cache()->open_count());
- EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
- // Add another mock transaction since the OnPush will create a new cache
- // transaction.
- std::unique_ptr<MockTransaction> mock_trans =
- CreateMockTransaction(request_url);
- AddMockTransaction(mock_trans.get());
- std::unique_ptr<MockServerPushHelper> push_helper =
- std::make_unique<MockServerPushHelper>(request_url);
- MockServerPushHelper* push_helper_ptr = push_helper.get();
- // Receive a server push and should cancel the push eventually.
- EXPECT_CALL(*push_helper_ptr, Cancel()).Times(1);
- push_delegate.OnPush(std::move(push_helper), NetLogWithSource());
- std::unique_ptr<MockServerPushHelper> push_helper2 =
- std::make_unique<MockServerPushHelper>(request_url);
- MockServerPushHelper* push_helper_ptr2 = push_helper2.get();
- // Receive another server push and should not cancel the push.
- EXPECT_CALL(*push_helper_ptr2, Cancel()).Times(0);
- push_delegate.OnPush(std::move(push_helper2), NetLogWithSource());
- base::RunLoop().RunUntilIdle();
- // Make sure no new net layer transaction is created.
- EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
- EXPECT_EQ(1, mock_cache.disk_cache()->open_count());
- EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
- RemoveMockTransaction(mock_trans.get());
- }
- // Test the server push lookup is based on the full url.
- TEST(HttpCacheLookupManagerTest, ServerPushLookupOnUrl) {
- base::test::TaskEnvironment task_environment;
- MockHttpCache mock_cache;
- HttpCacheLookupManager push_delegate(mock_cache.http_cache());
- GURL request_url("http://www.example.com/pushed.jpg?u=0");
- GURL request_url2("http://www.example.com/pushed.jpg?u=1");
- // Populate the cache entry so that the cache lookup for server push hits.
- PopulateCacheEntry(mock_cache.http_cache(), request_url);
- EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
- EXPECT_EQ(0, mock_cache.disk_cache()->open_count());
- EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
- // Add another mock transaction since the OnPush will create a new cache
- // transaction.
- std::unique_ptr<MockTransaction> mock_trans =
- CreateMockTransaction(request_url);
- AddMockTransaction(mock_trans.get());
- std::unique_ptr<MockServerPushHelper> push_helper =
- std::make_unique<MockServerPushHelper>(request_url);
- MockServerPushHelper* push_helper_ptr = push_helper.get();
- // Receive a server push and should cancel the push eventually.
- EXPECT_CALL(*push_helper_ptr, Cancel()).Times(1);
- push_delegate.OnPush(std::move(push_helper), NetLogWithSource());
- // Run until the lookup transaction finishes for the first server push.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
- EXPECT_EQ(1, mock_cache.disk_cache()->open_count());
- EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
- RemoveMockTransaction(mock_trans.get());
- AddMockTransaction(mock_trans.get());
- // Receive the second server push with same url after the first lookup
- // finishes, and should cancel the push.
- std::unique_ptr<MockServerPushHelper> push_helper2 =
- std::make_unique<MockServerPushHelper>(request_url);
- MockServerPushHelper* push_helper_ptr2 = push_helper2.get();
- EXPECT_CALL(*push_helper_ptr2, Cancel()).Times(1);
- push_delegate.OnPush(std::move(push_helper2), NetLogWithSource());
- // Run until the lookup transaction finishes for the second server push.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
- EXPECT_EQ(2, mock_cache.disk_cache()->open_count());
- EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
- RemoveMockTransaction(mock_trans.get());
- std::unique_ptr<MockTransaction> mock_trans3 =
- CreateMockTransaction(request_url2);
- AddMockTransaction(mock_trans3.get());
- // Receive the third server push with a different url after lookup for a
- // similar server push has been completed, should not cancel the push.
- std::unique_ptr<MockServerPushHelper> push_helper3 =
- std::make_unique<MockServerPushHelper>(request_url2);
- MockServerPushHelper* push_helper_ptr3 = push_helper3.get();
- EXPECT_CALL(*push_helper_ptr3, Cancel()).Times(0);
- push_delegate.OnPush(std::move(push_helper3), NetLogWithSource());
- base::RunLoop().RunUntilIdle();
- // Make sure no new net layer transaction is created.
- EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
- EXPECT_EQ(2, mock_cache.disk_cache()->open_count());
- EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
- RemoveMockTransaction(mock_trans3.get());
- }
- } // namespace net
|