15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var_tracker.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/test_globals.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int mock_var_alive_count = 0; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockStringVar : public StringVar { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockStringVar(const std::string& str) : StringVar(str) { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_var_alive_count++; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MockStringVar() { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_var_alive_count--; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasValidVarID() { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetExistingVarID() != 0; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockObjectVar : public Var { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockObjectVar() : Var() { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_var_alive_count++; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MockObjectVar() { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_var_alive_count--; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual PP_VarType GetType() const OVERRIDE { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_VARTYPE_OBJECT; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasValidVarID() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetExistingVarID() != 0; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VarTrackerTest : public testing::Test { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VarTrackerTest() {} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test implementation. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, mock_var_alive_count); 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProxyLock::EnableLockingOnThreadForTest(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() OVERRIDE { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VarTracker& var_tracker() { return *globals_.GetVarTracker(); } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestGlobals globals_; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that ResetVarID is called when the last PP_Var ref was deleted but the 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object lives on. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VarTrackerTest, LastResourceRef) { 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProxyAutoLock lock; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MockStringVar> var(new MockStringVar(std::string("xyz"))); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var pp_var = var->GetPPVar(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var->HasValidVarID()); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID())); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Releasing it should keep the object (because we have a ref) but reset the 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // var_id_. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(var->HasValidVarID()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var = NULL; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, mock_var_alive_count); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VarTrackerTest, GetPluginRefAgain) { 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProxyAutoLock lock; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MockStringVar> var(new MockStringVar(std::string("xyz"))); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var pp_var = var->GetPPVar(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(var->HasValidVarID()); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Obtaining PP_Var ref again, and add ref from VarTracker. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp_var = var->GetPPVar(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var->HasValidVarID()); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID())); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MockStringVar> another_var = 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<MockStringVar*>(var_tracker().GetVar(pp_var)); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Releasing it again. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(var->HasValidVarID()); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var = NULL; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(var_tracker().GetVar(pp_var)); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) another_var = NULL; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(var_tracker().GetVar(pp_var)); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, mock_var_alive_count); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests when the plugin is holding a ref to a PP_Var when the instance is 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// owned only by VarTracker. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VarTrackerTest, PluginRefWithoutVarRef) { 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProxyAutoLock lock; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a PP_Var with one ref held by the plugin, and release the reference. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MockStringVar> var(new MockStringVar(std::string("zzz"))); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var pp_var = var->GetPPVar(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var = NULL; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The var is owned only by VarTracker. PP_Var must be still valid. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().GetVar(pp_var)); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().ReleaseVar(pp_var); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, mock_var_alive_count); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(var_tracker().GetVar(pp_var)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests on Var having type of PP_VARTYPE_OBJECT. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VarTrackerTest, ObjectRef) { 137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProxyAutoLock lock; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MockObjectVar> var(new MockObjectVar()); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var pp_var = var->GetPPVar(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(var->HasValidVarID()); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Obtaining PP_Var ref again, and add ref from VarTracker. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp_var = var->GetPPVar(); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var->HasValidVarID()); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID())); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MockObjectVar> another_var = 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<MockObjectVar*>(var_tracker().GetVar(pp_var)); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Releasing all references, then only VarTracker own the instance. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var = NULL; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().GetVar(pp_var)); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) another_var = NULL; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().GetVar(pp_var)); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, mock_var_alive_count); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Releasing plugin reference. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, mock_var_alive_count); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 166