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