http_cache_lookup_manager_unittest.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. // Copyright (c) 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include <string>
  6. #include "base/feature_list.h"
  7. #include "base/run_loop.h"
  8. #include "base/test/task_environment.h"
  9. #include "net/base/features.h"
  10. #include "net/base/net_errors.h"
  11. #include "net/base/schemeful_site.h"
  12. #include "net/base/test_completion_callback.h"
  13. #include "net/http/http_cache_lookup_manager.h"
  14. #include "net/http/http_transaction_test_util.h"
  15. #include "net/http/mock_http_cache.h"
  16. #include "net/test/gtest_util.h"
  17. #include "testing/gmock/include/gmock/gmock.h"
  18. #include "testing/gtest/include/gtest/gtest-param-test.h"
  19. #include "testing/gtest/include/gtest/gtest.h"
  20. using net::test::IsOk;
  21. namespace net {
  22. namespace {
  23. class MockServerPushHelper : public ServerPushDelegate::ServerPushHelper {
  24. public:
  25. explicit MockServerPushHelper(const GURL& url)
  26. : request_url_(url),
  27. network_isolation_key_(SchemefulSite(url), SchemefulSite(url)) {}
  28. const GURL& GetURL() const override { return request_url_; }
  29. NetworkIsolationKey GetNetworkIsolationKey() const override {
  30. return network_isolation_key_;
  31. }
  32. void set_network_isolation_key(
  33. const net::NetworkIsolationKey& network_isolation_key) {
  34. network_isolation_key_ = network_isolation_key;
  35. }
  36. MOCK_METHOD0(Cancel, void());
  37. private:
  38. const GURL request_url_;
  39. NetworkIsolationKey network_isolation_key_;
  40. };
  41. std::unique_ptr<MockTransaction> CreateMockTransaction(const GURL& url) {
  42. MockTransaction mock_trans = {
  43. url.spec().c_str(),
  44. "GET",
  45. base::Time(),
  46. "",
  47. LOAD_NORMAL,
  48. DefaultTransportInfo(),
  49. "HTTP/1.1 200 OK",
  50. "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
  51. "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n",
  52. base::Time(),
  53. "<html><body>Google Blah Blah</body></html>",
  54. {},
  55. TEST_MODE_NORMAL,
  56. nullptr,
  57. nullptr,
  58. nullptr,
  59. 0,
  60. 0,
  61. OK,
  62. };
  63. return std::make_unique<MockTransaction>(mock_trans);
  64. }
  65. void PopulateCacheEntry(HttpCache* cache, const GURL& request_url) {
  66. TestCompletionCallback callback;
  67. std::unique_ptr<MockTransaction> mock_trans =
  68. CreateMockTransaction(request_url);
  69. AddMockTransaction(mock_trans.get());
  70. MockHttpRequest request(*(mock_trans.get()));
  71. std::unique_ptr<HttpTransaction> trans;
  72. int rv = cache->CreateTransaction(DEFAULT_PRIORITY, &trans);
  73. EXPECT_THAT(rv, IsOk());
  74. ASSERT_TRUE(trans.get());
  75. rv = trans->Start(&request, callback.callback(), NetLogWithSource());
  76. base::RunLoop().RunUntilIdle();
  77. if (rv == ERR_IO_PENDING)
  78. rv = callback.WaitForResult();
  79. ASSERT_EQ(mock_trans->start_return_code, rv);
  80. if (OK != rv)
  81. return;
  82. const HttpResponseInfo* response = trans->GetResponseInfo();
  83. ASSERT_TRUE(response);
  84. std::string content;
  85. rv = ReadTransaction(trans.get(), &content);
  86. EXPECT_THAT(rv, IsOk());
  87. std::string expected(mock_trans->data);
  88. EXPECT_EQ(expected, content);
  89. RemoveMockTransaction(mock_trans.get());
  90. }
  91. } // namespace
  92. TEST(HttpCacheLookupManagerTest, ServerPushMissCache) {
  93. base::test::TaskEnvironment task_environment;
  94. MockHttpCache mock_cache;
  95. HttpCacheLookupManager push_delegate(mock_cache.http_cache());
  96. GURL request_url("http://www.example.com/pushed.jpg");
  97. std::unique_ptr<MockServerPushHelper> push_helper =
  98. std::make_unique<MockServerPushHelper>(request_url);
  99. MockServerPushHelper* push_helper_ptr = push_helper.get();
  100. // Receive a server push and should not cancel the push.
  101. EXPECT_CALL(*push_helper_ptr, Cancel()).Times(0);
  102. push_delegate.OnPush(std::move(push_helper), NetLogWithSource());
  103. base::RunLoop().RunUntilIdle();
  104. // Make sure no network transaction is created.
  105. EXPECT_EQ(0, mock_cache.network_layer()->transaction_count());
  106. EXPECT_EQ(0, mock_cache.disk_cache()->open_count());
  107. EXPECT_EQ(0, mock_cache.disk_cache()->create_count());
  108. }
  109. TEST(HttpCacheLookupManagerTest, ServerPushDoNotCreateCacheEntry) {
  110. base::test::TaskEnvironment task_environment;
  111. MockHttpCache mock_cache;
  112. HttpCacheLookupManager push_delegate(mock_cache.http_cache());
  113. GURL request_url("http://www.example.com/pushed.jpg");
  114. std::unique_ptr<MockServerPushHelper> push_helper =
  115. std::make_unique<MockServerPushHelper>(request_url);
  116. MockServerPushHelper* push_helper_ptr = push_helper.get();
  117. // Receive a server push and should not cancel the push.
  118. EXPECT_CALL(*push_helper_ptr, Cancel()).Times(0);
  119. push_delegate.OnPush(std::move(push_helper), NetLogWithSource());
  120. base::RunLoop().RunUntilIdle();
  121. // Receive another server push for the same url.
  122. std::unique_ptr<MockServerPushHelper> push_helper2 =
  123. std::make_unique<MockServerPushHelper>(request_url);
  124. MockServerPushHelper* push_helper_ptr2 = push_helper2.get();
  125. EXPECT_CALL(*push_helper_ptr2, Cancel()).Times(0);
  126. push_delegate.OnPush(std::move(push_helper2), NetLogWithSource());
  127. base::RunLoop().RunUntilIdle();
  128. // Verify no network transaction is created.
  129. EXPECT_EQ(0, mock_cache.network_layer()->transaction_count());
  130. EXPECT_EQ(0, mock_cache.disk_cache()->open_count());
  131. // Verify no cache entry is created for server push lookup.
  132. EXPECT_EQ(0, mock_cache.disk_cache()->create_count());
  133. }
  134. // Parameterized by whether the network isolation key are the same for the
  135. // server push and corresponding cache entry.
  136. class HttpCacheLookupManagerTest_NetworkIsolationKey
  137. : public ::testing::Test,
  138. public ::testing::WithParamInterface<
  139. bool /* use_same_network_isolation_key */> {};
  140. TEST_P(HttpCacheLookupManagerTest_NetworkIsolationKey, ServerPushCacheStatus) {
  141. bool use_same_network_isolation_key = GetParam();
  142. bool split_cache_enabled = base::FeatureList::IsEnabled(
  143. net::features::kSplitCacheByNetworkIsolationKey);
  144. base::test::TaskEnvironment task_environment;
  145. MockHttpCache mock_cache;
  146. HttpCacheLookupManager push_delegate(mock_cache.http_cache());
  147. GURL request_url("http://www.example.com/pushed.jpg");
  148. // Populate the cache entry so that the cache lookup for server push hits.
  149. PopulateCacheEntry(mock_cache.http_cache(), request_url);
  150. EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
  151. EXPECT_EQ(0, mock_cache.disk_cache()->open_count());
  152. EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
  153. // Add another mock transaction since the OnPush will create a new cache
  154. // transaction.
  155. std::unique_ptr<MockTransaction> mock_trans =
  156. CreateMockTransaction(request_url);
  157. AddMockTransaction(mock_trans.get());
  158. std::unique_ptr<MockServerPushHelper> push_helper =
  159. std::make_unique<MockServerPushHelper>(request_url);
  160. if (!use_same_network_isolation_key) {
  161. SchemefulSite site(GURL("http://www.abc.com"));
  162. push_helper->set_network_isolation_key(
  163. net::NetworkIsolationKey(site, site));
  164. }
  165. MockServerPushHelper* push_helper_ptr = push_helper.get();
  166. int expected_cancel_times =
  167. use_same_network_isolation_key || !split_cache_enabled ? 1 : 0;
  168. EXPECT_CALL(*push_helper_ptr, Cancel()).Times(expected_cancel_times);
  169. push_delegate.OnPush(std::move(push_helper), NetLogWithSource());
  170. base::RunLoop().RunUntilIdle();
  171. // Make sure no new net layer transaction is created.
  172. EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
  173. int expected_open_count =
  174. use_same_network_isolation_key || !split_cache_enabled ? 1 : 0;
  175. EXPECT_EQ(expected_open_count, mock_cache.disk_cache()->open_count());
  176. EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
  177. RemoveMockTransaction(mock_trans.get());
  178. }
  179. INSTANTIATE_TEST_SUITE_P(
  180. All,
  181. HttpCacheLookupManagerTest_NetworkIsolationKey,
  182. ::testing::Bool());
  183. // Test when a server push is received while the HttpCacheLookupManager has a
  184. // pending lookup transaction for the same URL, the new server push will not
  185. // send a new lookup transaction and should not be canceled.
  186. TEST(HttpCacheLookupManagerTest, ServerPushPendingLookup) {
  187. base::test::TaskEnvironment task_environment;
  188. MockHttpCache mock_cache;
  189. HttpCacheLookupManager push_delegate(mock_cache.http_cache());
  190. GURL request_url("http://www.example.com/pushed.jpg");
  191. // Populate the cache entry so that the cache lookup for server push hits.
  192. PopulateCacheEntry(mock_cache.http_cache(), request_url);
  193. EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
  194. EXPECT_EQ(0, mock_cache.disk_cache()->open_count());
  195. EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
  196. // Add another mock transaction since the OnPush will create a new cache
  197. // transaction.
  198. std::unique_ptr<MockTransaction> mock_trans =
  199. CreateMockTransaction(request_url);
  200. AddMockTransaction(mock_trans.get());
  201. std::unique_ptr<MockServerPushHelper> push_helper =
  202. std::make_unique<MockServerPushHelper>(request_url);
  203. MockServerPushHelper* push_helper_ptr = push_helper.get();
  204. // Receive a server push and should cancel the push eventually.
  205. EXPECT_CALL(*push_helper_ptr, Cancel()).Times(1);
  206. push_delegate.OnPush(std::move(push_helper), NetLogWithSource());
  207. std::unique_ptr<MockServerPushHelper> push_helper2 =
  208. std::make_unique<MockServerPushHelper>(request_url);
  209. MockServerPushHelper* push_helper_ptr2 = push_helper2.get();
  210. // Receive another server push and should not cancel the push.
  211. EXPECT_CALL(*push_helper_ptr2, Cancel()).Times(0);
  212. push_delegate.OnPush(std::move(push_helper2), NetLogWithSource());
  213. base::RunLoop().RunUntilIdle();
  214. // Make sure no new net layer transaction is created.
  215. EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
  216. EXPECT_EQ(1, mock_cache.disk_cache()->open_count());
  217. EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
  218. RemoveMockTransaction(mock_trans.get());
  219. }
  220. // Test the server push lookup is based on the full url.
  221. TEST(HttpCacheLookupManagerTest, ServerPushLookupOnUrl) {
  222. base::test::TaskEnvironment task_environment;
  223. MockHttpCache mock_cache;
  224. HttpCacheLookupManager push_delegate(mock_cache.http_cache());
  225. GURL request_url("http://www.example.com/pushed.jpg?u=0");
  226. GURL request_url2("http://www.example.com/pushed.jpg?u=1");
  227. // Populate the cache entry so that the cache lookup for server push hits.
  228. PopulateCacheEntry(mock_cache.http_cache(), request_url);
  229. EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
  230. EXPECT_EQ(0, mock_cache.disk_cache()->open_count());
  231. EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
  232. // Add another mock transaction since the OnPush will create a new cache
  233. // transaction.
  234. std::unique_ptr<MockTransaction> mock_trans =
  235. CreateMockTransaction(request_url);
  236. AddMockTransaction(mock_trans.get());
  237. std::unique_ptr<MockServerPushHelper> push_helper =
  238. std::make_unique<MockServerPushHelper>(request_url);
  239. MockServerPushHelper* push_helper_ptr = push_helper.get();
  240. // Receive a server push and should cancel the push eventually.
  241. EXPECT_CALL(*push_helper_ptr, Cancel()).Times(1);
  242. push_delegate.OnPush(std::move(push_helper), NetLogWithSource());
  243. // Run until the lookup transaction finishes for the first server push.
  244. base::RunLoop().RunUntilIdle();
  245. EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
  246. EXPECT_EQ(1, mock_cache.disk_cache()->open_count());
  247. EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
  248. RemoveMockTransaction(mock_trans.get());
  249. AddMockTransaction(mock_trans.get());
  250. // Receive the second server push with same url after the first lookup
  251. // finishes, and should cancel the push.
  252. std::unique_ptr<MockServerPushHelper> push_helper2 =
  253. std::make_unique<MockServerPushHelper>(request_url);
  254. MockServerPushHelper* push_helper_ptr2 = push_helper2.get();
  255. EXPECT_CALL(*push_helper_ptr2, Cancel()).Times(1);
  256. push_delegate.OnPush(std::move(push_helper2), NetLogWithSource());
  257. // Run until the lookup transaction finishes for the second server push.
  258. base::RunLoop().RunUntilIdle();
  259. EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
  260. EXPECT_EQ(2, mock_cache.disk_cache()->open_count());
  261. EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
  262. RemoveMockTransaction(mock_trans.get());
  263. std::unique_ptr<MockTransaction> mock_trans3 =
  264. CreateMockTransaction(request_url2);
  265. AddMockTransaction(mock_trans3.get());
  266. // Receive the third server push with a different url after lookup for a
  267. // similar server push has been completed, should not cancel the push.
  268. std::unique_ptr<MockServerPushHelper> push_helper3 =
  269. std::make_unique<MockServerPushHelper>(request_url2);
  270. MockServerPushHelper* push_helper_ptr3 = push_helper3.get();
  271. EXPECT_CALL(*push_helper_ptr3, Cancel()).Times(0);
  272. push_delegate.OnPush(std::move(push_helper3), NetLogWithSource());
  273. base::RunLoop().RunUntilIdle();
  274. // Make sure no new net layer transaction is created.
  275. EXPECT_EQ(1, mock_cache.network_layer()->transaction_count());
  276. EXPECT_EQ(2, mock_cache.disk_cache()->open_count());
  277. EXPECT_EQ(1, mock_cache.disk_cache()->create_count());
  278. RemoveMockTransaction(mock_trans3.get());
  279. }
  280. } // namespace net