summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins
diff options
context:
space:
mode:
authorbrettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-09 22:59:53 +0000
committerbrettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-09 22:59:53 +0000
commit5469a777480a8c4a7acc1f60f6f3d92190e030f4 (patch)
treed4d8e21163fcb21a4d6c7881b33c4f7110a61eb7 /webkit/glue/plugins
parent682e24154f1a22b2de8d4ef4a3042a9b76c147f7 (diff)
downloadchromium_src-5469a777480a8c4a7acc1f60f6f3d92190e030f4.zip
chromium_src-5469a777480a8c4a7acc1f60f6f3d92190e030f4.tar.gz
chromium_src-5469a777480a8c4a7acc1f60f6f3d92190e030f4.tar.bz2
Make it possible to write simple unit tests for the pepper implementation. This adds a mock plugin delegate that does nothing, and a helper unit test base class that sets up a dummy plugin instance and module for use in writing tests.
This implements some basic tests on the resource tracker and fixes a bug I found! TEST=this is BUG=none Review URL: http://codereview.chromium.org/5685002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68781 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r--webkit/glue/plugins/mock_plugin_delegate.cc187
-rw-r--r--webkit/glue/plugins/mock_plugin_delegate.h98
-rw-r--r--webkit/glue/plugins/mock_resource.h25
-rw-r--r--webkit/glue/plugins/pepper_plugin_delegate.h2
-rw-r--r--webkit/glue/plugins/pepper_resource.h1
-rw-r--r--webkit/glue/plugins/pepper_resource_tracker.cc19
-rw-r--r--webkit/glue/plugins/pepper_resource_tracker.h12
-rw-r--r--webkit/glue/plugins/ppapi_unittest.cc112
-rw-r--r--webkit/glue/plugins/ppapi_unittest.h46
-rw-r--r--webkit/glue/plugins/resource_tracker_unittest.cc116
10 files changed, 616 insertions, 2 deletions
diff --git a/webkit/glue/plugins/mock_plugin_delegate.cc b/webkit/glue/plugins/mock_plugin_delegate.cc
new file mode 100644
index 0000000..1d2be93
--- /dev/null
+++ b/webkit/glue/plugins/mock_plugin_delegate.cc
@@ -0,0 +1,187 @@
+// 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 "webkit/glue/plugins/mock_plugin_delegate.h"
+
+#include "base/message_loop_proxy.h"
+
+namespace pepper {
+
+MockPluginDelegate::MockPluginDelegate() {
+}
+
+MockPluginDelegate::~MockPluginDelegate() {
+}
+
+void MockPluginDelegate::InstanceCreated(pepper::PluginInstance* instance) {
+}
+
+void MockPluginDelegate::InstanceDeleted(pepper::PluginInstance* instance) {
+}
+
+MockPluginDelegate::PlatformImage2D* MockPluginDelegate::CreateImage2D(
+ int width,
+ int height) {
+ return NULL;
+}
+
+MockPluginDelegate::PlatformContext3D* MockPluginDelegate::CreateContext3D() {
+ return NULL;
+}
+
+MockPluginDelegate::PlatformVideoDecoder*
+MockPluginDelegate::CreateVideoDecoder(
+ const PP_VideoDecoderConfig_Dev& decoder_config) {
+ return NULL;
+}
+
+MockPluginDelegate::PlatformAudio* MockPluginDelegate::CreateAudio(
+ uint32_t sample_rate,
+ uint32_t sample_count,
+ PlatformAudio::Client* client) {
+ return NULL;
+}
+
+void MockPluginDelegate::NumberOfFindResultsChanged(int identifier,
+ int total,
+ bool final_result) {
+}
+
+void MockPluginDelegate::SelectedFindResultChanged(int identifier, int index) {
+}
+
+bool MockPluginDelegate::RunFileChooser(
+ const WebKit::WebFileChooserParams& params,
+ WebKit::WebFileChooserCompletion* chooser_completion) {
+ return false;
+}
+
+bool MockPluginDelegate::AsyncOpenFile(const FilePath& path,
+ int flags,
+ AsyncOpenFileCallback* callback) {
+ return false;
+}
+
+bool MockPluginDelegate::OpenFileSystem(
+ const GURL& url,
+ fileapi::FileSystemType type,
+ long long size,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ return false;
+}
+
+bool MockPluginDelegate::MakeDirectory(
+ const FilePath& path,
+ bool recursive,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ return false;
+}
+
+bool MockPluginDelegate::Query(
+ const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ return false;
+}
+
+bool MockPluginDelegate::Touch(
+ const FilePath& path,
+ const base::Time& last_access_time,
+ const base::Time& last_modified_time,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ return false;
+}
+
+bool MockPluginDelegate::Delete(
+ const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ return false;
+}
+
+bool MockPluginDelegate::Rename(
+ const FilePath& file_path,
+ const FilePath& new_file_path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ return false;
+}
+
+bool MockPluginDelegate::ReadDirectory(
+ const FilePath& directory_path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ return false;
+}
+
+base::PlatformFileError MockPluginDelegate::OpenModuleLocalFile(
+ const std::string& module_name,
+ const FilePath& path,
+ int flags,
+ base::PlatformFile* file) {
+ return base::PLATFORM_FILE_ERROR_FAILED;
+}
+
+base::PlatformFileError MockPluginDelegate::RenameModuleLocalFile(
+ const std::string& module_name,
+ const FilePath& path_from,
+ const FilePath& path_to) {
+ return base::PLATFORM_FILE_ERROR_FAILED;
+}
+
+base::PlatformFileError MockPluginDelegate::DeleteModuleLocalFileOrDir(
+ const std::string& module_name,
+ const FilePath& path,
+ bool recursive) {
+ return base::PLATFORM_FILE_ERROR_FAILED;
+}
+
+base::PlatformFileError MockPluginDelegate::CreateModuleLocalDir(
+ const std::string& module_name,
+ const FilePath& path) {
+ return base::PLATFORM_FILE_ERROR_FAILED;
+}
+
+base::PlatformFileError MockPluginDelegate::QueryModuleLocalFile(
+ const std::string& module_name,
+ const FilePath& path,
+ base::PlatformFileInfo* info) {
+ return base::PLATFORM_FILE_ERROR_FAILED;
+}
+
+base::PlatformFileError MockPluginDelegate::GetModuleLocalDirContents(
+ const std::string& module_name,
+ const FilePath& path,
+ PepperDirContents* contents) {
+ return base::PLATFORM_FILE_ERROR_FAILED;
+}
+
+scoped_refptr<base::MessageLoopProxy>
+MockPluginDelegate::GetFileThreadMessageLoopProxy() {
+ return scoped_refptr<base::MessageLoopProxy>();
+}
+
+FullscreenContainer* MockPluginDelegate::CreateFullscreenContainer(
+ PluginInstance* instance) {
+ return NULL;
+}
+
+std::string MockPluginDelegate::GetDefaultEncoding() {
+ return "iso-8859-1";
+}
+
+void MockPluginDelegate::ZoomLimitsChanged(double minimum_factor,
+ double maximum_factor) {
+}
+
+std::string MockPluginDelegate::ResolveProxy(const GURL& url) {
+ return std::string();
+}
+
+void MockPluginDelegate::DidStartLoading() {
+}
+
+void MockPluginDelegate::DidStopLoading() {
+}
+
+void MockPluginDelegate::SetContentRestriction(int restrictions) {
+}
+
+} // namespace pepper
diff --git a/webkit/glue/plugins/mock_plugin_delegate.h b/webkit/glue/plugins/mock_plugin_delegate.h
new file mode 100644
index 0000000..41c477e
--- /dev/null
+++ b/webkit/glue/plugins/mock_plugin_delegate.h
@@ -0,0 +1,98 @@
+// 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.
+
+#ifndef WEBKIT_GLUE_PLUGINS_MOCK_PLUGIN_DELEGATE_H_
+#define WEBKIT_GLUE_PLUGINS_MOCK_PLUGIN_DELEGATE_H_
+
+#include "webkit/glue/plugins/pepper_plugin_delegate.h"
+
+namespace pepper {
+
+class MockPluginDelegate : public PluginDelegate {
+ public:
+ MockPluginDelegate();
+ ~MockPluginDelegate();
+
+ virtual void InstanceCreated(pepper::PluginInstance* instance);
+ virtual void InstanceDeleted(pepper::PluginInstance* instance);
+ virtual PlatformImage2D* CreateImage2D(int width, int height);
+ virtual PlatformContext3D* CreateContext3D();
+ virtual PlatformVideoDecoder* CreateVideoDecoder(
+ const PP_VideoDecoderConfig_Dev& decoder_config);
+ virtual PlatformAudio* CreateAudio(uint32_t sample_rate,
+ uint32_t sample_count,
+ PlatformAudio::Client* client);
+ virtual void NumberOfFindResultsChanged(int identifier,
+ int total,
+ bool final_result);
+ virtual void SelectedFindResultChanged(int identifier, int index);
+ virtual bool RunFileChooser(
+ const WebKit::WebFileChooserParams& params,
+ WebKit::WebFileChooserCompletion* chooser_completion);
+ virtual bool AsyncOpenFile(const FilePath& path,
+ int flags,
+ AsyncOpenFileCallback* callback);
+ virtual bool OpenFileSystem(
+ const GURL& url,
+ fileapi::FileSystemType type,
+ long long size,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ virtual bool MakeDirectory(
+ const FilePath& path,
+ bool recursive,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ virtual bool Query(const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ virtual bool Touch(const FilePath& path,
+ const base::Time& last_access_time,
+ const base::Time& last_modified_time,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ virtual bool Delete(const FilePath& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ virtual bool Rename(const FilePath& file_path,
+ const FilePath& new_file_path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ virtual bool ReadDirectory(
+ const FilePath& directory_path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ virtual base::PlatformFileError OpenModuleLocalFile(
+ const std::string& module_name,
+ const FilePath& path,
+ int flags,
+ base::PlatformFile* file);
+ virtual base::PlatformFileError RenameModuleLocalFile(
+ const std::string& module_name,
+ const FilePath& path_from,
+ const FilePath& path_to);
+ virtual base::PlatformFileError DeleteModuleLocalFileOrDir(
+ const std::string& module_name,
+ const FilePath& path,
+ bool recursive);
+ virtual base::PlatformFileError CreateModuleLocalDir(
+ const std::string& module_name,
+ const FilePath& path);
+ virtual base::PlatformFileError QueryModuleLocalFile(
+ const std::string& module_name,
+ const FilePath& path,
+ base::PlatformFileInfo* info);
+ virtual base::PlatformFileError GetModuleLocalDirContents(
+ const std::string& module_name,
+ const FilePath& path,
+ PepperDirContents* contents);
+ virtual scoped_refptr<base::MessageLoopProxy>
+ GetFileThreadMessageLoopProxy();
+ virtual FullscreenContainer* CreateFullscreenContainer(
+ PluginInstance* instance);
+ virtual std::string GetDefaultEncoding();
+ virtual void ZoomLimitsChanged(double minimum_factor,
+ double maximum_factor);
+ virtual std::string ResolveProxy(const GURL& url);
+ virtual void DidStartLoading();
+ virtual void DidStopLoading();
+ virtual void SetContentRestriction(int restrictions);
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_MOCK_PLUGIN_DELEGATE_H_
diff --git a/webkit/glue/plugins/mock_resource.h b/webkit/glue/plugins/mock_resource.h
new file mode 100644
index 0000000..2b4cb48a
--- /dev/null
+++ b/webkit/glue/plugins/mock_resource.h
@@ -0,0 +1,25 @@
+// 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.
+
+#ifndef WEBKIT_GLUE_PLUGINS_MOCK_RESOURCE_H_
+#define WEBKIT_GLUE_PLUGINS_MOCK_RESOURCE_H_
+
+#include "webkit/glue/plugins/pepper_resource.h"
+
+namespace pepper {
+
+// Tests can derive from this to implement special test-specific resources.
+// It's assumed that a test will only need one mock resource, so it can
+// static_cast to get its own implementation.
+class MockResource : public Resource {
+ public:
+ MockResource(PluginModule* module) : Resource(module) {}
+ ~MockResource() {}
+
+ virtual MockResource* AsMockResource() { return this; }
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_MOCK_RESOURCE_H_
diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h
index 57b66ba..37a25d3 100644
--- a/webkit/glue/plugins/pepper_plugin_delegate.h
+++ b/webkit/glue/plugins/pepper_plugin_delegate.h
@@ -281,7 +281,7 @@ class PluginDelegate {
// Returns a MessageLoopProxy instance associated with the message loop
// of the file thread in this renderer.
virtual scoped_refptr<base::MessageLoopProxy>
- GetFileThreadMessageLoopProxy() = 0;
+ GetFileThreadMessageLoopProxy() = 0;
// Create a fullscreen container for a plugin instance. This effectively
// switches the plugin to fullscreen.
diff --git a/webkit/glue/plugins/pepper_resource.h b/webkit/glue/plugins/pepper_resource.h
index 3c4ebca..551b89d 100644
--- a/webkit/glue/plugins/pepper_resource.h
+++ b/webkit/glue/plugins/pepper_resource.h
@@ -26,6 +26,7 @@ namespace pepper {
F(Graphics2D) \
F(Graphics3D) \
F(ImageData) \
+ F(MockResource) \
F(ObjectVar) \
F(PluginModule) \
F(PrivateFontFile) \
diff --git a/webkit/glue/plugins/pepper_resource_tracker.cc b/webkit/glue/plugins/pepper_resource_tracker.cc
index f9d24ed..997ef63 100644
--- a/webkit/glue/plugins/pepper_resource_tracker.cc
+++ b/webkit/glue/plugins/pepper_resource_tracker.cc
@@ -22,6 +22,9 @@ scoped_refptr<Resource> ResourceTracker::GetResource(PP_Resource res) const {
return result->second.first;
}
+// static
+ResourceTracker* ResourceTracker::singleton_override_ = NULL;
+
ResourceTracker::ResourceTracker()
: last_id_(0) {
}
@@ -31,6 +34,8 @@ ResourceTracker::~ResourceTracker() {
// static
ResourceTracker* ResourceTracker::Get() {
+ if (singleton_override_)
+ return singleton_override_;
return Singleton<ResourceTracker>::get();
}
@@ -73,7 +78,7 @@ bool ResourceTracker::UnrefResource(PP_Resource res) {
void ResourceTracker::ForceDeletePluginResourceRefs(PP_Resource res) {
ResourceMap::iterator i = live_resources_.find(res);
- if (i != live_resources_.end())
+ if (i == live_resources_.end())
return; // Nothing to do.
i->second.second = 0;
@@ -169,4 +174,16 @@ PluginModule* ResourceTracker::GetModule(PP_Module module) {
return found->second;
}
+// static
+void ResourceTracker::SetSingletonOverride(ResourceTracker* tracker) {
+ DCHECK(!singleton_override_);
+ singleton_override_ = tracker;
+}
+
+// static
+void ResourceTracker::ClearSingletonOverride() {
+ DCHECK(singleton_override_);
+ singleton_override_ = NULL;
+}
+
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_resource_tracker.h b/webkit/glue/plugins/pepper_resource_tracker.h
index 8e294855..09ff976 100644
--- a/webkit/glue/plugins/pepper_resource_tracker.h
+++ b/webkit/glue/plugins/pepper_resource_tracker.h
@@ -9,6 +9,7 @@
#include <utility>
#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
#include "base/hash_tables.h"
#include "base/ref_counted.h"
#include "base/singleton.h"
@@ -21,6 +22,7 @@ namespace pepper {
class PluginInstance;
class PluginModule;
class Resource;
+class ResourceTrackerTest;
// This class maintains a global list of all live pepper resources. It allows
// us to check resource ID validity and to map them to a specific module.
@@ -91,6 +93,7 @@ class ResourceTracker {
private:
friend struct DefaultSingletonTraits<ResourceTracker>;
friend class Resource;
+ friend class ResourceTrackerTest;
// Prohibit creation other then by the Singleton class.
ResourceTracker();
@@ -101,6 +104,15 @@ class ResourceTracker {
// Resource class.
PP_Resource AddResource(Resource* resource);
+ // Overrides the singleton object. This is used for tests which want to
+ // specify their own tracker (otherwise, you can get cross-talk between
+ // tests since the data will live into the subsequent tests).
+ static void SetSingletonOverride(ResourceTracker* tracker);
+ static void ClearSingletonOverride();
+
+ // See SetSingletonOverride above.
+ static ResourceTracker* singleton_override_;
+
// Last assigned resource ID.
PP_Resource last_id_;
diff --git a/webkit/glue/plugins/ppapi_unittest.cc b/webkit/glue/plugins/ppapi_unittest.cc
new file mode 100644
index 0000000..b142fe9
--- /dev/null
+++ b/webkit/glue/plugins/ppapi_unittest.cc
@@ -0,0 +1,112 @@
+// 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 "webkit/glue/plugins/ppapi_unittest.h"
+
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/ppp_instance.h"
+#include "webkit/glue/plugins/mock_plugin_delegate.h"
+#include "webkit/glue/plugins/pepper_plugin_instance.h"
+#include "webkit/glue/plugins/pepper_plugin_module.h"
+
+namespace pepper {
+
+namespace {
+
+PpapiUnittest* current_unittest = NULL;
+
+const void* MockGetInterface(const char* interface_name) {
+ return current_unittest->GetMockInterface(interface_name);
+}
+
+int MockInitializeModule(PP_Module, PPB_GetInterface) {
+ return PP_OK;
+}
+
+// PepperPluginDelegate -------------------------------------
+
+// PPP_Instance implementation ------------------------------------------------
+
+PP_Bool Instance_DidCreate(PP_Instance pp_instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]) {
+ return PP_TRUE;
+}
+
+void Instance_DidDestroy(PP_Instance instance) {
+}
+
+void Instance_DidChangeView(PP_Instance pp_instance,
+ const PP_Rect* position,
+ const PP_Rect* clip) {
+}
+
+void Instance_DidChangeFocus(PP_Instance pp_instance, PP_Bool has_focus) {
+}
+
+PP_Bool Instance_HandleInputEvent(PP_Instance pp_instance,
+ const PP_InputEvent* event) {
+ return PP_FALSE;
+}
+
+PP_Bool Instance_HandleDocumentLoad(PP_Instance pp_instance,
+ PP_Resource pp_url_loader) {
+ return PP_FALSE;
+}
+
+PP_Var Instance_GetInstanceObject(PP_Instance pp_instance) {
+ return PP_MakeUndefined();
+}
+
+static PPP_Instance mock_instance_interface = {
+ &Instance_DidCreate,
+ &Instance_DidDestroy,
+ &Instance_DidChangeView,
+ &Instance_DidChangeFocus,
+ &Instance_HandleInputEvent,
+ &Instance_HandleDocumentLoad,
+ &Instance_GetInstanceObject
+};
+
+} // namespace
+
+// PpapiUnittest --------------------------------------------------------------
+
+PpapiUnittest::PpapiUnittest() {
+ DCHECK(!current_unittest);
+ current_unittest = this;
+}
+
+PpapiUnittest::~PpapiUnittest() {
+ DCHECK(current_unittest == this);
+ current_unittest = NULL;
+}
+
+void PpapiUnittest::SetUp() {
+ delegate_.reset(new MockPluginDelegate);
+
+ // Initialize the mock module.
+ module_ = new PluginModule;
+ PluginModule::EntryPoints entry_points;
+ entry_points.get_interface = &MockGetInterface;
+ entry_points.initialize_module = &MockInitializeModule;
+ ASSERT_TRUE(module_->InitAsInternalPlugin(entry_points));
+
+ // Initialize the mock instance.
+ instance_ = new PluginInstance(delegate_.get(), module(),
+ static_cast<const PPP_Instance*>(
+ GetMockInterface(PPP_INSTANCE_INTERFACE)));
+}
+
+void PpapiUnittest::TearDown() {
+}
+
+const void* PpapiUnittest::GetMockInterface(const char* interface_name) const {
+ if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
+ return &mock_instance_interface;
+ return NULL;
+}
+
+} // namespace pepper \ No newline at end of file
diff --git a/webkit/glue/plugins/ppapi_unittest.h b/webkit/glue/plugins/ppapi_unittest.h
new file mode 100644
index 0000000..0e0c60f
--- /dev/null
+++ b/webkit/glue/plugins/ppapi_unittest.h
@@ -0,0 +1,46 @@
+// 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.
+
+#ifndef WEBKIT_GLUE_PLUGINS_PPAPI_UNITTEST_H_
+#define WEBKIT_GLUE_PLUGINS_PPAPI_UNITTEST_H_
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace pepper {
+
+class MockPluginDelegate;
+class PluginInstance;
+class PluginModule;
+
+class PpapiUnittest : public testing::Test {
+ public:
+ PpapiUnittest();
+ virtual ~PpapiUnittest();
+
+ virtual void SetUp();
+ virtual void TearDown();
+
+ PluginModule* module() const { return module_.get(); }
+ PluginInstance* instance() const { return instance_.get(); }
+
+ // Provides access to the interfaces implemented by the test. The default one
+ // implements PPP_INSTANCE.
+ virtual const void* GetMockInterface(const char* interface_name) const;
+
+ private:
+ scoped_ptr<MockPluginDelegate> delegate_;
+
+ // Note: module must be declared first since we want it to get destroyed last.
+ scoped_refptr<PluginModule> module_;
+ scoped_refptr<PluginInstance> instance_;
+
+ DISALLOW_COPY_AND_ASSIGN(PpapiUnittest);
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PPAPI_UNITTEST_H_
diff --git a/webkit/glue/plugins/resource_tracker_unittest.cc b/webkit/glue/plugins/resource_tracker_unittest.cc
new file mode 100644
index 0000000..3b9fce3
--- /dev/null
+++ b/webkit/glue/plugins/resource_tracker_unittest.cc
@@ -0,0 +1,116 @@
+// 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 "webkit/glue/plugins/ppapi_unittest.h"
+
+#include "webkit/glue/plugins/pepper_resource_tracker.h"
+#include "webkit/glue/plugins/mock_resource.h"
+
+namespace pepper {
+
+namespace {
+
+class TrackedMockResource : public MockResource {
+ public:
+ static int tracked_objects_alive;
+
+ TrackedMockResource(PluginModule* module) : MockResource(module) {
+ tracked_objects_alive++;
+ }
+ ~TrackedMockResource() {
+ tracked_objects_alive--;
+ }
+};
+
+int TrackedMockResource::tracked_objects_alive = 0;
+
+} // namespace
+
+class ResourceTrackerTest : public PpapiUnittest {
+ public:
+ ResourceTrackerTest() {
+ }
+
+ virtual void SetUp() {
+ PpapiUnittest::SetUp();
+ ResourceTracker::SetSingletonOverride(&tracker_);
+ }
+ virtual void TearDown() {
+ ResourceTracker::ClearSingletonOverride();
+ PpapiUnittest::TearDown();
+ }
+
+ ResourceTracker& tracker() { return tracker_; }
+
+ private:
+ ResourceTracker tracker_;
+};
+
+TEST_F(ResourceTrackerTest, Ref) {
+ ASSERT_EQ(0, TrackedMockResource::tracked_objects_alive);
+ EXPECT_EQ(0u, tracker().GetLiveObjectsForModule(module()));
+ {
+ scoped_refptr<TrackedMockResource> new_resource(
+ new TrackedMockResource(module()));
+ ASSERT_EQ(1, TrackedMockResource::tracked_objects_alive);
+
+ // Since we haven't gotten a PP_Resource, it's not associated with the
+ // module.
+ EXPECT_EQ(0u, tracker().GetLiveObjectsForModule(module()));
+ }
+ ASSERT_EQ(0, TrackedMockResource::tracked_objects_alive);
+
+ // Make a new resource and get it as a PP_Resource.
+ PP_Resource resource_id = 0;
+ {
+ scoped_refptr<TrackedMockResource> new_resource(
+ new TrackedMockResource(module()));
+ ASSERT_EQ(1, TrackedMockResource::tracked_objects_alive);
+ resource_id = new_resource->GetReference();
+ EXPECT_EQ(1u, tracker().GetLiveObjectsForModule(module()));
+
+ // Resource IDs should be consistent.
+ PP_Resource resource_id_2 = new_resource->GetReference();
+ ASSERT_EQ(resource_id, resource_id_2);
+ }
+
+ // This time it should not have been deleted since the PP_Resource carries
+ // a ref.
+ ASSERT_EQ(1, TrackedMockResource::tracked_objects_alive);
+
+ // Now we have two refs, derefing twice should delete the object.
+ tracker().UnrefResource(resource_id);
+ ASSERT_EQ(1, TrackedMockResource::tracked_objects_alive);
+ tracker().UnrefResource(resource_id);
+ ASSERT_EQ(0, TrackedMockResource::tracked_objects_alive);
+}
+
+TEST_F(ResourceTrackerTest, ForceDelete) {
+ // Make two resources.
+ scoped_refptr<TrackedMockResource> resource1(
+ new TrackedMockResource(module()));
+ PP_Resource pp_resource1 = resource1->GetReference();
+ scoped_refptr<TrackedMockResource> resource2(
+ new TrackedMockResource(module()));
+ PP_Resource pp_resource2 = resource2->GetReference();
+
+ // Keep an "internal" ref to only the first (the PP_Resource also holds a
+ // ref to each resource on behalf of the plugin).
+ resource2 = NULL;
+
+ ASSERT_EQ(2, TrackedMockResource::tracked_objects_alive);
+ EXPECT_EQ(2u, tracker().GetLiveObjectsForModule(module()));
+
+ // Force delete both refs.
+ tracker().ForceDeletePluginResourceRefs(pp_resource1);
+ tracker().ForceDeletePluginResourceRefs(pp_resource2);
+ EXPECT_EQ(0u, tracker().GetLiveObjectsForModule(module()));
+
+ // The resource we have a scoped_refptr to should still be alive.
+ ASSERT_EQ(1, TrackedMockResource::tracked_objects_alive);
+ resource1 = NULL;
+ ASSERT_EQ(0, TrackedMockResource::tracked_objects_alive);
+}
+
+} // namespace pepper