| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/nacl_host/pnacl_host.h" | 5 #include "chrome/browser/nacl_host/pnacl_host.h" |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/files/scoped_temp_dir.h" | 9 #include "base/files/scoped_temp_dir.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 } | 40 } |
| 41 // Flush the blocking pool first, then any tasks it posted to the IO thread. | 41 // Flush the blocking pool first, then any tasks it posted to the IO thread. |
| 42 // Do 2 rounds of flushing, because some operations require 2 trips back and | 42 // Do 2 rounds of flushing, because some operations require 2 trips back and |
| 43 // forth between the threads. | 43 // forth between the threads. |
| 44 void FlushQueues() { | 44 void FlushQueues() { |
| 45 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 45 content::BrowserThread::GetBlockingPool()->FlushForTesting(); |
| 46 base::RunLoop().RunUntilIdle(); | 46 base::RunLoop().RunUntilIdle(); |
| 47 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | 47 content::BrowserThread::GetBlockingPool()->FlushForTesting(); |
| 48 base::RunLoop().RunUntilIdle(); | 48 base::RunLoop().RunUntilIdle(); |
| 49 } | 49 } |
| 50 int GetCacheSize() { return host_->disk_cache_->Size(); } | 50 int GetCacheSize() { |
| 51 return host_->disk_cache_->Size(); |
| 52 } |
| 51 | 53 |
| 52 public: // Required for derived classes to bind this method | 54 public: // Required for derived classes to bind this method |
| 53 // Callbacks used by tests which call GetNexeFd. | 55 // Callbacks used by tests which call GetNexeFd. |
| 54 // CallbackExpectMiss checks that the fd is valid and a miss is reported, | 56 // CallbackExpectMiss checks that the fd is valid and a miss is reported, |
| 55 // and also writes some data into the file, which is read back by | 57 // and also writes some data into the file, which is read back by |
| 56 // CallbackExpectHit | 58 // CallbackExpectHit |
| 57 void CallbackExpectMiss(base::PlatformFile fd, bool is_hit) { | 59 void CallbackExpectMiss(base::PlatformFile fd, bool is_hit) { |
| 58 EXPECT_FALSE(is_hit); | 60 EXPECT_FALSE(is_hit); |
| 59 ASSERT_FALSE(fd == base::kInvalidPlatformFileValue); | 61 ASSERT_FALSE(fd == base::kInvalidPlatformFileValue); |
| 60 base::PlatformFileInfo info; | 62 base::PlatformFileInfo info; |
| 61 EXPECT_TRUE(base::GetPlatformFileInfo(fd, &info)); | 63 EXPECT_TRUE(base::GetPlatformFileInfo(fd, &info)); |
| 62 EXPECT_FALSE(info.is_directory); | 64 EXPECT_FALSE(info.is_directory); |
| 63 EXPECT_EQ(0LL, info.size); | 65 EXPECT_EQ(0LL, info.size); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 90 int write_callback_count_; | 92 int write_callback_count_; |
| 91 content::TestBrowserThreadBundle thread_bundle_; | 93 content::TestBrowserThreadBundle thread_bundle_; |
| 92 base::ScopedTempDir temp_dir_; | 94 base::ScopedTempDir temp_dir_; |
| 93 }; | 95 }; |
| 94 | 96 |
| 95 static nacl::PnaclCacheInfo GetTestCacheInfo() { | 97 static nacl::PnaclCacheInfo GetTestCacheInfo() { |
| 96 nacl::PnaclCacheInfo info; | 98 nacl::PnaclCacheInfo info; |
| 97 info.pexe_url = GURL("http://www.google.com"); | 99 info.pexe_url = GURL("http://www.google.com"); |
| 98 info.abi_version = 0; | 100 info.abi_version = 0; |
| 99 info.opt_level = 0; | 101 info.opt_level = 0; |
| 100 info.has_no_store_header = false; | |
| 101 return info; | 102 return info; |
| 102 } | 103 } |
| 103 | 104 |
| 104 #define GET_NEXE_FD(renderer, instance, incognito, info, expect_hit) \ | 105 #define GET_NEXE_FD(renderer, instance, incognito, info, expect_hit)\ |
| 105 do { \ | 106 do { \ |
| 106 SCOPED_TRACE(""); \ | 107 SCOPED_TRACE(""); \ |
| 107 host_->GetNexeFd( \ | 108 host_->GetNexeFd( \ |
| 108 renderer, \ | 109 renderer, \ |
| 109 0, /* ignore render_view_id for now */ \ | 110 0, /* ignore render_view_id for now */ \ |
| 110 instance, \ | 111 instance, \ |
| 111 incognito, \ | 112 incognito, \ |
| 112 info, \ | 113 info, \ |
| 113 base::Bind(expect_hit ? &PnaclHostTest::CallbackExpectHit \ | 114 base::Bind(expect_hit ? &PnaclHostTest::CallbackExpectHit \ |
| 114 : &PnaclHostTest::CallbackExpectMiss, \ | 115 : &PnaclHostTest::CallbackExpectMiss, \ |
| 115 base::Unretained(this))); \ | 116 base::Unretained(this))); \ |
| 116 } while (0) | 117 } while (0) |
| 117 | 118 |
| 118 TEST_F(PnaclHostTest, BasicMiss) { | 119 TEST_F(PnaclHostTest, BasicMiss) { |
| 119 nacl::PnaclCacheInfo info = GetTestCacheInfo(); | 120 nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 120 // Test cold miss. | 121 // Test cold miss. |
| 121 GET_NEXE_FD(0, 0, false, info, false); | 122 GET_NEXE_FD(0, 0, false, info, false); |
| 122 EXPECT_EQ(1U, host_->pending_translations()); | 123 EXPECT_EQ(1U, host_->pending_translations()); |
| 123 FlushQueues(); | 124 FlushQueues(); |
| 124 EXPECT_EQ(1U, host_->pending_translations()); | 125 EXPECT_EQ(1U, host_->pending_translations()); |
| 125 EXPECT_EQ(1, temp_callback_count_); | 126 EXPECT_EQ(1, temp_callback_count_); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 156 host_->TranslationFinished(0, 0, true); | 157 host_->TranslationFinished(0, 0, true); |
| 157 FlushQueues(); | 158 FlushQueues(); |
| 158 GET_NEXE_FD(0, 1, false, info, true); | 159 GET_NEXE_FD(0, 1, false, info, true); |
| 159 FlushQueues(); | 160 FlushQueues(); |
| 160 EXPECT_EQ(2, temp_callback_count_); | 161 EXPECT_EQ(2, temp_callback_count_); |
| 161 EXPECT_EQ(0U, host_->pending_translations()); | 162 EXPECT_EQ(0U, host_->pending_translations()); |
| 162 } | 163 } |
| 163 | 164 |
| 164 TEST_F(PnaclHostTest, TranslationErrors) { | 165 TEST_F(PnaclHostTest, TranslationErrors) { |
| 165 nacl::PnaclCacheInfo info = GetTestCacheInfo(); | 166 nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 167 info.pexe_url = GURL("http://www.google.com"); |
| 166 GET_NEXE_FD(0, 0, false, info, false); | 168 GET_NEXE_FD(0, 0, false, info, false); |
| 167 // Early abort, before temp file request returns | 169 // Early abort, before temp file request returns |
| 168 host_->TranslationFinished(0, 0, false); | 170 host_->TranslationFinished(0, 0, false); |
| 169 FlushQueues(); | 171 FlushQueues(); |
| 170 EXPECT_EQ(0U, host_->pending_translations()); | 172 EXPECT_EQ(0U, host_->pending_translations()); |
| 171 EXPECT_EQ(0, temp_callback_count_); | 173 EXPECT_EQ(0, temp_callback_count_); |
| 172 // Check that another request for the same info misses successfully. | 174 // Check that another request for the same info misses successfully. |
| 173 GET_NEXE_FD(0, 0, false, info, false); | 175 GET_NEXE_FD(0, 0, false, info, false); |
| 174 FlushQueues(); | 176 FlushQueues(); |
| 175 host_->TranslationFinished(0, 0, true); | 177 host_->TranslationFinished(0, 0, true); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 EXPECT_EQ(2U, host_->pending_translations()); | 340 EXPECT_EQ(2U, host_->pending_translations()); |
| 339 FlushQueues(); | 341 FlushQueues(); |
| 340 EXPECT_EQ(2U, host_->pending_translations()); | 342 EXPECT_EQ(2U, host_->pending_translations()); |
| 341 EXPECT_EQ(1, temp_callback_count_); | 343 EXPECT_EQ(1, temp_callback_count_); |
| 342 host_->TranslationFinished(0, 0, true); | 344 host_->TranslationFinished(0, 0, true); |
| 343 FlushQueues(); | 345 FlushQueues(); |
| 344 EXPECT_EQ(2, temp_callback_count_); | 346 EXPECT_EQ(2, temp_callback_count_); |
| 345 EXPECT_EQ(0U, host_->pending_translations()); | 347 EXPECT_EQ(0U, host_->pending_translations()); |
| 346 } | 348 } |
| 347 | 349 |
| 348 // Test that pexes with the no-store header do not get cached. | |
| 349 TEST_F(PnaclHostTest, CacheControlNoStore) { | |
| 350 nacl::PnaclCacheInfo info = GetTestCacheInfo(); | |
| 351 info.has_no_store_header = true; | |
| 352 GET_NEXE_FD(0, 0, false, info, false); | |
| 353 FlushQueues(); | |
| 354 EXPECT_EQ(1, temp_callback_count_); | |
| 355 host_->TranslationFinished(0, 0, true); | |
| 356 FlushQueues(); | |
| 357 EXPECT_EQ(0U, host_->pending_translations()); | |
| 358 EXPECT_EQ(0, GetCacheSize()); | |
| 359 } | |
| 360 | |
| 361 // Test that no-store pexes do not wait, but do duplicate translations | |
| 362 TEST_F(PnaclHostTest, NoStoreOverlappedMiss) { | |
| 363 nacl::PnaclCacheInfo info = GetTestCacheInfo(); | |
| 364 info.has_no_store_header = true; | |
| 365 GET_NEXE_FD(0, 0, false, info, false); | |
| 366 GET_NEXE_FD(0, 1, false, info, false); | |
| 367 FlushQueues(); | |
| 368 // Check that both translations have returned misses, (i.e. that the | |
| 369 // second one has not blocked on the first one) | |
| 370 EXPECT_EQ(2, temp_callback_count_); | |
| 371 host_->TranslationFinished(0, 0, true); | |
| 372 host_->TranslationFinished(0, 1, true); | |
| 373 FlushQueues(); | |
| 374 EXPECT_EQ(0U, host_->pending_translations()); | |
| 375 | |
| 376 // Same test, but issue the 2nd request after the first has returned a miss. | |
| 377 info.abi_version = 222; | |
| 378 GET_NEXE_FD(0, 0, false, info, false); | |
| 379 FlushQueues(); | |
| 380 EXPECT_EQ(3, temp_callback_count_); | |
| 381 GET_NEXE_FD(0, 1, false, info, false); | |
| 382 FlushQueues(); | |
| 383 EXPECT_EQ(4, temp_callback_count_); | |
| 384 host_->RendererClosing(0); | |
| 385 } | |
| 386 | |
| 387 TEST_F(PnaclHostTest, ClearTranslationCache) { | 350 TEST_F(PnaclHostTest, ClearTranslationCache) { |
| 388 nacl::PnaclCacheInfo info = GetTestCacheInfo(); | 351 nacl::PnaclCacheInfo info = GetTestCacheInfo(); |
| 389 // Add 2 entries in the cache | 352 // Add 2 entries in the cache |
| 390 GET_NEXE_FD(0, 0, false, info, false); | 353 GET_NEXE_FD(0, 0, false, info, false); |
| 391 info.abi_version = 222; | 354 info.abi_version = 222; |
| 392 GET_NEXE_FD(0, 1, false, info, false); | 355 GET_NEXE_FD(0, 1, false, info, false); |
| 393 FlushQueues(); | 356 FlushQueues(); |
| 394 EXPECT_EQ(2, temp_callback_count_); | 357 EXPECT_EQ(2, temp_callback_count_); |
| 395 host_->TranslationFinished(0, 0, true); | 358 host_->TranslationFinished(0, 0, true); |
| 396 host_->TranslationFinished(0, 1, true); | 359 host_->TranslationFinished(0, 1, true); |
| 397 FlushQueues(); | 360 FlushQueues(); |
| 398 EXPECT_EQ(0U, host_->pending_translations()); | 361 EXPECT_EQ(0U, host_->pending_translations()); |
| 399 EXPECT_EQ(2, GetCacheSize()); | 362 EXPECT_EQ(2, GetCacheSize()); |
| 400 net::TestCompletionCallback cb; | 363 net::TestCompletionCallback cb; |
| 401 // Since we are using a memory backend, the clear should happen immediately. | 364 // Since we are using a memory backend, the clear should happen immediately. |
| 402 host_->ClearTranslationCacheEntriesBetween( | 365 host_->ClearTranslationCacheEntriesBetween(base::Time(), base::Time(), |
| 403 base::Time(), base::Time(), base::Bind(cb.callback(), 0)); | 366 base::Bind(cb.callback(), 0)); |
| 404 EXPECT_EQ(0, cb.GetResult(net::ERR_IO_PENDING)); | 367 EXPECT_EQ(0, cb.GetResult(net::ERR_IO_PENDING)); |
| 405 // Check that the translation cache has been cleared | 368 // Check that the translation cache has been cleared |
| 406 EXPECT_EQ(0, GetCacheSize()); | 369 EXPECT_EQ(0, GetCacheSize()); |
| 407 host_->RendererClosing(0); | 370 host_->RendererClosing(0); |
| 408 } | 371 } |
| 409 | 372 |
| 410 } // namespace pnacl | 373 } // namespace pnacl |
| OLD | NEW |