diff options
author | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-09 22:59:53 +0000 |
---|---|---|
committer | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-09 22:59:53 +0000 |
commit | 5469a777480a8c4a7acc1f60f6f3d92190e030f4 (patch) | |
tree | d4d8e21163fcb21a4d6c7881b33c4f7110a61eb7 /webkit/glue/plugins | |
parent | 682e24154f1a22b2de8d4ef4a3042a9b76c147f7 (diff) | |
download | chromium_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.cc | 187 | ||||
-rw-r--r-- | webkit/glue/plugins/mock_plugin_delegate.h | 98 | ||||
-rw-r--r-- | webkit/glue/plugins/mock_resource.h | 25 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_delegate.h | 2 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_resource.h | 1 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_resource_tracker.cc | 19 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_resource_tracker.h | 12 | ||||
-rw-r--r-- | webkit/glue/plugins/ppapi_unittest.cc | 112 | ||||
-rw-r--r-- | webkit/glue/plugins/ppapi_unittest.h | 46 | ||||
-rw-r--r-- | webkit/glue/plugins/resource_tracker_unittest.cc | 116 |
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 |