This source file includes following definitions.
- thread_bundle_
- SetUp
- TearDown
- FlushQueues
- GetCacheSize
- CacheIsInitialized
- ReInitBackend
- CallbackExpectMiss
- CallbackExpectHit
- GetTestCacheInfo
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- SetUp
- DeInit
- TEST_F
#include "components/nacl/browser/pnacl_host.h"
#include <stdio.h>
#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/threading/sequenced_worker_pool.h"
#include "components/nacl/browser/pnacl_translation_cache.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/test_completion_callback.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_WIN)
#define snprintf _snprintf
#endif
namespace pnacl {
class PnaclHostTest : public testing::Test {
protected:
PnaclHostTest()
: host_(NULL),
temp_callback_count_(0),
write_callback_count_(0),
thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
virtual void SetUp() {
host_ = new PnaclHost();
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
host_->InitForTest(temp_dir_.path(), true);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(PnaclHost::CacheReady, host_->cache_state_);
}
virtual void TearDown() {
EXPECT_EQ(0U, host_->pending_translations());
host_->RendererClosing(0);
FlushQueues();
EXPECT_EQ(PnaclHost::CacheUninitialized, host_->cache_state_);
delete host_;
}
void FlushQueues() {
content::BrowserThread::GetBlockingPool()->FlushForTesting();
base::RunLoop().RunUntilIdle();
content::BrowserThread::GetBlockingPool()->FlushForTesting();
base::RunLoop().RunUntilIdle();
}
int GetCacheSize() { return host_->disk_cache_->Size(); }
int CacheIsInitialized() {
return host_->cache_state_ == PnaclHost::CacheReady;
}
void ReInitBackend() {
host_->InitForTest(temp_dir_.path(), true);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(PnaclHost::CacheReady, host_->cache_state_);
}
public:
void CallbackExpectMiss(base::PlatformFile fd, bool is_hit) {
EXPECT_FALSE(is_hit);
ASSERT_FALSE(fd == base::kInvalidPlatformFileValue);
base::PlatformFileInfo info;
EXPECT_TRUE(base::GetPlatformFileInfo(fd, &info));
EXPECT_FALSE(info.is_directory);
EXPECT_EQ(0LL, info.size);
char str[16];
memset(str, 0x0, 16);
snprintf(str, 16, "testdata%d", ++write_callback_count_);
EXPECT_EQ(16, base::WritePlatformFile(fd, 0, str, 16));
temp_callback_count_++;
}
void CallbackExpectHit(base::PlatformFile fd, bool is_hit) {
EXPECT_TRUE(is_hit);
ASSERT_FALSE(fd == base::kInvalidPlatformFileValue);
base::PlatformFileInfo info;
EXPECT_TRUE(base::GetPlatformFileInfo(fd, &info));
EXPECT_FALSE(info.is_directory);
EXPECT_EQ(16LL, info.size);
char data[16];
memset(data, 0x0, 16);
char str[16];
memset(str, 0x0, 16);
snprintf(str, 16, "testdata%d", write_callback_count_);
EXPECT_EQ(16, base::ReadPlatformFile(fd, 0, data, 16));
EXPECT_STREQ(str, data);
temp_callback_count_++;
}
protected:
PnaclHost* host_;
int temp_callback_count_;
int write_callback_count_;
content::TestBrowserThreadBundle thread_bundle_;
base::ScopedTempDir temp_dir_;
};
static nacl::PnaclCacheInfo GetTestCacheInfo() {
nacl::PnaclCacheInfo info;
info.pexe_url = GURL("http://www.google.com");
info.abi_version = 0;
info.opt_level = 0;
info.has_no_store_header = false;
return info;
}
#define GET_NEXE_FD(renderer, instance, incognito, info, expect_hit) \
do { \
SCOPED_TRACE(""); \
host_->GetNexeFd( \
renderer, \
0, \
instance, \
incognito, \
info, \
base::Bind(expect_hit ? &PnaclHostTest::CallbackExpectHit \
: &PnaclHostTest::CallbackExpectMiss, \
base::Unretained(this))); \
} while (0)
TEST_F(PnaclHostTest, BasicMiss) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
EXPECT_EQ(1U, host_->pending_translations());
FlushQueues();
EXPECT_EQ(1U, host_->pending_translations());
EXPECT_EQ(1, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
FlushQueues();
EXPECT_EQ(0U, host_->pending_translations());
info.etag = std::string("something else");
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
EXPECT_EQ(1U, host_->pending_translations());
host_->RendererClosing(0);
FlushQueues();
EXPECT_FALSE(CacheIsInitialized());
}
TEST_F(PnaclHostTest, BadArguments) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
EXPECT_EQ(1U, host_->pending_translations());
host_->TranslationFinished(0, 1, true);
EXPECT_EQ(1U, host_->pending_translations());
host_->RendererClosing(1);
EXPECT_EQ(1U, host_->pending_translations());
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
host_->RendererClosing(0);
}
TEST_F(PnaclHostTest, BasicHit) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
FlushQueues();
GET_NEXE_FD(0, 1, false, info, true);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
EXPECT_EQ(0U, host_->pending_translations());
}
TEST_F(PnaclHostTest, TranslationErrors) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
host_->TranslationFinished(0, 0, false);
FlushQueues();
EXPECT_EQ(0U, host_->pending_translations());
EXPECT_EQ(0, temp_callback_count_);
EXPECT_FALSE(CacheIsInitialized());
ReInitBackend();
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
host_->TranslationFinished(0, 0, true);
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
EXPECT_EQ(0U, host_->pending_translations());
info.abi_version = 222;
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
host_->TranslationFinished(0, 0, false);
FlushQueues();
EXPECT_EQ(0U, host_->pending_translations());
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
EXPECT_EQ(3, temp_callback_count_);
host_->TranslationFinished(0, 0, false);
EXPECT_EQ(0U, host_->pending_translations());
}
TEST_F(PnaclHostTest, OverlappedMissesAfterTempReturn) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
EXPECT_EQ(1U, host_->pending_translations());
GET_NEXE_FD(0, 1, false, info, true);
FlushQueues();
EXPECT_EQ(2U, host_->pending_translations());
EXPECT_EQ(1, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
EXPECT_EQ(0U, host_->pending_translations());
}
TEST_F(PnaclHostTest, OverlappedMissesBeforeTempReturn) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
GET_NEXE_FD(0, 1, false, info, true);
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
EXPECT_EQ(2U, host_->pending_translations());
FlushQueues();
EXPECT_EQ(2U, host_->pending_translations());
EXPECT_EQ(1, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
EXPECT_EQ(0U, host_->pending_translations());
}
TEST_F(PnaclHostTest, OverlappedHitsBeforeTempReturn) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
FlushQueues();
EXPECT_EQ(0U, host_->pending_translations());
GET_NEXE_FD(0, 0, false, info, true);
GET_NEXE_FD(0, 1, false, info, true);
FlushQueues();
EXPECT_EQ(3, temp_callback_count_);
EXPECT_EQ(0U, host_->pending_translations());
}
TEST_F(PnaclHostTest, OverlappedHitsAfterTempReturn) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
FlushQueues();
EXPECT_EQ(0U, host_->pending_translations());
GET_NEXE_FD(0, 0, false, info, true);
FlushQueues();
GET_NEXE_FD(0, 1, false, info, true);
FlushQueues();
EXPECT_EQ(3, temp_callback_count_);
EXPECT_EQ(0U, host_->pending_translations());
}
TEST_F(PnaclHostTest, OverlappedMissesRendererClosing) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
GET_NEXE_FD(1, 1, false, info, false);
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
EXPECT_EQ(2U, host_->pending_translations());
FlushQueues();
EXPECT_EQ(2U, host_->pending_translations());
EXPECT_EQ(1, temp_callback_count_);
host_->RendererClosing(0);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
EXPECT_EQ(1U, host_->pending_translations());
host_->RendererClosing(1);
}
TEST_F(PnaclHostTest, Incognito) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, true, info, false);
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
FlushQueues();
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
FlushQueues();
GET_NEXE_FD(0, 0, true, info, true);
FlushQueues();
EXPECT_EQ(3, temp_callback_count_);
}
TEST_F(PnaclHostTest, IncognitoOverlappedMiss) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, true, info, false);
GET_NEXE_FD(0, 1, false, info, false);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
host_->TranslationFinished(0, 1, true);
FlushQueues();
EXPECT_EQ(0U, host_->pending_translations());
info.abi_version = 222;
GET_NEXE_FD(0, 0, true, info, false);
FlushQueues();
EXPECT_EQ(3, temp_callback_count_);
GET_NEXE_FD(0, 1, false, info, false);
FlushQueues();
EXPECT_EQ(4, temp_callback_count_);
host_->RendererClosing(0);
}
TEST_F(PnaclHostTest, IncognitoSecondOverlappedMiss) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
GET_NEXE_FD(0, 1, true, info, true);
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
EXPECT_EQ(2U, host_->pending_translations());
FlushQueues();
EXPECT_EQ(2U, host_->pending_translations());
EXPECT_EQ(1, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
EXPECT_EQ(0U, host_->pending_translations());
}
TEST_F(PnaclHostTest, CacheControlNoStore) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
info.has_no_store_header = true;
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
EXPECT_EQ(1, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
FlushQueues();
EXPECT_EQ(0U, host_->pending_translations());
EXPECT_EQ(0, GetCacheSize());
}
TEST_F(PnaclHostTest, NoStoreOverlappedMiss) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
info.has_no_store_header = true;
GET_NEXE_FD(0, 0, false, info, false);
GET_NEXE_FD(0, 1, false, info, false);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
host_->TranslationFinished(0, 1, true);
FlushQueues();
EXPECT_EQ(0U, host_->pending_translations());
info.abi_version = 222;
GET_NEXE_FD(0, 0, false, info, false);
FlushQueues();
EXPECT_EQ(3, temp_callback_count_);
GET_NEXE_FD(0, 1, false, info, false);
FlushQueues();
EXPECT_EQ(4, temp_callback_count_);
host_->RendererClosing(0);
}
TEST_F(PnaclHostTest, ClearTranslationCache) {
nacl::PnaclCacheInfo info = GetTestCacheInfo();
GET_NEXE_FD(0, 0, false, info, false);
info.abi_version = 222;
GET_NEXE_FD(0, 1, false, info, false);
FlushQueues();
EXPECT_EQ(2, temp_callback_count_);
host_->TranslationFinished(0, 0, true);
host_->TranslationFinished(0, 1, true);
FlushQueues();
EXPECT_EQ(0U, host_->pending_translations());
EXPECT_EQ(2, GetCacheSize());
net::TestCompletionCallback cb;
host_->ClearTranslationCacheEntriesBetween(
base::Time(), base::Time(), base::Bind(cb.callback(), 0));
EXPECT_EQ(0, GetCacheSize());
EXPECT_EQ(0, cb.GetResult(net::ERR_IO_PENDING));
EXPECT_FALSE(CacheIsInitialized());
}
class PnaclHostTestDisk : public PnaclHostTest {
protected:
virtual void SetUp() {
host_ = new PnaclHost();
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
host_->InitForTest(temp_dir_.path(), false);
EXPECT_EQ(PnaclHost::CacheInitializing, host_->cache_state_);
}
void DeInit() {
host_->DeInitIfSafe();
}
};
TEST_F(PnaclHostTestDisk, DeInitWhileInitializing) {
DeInit();
base::RunLoop().RunUntilIdle();
}
}