diff options
author | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-18 13:54:59 +0000 |
---|---|---|
committer | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-18 13:54:59 +0000 |
commit | 67a7851692243892bb2d7253d2f1974833e57432 (patch) | |
tree | 98bdc05f9af985cbcc8b9cc6ea0ccf472a85b588 /chrome/browser/idbbindingutilities_browsertest.cc | |
parent | e40cc399bd7e438579d6fcfa208103c12caf9052 (diff) | |
download | chromium_src-67a7851692243892bb2d7253d2f1974833e57432.zip chromium_src-67a7851692243892bb2d7253d2f1974833e57432.tar.gz chromium_src-67a7851692243892bb2d7253d2f1974833e57432.tar.bz2 |
Adds IDBKeyPath parser / extractor, and provides a mechanism to call it sandboxed.
TEST=idbkeypathextractor_browsertests.cc
Review URL: http://codereview.chromium.org/3043037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@56524 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/idbbindingutilities_browsertest.cc')
-rw-r--r-- | chrome/browser/idbbindingutilities_browsertest.cc | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/chrome/browser/idbbindingutilities_browsertest.cc b/chrome/browser/idbbindingutilities_browsertest.cc new file mode 100644 index 0000000..3172012 --- /dev/null +++ b/chrome/browser/idbbindingutilities_browsertest.cc @@ -0,0 +1,269 @@ +// Copyright (c) 2010 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 "base/utf_string_conversions.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "chrome/browser/utility_process_host.h" +#include "chrome/common/indexed_db_key.h" +#include "chrome/common/serialized_script_value.h" +#include "chrome/test/in_process_browser_test.h" +#include "chrome/test/ui_test_utils.h" +#include "googleurl/src/gurl.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/glue/idb_bindings.h" + +using WebKit::WebSerializedScriptValue; + +// Sanity test, check the function call directly outside the sandbox. +TEST(IDBKeyPathWithoutSandbox, Value) { + char16 data[] = {0x0353,0x6f66,0x536f,0x7a03,0x6f6f,0x017b}; + std::vector<WebSerializedScriptValue> serialized_values; + serialized_values.push_back( + WebSerializedScriptValue::fromString(string16(data, arraysize(data)))); + serialized_values.push_back( + WebSerializedScriptValue::fromString(string16())); + + std::vector<WebKit::WebIDBKey> values; + string16 key_path(UTF8ToUTF16("foo")); + bool error = webkit_glue::IDBKeysFromValuesAndKeyPath( + serialized_values, key_path, &values); + + ASSERT_EQ(size_t(2), values.size()); + ASSERT_EQ(WebKit::WebIDBKey::StringType, values[0].type()); + ASSERT_EQ(UTF8ToUTF16("zoo"), values[0].string()); + ASSERT_EQ(WebKit::WebIDBKey::InvalidType, values[1].type()); + ASSERT_FALSE(error); + + values.clear(); + key_path = UTF8ToUTF16("PropertyNotAvailable"); + error = webkit_glue::IDBKeysFromValuesAndKeyPath( + serialized_values, key_path, &values); + + ASSERT_EQ(size_t(2), values.size()); + ASSERT_EQ(WebKit::WebIDBKey::InvalidType, values[0].type()); + ASSERT_EQ(WebKit::WebIDBKey::InvalidType, values[1].type()); + ASSERT_FALSE(error); + + values.clear(); + key_path = UTF8ToUTF16("!+Invalid[KeyPath[[["); + error = webkit_glue::IDBKeysFromValuesAndKeyPath( + serialized_values, key_path, &values); + + ASSERT_TRUE(error); + ASSERT_EQ(size_t(2), values.size()); + ASSERT_EQ(WebKit::WebIDBKey::InvalidType, values[0].type()); + ASSERT_EQ(WebKit::WebIDBKey::InvalidType, values[1].type()); +} + +class IDBKeyPathHelper : public UtilityProcessHost::Client { + public: + IDBKeyPathHelper() + : expected_id_(0), + utility_process_host_(NULL), + value_for_key_path_failed_(false) { + } + + void CreateUtilityProcess(ResourceDispatcherHost* resource_dispatcher_host) { + if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { + ChromeThread::PostTask( + ChromeThread::IO, FROM_HERE, + NewRunnableMethod(this, &IDBKeyPathHelper::CreateUtilityProcess, + resource_dispatcher_host)); + return; + } + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + utility_process_host_ = + new UtilityProcessHost(resource_dispatcher_host, this, + ChromeThread::IO); + utility_process_host_->StartBatchMode(); + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, + new MessageLoop::QuitTask()); + } + + void DestroyUtilityProcess() { + if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { + ChromeThread::PostTask( + ChromeThread::IO, FROM_HERE, + NewRunnableMethod(this, &IDBKeyPathHelper::DestroyUtilityProcess)); + return; + } + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + utility_process_host_->EndBatchMode(); + utility_process_host_ = NULL; + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, + new MessageLoop::QuitTask()); + } + + void SetExpected(int expected_id, + const std::vector<IndexedDBKey>& expected_values, + bool failed) { + expected_id_ = expected_id; + expected_values_ = expected_values; + value_for_key_path_failed_ = failed; + } + + void CheckValuesForKeyPath( + int id, const std::vector<SerializedScriptValue>& serialized_values, + const string16& key_path) { + if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { + ChromeThread::PostTask( + ChromeThread::IO, FROM_HERE, + NewRunnableMethod(this, &IDBKeyPathHelper::CheckValuesForKeyPath, + id, serialized_values, key_path)); + return; + } + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + bool ret = + utility_process_host_->StartIDBKeysFromValuesAndKeyPath( + id, serialized_values, key_path); + ASSERT_TRUE(ret); + } + + // UtilityProcessHost::Client + virtual void OnIDBKeysFromValuesAndKeyPathSucceeded( + int id, const std::vector<IndexedDBKey>& values) { + EXPECT_EQ(expected_id_, id); + EXPECT_FALSE(value_for_key_path_failed_); + ASSERT_EQ(expected_values_.size(), values.size()); + size_t pos = 0; + for (std::vector<IndexedDBKey>::const_iterator i(values.begin()); + i != values.end(); ++i, ++pos) { + ASSERT_EQ(expected_values_[pos].type(), i->type()); + if (i->type() == WebKit::WebIDBKey::StringType) { + ASSERT_EQ(expected_values_[pos].string(), i->string()); + } else if (i->type() == WebKit::WebIDBKey::NumberType) { + ASSERT_EQ(expected_values_[pos].number(), i->number()); + } + } + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, + new MessageLoop::QuitTask()); + } + + virtual void OnIDBKeysFromValuesAndKeyPathFailed(int id) { + EXPECT_TRUE(value_for_key_path_failed_); + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, + new MessageLoop::QuitTask()); + } + + private: + int expected_id_; + std::vector<IndexedDBKey> expected_values_; + UtilityProcessHost* utility_process_host_; + bool value_for_key_path_failed_; +}; + +// This test fixture runs in the UI thread. However, most of the work done by +// UtilityProcessHost (and wrapped by IDBKeyPathHelper above) happens on the IO +// thread. This fixture delegates to IDBKeyPathHelper and blocks via +// "ui_test_utils::RunMessageLoop()", until IDBKeyPathHelper posts a quit +// message the MessageLoop. +class ScopedIDBKeyPathHelper { + public: + ScopedIDBKeyPathHelper() { + key_path_helper_ = new IDBKeyPathHelper(); + key_path_helper_->CreateUtilityProcess( + g_browser_process->resource_dispatcher_host()); + ui_test_utils::RunMessageLoop(); + } + + ~ScopedIDBKeyPathHelper() { + key_path_helper_->DestroyUtilityProcess(); + ui_test_utils::RunMessageLoop(); + } + + void SetExpected(int id, const std::vector<IndexedDBKey>& expected_values, + bool failed) { + key_path_helper_->SetExpected(id, expected_values, failed); + } + + void CheckValuesForKeyPath( + int id, + const std::vector<SerializedScriptValue>& serialized_script_values, + const string16& key_path) { + key_path_helper_->CheckValuesForKeyPath(id, serialized_script_values, + key_path); + ui_test_utils::RunMessageLoop(); + } + + private: + scoped_refptr<IDBKeyPathHelper> key_path_helper_; +}; + +IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, IDBKeyPathExtract) { + ScopedIDBKeyPathHelper scoped_helper; + const int kId = 7; + std::vector<IndexedDBKey> expected_values; + IndexedDBKey value; + value.Set(UTF8ToUTF16("zoo")); + expected_values.push_back(value); + + IndexedDBKey invalid_value; + invalid_value.SetInvalid(); + expected_values.push_back(invalid_value); + + scoped_helper.SetExpected(kId, expected_values, false); + + char16 data[] = {0x0353,0x6f66,0x536f,0x7a03,0x6f6f,0x017b}; + std::vector<SerializedScriptValue> serialized_values; + serialized_values.push_back( + SerializedScriptValue(false, false, string16(data, arraysize(data)))); + serialized_values.push_back( + SerializedScriptValue(true, false, string16())); + scoped_helper.CheckValuesForKeyPath( + kId, serialized_values, UTF8ToUTF16("foo")); +} + +IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, IDBKeyPathPropertyNotAvailable) { + ScopedIDBKeyPathHelper scoped_helper; + const int kId = 7; + std::vector<IndexedDBKey> expected_values; + IndexedDBKey invalid_value; + invalid_value.SetInvalid(); + expected_values.push_back(invalid_value); + expected_values.push_back(invalid_value); + + scoped_helper.SetExpected(kId, expected_values, false); + + char16 data[] = {0x0353,0x6f66,0x536f,0x7a03,0x6f6f,0x017b}; + std::vector<SerializedScriptValue> serialized_values; + serialized_values.push_back( + SerializedScriptValue(false, false, string16(data, arraysize(data)))); + serialized_values.push_back( + SerializedScriptValue(true, false, string16())); + scoped_helper.CheckValuesForKeyPath(kId, serialized_values, + UTF8ToUTF16("PropertyNotAvailable")); +} + +IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, IDBKeyPathMultipleCalls) { + ScopedIDBKeyPathHelper scoped_helper; + const int kId = 7; + std::vector<IndexedDBKey> expected_values; + IndexedDBKey invalid_value; + invalid_value.SetInvalid(); + expected_values.push_back(invalid_value); + expected_values.push_back(invalid_value); + + scoped_helper.SetExpected(kId, expected_values, true); + + char16 data[] = {0x0353,0x6f66,0x536f,0x7a03,0x6f6f,0x017b}; + std::vector<SerializedScriptValue> serialized_values; + serialized_values.push_back( + SerializedScriptValue(false, false, string16(data, arraysize(data)))); + serialized_values.push_back( + SerializedScriptValue(true, false, string16())); + scoped_helper.CheckValuesForKeyPath(kId, serialized_values, + UTF8ToUTF16("!+Invalid[KeyPath[[[")); + + // Call again with the Utility process in batch mode and with valid keys. + expected_values.clear(); + IndexedDBKey value; + value.Set(UTF8ToUTF16("zoo")); + expected_values.push_back(value); + expected_values.push_back(invalid_value); + scoped_helper.SetExpected(kId + 1, expected_values, false); + scoped_helper.CheckValuesForKeyPath(kId + 1, serialized_values, + UTF8ToUTF16("foo")); +} |