[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 1 | // Copyright 2013 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 | |
[email protected] | 7c766e9 | 2013-11-22 20:44:02 | [diff] [blame^] | 5 | #include "components/nacl/browser/pnacl_host.h" |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 6 | |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 7 | #include <stdio.h> |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 8 | #include "base/bind.h" |
| 9 | #include "base/files/scoped_temp_dir.h" |
| 10 | #include "base/run_loop.h" |
| 11 | #include "base/threading/sequenced_worker_pool.h" |
[email protected] | 30a9071 | 2013-11-18 16:26:11 | [diff] [blame] | 12 | #include "components/nacl/browser/pnacl_translation_cache.h" |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 13 | #include "content/public/browser/browser_thread.h" |
| 14 | #include "content/public/test/test_browser_thread_bundle.h" |
[email protected] | abc31ee | 2013-08-09 07:25:35 | [diff] [blame] | 15 | #include "net/base/test_completion_callback.h" |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 16 | #include "testing/gtest/include/gtest/gtest.h" |
| 17 | |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 18 | #if defined(OS_WIN) |
| 19 | #define snprintf _snprintf |
| 20 | #endif |
| 21 | |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 22 | namespace pnacl { |
| 23 | |
| 24 | class PnaclHostTest : public testing::Test { |
| 25 | protected: |
| 26 | PnaclHostTest() |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 27 | : host_(NULL), |
| 28 | temp_callback_count_(0), |
| 29 | write_callback_count_(0), |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 30 | thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {} |
| 31 | virtual void SetUp() { |
| 32 | host_ = new PnaclHost(); |
| 33 | ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 34 | host_->InitForTest(temp_dir_.path()); |
[email protected] | 779dc178 | 2013-10-25 22:07:30 | [diff] [blame] | 35 | base::RunLoop().RunUntilIdle(); |
| 36 | EXPECT_EQ(PnaclHost::CacheReady, host_->cache_state_); |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 37 | } |
| 38 | virtual void TearDown() { |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 39 | EXPECT_EQ(0U, host_->pending_translations()); |
[email protected] | 779dc178 | 2013-10-25 22:07:30 | [diff] [blame] | 40 | // Give the host a chance to de-init the backend, and then delete it. |
| 41 | host_->RendererClosing(0); |
| 42 | FlushQueues(); |
| 43 | EXPECT_EQ(PnaclHost::CacheUninitialized, host_->cache_state_); |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 44 | delete host_; |
| 45 | } |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 46 | // Flush the blocking pool first, then any tasks it posted to the IO thread. |
| 47 | // Do 2 rounds of flushing, because some operations require 2 trips back and |
| 48 | // forth between the threads. |
| 49 | void FlushQueues() { |
| 50 | content::BrowserThread::GetBlockingPool()->FlushForTesting(); |
| 51 | base::RunLoop().RunUntilIdle(); |
| 52 | content::BrowserThread::GetBlockingPool()->FlushForTesting(); |
| 53 | base::RunLoop().RunUntilIdle(); |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 54 | } |
[email protected] | 8311d57 | 2013-09-05 21:46:16 | [diff] [blame] | 55 | int GetCacheSize() { return host_->disk_cache_->Size(); } |
[email protected] | 779dc178 | 2013-10-25 22:07:30 | [diff] [blame] | 56 | int CacheIsInitialized() { |
| 57 | return host_->cache_state_ == PnaclHost::CacheReady; |
| 58 | } |
| 59 | void ReInitBackend() { |
| 60 | host_->InitForTest(temp_dir_.path()); |
| 61 | base::RunLoop().RunUntilIdle(); |
| 62 | EXPECT_EQ(PnaclHost::CacheReady, host_->cache_state_); |
| 63 | } |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 64 | |
| 65 | public: // Required for derived classes to bind this method |
[email protected] | 8311d57 | 2013-09-05 21:46:16 | [diff] [blame] | 66 | // Callbacks used by tests which call GetNexeFd. |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 67 | // CallbackExpectMiss checks that the fd is valid and a miss is reported, |
| 68 | // and also writes some data into the file, which is read back by |
| 69 | // CallbackExpectHit |
| 70 | void CallbackExpectMiss(base::PlatformFile fd, bool is_hit) { |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 71 | EXPECT_FALSE(is_hit); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 72 | ASSERT_FALSE(fd == base::kInvalidPlatformFileValue); |
| 73 | base::PlatformFileInfo info; |
| 74 | EXPECT_TRUE(base::GetPlatformFileInfo(fd, &info)); |
| 75 | EXPECT_FALSE(info.is_directory); |
| 76 | EXPECT_EQ(0LL, info.size); |
| 77 | char str[16]; |
| 78 | memset(str, 0x0, 16); |
| 79 | snprintf(str, 16, "testdata%d", ++write_callback_count_); |
| 80 | EXPECT_EQ(16, base::WritePlatformFile(fd, 0, str, 16)); |
| 81 | temp_callback_count_++; |
| 82 | } |
| 83 | void CallbackExpectHit(base::PlatformFile fd, bool is_hit) { |
| 84 | EXPECT_TRUE(is_hit); |
| 85 | ASSERT_FALSE(fd == base::kInvalidPlatformFileValue); |
| 86 | base::PlatformFileInfo info; |
| 87 | EXPECT_TRUE(base::GetPlatformFileInfo(fd, &info)); |
| 88 | EXPECT_FALSE(info.is_directory); |
| 89 | EXPECT_EQ(16LL, info.size); |
| 90 | char data[16]; |
| 91 | memset(data, 0x0, 16); |
| 92 | char str[16]; |
| 93 | memset(str, 0x0, 16); |
| 94 | snprintf(str, 16, "testdata%d", write_callback_count_); |
| 95 | EXPECT_EQ(16, base::ReadPlatformFile(fd, 0, data, 16)); |
| 96 | EXPECT_STREQ(str, data); |
| 97 | temp_callback_count_++; |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | protected: |
| 101 | PnaclHost* host_; |
| 102 | int temp_callback_count_; |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 103 | int write_callback_count_; |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 104 | content::TestBrowserThreadBundle thread_bundle_; |
| 105 | base::ScopedTempDir temp_dir_; |
| 106 | }; |
| 107 | |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 108 | static nacl::PnaclCacheInfo GetTestCacheInfo() { |
| 109 | nacl::PnaclCacheInfo info; |
| 110 | info.pexe_url = GURL("http://www.google.com"); |
| 111 | info.abi_version = 0; |
| 112 | info.opt_level = 0; |
[email protected] | 8311d57 | 2013-09-05 21:46:16 | [diff] [blame] | 113 | info.has_no_store_header = false; |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 114 | return info; |
| 115 | } |
| 116 | |
[email protected] | 8311d57 | 2013-09-05 21:46:16 | [diff] [blame] | 117 | #define GET_NEXE_FD(renderer, instance, incognito, info, expect_hit) \ |
| 118 | do { \ |
| 119 | SCOPED_TRACE(""); \ |
| 120 | host_->GetNexeFd( \ |
| 121 | renderer, \ |
| 122 | 0, /* ignore render_view_id for now */ \ |
| 123 | instance, \ |
| 124 | incognito, \ |
| 125 | info, \ |
| 126 | base::Bind(expect_hit ? &PnaclHostTest::CallbackExpectHit \ |
| 127 | : &PnaclHostTest::CallbackExpectMiss, \ |
| 128 | base::Unretained(this))); \ |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 129 | } while (0) |
| 130 | |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 131 | TEST_F(PnaclHostTest, BasicMiss) { |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 132 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 133 | // Test cold miss. |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 134 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 135 | EXPECT_EQ(1U, host_->pending_translations()); |
| 136 | FlushQueues(); |
| 137 | EXPECT_EQ(1U, host_->pending_translations()); |
| 138 | EXPECT_EQ(1, temp_callback_count_); |
[email protected] | 26f14b5a | 2013-08-07 19:23:13 | [diff] [blame] | 139 | host_->TranslationFinished(0, 0, true); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 140 | FlushQueues(); |
| 141 | EXPECT_EQ(0U, host_->pending_translations()); |
| 142 | // Test that a different cache info field also misses. |
| 143 | info.etag = std::string("something else"); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 144 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 145 | FlushQueues(); |
| 146 | EXPECT_EQ(2, temp_callback_count_); |
| 147 | EXPECT_EQ(1U, host_->pending_translations()); |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 148 | host_->RendererClosing(0); |
[email protected] | 779dc178 | 2013-10-25 22:07:30 | [diff] [blame] | 149 | FlushQueues(); |
| 150 | // Check that the cache has de-initialized after the last renderer goes away. |
| 151 | EXPECT_FALSE(CacheIsInitialized()); |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 152 | } |
| 153 | |
| 154 | TEST_F(PnaclHostTest, BadArguments) { |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 155 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 156 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 157 | EXPECT_EQ(1U, host_->pending_translations()); |
[email protected] | 26f14b5a | 2013-08-07 19:23:13 | [diff] [blame] | 158 | host_->TranslationFinished(0, 1, true); // nonexistent translation |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 159 | EXPECT_EQ(1U, host_->pending_translations()); |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 160 | host_->RendererClosing(1); // nonexistent renderer |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 161 | EXPECT_EQ(1U, host_->pending_translations()); |
| 162 | FlushQueues(); |
| 163 | EXPECT_EQ(1, temp_callback_count_); |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 164 | host_->RendererClosing(0); // close without finishing |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 165 | } |
| 166 | |
| 167 | TEST_F(PnaclHostTest, BasicHit) { |
| 168 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 169 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 170 | FlushQueues(); |
| 171 | EXPECT_EQ(1, temp_callback_count_); |
| 172 | host_->TranslationFinished(0, 0, true); |
| 173 | FlushQueues(); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 174 | GET_NEXE_FD(0, 1, false, info, true); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 175 | FlushQueues(); |
| 176 | EXPECT_EQ(2, temp_callback_count_); |
| 177 | EXPECT_EQ(0U, host_->pending_translations()); |
| 178 | } |
| 179 | |
| 180 | TEST_F(PnaclHostTest, TranslationErrors) { |
| 181 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 182 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 183 | // Early abort, before temp file request returns |
| 184 | host_->TranslationFinished(0, 0, false); |
| 185 | FlushQueues(); |
| 186 | EXPECT_EQ(0U, host_->pending_translations()); |
| 187 | EXPECT_EQ(0, temp_callback_count_); |
[email protected] | 779dc178 | 2013-10-25 22:07:30 | [diff] [blame] | 188 | // The backend will have been freed when the query comes back and there |
| 189 | // are no pending translations. |
| 190 | EXPECT_FALSE(CacheIsInitialized()); |
| 191 | ReInitBackend(); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 192 | // Check that another request for the same info misses successfully. |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 193 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 194 | FlushQueues(); |
| 195 | host_->TranslationFinished(0, 0, true); |
| 196 | FlushQueues(); |
| 197 | EXPECT_EQ(1, temp_callback_count_); |
| 198 | EXPECT_EQ(0U, host_->pending_translations()); |
| 199 | |
| 200 | // Now try sending the error after the temp file request returns |
| 201 | info.abi_version = 222; |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 202 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 203 | FlushQueues(); |
| 204 | EXPECT_EQ(2, temp_callback_count_); |
| 205 | host_->TranslationFinished(0, 0, false); |
| 206 | FlushQueues(); |
| 207 | EXPECT_EQ(0U, host_->pending_translations()); |
| 208 | // Check another successful miss |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 209 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 210 | FlushQueues(); |
| 211 | EXPECT_EQ(3, temp_callback_count_); |
| 212 | host_->TranslationFinished(0, 0, false); |
| 213 | EXPECT_EQ(0U, host_->pending_translations()); |
| 214 | } |
| 215 | |
[email protected] | ac65e6f | 2013-08-30 00:47:32 | [diff] [blame] | 216 | TEST_F(PnaclHostTest, OverlappedMissesAfterTempReturn) { |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 217 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 218 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 219 | FlushQueues(); |
| 220 | EXPECT_EQ(1, temp_callback_count_); |
| 221 | EXPECT_EQ(1U, host_->pending_translations()); |
| 222 | // Test that a second request for the same nexe while the first one is still |
| 223 | // outstanding eventually hits. |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 224 | GET_NEXE_FD(0, 1, false, info, true); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 225 | FlushQueues(); |
| 226 | EXPECT_EQ(2U, host_->pending_translations()); |
| 227 | // The temp file should not be returned to the second request until after the |
| 228 | // first is finished translating. |
| 229 | EXPECT_EQ(1, temp_callback_count_); |
| 230 | host_->TranslationFinished(0, 0, true); |
| 231 | FlushQueues(); |
| 232 | EXPECT_EQ(2, temp_callback_count_); |
| 233 | EXPECT_EQ(0U, host_->pending_translations()); |
| 234 | } |
| 235 | |
[email protected] | ac65e6f | 2013-08-30 00:47:32 | [diff] [blame] | 236 | TEST_F(PnaclHostTest, OverlappedMissesBeforeTempReturn) { |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 237 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 238 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 239 | // Send the 2nd fd request before the first one returns a temp file. |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 240 | GET_NEXE_FD(0, 1, false, info, true); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 241 | FlushQueues(); |
| 242 | EXPECT_EQ(1, temp_callback_count_); |
| 243 | EXPECT_EQ(2U, host_->pending_translations()); |
| 244 | FlushQueues(); |
| 245 | EXPECT_EQ(2U, host_->pending_translations()); |
| 246 | EXPECT_EQ(1, temp_callback_count_); |
| 247 | host_->TranslationFinished(0, 0, true); |
| 248 | FlushQueues(); |
| 249 | EXPECT_EQ(2, temp_callback_count_); |
| 250 | EXPECT_EQ(0U, host_->pending_translations()); |
| 251 | } |
| 252 | |
| 253 | TEST_F(PnaclHostTest, OverlappedHitsBeforeTempReturn) { |
| 254 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 255 | // Store one in the cache and complete it. |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 256 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 257 | FlushQueues(); |
| 258 | EXPECT_EQ(1, temp_callback_count_); |
| 259 | host_->TranslationFinished(0, 0, true); |
| 260 | FlushQueues(); |
| 261 | EXPECT_EQ(0U, host_->pending_translations()); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 262 | GET_NEXE_FD(0, 0, false, info, true); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 263 | // Request the second before the first temp file returns. |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 264 | GET_NEXE_FD(0, 1, false, info, true); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 265 | FlushQueues(); |
| 266 | EXPECT_EQ(3, temp_callback_count_); |
| 267 | EXPECT_EQ(0U, host_->pending_translations()); |
| 268 | } |
| 269 | |
| 270 | TEST_F(PnaclHostTest, OverlappedHitsAfterTempReturn) { |
| 271 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 272 | // Store one in the cache and complete it. |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 273 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 274 | FlushQueues(); |
| 275 | EXPECT_EQ(1, temp_callback_count_); |
| 276 | host_->TranslationFinished(0, 0, true); |
| 277 | FlushQueues(); |
| 278 | EXPECT_EQ(0U, host_->pending_translations()); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 279 | GET_NEXE_FD(0, 0, false, info, true); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 280 | FlushQueues(); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 281 | GET_NEXE_FD(0, 1, false, info, true); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 282 | FlushQueues(); |
| 283 | EXPECT_EQ(3, temp_callback_count_); |
| 284 | EXPECT_EQ(0U, host_->pending_translations()); |
| 285 | } |
| 286 | |
[email protected] | ac65e6f | 2013-08-30 00:47:32 | [diff] [blame] | 287 | TEST_F(PnaclHostTest, OverlappedMissesRendererClosing) { |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 288 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 289 | GET_NEXE_FD(0, 0, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 290 | // Send the 2nd fd request from a different renderer. |
| 291 | // Test that it eventually gets an fd after the first renderer closes. |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 292 | GET_NEXE_FD(1, 1, false, info, false); |
[email protected] | d40657e | 2013-08-08 18:19:23 | [diff] [blame] | 293 | FlushQueues(); |
| 294 | EXPECT_EQ(1, temp_callback_count_); |
| 295 | EXPECT_EQ(2U, host_->pending_translations()); |
| 296 | FlushQueues(); |
| 297 | EXPECT_EQ(2U, host_->pending_translations()); |
| 298 | EXPECT_EQ(1, temp_callback_count_); |
| 299 | host_->RendererClosing(0); |
| 300 | FlushQueues(); |
| 301 | EXPECT_EQ(2, temp_callback_count_); |
| 302 | EXPECT_EQ(1U, host_->pending_translations()); |
| 303 | host_->RendererClosing(1); |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 304 | } |
| 305 | |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 306 | TEST_F(PnaclHostTest, Incognito) { |
| 307 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 308 | GET_NEXE_FD(0, 0, true, info, false); |
| 309 | FlushQueues(); |
| 310 | EXPECT_EQ(1, temp_callback_count_); |
| 311 | host_->TranslationFinished(0, 0, true); |
| 312 | FlushQueues(); |
| 313 | // Check that an incognito translation is not stored in the cache |
| 314 | GET_NEXE_FD(0, 0, false, info, false); |
| 315 | FlushQueues(); |
| 316 | EXPECT_EQ(2, temp_callback_count_); |
| 317 | host_->TranslationFinished(0, 0, true); |
| 318 | FlushQueues(); |
| 319 | // Check that an incognito translation can hit from a normal one. |
| 320 | GET_NEXE_FD(0, 0, true, info, true); |
| 321 | FlushQueues(); |
| 322 | EXPECT_EQ(3, temp_callback_count_); |
| 323 | } |
| 324 | |
[email protected] | ac65e6f | 2013-08-30 00:47:32 | [diff] [blame] | 325 | TEST_F(PnaclHostTest, IncognitoOverlappedMiss) { |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 326 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 327 | GET_NEXE_FD(0, 0, true, info, false); |
| 328 | GET_NEXE_FD(0, 1, false, info, false); |
| 329 | FlushQueues(); |
| 330 | // Check that both translations have returned misses, (i.e. that the |
| 331 | // second one has not blocked on the incognito one) |
| 332 | EXPECT_EQ(2, temp_callback_count_); |
| 333 | host_->TranslationFinished(0, 0, true); |
| 334 | host_->TranslationFinished(0, 1, true); |
| 335 | FlushQueues(); |
| 336 | EXPECT_EQ(0U, host_->pending_translations()); |
| 337 | |
| 338 | // Same test, but issue the 2nd request after the first has returned a miss. |
| 339 | info.abi_version = 222; |
| 340 | GET_NEXE_FD(0, 0, true, info, false); |
| 341 | FlushQueues(); |
| 342 | EXPECT_EQ(3, temp_callback_count_); |
| 343 | GET_NEXE_FD(0, 1, false, info, false); |
| 344 | FlushQueues(); |
| 345 | EXPECT_EQ(4, temp_callback_count_); |
| 346 | host_->RendererClosing(0); |
| 347 | } |
| 348 | |
[email protected] | ac65e6f | 2013-08-30 00:47:32 | [diff] [blame] | 349 | TEST_F(PnaclHostTest, IncognitoSecondOverlappedMiss) { |
[email protected] | 4241eb0 | 2013-08-08 22:15:41 | [diff] [blame] | 350 | // If the non-incognito request comes first, it should |
| 351 | // behave exactly like OverlappedMissBeforeTempReturn |
| 352 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 353 | GET_NEXE_FD(0, 0, false, info, false); |
| 354 | // Send the 2nd fd request before the first one returns a temp file. |
| 355 | GET_NEXE_FD(0, 1, true, info, true); |
| 356 | FlushQueues(); |
| 357 | EXPECT_EQ(1, temp_callback_count_); |
| 358 | EXPECT_EQ(2U, host_->pending_translations()); |
| 359 | FlushQueues(); |
| 360 | EXPECT_EQ(2U, host_->pending_translations()); |
| 361 | EXPECT_EQ(1, temp_callback_count_); |
| 362 | host_->TranslationFinished(0, 0, true); |
| 363 | FlushQueues(); |
| 364 | EXPECT_EQ(2, temp_callback_count_); |
| 365 | EXPECT_EQ(0U, host_->pending_translations()); |
| 366 | } |
| 367 | |
[email protected] | 8311d57 | 2013-09-05 21:46:16 | [diff] [blame] | 368 | // Test that pexes with the no-store header do not get cached. |
| 369 | TEST_F(PnaclHostTest, CacheControlNoStore) { |
| 370 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 371 | info.has_no_store_header = true; |
| 372 | GET_NEXE_FD(0, 0, false, info, false); |
| 373 | FlushQueues(); |
| 374 | EXPECT_EQ(1, temp_callback_count_); |
| 375 | host_->TranslationFinished(0, 0, true); |
| 376 | FlushQueues(); |
| 377 | EXPECT_EQ(0U, host_->pending_translations()); |
| 378 | EXPECT_EQ(0, GetCacheSize()); |
| 379 | } |
| 380 | |
| 381 | // Test that no-store pexes do not wait, but do duplicate translations |
| 382 | TEST_F(PnaclHostTest, NoStoreOverlappedMiss) { |
| 383 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 384 | info.has_no_store_header = true; |
| 385 | GET_NEXE_FD(0, 0, false, info, false); |
| 386 | GET_NEXE_FD(0, 1, false, info, false); |
| 387 | FlushQueues(); |
| 388 | // Check that both translations have returned misses, (i.e. that the |
| 389 | // second one has not blocked on the first one) |
| 390 | EXPECT_EQ(2, temp_callback_count_); |
| 391 | host_->TranslationFinished(0, 0, true); |
| 392 | host_->TranslationFinished(0, 1, true); |
| 393 | FlushQueues(); |
| 394 | EXPECT_EQ(0U, host_->pending_translations()); |
| 395 | |
| 396 | // Same test, but issue the 2nd request after the first has returned a miss. |
| 397 | info.abi_version = 222; |
| 398 | GET_NEXE_FD(0, 0, false, info, false); |
| 399 | FlushQueues(); |
| 400 | EXPECT_EQ(3, temp_callback_count_); |
| 401 | GET_NEXE_FD(0, 1, false, info, false); |
| 402 | FlushQueues(); |
| 403 | EXPECT_EQ(4, temp_callback_count_); |
| 404 | host_->RendererClosing(0); |
| 405 | } |
| 406 | |
[email protected] | abc31ee | 2013-08-09 07:25:35 | [diff] [blame] | 407 | TEST_F(PnaclHostTest, ClearTranslationCache) { |
| 408 | nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 409 | // Add 2 entries in the cache |
| 410 | GET_NEXE_FD(0, 0, false, info, false); |
| 411 | info.abi_version = 222; |
| 412 | GET_NEXE_FD(0, 1, false, info, false); |
| 413 | FlushQueues(); |
| 414 | EXPECT_EQ(2, temp_callback_count_); |
| 415 | host_->TranslationFinished(0, 0, true); |
| 416 | host_->TranslationFinished(0, 1, true); |
| 417 | FlushQueues(); |
| 418 | EXPECT_EQ(0U, host_->pending_translations()); |
| 419 | EXPECT_EQ(2, GetCacheSize()); |
| 420 | net::TestCompletionCallback cb; |
| 421 | // Since we are using a memory backend, the clear should happen immediately. |
[email protected] | 8311d57 | 2013-09-05 21:46:16 | [diff] [blame] | 422 | host_->ClearTranslationCacheEntriesBetween( |
| 423 | base::Time(), base::Time(), base::Bind(cb.callback(), 0)); |
[email protected] | 779dc178 | 2013-10-25 22:07:30 | [diff] [blame] | 424 | // Check that the translation cache has been cleared before flushing the |
| 425 | // queues, because the backend will be freed once it is. |
[email protected] | abc31ee | 2013-08-09 07:25:35 | [diff] [blame] | 426 | EXPECT_EQ(0, GetCacheSize()); |
[email protected] | 779dc178 | 2013-10-25 22:07:30 | [diff] [blame] | 427 | EXPECT_EQ(0, cb.GetResult(net::ERR_IO_PENDING)); |
| 428 | // Now check that the backend has been freed. |
| 429 | EXPECT_FALSE(CacheIsInitialized()); |
[email protected] | abc31ee | 2013-08-09 07:25:35 | [diff] [blame] | 430 | } |
| 431 | |
[email protected] | 57bd6798 | 2013-07-21 06:07:30 | [diff] [blame] | 432 | } // namespace pnacl |