diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-23 20:01:21 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-23 20:01:21 +0000 |
commit | 725c05196e3a8bcfc9b0114ff920252c67d54dd3 (patch) | |
tree | e078f6c8df5fb197cfb1c31d07384efafce4066c /ppapi | |
parent | 0ce348504238ae1aeb7e2555ea21301b0a428214 (diff) | |
download | chromium_src-725c05196e3a8bcfc9b0114ff920252c67d54dd3.zip chromium_src-725c05196e3a8bcfc9b0114ff920252c67d54dd3.tar.gz chromium_src-725c05196e3a8bcfc9b0114ff920252c67d54dd3.tar.bz2 |
Add a test for PPP_Instance_Private_Proxy, to verify reference counting.
BUG=90240
TEST=this test
Review URL: http://codereview.chromium.org/7974013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102556 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/ppapi_tests.gypi | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_var_deprecated_proxy.cc | 2 | ||||
-rw-r--r-- | ppapi/proxy/ppp_instance_private_proxy_unittest.cc | 191 | ||||
-rw-r--r-- | ppapi/proxy/ppp_instance_proxy_unittest.cc (renamed from ppapi/proxy/ppp_instance_proxy_test.cc) | 16 | ||||
-rw-r--r-- | ppapi/proxy/ppp_messaging_proxy_unittest.cc (renamed from ppapi/proxy/ppp_messaging_proxy_test.cc) | 0 |
5 files changed, 200 insertions, 14 deletions
diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi index 9a68fa0..3ef929d 100644 --- a/ppapi/ppapi_tests.gypi +++ b/ppapi/ppapi_tests.gypi @@ -212,8 +212,9 @@ 'proxy/ppapi_proxy_test.cc', 'proxy/ppapi_proxy_test.h', 'proxy/ppb_var_unittest.cc', - 'proxy/ppp_instance_proxy_test.cc', - 'proxy/ppp_messaging_proxy_test.cc', + 'proxy/ppp_instance_private_proxy_unittest.cc', + 'proxy/ppp_instance_proxy_unittest.cc', + 'proxy/ppp_messaging_proxy_unittest.cc', 'proxy/serialized_var_unittest.cc', 'shared_impl/resource_tracker_unittest.cc', ], diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.cc b/ppapi/proxy/ppb_var_deprecated_proxy.cc index 1850dc0f..f4a4431 100644 --- a/ppapi/proxy/ppb_var_deprecated_proxy.cc +++ b/ppapi/proxy/ppb_var_deprecated_proxy.cc @@ -55,7 +55,7 @@ PluginDispatcher* CheckExceptionAndGetDispatcher(const PP_Var& object, return NULL; } -// PPP_Var_Deprecated plugin --------------------------------------------------- +// PPB_Var_Deprecated plugin --------------------------------------------------- void AddRefVar(PP_Var var) { PluginResourceTracker::GetInstance()->var_tracker().AddRefVar(var); diff --git a/ppapi/proxy/ppp_instance_private_proxy_unittest.cc b/ppapi/proxy/ppp_instance_private_proxy_unittest.cc new file mode 100644 index 0000000..a192154 --- /dev/null +++ b/ppapi/proxy/ppp_instance_private_proxy_unittest.cc @@ -0,0 +1,191 @@ +// Copyright (c) 2011 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 "ppapi/c/dev/ppb_var_deprecated.h" +#include "ppapi/c/dev/ppp_class_deprecated.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/private/ppp_instance_private.h" +#include "ppapi/proxy/host_dispatcher.h" +#include "ppapi/proxy/ppapi_proxy_test.h" + +namespace ppapi { +namespace proxy { + +namespace { +const PP_Instance kInstance = 0xdeadbeef; + +PP_Var MakeObjectVar(int64_t object_id) { + PP_Var ret; + ret.type = PP_VARTYPE_OBJECT; + ret.value.as_id = object_id; + return ret; +} + +PluginDispatcher* plugin_dispatcher = NULL; +// Return the plugin-side proxy for PPB_Var_Deprecated. +const PPB_Var_Deprecated* plugin_var_deprecated_if() { + // The test code must set the plugin dispatcher. + CHECK(plugin_dispatcher); + // Grab the plugin-side proxy for PPB_Var_Deprecated (for CreateObject). + return static_cast<const PPB_Var_Deprecated*>( + plugin_dispatcher->GetBrowserInterface( + PPB_VAR_DEPRECATED_INTERFACE)); +} + +// Mock PPP_Instance_Private. +PP_Var instance_obj; +PP_Var GetInstanceObject(PP_Instance /*instance*/) { + // The 1 ref we got from CreateObject will be passed to the host. We want to + // have a ref of our own. + plugin_var_deprecated_if()->AddRef(instance_obj); + return instance_obj; +} + +PPP_Instance_Private ppp_instance_private_mock = { + &GetInstanceObject +}; + +// We need to mock PPP_Instance, so that we can create and destroy the pretend +// instance that PPP_Instance_Private uses. +PP_Bool DidCreate(PP_Instance /*instance*/, uint32_t /*argc*/, + const char* /*argn*/[], const char* /*argv*/[]) { + // Create an object var. This should exercise the typical path for creating + // instance objects. + instance_obj = + plugin_var_deprecated_if()->CreateObject(kInstance, NULL, NULL); + return PP_TRUE; +} + +void DidDestroy(PP_Instance /*instance*/) { + // Decrement the reference count for our instance object. It should be + // deleted. + plugin_var_deprecated_if()->Release(instance_obj); +} + +PPP_Instance_1_0 ppp_instance_mock = { &DidCreate, &DidDestroy }; + +} // namespace + +// Mock PPB_Var_Deprecated, so that we can emulate creating an Object Var. +std::map<int64_t, int> id_refcount_map; +void AddRefVar(PP_Var var) { + CHECK(var.type >= PP_VARTYPE_STRING); // Must be a ref-counted type. + CHECK(id_refcount_map.find(var.value.as_id) != id_refcount_map.end()); + ++id_refcount_map[var.value.as_id]; +} + +void ReleaseVar(PP_Var var) { + CHECK(var.type >= PP_VARTYPE_STRING); // Must be a ref-counted type. + std::map<int64_t, int>::iterator iter = id_refcount_map.find(var.value.as_id); + CHECK(iter != id_refcount_map.end()); + CHECK(iter->second > 0); + if (--(iter->second) == 0) + id_refcount_map.erase(iter); +} + +PP_Var CreateObject(PP_Instance instance, + const PPP_Class_Deprecated* /*ppp_class*/, + void* /*ppp_class_data*/) { + static int64_t last_id = 0; + ++last_id; + // Set the refcount to 0. It should really be 1, but that ref gets passed to + // the plugin immediately (and we don't emulate all of that behavior here). + id_refcount_map[last_id] = 0; + return MakeObjectVar(last_id); +} + +const PPB_Var_Deprecated ppb_var_deprecated_mock = { + &AddRefVar, + &ReleaseVar, + NULL, // VarFromUtf8 + NULL, // VarToUtf8 + NULL, // HasProperty + NULL, // HasMethod + NULL, // GetProperty + NULL, // EnumerateProperties + NULL, // SetProperty + NULL, // RemoveProperty + NULL, // Call + NULL, // Construct + NULL, // IsInstanceOf + &CreateObject +}; + +const PPB_Var ppb_var_mock = { &AddRefVar, &ReleaseVar }; + +class PPP_Instance_Private_ProxyTest : public TwoWayTest { + public: + PPP_Instance_Private_ProxyTest() + : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) { + plugin().RegisterTestInterface(PPP_INSTANCE_PRIVATE_INTERFACE, + &ppp_instance_private_mock); + plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_1_0, + &ppp_instance_mock); + host().RegisterTestInterface(PPB_VAR_DEPRECATED_INTERFACE, + &ppb_var_deprecated_mock); + host().RegisterTestInterface(PPB_VAR_INTERFACE, + &ppb_var_mock); + } +}; + +TEST_F(PPP_Instance_Private_ProxyTest, PPPInstancePrivate) { + // This test controls its own instance; we can't use the one that + // PluginProxyTestHarness provides. + ASSERT_NE(kInstance, pp_instance()); + HostDispatcher::SetForInstance(kInstance, host().host_dispatcher()); + + // This file-local global is used by the PPP_Instance mock above in order to + // access PPB_Var_Deprecated. + plugin_dispatcher = plugin().plugin_dispatcher(); + + // Grab the host-side proxy for PPP_Instance and PPP_Instance_Private. + const PPP_Instance_Private* ppp_instance_private = + static_cast<const PPP_Instance_Private*>( + host().host_dispatcher()->GetProxiedInterface( + PPP_INSTANCE_PRIVATE_INTERFACE)); + const PPP_Instance_1_0* ppp_instance = static_cast<const PPP_Instance_1_0*>( + host().host_dispatcher()->GetProxiedInterface( + PPP_INSTANCE_INTERFACE_1_0)); + + // Initialize an Instance, so that the plugin-side machinery will work + // properly. + EXPECT_EQ(PP_TRUE, ppp_instance->DidCreate(kInstance, 0, NULL, NULL)); + + // Now instance_obj is valid and should have a ref-count of 1. + PluginVarTracker& plugin_var_tracker = + PluginResourceTracker::GetInstance()->var_tracker(); + // Check the plugin-side reference count. + EXPECT_EQ(1, plugin_var_tracker.GetRefCountForObject(instance_obj)); + // Check the host-side var and reference count. + ASSERT_EQ(1u, id_refcount_map.size()); + EXPECT_EQ(plugin_var_tracker.GetHostObject(instance_obj).value.as_id, + id_refcount_map.begin()->first); + EXPECT_EQ(0, id_refcount_map.begin()->second); + + // Call from the browser side to get the instance object. + PP_Var host_obj = ppp_instance_private->GetInstanceObject(kInstance); + EXPECT_EQ(instance_obj.type, host_obj.type); + EXPECT_EQ(host_obj.value.as_id, + plugin_var_tracker.GetHostObject(instance_obj).value.as_id); + EXPECT_EQ(1, plugin_var_tracker.GetRefCountForObject(instance_obj)); + ASSERT_EQ(1u, id_refcount_map.size()); + // The browser should be passed a reference. + EXPECT_EQ(1, id_refcount_map.begin()->second); + + // The plugin is going away; generally, so will all references to its instance + // object. + ReleaseVar(host_obj); + // Destroy the instance. DidDestroy above decrements the reference count for + // instance_obj, so it should also be destroyed. + ppp_instance->DidDestroy(kInstance); + EXPECT_EQ(-1, plugin_var_tracker.GetRefCountForObject(instance_obj)); + // Check the host-side reference count. + EXPECT_EQ(0u, id_refcount_map.size()); +} + +} // namespace proxy +} // namespace ppapi + diff --git a/ppapi/proxy/ppp_instance_proxy_test.cc b/ppapi/proxy/ppp_instance_proxy_unittest.cc index dbc749d..f28215a 100644 --- a/ppapi/proxy/ppp_instance_proxy_test.cc +++ b/ppapi/proxy/ppp_instance_proxy_unittest.cc @@ -4,11 +4,11 @@ #include "base/synchronization/waitable_event.h" #include "ipc/ipc_message_utils.h" -#include "ppapi/c/dev/ppb_fullscreen_dev.h" #include "ppapi/c/pp_var.h" #include "ppapi/c/ppb_core.h" #include "ppapi/c/ppb_url_loader.h" #include "ppapi/c/ppp_instance.h" +#include "ppapi/c/private/ppb_flash_fullscreen.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppapi_proxy_test.h" @@ -68,12 +68,6 @@ PP_Bool HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) { return PP_FALSE; } -PP_Var var_to_return; -PP_Var GetInstanceObject(PP_Instance instance) { - received_instance = instance; - return var_to_return; -} - // Clear all the 'received' values for our mock. Call this before you expect // one of the functions to be invoked. TODO(dmichael): It would be better to // have a flag also for each function, so we know the right one got called. @@ -95,12 +89,12 @@ PPP_Instance_1_0 ppp_instance_1_0 = { &HandleDocumentLoad }; -// PPP_Instance_Proxy::DidChangeView relies on PPB_FullscreenDev being +// PPP_Instance_Proxy::DidChangeView relies on PPB_Fullscreen being // available with a valid implementation of IsFullScreen, so we mock it. PP_Bool IsFullscreen(PP_Instance instance) { return PP_FALSE; } -PPB_Fullscreen_Dev ppb_fullscreen_dev = { &IsFullscreen }; +PPB_FlashFullscreen ppb_flash_fullscreen = { &IsFullscreen }; } // namespace @@ -113,8 +107,8 @@ class PPP_Instance_ProxyTest : public TwoWayTest { TEST_F(PPP_Instance_ProxyTest, PPPInstance1_0) { plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_1_0, &ppp_instance_1_0); - host().RegisterTestInterface(PPB_FULLSCREEN_DEV_INTERFACE, - &ppb_fullscreen_dev); + host().RegisterTestInterface(PPB_FLASHFULLSCREEN_INTERFACE, + &ppb_flash_fullscreen); // Grab the host-side proxy for the 1.0 interface. const PPP_Instance_1_0* ppp_instance = static_cast<const PPP_Instance_1_0*>( diff --git a/ppapi/proxy/ppp_messaging_proxy_test.cc b/ppapi/proxy/ppp_messaging_proxy_unittest.cc index 25c7e55..25c7e55 100644 --- a/ppapi/proxy/ppp_messaging_proxy_test.cc +++ b/ppapi/proxy/ppp_messaging_proxy_unittest.cc |