diff options
author | erg <erg@chromium.org> | 2016-02-18 10:47:16 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-18 18:48:11 +0000 |
commit | 33299a9ba6a3ead1b0ff1e1bfe9dd8d4ee961d8b (patch) | |
tree | 5869c50849ad5b19147979a0abd7a0f4c20d7a9c | |
parent | 8eb8fa6b1082bcee64d5bc98ed8d1004378c0331 (diff) | |
download | chromium_src-33299a9ba6a3ead1b0ff1e1bfe9dd8d4ee961d8b.zip chromium_src-33299a9ba6a3ead1b0ff1e1bfe9dd8d4ee961d8b.tar.gz chromium_src-33299a9ba6a3ead1b0ff1e1bfe9dd8d4ee961d8b.tar.bz2 |
mojo: Remove the mojo:filesystem sqlite binding code.
As the performance isn't great, and since we need to make changes to how
mojo:filesystem works to integrate with chrome in general, drop the two
previous users of mojo:filesystem: the mojo:network_service cookie store
and the underlying sqlite bridge code.
BUG=585587
Review URL: https://codereview.chromium.org/1710693002
Cr-Commit-Position: refs/heads/master@{#376212}
-rw-r--r-- | BUILD.gn | 1 | ||||
-rw-r--r-- | mojo/services/network/BUILD.gn | 4 | ||||
-rw-r--r-- | mojo/services/network/mojo_persistent_cookie_store.cc | 100 | ||||
-rw-r--r-- | mojo/services/network/mojo_persistent_cookie_store.h | 65 | ||||
-rw-r--r-- | mojo/services/network/network_context.cc | 23 | ||||
-rw-r--r-- | mojo/services/network/network_context.h | 2 | ||||
-rw-r--r-- | mojo/services/network/network_service_delegate.cc | 85 | ||||
-rw-r--r-- | mojo/services/network/network_service_delegate.h | 24 | ||||
-rw-r--r-- | mojo/tools/data/apptests | 4 | ||||
-rw-r--r-- | sql/mojo/BUILD.gn | 62 | ||||
-rw-r--r-- | sql/mojo/DEPS | 6 | ||||
-rw-r--r-- | sql/mojo/mojo_vfs.cc | 455 | ||||
-rw-r--r-- | sql/mojo/mojo_vfs.h | 45 | ||||
-rw-r--r-- | sql/mojo/sql_test_base.cc | 164 | ||||
-rw-r--r-- | sql/mojo/sql_test_base.h | 92 | ||||
-rw-r--r-- | sql/mojo/vfs_unittest.cc | 340 |
16 files changed, 4 insertions, 1468 deletions
@@ -604,7 +604,6 @@ group("mojo_apptests") { "//media/mojo/services:tests", "//mojo/services/network:apptests", "//mojo/shell:apptests", - "//sql/mojo:apptests", "//ui/views/mus:tests", ] } diff --git a/mojo/services/network/BUILD.gn b/mojo/services/network/BUILD.gn index e5c3ef2..aad26845 100644 --- a/mojo/services/network/BUILD.gn +++ b/mojo/services/network/BUILD.gn @@ -59,8 +59,6 @@ source_set("lib") { "http_connection_impl.h", "http_server_impl.cc", "http_server_impl.h", - "mojo_persistent_cookie_store.cc", - "mojo_persistent_cookie_store.h", "net_adapters.cc", "net_adapters.h", "net_address_type_converters.cc", @@ -92,7 +90,6 @@ source_set("lib") { deps = [ "//base", - "//components/filesystem/public/interfaces", "//mojo/common:common_base", "//mojo/common:url_type_converters", "//mojo/message_pump", @@ -104,7 +101,6 @@ source_set("lib") { "//net", "//net:extras", "//net:http_server", - "//sql/mojo", "//url", ] } diff --git a/mojo/services/network/mojo_persistent_cookie_store.cc b/mojo/services/network/mojo_persistent_cookie_store.cc deleted file mode 100644 index ac37194..0000000 --- a/mojo/services/network/mojo_persistent_cookie_store.cc +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2015 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 "mojo/services/network/mojo_persistent_cookie_store.h" - -#include "base/bind.h" -#include "base/synchronization/waitable_event.h" -#include "mojo/services/network/network_service_delegate.h" -#include "net/extras/sqlite/sqlite_persistent_cookie_store.h" - -namespace mojo { - -MojoPersistentCookieStore::MojoPersistentCookieStore( - NetworkServiceDelegate* network_service_delegate, - const base::FilePath& path, - const scoped_refptr<base::SequencedTaskRunner>& client_task_runner, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, - bool restore_old_session_cookies, - net::CookieCryptoDelegate* crypto_delegate) - : network_service_delegate_(network_service_delegate) { - sql_cookie_store_ = new net::SQLitePersistentCookieStore( - path, - client_task_runner, - background_task_runner, - restore_old_session_cookies, - crypto_delegate); - network_service_delegate_->AddObserver(this); -} - -void MojoPersistentCookieStore::Load(const LoadedCallback& loaded_callback) { - if (sql_cookie_store_) - sql_cookie_store_->Load(loaded_callback); -} - -void MojoPersistentCookieStore::LoadCookiesForKey( - const std::string& key, - const LoadedCallback& callback) { - if (sql_cookie_store_) - sql_cookie_store_->LoadCookiesForKey(key, callback); -} - -void MojoPersistentCookieStore::AddCookie(const net::CanonicalCookie& cc) { - if (sql_cookie_store_) - sql_cookie_store_->AddCookie(cc); -} - -void MojoPersistentCookieStore::UpdateCookieAccessTime( - const net::CanonicalCookie& cc) { - if (sql_cookie_store_) - sql_cookie_store_->UpdateCookieAccessTime(cc); -} - -void MojoPersistentCookieStore::DeleteCookie(const net::CanonicalCookie& cc) { - if (sql_cookie_store_) - sql_cookie_store_->DeleteCookie(cc); -} - -void MojoPersistentCookieStore::SetForceKeepSessionState() { - if (sql_cookie_store_) - sql_cookie_store_->SetForceKeepSessionState(); -} - -void MojoPersistentCookieStore::Flush(const base::Closure& callback) { - if (sql_cookie_store_) - sql_cookie_store_->Flush(callback); -} - -MojoPersistentCookieStore::~MojoPersistentCookieStore() { - RemoveObserver(); -} - -void MojoPersistentCookieStore::RemoveObserver() { - if (network_service_delegate_) { - network_service_delegate_->RemoveObserver(this); - network_service_delegate_ = nullptr; - } -} - -namespace { - -void SignalComplete(base::WaitableEvent* event) { - event->Signal(); -} - -} // namespace - -void MojoPersistentCookieStore::OnIOWorkerThreadShutdown() { - // We need to shut down synchronously here. This will block our thread until - // the backend has shut down. - base::WaitableEvent done_event(false, false); - sql_cookie_store_->Close(base::Bind(&SignalComplete, &done_event)); - done_event.Wait(); - - sql_cookie_store_ = NULL; - - RemoveObserver(); -} - -} // namespace mojo diff --git a/mojo/services/network/mojo_persistent_cookie_store.h b/mojo/services/network/mojo_persistent_cookie_store.h deleted file mode 100644 index 97e8b6d..0000000 --- a/mojo/services/network/mojo_persistent_cookie_store.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2015 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. - -#ifndef MOJO_SERVICES_NETWORK_MOJO_PERSISTENT_COOKIE_STORE_H_ -#define MOJO_SERVICES_NETWORK_MOJO_PERSISTENT_COOKIE_STORE_H_ - -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/sequenced_task_runner.h" -#include "mojo/services/network/network_service_delegate_observer.h" -#include "net/cookies/cookie_monster.h" -#include "net/extras/sqlite/cookie_crypto_delegate.h" - -namespace net { -class SQLitePersistentCookieStore; -} // namespace net - -namespace mojo { -class NetworkServiceDelegate; - -// A PersistentCookieStore that listens to NetworkContext's and tries to -// gracefully shutdown when our Connection is about to be closed. -class MojoPersistentCookieStore - : public net::CookieMonster::PersistentCookieStore, - public NetworkServiceDelegateObserver { - public: - MojoPersistentCookieStore( - NetworkServiceDelegate* network_service_delegate, - const base::FilePath& path, - const scoped_refptr<base::SequencedTaskRunner>& client_task_runner, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, - bool restore_old_session_cookies, - net::CookieCryptoDelegate* crypto_delegate); - - // CookieMonster::PersistentCookieStore: - void Load(const LoadedCallback& loaded_callback) override; - void LoadCookiesForKey(const std::string& key, - const LoadedCallback& callback) override; - void AddCookie(const net::CanonicalCookie& cc) override; - void UpdateCookieAccessTime(const net::CanonicalCookie& cc) override; - void DeleteCookie(const net::CanonicalCookie& cc) override; - void SetForceKeepSessionState() override; - void Flush(const base::Closure& callback) override; - - // NetworkServiceDelegateObserver: - void OnIOWorkerThreadShutdown() override; - - private: - ~MojoPersistentCookieStore() override; - - void RemoveObserver(); - - NetworkServiceDelegate* network_service_delegate_; - - // We own the |sql_cookie_store_| that we proxy for. We delete this during - // OnIOWorkerThreadShutdown(). - scoped_refptr<net::SQLitePersistentCookieStore> sql_cookie_store_; - - DISALLOW_COPY_AND_ASSIGN(MojoPersistentCookieStore); -}; - -} // namespace mojo - -#endif // MOJO_SERVICES_NETWORK_MOJO_PERSISTENT_COOKIE_STORE_H_ diff --git a/mojo/services/network/network_context.cc b/mojo/services/network/network_context.cc index 6129ed4..2272238 100644 --- a/mojo/services/network/network_context.cc +++ b/mojo/services/network/network_context.cc @@ -19,7 +19,6 @@ #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "mojo/common/user_agent.h" -#include "mojo/services/network/mojo_persistent_cookie_store.h" #include "mojo/services/network/url_loader_impl.h" #include "net/cookies/cookie_monster.h" #include "net/dns/host_resolver.h" @@ -110,10 +109,8 @@ NetworkContext::NetworkContext( NetworkContext::NetworkContext( const base::FilePath& base_path, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, NetworkServiceDelegate* delegate) - : NetworkContext(MakeURLRequestContext(base_path, background_task_runner, - delegate)) { + : NetworkContext(MakeURLRequestContext(base_path, delegate)) { } NetworkContext::~NetworkContext() { @@ -148,7 +145,6 @@ size_t NetworkContext::GetURLLoaderCountForTesting() { // static scoped_ptr<net::URLRequestContext> NetworkContext::MakeURLRequestContext( const base::FilePath& base_path, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, NetworkServiceDelegate* delegate) { net::URLRequestContextBuilder builder; net::URLRequestContextBuilder::HttpNetworkSessionParams params; @@ -197,23 +193,6 @@ scoped_ptr<net::URLRequestContext> NetworkContext::MakeURLRequestContext( builder.EnableHttpCache(cache_params); builder.set_file_enabled(true); - if (background_task_runner) { - // TODO(erg): This only gets run on non-android system. Currently, any - // attempts from the network_service trying to access the filesystem break - // the apptests on android. (And only the apptests on android. Mandoline - // shell works fine on android, as does apptests on desktop.) - MojoPersistentCookieStore* cookie_store = - new MojoPersistentCookieStore( - delegate, - base::FilePath(FILE_PATH_LITERAL("Cookies")), - base::MessageLoop::current()->task_runner(), - background_task_runner, - false, // TODO(erg): Make RESTORED_SESSION_COOKIES configurable. - nullptr); - builder.SetCookieAndChannelIdStores( - new net::CookieMonster(cookie_store, nullptr), nullptr); - } - return builder.Build(); } diff --git a/mojo/services/network/network_context.h b/mojo/services/network/network_context.h index e01f0be..36da6d9 100644 --- a/mojo/services/network/network_context.h +++ b/mojo/services/network/network_context.h @@ -33,7 +33,6 @@ class NetworkContext { scoped_ptr<net::URLRequestContext> url_request_context); NetworkContext( const base::FilePath& base_path, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, NetworkServiceDelegate* delegate); ~NetworkContext(); @@ -52,7 +51,6 @@ class NetworkContext { static scoped_ptr<net::URLRequestContext> MakeURLRequestContext( const base::FilePath& base_path, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, NetworkServiceDelegate* delegate); class MojoNetLog; diff --git a/mojo/services/network/network_service_delegate.cc b/mojo/services/network/network_service_delegate.cc index 84334fc..b1920f7 100644 --- a/mojo/services/network/network_service_delegate.cc +++ b/mojo/services/network/network_service_delegate.cc @@ -22,55 +22,17 @@ #include "mojo/services/network/web_socket_factory_impl.h" #include "mojo/shell/public/cpp/connection.h" #include "mojo/util/capture_util.h" -#include "sql/mojo/mojo_vfs.h" namespace { -const char kSQLThreadName[] = "SQL_IO_Thread"; const char kUserDataDir[] = "user-data-dir"; -// SQL blocks on the filesystem service, so perform all SQL functions on a -// separate thread. -class SQLThread : public base::Thread { - public: - SQLThread(filesystem::DirectoryPtr directory) - : base::Thread(kSQLThreadName), - directory_info_(directory.PassInterface()) { - base::Thread::Options options; - options.message_pump_factory = - base::Bind(&mojo::common::MessagePumpMojo::Create); - StartWithOptions(options); - } - ~SQLThread() override { Stop(); } - - void Init() override { - filesystem::DirectoryPtr directory; - directory.Bind(std::move(directory_info_)); - vfs_.reset(new sql::ScopedMojoFilesystemVFS(std::move(directory))); - } - - void CleanUp() override { - vfs_.reset(); - } - - private: - // Our VFS which wraps sqlite so that we can reuse the current sqlite code. - scoped_ptr<sql::ScopedMojoFilesystemVFS> vfs_; - - // This member is used to safely pass data from one thread to another. It is - // set in the constructor and is consumed in Init(). - mojo::InterfacePtrInfo<filesystem::Directory> directory_info_; - - DISALLOW_COPY_AND_ASSIGN(SQLThread); -}; - } // namespace namespace mojo { NetworkServiceDelegate::NetworkServiceDelegate() - : shell_(nullptr), - binding_(this) { + : shell_(nullptr) { } NetworkServiceDelegate::~NetworkServiceDelegate() { @@ -90,24 +52,6 @@ void NetworkServiceDelegate::Initialize(Shell* shell, const std::string& url, uint32_t id) { shell_ = shell; -#if !defined(OS_ANDROID) - // TODO(erg): The following doesn't work when running the android - // apptests. It works in the mandoline shell (on desktop and on android), and - // in the apptests on desktop. However, on android, whenever we make the call - // to OpenFileSystem, the entire mojo system hangs to the point where writes - // to stderr that previously would have printed to our console aren't. The - // apptests are also fairly resistant to being run under gdb on android. - shell_->ConnectToInterface("mojo:filesystem", &files_); - - filesystem::FileError error = filesystem::FileError::FAILED; - filesystem::DirectoryPtr directory; - files_->OpenFileSystem("origin", GetProxy(&directory), - binding_.CreateInterfacePtrAndBind(), Capture(&error)); - files_.WaitForIncomingResponse(); - - io_worker_thread_.reset(new SQLThread(std::move(directory))); -#endif - // TODO(erg): Find everything else that writes to the filesystem and // transition it to proxying mojo:filesystem. We shouldn't have any path // calculation code here, but sadly need it until the transition is done. In @@ -123,11 +67,7 @@ void NetworkServiceDelegate::Initialize(Shell* shell, const std::string& url, base_path = base_path.Append(FILE_PATH_LITERAL("network_service")); } - scoped_refptr<base::SequencedTaskRunner> worker_thread; -#if !defined(OS_ANDROID) - worker_thread = io_worker_thread_->task_runner(); -#endif - context_.reset(new NetworkContext(base_path, worker_thread, this)); + context_.reset(new NetworkContext(base_path, this)); tracing_.Initialize(shell_, url); } @@ -141,13 +81,10 @@ bool NetworkServiceDelegate::AcceptConnection(Connection* connection) { } bool NetworkServiceDelegate::ShellConnectionLost() { - EnsureIOThreadShutdown(); return true; } void NetworkServiceDelegate::Quit() { - EnsureIOThreadShutdown(); - // Destroy the NetworkContext now as it requires MessageLoop::current() upon // destruction and it is the last moment we know for sure that it is // running. @@ -180,22 +117,4 @@ void NetworkServiceDelegate::Create( std::move(request)); } -void NetworkServiceDelegate::OnFileSystemShutdown() { - EnsureIOThreadShutdown(); -} - -void NetworkServiceDelegate::EnsureIOThreadShutdown() { - if (io_worker_thread_) { - // Broadcast to the entire system that we have to shut down anything - // depending on the worker thread. Either we're shutting down or the - // filesystem service is shutting down. - FOR_EACH_OBSERVER(NetworkServiceDelegateObserver, observers_, - OnIOWorkerThreadShutdown()); - - // Destroy the io worker thread here so that we can commit any pending - // cookies here. - io_worker_thread_.reset(); - } -} - } // namespace mojo diff --git a/mojo/services/network/network_service_delegate.h b/mojo/services/network/network_service_delegate.h index 367eb9a..7890c22 100644 --- a/mojo/services/network/network_service_delegate.h +++ b/mojo/services/network/network_service_delegate.h @@ -7,7 +7,6 @@ #include "base/observer_list.h" #include "base/threading/thread.h" -#include "components/filesystem/public/interfaces/file_system.mojom.h" #include "mojo/services/network/network_context.h" #include "mojo/services/network/public/interfaces/cookie_store.mojom.h" #include "mojo/services/network/public/interfaces/network_service.mojom.h" @@ -18,10 +17,6 @@ #include "mojo/shell/public/cpp/shell.h" #include "mojo/shell/public/cpp/shell_client.h" -namespace sql { -class ScopedMojoFilesystemVFS; -} - namespace mojo { class NetworkServiceDelegateObserver; @@ -29,8 +24,7 @@ class NetworkServiceDelegate : public ShellClient, public InterfaceFactory<NetworkService>, public InterfaceFactory<CookieStore>, public InterfaceFactory<WebSocketFactory>, - public InterfaceFactory<URLLoaderFactory>, - public filesystem::FileSystemClient { + public InterfaceFactory<URLLoaderFactory> { public: NetworkServiceDelegate(); ~NetworkServiceDelegate() override; @@ -39,10 +33,6 @@ class NetworkServiceDelegate : public ShellClient, void RemoveObserver(NetworkServiceDelegateObserver* observer); private: - // Notifies all of our observers of a Shuts down our IO thread. Safe to call - // multiple times. - void EnsureIOThreadShutdown(); - // mojo::ShellClient implementation. void Initialize(Shell* shell, const std::string& url, uint32_t id) override; bool AcceptConnection(Connection* connection) override; @@ -65,9 +55,6 @@ class NetworkServiceDelegate : public ShellClient, void Create(Connection* connection, InterfaceRequest<URLLoaderFactory> request) override; - // Overridden from FileSystemClient: - void OnFileSystemShutdown() override; - private: Shell* shell_; mojo::TracingImpl tracing_; @@ -75,15 +62,6 @@ class NetworkServiceDelegate : public ShellClient, // Observers that want notifications that our worker thread is going away. base::ObserverList<NetworkServiceDelegateObserver> observers_; - Binding<filesystem::FileSystemClient> binding_; - - // A worker thread that blocks for file IO. - scoped_ptr<base::Thread> io_worker_thread_; - - // Our connection to the filesystem service, which stores our cookies and - // other data. - filesystem::FileSystemPtr files_; - scoped_ptr<NetworkContext> context_; }; diff --git a/mojo/tools/data/apptests b/mojo/tools/data/apptests index 0a7f9d6..a67ff16 100644 --- a/mojo/tools/data/apptests +++ b/mojo/tools/data/apptests @@ -79,10 +79,6 @@ if config.target_os != config.OS_ANDROID: # }, # TODO(crbug.com/560626): Fix and enable mus_apptests on Android. mus_apptests, - { - 'test': 'mojo:sql_apptests', - 'type': 'gtest_isolated', - }, # TODO(sky): enable when works (http://crbug.com/577274 and likely # http://crbug.com/569367). # { diff --git a/sql/mojo/BUILD.gn b/sql/mojo/BUILD.gn deleted file mode 100644 index b7a3793..0000000 --- a/sql/mojo/BUILD.gn +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2015 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. - -import("//mojo/public/mojo_application.gni") - -source_set("mojo") { - sources = [ - "mojo_vfs.cc", - "mojo_vfs.h", - ] - - # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. - configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] - - defines = [ "SQL_IMPLEMENTATION" ] - - deps = [ - "//base", - "//base/third_party/dynamic_annotations", - "//components/filesystem/public/interfaces", - "//mojo/common", - "//mojo/platform_handle", - "//mojo/shell/public/cpp", - "//third_party/sqlite", - ] -} - -mojo_native_application("apptests") { - output_name = "sql_apptests" - - testonly = true - - # Instead of using the code in //sql/test/sql_test_base.h, we should use the - # mojo test base class. - defines = [ "MOJO_APPTEST_IMPL" ] - - sources = [ - "../connection_unittest.cc", - "../statement_unittest.cc", - "../test/paths.cc", - "../test/paths.h", - "../transaction_unittest.cc", - "sql_test_base.cc", - "sql_test_base.h", - "vfs_unittest.cc", - ] - - deps = [ - ":mojo", - "//base", - "//base/test:test_support", - "//components/filesystem/public/interfaces", - "//mojo/public/cpp/bindings", - "//mojo/shell/public/cpp:sources", - "//mojo/shell/public/cpp:test_support", - "//sql", - "//sql:redirection_header", - "//sql:test_support", - "//testing/gtest:gtest", - ] -} diff --git a/sql/mojo/DEPS b/sql/mojo/DEPS deleted file mode 100644 index 9dd7c02..0000000 --- a/sql/mojo/DEPS +++ /dev/null @@ -1,6 +0,0 @@ -include_rules = [ - "+components/filesystem", - "+mojo/shell", - "+mojo/public", - "+mojo/util", -] diff --git a/sql/mojo/mojo_vfs.cc b/sql/mojo/mojo_vfs.cc deleted file mode 100644 index bd962d0..0000000 --- a/sql/mojo/mojo_vfs.cc +++ /dev/null @@ -1,455 +0,0 @@ -// Copyright 2015 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 "sql/mojo/mojo_vfs.h" - -#include <stddef.h> -#include <stdint.h> -#include <utility> - -#include "base/logging.h" -#include "base/rand_util.h" -#include "base/strings/stringprintf.h" -#include "base/trace_event/trace_event.h" -#include "components/filesystem/public/interfaces/file.mojom.h" -#include "components/filesystem/public/interfaces/file_system.mojom.h" -#include "components/filesystem/public/interfaces/types.mojom.h" -#include "mojo/public/cpp/bindings/lib/template_util.h" -#include "mojo/util/capture_util.h" -#include "third_party/sqlite/sqlite3.h" - -using mojo::Capture; - -namespace sql { - -sqlite3_vfs* GetParentVFS(sqlite3_vfs* mojo_vfs) { - return static_cast<ScopedMojoFilesystemVFS*>(mojo_vfs->pAppData)->parent_; -} - -filesystem::DirectoryPtr& GetRootDirectory(sqlite3_vfs* mojo_vfs) { - return static_cast<ScopedMojoFilesystemVFS*>(mojo_vfs->pAppData)-> - root_directory_; -} - -namespace { - -// Implementation of the sqlite3 Mojo proxying vfs. -// -// This is a bunch of C callback objects which transparently proxy sqlite3's -// filesystem reads/writes over the mojo:filesystem service. The main -// entrypoint is sqlite3_mojovfs(), which proxies all the file open/delete/etc -// operations. mojo:filesystem has support for passing a raw file descriptor -// over the IPC barrier, and most of the implementation of sqlite3_io_methods -// is derived from the default sqlite3 unix VFS and operates on the raw file -// descriptors. - -const int kMaxPathName = 512; - -// A struct which extends the base sqlite3_file to also hold on to a file -// pipe. We reinterpret_cast our sqlite3_file structs to this struct -// instead. This is "safe" because this struct is really just a slab of -// malloced memory, of which we tell sqlite how large we want with szOsFile. -struct MojoVFSFile { - // The "vtable" of our sqlite3_file "subclass". - sqlite3_file base; - - // We keep an open pipe to the File object to keep it from cleaning itself - // up. - filesystem::FilePtr file_ptr; -}; - -filesystem::FilePtr& GetFSFile(sqlite3_file* vfs_file) { - return reinterpret_cast<MojoVFSFile*>(vfs_file)->file_ptr; -} - -int MojoVFSClose(sqlite3_file* file) { - DVLOG(1) << "MojoVFSClose(*)"; - TRACE_EVENT0("sql", "MojoVFSClose"); - using filesystem::FilePtr; - filesystem::FileError error = filesystem::FileError::FAILED; - // Must call File::Close explicitly instead of just deleting the file, since - // otherwise we wouldn't have an object to wait on. - GetFSFile(file)->Close(mojo::Capture(&error)); - GetFSFile(file).WaitForIncomingResponse(); - GetFSFile(file).~FilePtr(); - return SQLITE_OK; -} - -int MojoVFSRead(sqlite3_file* sql_file, - void* buffer, - int size, - sqlite3_int64 offset) { - DVLOG(1) << "MojoVFSRead (" << size << " @ " << offset << ")"; - TRACE_EVENT0("sql", "MojoVFSRead"); - filesystem::FileError error = filesystem::FileError::FAILED; - mojo::Array<uint8_t> mojo_data; - GetFSFile(sql_file)->Read(size, offset, filesystem::Whence::FROM_BEGIN, - Capture(&error, &mojo_data)); - GetFSFile(sql_file).WaitForIncomingResponse(); - - if (error != filesystem::FileError::OK) { - // TODO(erg): Better implementation here. - NOTIMPLEMENTED(); - return SQLITE_IOERR_READ; - } - - if (mojo_data.size()) - memcpy(buffer, &mojo_data.front(), mojo_data.size()); - if (mojo_data.size() == static_cast<size_t>(size)) - return SQLITE_OK; - - // We didn't read the entire buffer. Fill the rest of the buffer with zeros. - memset(reinterpret_cast<char*>(buffer) + mojo_data.size(), 0, - size - mojo_data.size()); - - return SQLITE_IOERR_SHORT_READ; -} - -int MojoVFSWrite(sqlite3_file* sql_file, - const void* buffer, - int size, - sqlite_int64 offset) { - DVLOG(1) << "MojoVFSWrite(*, " << size << ", " << offset << ")"; - TRACE_EVENT0("sql", "MojoVFSWrite"); - mojo::Array<uint8_t> mojo_data(size); - memcpy(&mojo_data.front(), buffer, size); - - filesystem::FileError error = filesystem::FileError::FAILED; - uint32_t num_bytes_written = 0; - GetFSFile(sql_file)->Write(std::move(mojo_data), offset, - filesystem::Whence::FROM_BEGIN, - Capture(&error, &num_bytes_written)); - GetFSFile(sql_file).WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) { - // TODO(erg): Better implementation here. - NOTIMPLEMENTED(); - return SQLITE_IOERR_WRITE; - } - if (num_bytes_written != static_cast<uint32_t>(size)) { - NOTIMPLEMENTED(); - return SQLITE_IOERR_WRITE; - } - - return SQLITE_OK; -} - -int MojoVFSTruncate(sqlite3_file* sql_file, sqlite_int64 size) { - DVLOG(1) << "MojoVFSTruncate(*, " << size << ")"; - TRACE_EVENT0("sql", "MojoVFSTruncate"); - filesystem::FileError error = filesystem::FileError::FAILED; - GetFSFile(sql_file)->Truncate(size, Capture(&error)); - GetFSFile(sql_file).WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) { - // TODO(erg): Better implementation here. - NOTIMPLEMENTED(); - return SQLITE_IOERR_TRUNCATE; - } - - return SQLITE_OK; -} - -int MojoVFSSync(sqlite3_file* sql_file, int flags) { - DVLOG(1) << "MojoVFSSync(*, " << flags << ")"; - TRACE_EVENT0("sql", "MojoVFSSync"); - filesystem::FileError error = filesystem::FileError::FAILED; - GetFSFile(sql_file)->Flush(Capture(&error)); - GetFSFile(sql_file).WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) { - // TODO(erg): Better implementation here. - NOTIMPLEMENTED(); - return SQLITE_IOERR_FSYNC; - } - - return SQLITE_OK; -} - -int MojoVFSFileSize(sqlite3_file* sql_file, sqlite_int64* size) { - DVLOG(1) << "MojoVFSFileSize(*)"; - TRACE_EVENT0("sql", "MojoVFSFileSize"); - - filesystem::FileError err = filesystem::FileError::FAILED; - filesystem::FileInformationPtr file_info; - GetFSFile(sql_file)->Stat(Capture(&err, &file_info)); - GetFSFile(sql_file).WaitForIncomingResponse(); - - if (err != filesystem::FileError::OK) { - // TODO(erg): Better implementation here. - NOTIMPLEMENTED(); - return SQLITE_IOERR_FSTAT; - } - - *size = file_info->size; - return SQLITE_OK; -} - -// TODO(erg): The current base::File interface isn't sufficient to handle -// sqlite's locking primitives, which are done on byte ranges in the file. (See -// "File Locking Notes" in sqlite3.c.) -int MojoVFSLock(sqlite3_file* pFile, int eLock) { - DVLOG(1) << "MojoVFSLock(*, " << eLock << ")"; - return SQLITE_OK; -} -int MojoVFSUnlock(sqlite3_file* pFile, int eLock) { - DVLOG(1) << "MojoVFSUnlock(*, " << eLock << ")"; - return SQLITE_OK; -} -int MojoVFSCheckReservedLock(sqlite3_file* pFile, int* pResOut) { - DVLOG(1) << "MojoVFSCheckReservedLock(*)"; - *pResOut = 0; - return SQLITE_OK; -} - -// TODO(erg): This is the minimal implementation to get a few tests passing; -// lots more needs to be done here. -int MojoVFSFileControl(sqlite3_file* pFile, int op, void* pArg) { - DVLOG(1) << "MojoVFSFileControl(*, " << op << ", *)"; - if (op == SQLITE_FCNTL_PRAGMA) { - // Returning NOTFOUND tells sqlite that we aren't doing any processing. - return SQLITE_NOTFOUND; - } - - return SQLITE_OK; -} - -int MojoVFSSectorSize(sqlite3_file* pFile) { - DVLOG(1) << "MojoVFSSectorSize(*)"; - // Use the default sector size. - return 0; -} - -int MojoVFSDeviceCharacteristics(sqlite3_file* pFile) { - DVLOG(1) << "MojoVFSDeviceCharacteristics(*)"; - // TODO(erg): Figure out what to return here. (This function is super spammy, - // so not leaving a NOTIMPLEMENTED().) - return 0; -} - -static sqlite3_io_methods mojo_vfs_io_methods = { - 1, /* iVersion */ - MojoVFSClose, /* xClose */ - MojoVFSRead, /* xRead */ - MojoVFSWrite, /* xWrite */ - MojoVFSTruncate, /* xTruncate */ - MojoVFSSync, /* xSync */ - MojoVFSFileSize, /* xFileSize */ - MojoVFSLock, /* xLock */ - MojoVFSUnlock, /* xUnlock */ - MojoVFSCheckReservedLock, /* xCheckReservedLock */ - MojoVFSFileControl, /* xFileControl */ - MojoVFSSectorSize, /* xSectorSize */ - MojoVFSDeviceCharacteristics, /* xDeviceCharacteristics */ -}; - -int MojoVFSOpen(sqlite3_vfs* mojo_vfs, - const char* name, - sqlite3_file* file, - int flags, - int* pOutFlags) { - DVLOG(1) << "MojoVFSOpen(*, " << name << ", *, " << flags << ")"; - TRACE_EVENT2("sql", "MojoVFSOpen", - "name", name, - "flags", flags); - int open_flags = 0; - if (flags & SQLITE_OPEN_EXCLUSIVE) { - DCHECK(flags & SQLITE_OPEN_CREATE); - open_flags = filesystem::kFlagCreate; - } else if (flags & SQLITE_OPEN_CREATE) { - DCHECK(flags & SQLITE_OPEN_READWRITE); - open_flags = filesystem::kFlagOpenAlways; - } else { - open_flags = filesystem::kFlagOpen; - } - open_flags |= filesystem::kFlagRead; - if (flags & SQLITE_OPEN_READWRITE) - open_flags |= filesystem::kFlagWrite; - if (flags & SQLITE_OPEN_DELETEONCLOSE) - open_flags |= filesystem::kDeleteOnClose; - - mojo::String mojo_name; - if (name) { - // Don't let callers open the pattern of our temporary databases. When we - // open with a null name and SQLITE_OPEN_DELETEONCLOSE, we unlink the - // database after we open it. If we create a database here, close it - // normally, and then open the same file through the other path, we could - // delete the database. - CHECK(strncmp("Temp_", name, 5) != 0); - mojo_name = name; - } else { - DCHECK(flags & SQLITE_OPEN_DELETEONCLOSE); - static int temp_number = 0; - mojo_name = base::StringPrintf("Temp_%d.db", temp_number++); - } - - // Grab the incoming file - filesystem::FilePtr file_ptr; - filesystem::FileError error = filesystem::FileError::FAILED; - GetRootDirectory(mojo_vfs)->OpenFile(mojo_name, GetProxy(&file_ptr), - open_flags, Capture(&error)); - GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) { - // TODO(erg): Translate more of the mojo error codes into sqlite error - // codes. - return SQLITE_CANTOPEN; - } - - // Set the method table so we can be closed (and run the manual dtor call to - // match the following placement news). - file->pMethods = &mojo_vfs_io_methods; - - // |file| is actually a malloced buffer of size szOsFile. This means that we - // need to manually use placement new to construct the C++ object which owns - // the pipe to our file. - new (&GetFSFile(file)) filesystem::FilePtr(std::move(file_ptr)); - - return SQLITE_OK; -} - -int MojoVFSDelete(sqlite3_vfs* mojo_vfs, const char* filename, int sync_dir) { - DVLOG(1) << "MojoVFSDelete(*, " << filename << ", " << sync_dir << ")"; - TRACE_EVENT2("sql", "MojoVFSDelete", - "name", filename, - "sync_dir", sync_dir); - // TODO(erg): The default windows sqlite VFS has retry code to work around - // antivirus software keeping files open. We'll probably have to do something - // like that in the far future if we ever support Windows. - filesystem::FileError error = filesystem::FileError::FAILED; - GetRootDirectory(mojo_vfs)->Delete(filename, 0, Capture(&error)); - GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); - - if (error == filesystem::FileError::OK && sync_dir) { - GetRootDirectory(mojo_vfs)->Flush(Capture(&error)); - GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); - } - - return error == filesystem::FileError::OK ? SQLITE_OK : SQLITE_IOERR_DELETE; -} - -int MojoVFSAccess(sqlite3_vfs* mojo_vfs, - const char* filename, - int flags, - int* result) { - DVLOG(1) << "MojoVFSAccess(*, " << filename << ", " << flags << ", *)"; - TRACE_EVENT2("sql", "MojoVFSAccess", - "name", filename, - "flags", flags); - filesystem::FileError error = filesystem::FileError::FAILED; - - if (flags == SQLITE_ACCESS_READWRITE || flags == SQLITE_ACCESS_READ) { - bool is_writable = false; - GetRootDirectory(mojo_vfs) - ->IsWritable(filename, Capture(&error, &is_writable)); - GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); - *result = is_writable; - return SQLITE_OK; - } - - if (flags == SQLITE_ACCESS_EXISTS) { - bool exists = false; - GetRootDirectory(mojo_vfs)->Exists(filename, Capture(&error, &exists)); - GetRootDirectory(mojo_vfs).WaitForIncomingResponse(); - *result = exists; - return SQLITE_OK; - } - - return SQLITE_IOERR; -} - -int MojoVFSFullPathname(sqlite3_vfs* mojo_vfs, - const char* relative_path, - int absolute_path_size, - char* absolute_path) { - // The sandboxed process doesn't need to know the absolute path of the file. - sqlite3_snprintf(absolute_path_size, absolute_path, "%s", relative_path); - return SQLITE_OK; -} - -// Don't let SQLite dynamically load things. (If we are using the -// mojo:filesystem proxying VFS, then it's highly likely that we are sandboxed -// and that any attempt to dlopen() a shared object is folly.) -void* MojoVFSDlOpen(sqlite3_vfs*, const char*) { - return 0; -} - -void MojoVFSDlError(sqlite3_vfs*, int buf_size, char* error_msg) { - sqlite3_snprintf(buf_size, error_msg, "Dynamic loading not supported"); -} - -void (*MojoVFSDlSym(sqlite3_vfs*, void*, const char*))(void) { - return 0; -} - -void MojoVFSDlClose(sqlite3_vfs*, void*) { - return; -} - -int MojoVFSRandomness(sqlite3_vfs* mojo_vfs, int size, char* out) { - base::RandBytes(out, size); - return size; -} - -// Proxy the rest of the calls down to the OS specific handler. -int MojoVFSSleep(sqlite3_vfs* mojo_vfs, int micro) { - return GetParentVFS(mojo_vfs)->xSleep(GetParentVFS(mojo_vfs), micro); -} - -int MojoVFSCurrentTime(sqlite3_vfs* mojo_vfs, double* time) { - return GetParentVFS(mojo_vfs)->xCurrentTime(GetParentVFS(mojo_vfs), time); -} - -int MojoVFSGetLastError(sqlite3_vfs* mojo_vfs, int a, char* b) { - return 0; -} - -int MojoVFSCurrentTimeInt64(sqlite3_vfs* mojo_vfs, sqlite3_int64* out) { - return GetParentVFS(mojo_vfs)->xCurrentTimeInt64(GetParentVFS(mojo_vfs), out); -} - -static sqlite3_vfs mojo_vfs = { - 1, /* iVersion */ - sizeof(MojoVFSFile), /* szOsFile */ - kMaxPathName, /* mxPathname */ - 0, /* pNext */ - "mojo", /* zName */ - 0, /* pAppData */ - MojoVFSOpen, /* xOpen */ - MojoVFSDelete, /* xDelete */ - MojoVFSAccess, /* xAccess */ - MojoVFSFullPathname, /* xFullPathname */ - MojoVFSDlOpen, /* xDlOpen */ - MojoVFSDlError, /* xDlError */ - MojoVFSDlSym, /* xDlSym */ - MojoVFSDlClose, /* xDlClose */ - MojoVFSRandomness, /* xRandomness */ - MojoVFSSleep, /* xSleep */ - MojoVFSCurrentTime, /* xCurrentTime */ - MojoVFSGetLastError, /* xGetLastError */ - MojoVFSCurrentTimeInt64 /* xCurrentTimeInt64 */ -}; - -} // namespace - -ScopedMojoFilesystemVFS::ScopedMojoFilesystemVFS( - filesystem::DirectoryPtr root_directory) - : parent_(sqlite3_vfs_find(NULL)), - root_directory_(std::move(root_directory)) { - CHECK(!mojo_vfs.pAppData); - mojo_vfs.pAppData = this; - mojo_vfs.mxPathname = parent_->mxPathname; - - CHECK(sqlite3_vfs_register(&mojo_vfs, 1) == SQLITE_OK); -} - -ScopedMojoFilesystemVFS::~ScopedMojoFilesystemVFS() { - CHECK(mojo_vfs.pAppData); - mojo_vfs.pAppData = nullptr; - - CHECK(sqlite3_vfs_register(parent_, 1) == SQLITE_OK); - CHECK(sqlite3_vfs_unregister(&mojo_vfs) == SQLITE_OK); -} - -filesystem::DirectoryPtr& ScopedMojoFilesystemVFS::GetDirectory() { - return root_directory_; -} - -} // namespace sql diff --git a/sql/mojo/mojo_vfs.h b/sql/mojo/mojo_vfs.h deleted file mode 100644 index dc83593..0000000 --- a/sql/mojo/mojo_vfs.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 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. - -#ifndef SQL_MOJO_MOJO_VFS_H_ -#define SQL_MOJO_MOJO_VFS_H_ - -#include "base/macros.h" -#include "components/filesystem/public/interfaces/directory.mojom.h" - -typedef struct sqlite3_vfs sqlite3_vfs; - -namespace sql { - -// Changes the default sqlite3 vfs to a vfs that uses proxies calls to the -// mojo:filesystem service. Instantiating this object transparently changes how -// the entire //sql/ subsystem works in the process of the caller; all paths -// are treated as relative to |directory|. -class ScopedMojoFilesystemVFS { - public: - explicit ScopedMojoFilesystemVFS(filesystem::DirectoryPtr directory); - ~ScopedMojoFilesystemVFS(); - - // Returns the directory of the current VFS. - filesystem::DirectoryPtr& GetDirectory(); - - private: - friend sqlite3_vfs* GetParentVFS(sqlite3_vfs* mojo_vfs); - friend filesystem::DirectoryPtr& GetRootDirectory(sqlite3_vfs* mojo_vfs); - - // The default vfs at the time MojoVFS was installed. We use the to pass - // through things like randomness requests and per-platform sleep calls. - sqlite3_vfs* parent_; - - // When we initialize the subsystem, we are given a filesystem::Directory - // object, which is the root directory of a mojo:filesystem. All access to - // various files are specified from this root directory. - filesystem::DirectoryPtr root_directory_; - - DISALLOW_COPY_AND_ASSIGN(ScopedMojoFilesystemVFS); -}; - -} // namespace sql - -#endif // SQL_MOJO_MOJO_VFS_H_ diff --git a/sql/mojo/sql_test_base.cc b/sql/mojo/sql_test_base.cc deleted file mode 100644 index baecd04..0000000 --- a/sql/mojo/sql_test_base.cc +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2015 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 "sql/mojo/sql_test_base.h" - -#include <stddef.h> -#include <stdint.h> -#include <utility> - -#include "mojo/shell/public/cpp/shell.h" -#include "mojo/util/capture_util.h" -#include "sql/mojo/mojo_vfs.h" -#include "sql/test/test_helpers.h" - -using mojo::Capture; - -namespace sql { - -SQLTestBase::SQLTestBase() - : binding_(this) { -} - -SQLTestBase::~SQLTestBase() { -} - -base::FilePath SQLTestBase::db_path() { - return base::FilePath(FILE_PATH_LITERAL("SQLTest.db")); -} - -sql::Connection& SQLTestBase::db() { - return db_; -} - -bool SQLTestBase::Reopen() { - db_.Close(); - return db_.Open(db_path()); -} - -bool SQLTestBase::GetPathExists(const base::FilePath& path) { - filesystem::FileError error = filesystem::FileError::FAILED; - bool exists = false; - vfs_->GetDirectory()->Exists(path.AsUTF8Unsafe(), Capture(&error, &exists)); - vfs_->GetDirectory().WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) - return false; - return exists; -} - -bool SQLTestBase::CorruptSizeInHeaderOfDB() { - // See http://www.sqlite.org/fileformat.html#database_header - const size_t kHeaderSize = 100; - - mojo::Array<uint8_t> header; - - filesystem::FileError error = filesystem::FileError::FAILED; - filesystem::FilePtr file_ptr; - vfs_->GetDirectory()->OpenFile( - mojo::String(db_path().AsUTF8Unsafe()), GetProxy(&file_ptr), - filesystem::kFlagRead | filesystem::kFlagWrite | - filesystem::kFlagOpenAlways, - Capture(&error)); - vfs_->GetDirectory().WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) - return false; - - file_ptr->Read(kHeaderSize, 0, filesystem::Whence::FROM_BEGIN, - Capture(&error, &header)); - file_ptr.WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) - return false; - - filesystem::FileInformationPtr info; - file_ptr->Stat(Capture(&error, &info)); - file_ptr.WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) - return false; - int64_t db_size = info->size; - - test::CorruptSizeInHeaderMemory(&header.front(), db_size); - - uint32_t num_bytes_written = 0; - file_ptr->Write(std::move(header), 0, filesystem::Whence::FROM_BEGIN, - Capture(&error, &num_bytes_written)); - file_ptr.WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) - return false; - if (num_bytes_written != kHeaderSize) - return false; - - return true; -} - -void SQLTestBase::WriteJunkToDatabase(WriteJunkType type) { - uint32_t flags = 0; - if (type == TYPE_OVERWRITE_AND_TRUNCATE) - flags = filesystem::kFlagWrite | filesystem::kFlagCreate; - else - flags = filesystem::kFlagWrite | filesystem::kFlagOpen; - - filesystem::FileError error = filesystem::FileError::FAILED; - filesystem::FilePtr file_ptr; - vfs_->GetDirectory()->OpenFile( - mojo::String(db_path().AsUTF8Unsafe()), GetProxy(&file_ptr), - flags, - Capture(&error)); - vfs_->GetDirectory().WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) - return; - - const char* kJunk = "Now is the winter of our discontent."; - mojo::Array<uint8_t> data(strlen(kJunk)); - memcpy(&data.front(), kJunk, strlen(kJunk)); - - uint32_t num_bytes_written = 0; - file_ptr->Write(std::move(data), 0, filesystem::Whence::FROM_BEGIN, - Capture(&error, &num_bytes_written)); - file_ptr.WaitForIncomingResponse(); -} - -void SQLTestBase::TruncateDatabase() { - filesystem::FileError error = filesystem::FileError::FAILED; - filesystem::FilePtr file_ptr; - vfs_->GetDirectory()->OpenFile( - mojo::String(db_path().AsUTF8Unsafe()), GetProxy(&file_ptr), - filesystem::kFlagWrite | filesystem::kFlagOpen, - Capture(&error)); - vfs_->GetDirectory().WaitForIncomingResponse(); - if (error != filesystem::FileError::OK) - return; - - file_ptr->Truncate(0, Capture(&error)); - file_ptr.WaitForIncomingResponse(); - ASSERT_EQ(filesystem::FileError::OK, error); -} - -void SQLTestBase::SetUp() { - ApplicationTestBase::SetUp(); - - shell()->ConnectToInterface("mojo:filesystem", &files_); - - filesystem::FileError error = filesystem::FileError::FAILED; - filesystem::DirectoryPtr directory; - files()->OpenFileSystem("temp", GetProxy(&directory), - binding_.CreateInterfacePtrAndBind(), - Capture(&error)); - ASSERT_TRUE(files().WaitForIncomingResponse()); - ASSERT_EQ(filesystem::FileError::OK, error); - - vfs_.reset(new ScopedMojoFilesystemVFS(std::move(directory))); - ASSERT_TRUE(db_.Open(db_path())); -} - -void SQLTestBase::TearDown() { - db_.Close(); - vfs_.reset(); - - ApplicationTestBase::TearDown(); -} - -void SQLTestBase::OnFileSystemShutdown() { -} - -} // namespace sql diff --git a/sql/mojo/sql_test_base.h b/sql/mojo/sql_test_base.h deleted file mode 100644 index 2fba5aa..0000000 --- a/sql/mojo/sql_test_base.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2015 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. - -#ifndef SQL_MOJO_SQL_TEST_BASE_H_ -#define SQL_MOJO_SQL_TEST_BASE_H_ - -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "components/filesystem/public/interfaces/file_system.mojom.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/shell/public/cpp/application_test_base.h" -#include "sql/connection.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sql { - -class Connection; -class ScopedMojoFilesystemVFS; - -// Base class for SQL tests. -// -// WARNING: We want to run the same gtest based unit test code both against -// chromium (which uses this implementation here), and the mojo code (which -// uses a different class named SQLTestBase). These two classes need to have -// the same interface because we compile time switch them based on a -// #define. We need to have two different implementations because the mojo -// version derives from mojo::test::ApplicationTestBase instead of -// testing::Test. -class SQLTestBase : public mojo::test::ApplicationTestBase, - public filesystem::FileSystemClient { - public: - SQLTestBase(); - ~SQLTestBase() override; - - enum WriteJunkType { - TYPE_OVERWRITE_AND_TRUNCATE, - TYPE_OVERWRITE - }; - - // Returns the path to the database. - base::FilePath db_path(); - - // Returns a connection to the database at db_path(). - sql::Connection& db(); - - // Closes the current connection to the database and reopens it. - bool Reopen(); - - // Proxying method around base::PathExists. - bool GetPathExists(const base::FilePath& path); - - // SQLite stores the database size in the header, and if the actual - // OS-derived size is smaller, the database is considered corrupt. - // [This case is actually a common form of corruption in the wild.] - // This helper sets the in-header size to one page larger than the - // actual file size. The resulting file will return SQLITE_CORRUPT - // for most operations unless PRAGMA writable_schema is turned ON. - // - // Returns false if any error occurs accessing the file. - bool CorruptSizeInHeaderOfDB(); - - // Writes junk to the start of the file. - void WriteJunkToDatabase(WriteJunkType type); - - // Sets the database file size to 0. - void TruncateDatabase(); - - // Overridden from testing::Test: - void SetUp() override; - void TearDown() override; - - // Overridden from FileSystemClient: - void OnFileSystemShutdown() override; - - protected: - filesystem::FileSystemPtr& files() { return files_; } - - private: - filesystem::FileSystemPtr files_; - - scoped_ptr<ScopedMojoFilesystemVFS> vfs_; - mojo::Binding<filesystem::FileSystemClient> binding_; - sql::Connection db_; - - DISALLOW_COPY_AND_ASSIGN(SQLTestBase); -}; - -} // namespace sql - -#endif // SQL_MOJO_SQL_TEST_BASE_H_ diff --git a/sql/mojo/vfs_unittest.cc b/sql/mojo/vfs_unittest.cc deleted file mode 100644 index 395f7ba..0000000 --- a/sql/mojo/vfs_unittest.cc +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright 2015 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 <stdint.h> -#include <memory> -#include <utility> - -#include "base/macros.h" -#include "components/filesystem/public/interfaces/file_system.mojom.h" -#include "mojo/shell/public/cpp/application_test_base.h" -#include "mojo/shell/public/cpp/shell.h" -#include "mojo/util/capture_util.h" -#include "sql/mojo/mojo_vfs.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/sqlite/sqlite3.h" - -namespace std { - -// This deleter lets us be safe with sqlite3 objects, which aren't really the -// structs, but slabs of new uint8_t[size]. -template <> -struct default_delete<sqlite3_file> { - inline void operator()(sqlite3_file* ptr) const { - // Why don't we call file->pMethods->xClose() here? Because it's not - // guaranteed to be valid. sqlite3_file "objects" can be in partially - // initialized states. - delete [] reinterpret_cast<uint8_t*>(ptr); - } -}; - -} // namespace std - -namespace sql { - -const char kFileName[] = "TestingDatabase.db"; - -class VFSTest : public mojo::test::ApplicationTestBase, - public filesystem::FileSystemClient { - public: - VFSTest() : binding_(this) {} - ~VFSTest() override {} - - sqlite3_vfs* vfs() { - return sqlite3_vfs_find(NULL); - } - - scoped_ptr<sqlite3_file> MakeFile() { - return scoped_ptr<sqlite3_file>(reinterpret_cast<sqlite3_file*>( - new uint8_t[vfs()->szOsFile])); - } - - void SetUp() override { - mojo::test::ApplicationTestBase::SetUp(); - - shell()->ConnectToInterface("mojo:filesystem", &files_); - - filesystem::FileError error = filesystem::FileError::FAILED; - filesystem::DirectoryPtr directory; - files_->OpenFileSystem("temp", GetProxy(&directory), - binding_.CreateInterfacePtrAndBind(), - mojo::Capture(&error)); - ASSERT_TRUE(files_.WaitForIncomingResponse()); - ASSERT_EQ(filesystem::FileError::OK, error); - - vfs_.reset(new ScopedMojoFilesystemVFS(std::move(directory))); - } - - void TearDown() override { - vfs_.reset(); - mojo::test::ApplicationTestBase::TearDown(); - } - - void OnFileSystemShutdown() override { - } - - private: - filesystem::FileSystemPtr files_; - scoped_ptr<ScopedMojoFilesystemVFS> vfs_; - mojo::Binding<filesystem::FileSystemClient> binding_; - - DISALLOW_COPY_AND_ASSIGN(VFSTest); -}; - -TEST_F(VFSTest, TestInstalled) { - EXPECT_EQ("mojo", std::string(vfs()->zName)); -} - -TEST_F(VFSTest, ExclusiveOpen) { - // Opening a non-existent file exclusively should work. - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen(vfs(), kFileName, file.get(), - SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_CREATE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - // Opening it a second time exclusively shouldn't. - scoped_ptr<sqlite3_file> file2(MakeFile()); - rc = vfs()->xOpen(vfs(), kFileName, file2.get(), - SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_CREATE, - &out_flags); - EXPECT_NE(SQLITE_OK, rc); - - file->pMethods->xClose(file.get()); -} - -TEST_F(VFSTest, NonexclusiveOpen) { - // Opening a non-existent file should work. - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen(vfs(), kFileName, file.get(), - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - // Opening it a second time should work. - scoped_ptr<sqlite3_file> file2(MakeFile()); - rc = vfs()->xOpen(vfs(), kFileName, file2.get(), - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - file->pMethods->xClose(file.get()); - file->pMethods->xClose(file2.get()); -} - -TEST_F(VFSTest, NullFilenameOpen) { - // Opening a file with a null filename should return a valid file object. - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen( - vfs(), nullptr, file.get(), - SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - file->pMethods->xClose(file.get()); -} - -TEST_F(VFSTest, DeleteOnClose) { - { - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen( - vfs(), kFileName, file.get(), - SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - file->pMethods->xClose(file.get()); - } - - // The file shouldn't exist now. - int result = 0; - vfs()->xAccess(vfs(), kFileName, SQLITE_ACCESS_EXISTS, &result); - EXPECT_FALSE(result); -} - -TEST_F(VFSTest, TestNonExistence) { - // We shouldn't have a file exist yet in a fresh directory. - int result = 0; - vfs()->xAccess(vfs(), kFileName, SQLITE_ACCESS_EXISTS, &result); - EXPECT_FALSE(result); -} - -TEST_F(VFSTest, TestExistence) { - { - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen(vfs(), kFileName, file.get(), - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - file->pMethods->xClose(file.get()); - } - - int result = 0; - vfs()->xAccess(vfs(), kFileName, SQLITE_ACCESS_EXISTS, &result); - EXPECT_TRUE(result); -} - -TEST_F(VFSTest, TestDelete) { - { - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen(vfs(), kFileName, file.get(), - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - file->pMethods->xClose(file.get()); - } - - int result = 0; - vfs()->xAccess(vfs(), kFileName, SQLITE_ACCESS_EXISTS, &result); - EXPECT_TRUE(result); - - vfs()->xDelete(vfs(), kFileName, 0); - - vfs()->xAccess(vfs(), kFileName, SQLITE_ACCESS_EXISTS, &result); - EXPECT_FALSE(result); -} - -TEST_F(VFSTest, TestWriteAndRead) { - const char kBuffer[] = "One Two Three Four Five Six Seven"; - const int kBufferSize = arraysize(kBuffer); - - { - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen(vfs(), kFileName, file.get(), - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - for (int i = 0; i < 10; ++i) { - rc = file->pMethods->xWrite(file.get(), kBuffer, kBufferSize, - i * kBufferSize); - EXPECT_EQ(SQLITE_OK, rc); - } - - file->pMethods->xClose(file.get()); - } - - // Expect that the size of the file is 10 * arraysize(kBuffer); - { - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen(vfs(), kFileName, file.get(), - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - sqlite_int64 size; - rc = file->pMethods->xFileSize(file.get(), &size); - EXPECT_EQ(SQLITE_OK, rc); - EXPECT_EQ(10 * kBufferSize, size); - - file->pMethods->xClose(file.get()); - } - - // We should be able to read things back. - { - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen(vfs(), kFileName, file.get(), - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - char data_buffer[kBufferSize]; - memset(data_buffer, '8', kBufferSize); - for (int i = 0; i < 10; ++i) { - rc = file->pMethods->xRead(file.get(), data_buffer, kBufferSize, - i * kBufferSize); - EXPECT_EQ(SQLITE_OK, rc); - EXPECT_TRUE(strncmp(kBuffer, &data_buffer[0], kBufferSize) == 0); - } - - file->pMethods->xClose(file.get()); - } -} - -TEST_F(VFSTest, PartialRead) { - const char kBuffer[] = "One Two Three Four Five Six Seven"; - const int kBufferSize = arraysize(kBuffer); - - // Write the data once. - { - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen(vfs(), kFileName, file.get(), - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - rc = file->pMethods->xWrite(file.get(), kBuffer, kBufferSize, 0); - EXPECT_EQ(SQLITE_OK, rc); - - file->pMethods->xClose(file.get()); - } - - // Now attempt to read kBufferSize + 5 from a file sized to kBufferSize. - { - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen(vfs(), kFileName, file.get(), - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - const char kBufferWithFiveNulls[] = - "One Two Three Four Five Six Seven\0\0\0\0\0"; - const int kBufferWithFiveNullsSize = arraysize(kBufferWithFiveNulls); - - char data_buffer[kBufferWithFiveNullsSize]; - memset(data_buffer, '8', kBufferWithFiveNullsSize); - rc = file->pMethods->xRead(file.get(), data_buffer, - kBufferWithFiveNullsSize, 0); - EXPECT_EQ(SQLITE_IOERR_SHORT_READ, rc); - - EXPECT_TRUE(strncmp(kBufferWithFiveNulls, &data_buffer[0], - kBufferWithFiveNullsSize) == 0); - - file->pMethods->xClose(file.get()); - } -} - -TEST_F(VFSTest, Truncate) { - const char kBuffer[] = "One Two Three Four Five Six Seven"; - const int kBufferSize = arraysize(kBuffer); - const int kCharsToThree = 13; - - scoped_ptr<sqlite3_file> file(MakeFile()); - int out_flags; - int rc = vfs()->xOpen(vfs(), kFileName, file.get(), - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - &out_flags); - EXPECT_EQ(SQLITE_OK, rc); - - rc = file->pMethods->xWrite(file.get(), kBuffer, kBufferSize, 0); - EXPECT_EQ(SQLITE_OK, rc); - - sqlite_int64 size; - rc = file->pMethods->xFileSize(file.get(), &size); - EXPECT_EQ(SQLITE_OK, rc); - EXPECT_EQ(kBufferSize, size); - - rc = file->pMethods->xTruncate(file.get(), kCharsToThree); - EXPECT_EQ(SQLITE_OK, rc); - - rc = file->pMethods->xFileSize(file.get(), &size); - EXPECT_EQ(SQLITE_OK, rc); - EXPECT_EQ(kCharsToThree, size); - - file->pMethods->xClose(file.get()); -} - -} // namespace sql |