var_tracker_unittest.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "testing/gtest/include/gtest/gtest.h" 6 7#include "base/compiler_specific.h" 8#include "ppapi/shared_impl/proxy_lock.h" 9#include "ppapi/shared_impl/var.h" 10#include "ppapi/shared_impl/var_tracker.h" 11#include "ppapi/shared_impl/test_globals.h" 12 13namespace ppapi { 14 15namespace { 16 17int mock_var_alive_count = 0; 18 19class MockStringVar : public StringVar { 20 public: 21 MockStringVar(const std::string& str) : StringVar(str) { 22 mock_var_alive_count++; 23 } 24 virtual ~MockStringVar() { 25 mock_var_alive_count--; 26 } 27 bool HasValidVarID() { 28 return GetExistingVarID() != 0; 29 } 30}; 31 32class MockObjectVar : public Var { 33 public: 34 MockObjectVar() : Var() { 35 mock_var_alive_count++; 36 } 37 virtual ~MockObjectVar() { 38 mock_var_alive_count--; 39 } 40 virtual PP_VarType GetType() const OVERRIDE { 41 return PP_VARTYPE_OBJECT; 42 } 43 bool HasValidVarID() { 44 return GetExistingVarID() != 0; 45 } 46}; 47 48} // namespace 49 50class VarTrackerTest : public testing::Test { 51 public: 52 VarTrackerTest() {} 53 54 // Test implementation. 55 virtual void SetUp() OVERRIDE { 56 ASSERT_EQ(0, mock_var_alive_count); 57 ProxyLock::EnableLockingOnThreadForTest(); 58 } 59 virtual void TearDown() OVERRIDE { 60 } 61 62 VarTracker& var_tracker() { return *globals_.GetVarTracker(); } 63 64 private: 65 TestGlobals globals_; 66}; 67 68// Test that ResetVarID is called when the last PP_Var ref was deleted but the 69// object lives on. 70TEST_F(VarTrackerTest, LastResourceRef) { 71 ProxyAutoLock lock; 72 scoped_refptr<MockStringVar> var(new MockStringVar(std::string("xyz"))); 73 PP_Var pp_var = var->GetPPVar(); 74 EXPECT_TRUE(var->HasValidVarID()); 75 EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID())); 76 77 // Releasing it should keep the object (because we have a ref) but reset the 78 // var_id_. 79 EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); 80 EXPECT_FALSE(var->HasValidVarID()); 81 EXPECT_EQ(1, mock_var_alive_count); 82 83 var = NULL; 84 EXPECT_EQ(0, mock_var_alive_count); 85} 86 87TEST_F(VarTrackerTest, GetPluginRefAgain) { 88 ProxyAutoLock lock; 89 scoped_refptr<MockStringVar> var(new MockStringVar(std::string("xyz"))); 90 PP_Var pp_var = var->GetPPVar(); 91 EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); 92 EXPECT_FALSE(var->HasValidVarID()); 93 EXPECT_EQ(1, mock_var_alive_count); 94 95 // Obtaining PP_Var ref again, and add ref from VarTracker. 96 pp_var = var->GetPPVar(); 97 EXPECT_TRUE(var->HasValidVarID()); 98 EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID())); 99 scoped_refptr<MockStringVar> another_var = 100 static_cast<MockStringVar*>(var_tracker().GetVar(pp_var)); 101 EXPECT_EQ(1, mock_var_alive_count); 102 103 // Releasing it again. 104 EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); 105 EXPECT_FALSE(var->HasValidVarID()); 106 EXPECT_EQ(1, mock_var_alive_count); 107 108 var = NULL; 109 EXPECT_FALSE(var_tracker().GetVar(pp_var)); 110 EXPECT_EQ(1, mock_var_alive_count); 111 another_var = NULL; 112 EXPECT_FALSE(var_tracker().GetVar(pp_var)); 113 EXPECT_EQ(0, mock_var_alive_count); 114} 115 116// Tests when the plugin is holding a ref to a PP_Var when the instance is 117// owned only by VarTracker. 118TEST_F(VarTrackerTest, PluginRefWithoutVarRef) { 119 ProxyAutoLock lock; 120 // Make a PP_Var with one ref held by the plugin, and release the reference. 121 scoped_refptr<MockStringVar> var(new MockStringVar(std::string("zzz"))); 122 PP_Var pp_var = var->GetPPVar(); 123 EXPECT_EQ(1, mock_var_alive_count); 124 var = NULL; 125 EXPECT_EQ(1, mock_var_alive_count); 126 127 // The var is owned only by VarTracker. PP_Var must be still valid. 128 EXPECT_TRUE(var_tracker().GetVar(pp_var)); 129 130 var_tracker().ReleaseVar(pp_var); 131 EXPECT_EQ(0, mock_var_alive_count); 132 EXPECT_FALSE(var_tracker().GetVar(pp_var)); 133} 134 135// Tests on Var having type of PP_VARTYPE_OBJECT. 136TEST_F(VarTrackerTest, ObjectRef) { 137 ProxyAutoLock lock; 138 scoped_refptr<MockObjectVar> var(new MockObjectVar()); 139 PP_Var pp_var = var->GetPPVar(); 140 EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); 141 EXPECT_FALSE(var->HasValidVarID()); 142 EXPECT_EQ(1, mock_var_alive_count); 143 144 // Obtaining PP_Var ref again, and add ref from VarTracker. 145 pp_var = var->GetPPVar(); 146 EXPECT_TRUE(var->HasValidVarID()); 147 EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID())); 148 scoped_refptr<MockObjectVar> another_var = 149 static_cast<MockObjectVar*>(var_tracker().GetVar(pp_var)); 150 EXPECT_EQ(1, mock_var_alive_count); 151 152 // Releasing all references, then only VarTracker own the instance. 153 var = NULL; 154 EXPECT_TRUE(var_tracker().GetVar(pp_var)); 155 EXPECT_EQ(1, mock_var_alive_count); 156 another_var = NULL; 157 EXPECT_TRUE(var_tracker().GetVar(pp_var)); 158 EXPECT_EQ(1, mock_var_alive_count); 159 160 // Releasing plugin reference. 161 EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); 162 EXPECT_EQ(0, mock_var_alive_count); 163} 164 165} // namespace ppapi 166