Chromium Code Reviews| Index: ppapi/shared_impl/var_tracker_unittest.cc |
| diff --git a/ppapi/shared_impl/var_tracker_unittest.cc b/ppapi/shared_impl/var_tracker_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4f3bbd99d5a5c053821c50f1c084d6b339e91479 |
| --- /dev/null |
| +++ b/ppapi/shared_impl/var_tracker_unittest.cc |
| @@ -0,0 +1,170 @@ |
| +// 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 "testing/gtest/include/gtest/gtest.h" |
| + |
| +#include "base/compiler_specific.h" |
| +#include "ppapi/shared_impl/var.h" |
| +#include "ppapi/shared_impl/var_tracker.h" |
| +#include "ppapi/shared_impl/test_globals.h" |
| + |
| +namespace ppapi { |
| + |
| +namespace { |
| + |
| +int mock_var_alive_count = 0; |
| + |
| +class MockStringVar : public StringVar { |
| + public: |
| + MockStringVar(const std::string& str) : StringVar(str) { |
| + mock_var_alive_count++; |
| + } |
| + virtual ~MockStringVar() { |
| + mock_var_alive_count--; |
| + } |
| + bool HasValidVarID() { |
| + return GetExistingVarID() != 0; |
| + } |
| +}; |
| + |
| +class MockObjectVar : public Var { |
| + public: |
| + MockObjectVar() : Var() { |
| + mock_var_alive_count++; |
| + } |
| + virtual ~MockObjectVar() { |
| + mock_var_alive_count--; |
| + } |
| + virtual PP_Var GetPPVar() OVERRIDE { |
| + int32 id = GetOrCreateVarID(); |
| + if (!id) |
| + return PP_MakeNull(); |
| + |
| + PP_Var result; |
| + result.type = PP_VARTYPE_OBJECT; |
| + result.padding = 0; |
| + result.value.as_id = id; |
| + return result; |
| + } |
| + virtual PP_VarType GetType() const OVERRIDE { |
| + return PP_VARTYPE_OBJECT; |
| + } |
| + bool HasValidVarID() { |
| + return GetExistingVarID() != 0; |
| + } |
| +}; |
| + |
| +} // namespace |
| + |
| +class VarTrackerTest : public testing::Test { |
| + public: |
| + VarTrackerTest() {} |
| + |
| + // Test implementation. |
| + virtual void SetUp() OVERRIDE { |
| + ASSERT_EQ(0, mock_var_alive_count); |
| + } |
| + virtual void TearDown() OVERRIDE { |
| + } |
| + |
| + VarTracker& var_tracker() { return *globals_.GetVarTracker(); } |
| + |
| + private: |
| + TestGlobals globals_; |
| +}; |
| + |
| +// Test that ResetVarID is called when the last PP_Var ref was deleted but the |
| +// object lives on. |
| +TEST_F(VarTrackerTest, LastResourceRef) { |
| + scoped_refptr<MockStringVar> var(new MockStringVar(std::string("xyz"))); |
| + PP_Var pp_var = var->GetPPVar(); |
| + EXPECT_TRUE(var->HasValidVarID()); |
| + EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID())); |
| + |
| + // Releasing it should keep the object (because we have a ref) but reset the |
| + // var_id_. |
| + EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); |
| + EXPECT_FALSE(var->HasValidVarID()); |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + |
| + var = NULL; |
| + EXPECT_EQ(0, mock_var_alive_count); |
| +} |
| + |
| +TEST_F(VarTrackerTest, GetResourceRefAgain) { |
|
brettw
2011/12/15 16:58:45
Can you substitute every time you say "Resource" i
Takashi Toyoshima
2011/12/16 04:28:45
Done.
|
| + scoped_refptr<MockStringVar> var(new MockStringVar(std::string("xyz"))); |
| + PP_Var pp_var = var->GetPPVar(); |
| + EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); |
| + EXPECT_FALSE(var->HasValidVarID()); |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + |
| + // Obtaining PP_Var ref again, and add ref from VarTracker. |
| + pp_var = var->GetPPVar(); |
| + EXPECT_TRUE(var->HasValidVarID()); |
| + EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID())); |
| + scoped_refptr<MockStringVar> another_var = |
| + static_cast<MockStringVar*>(var_tracker().GetVar(pp_var)); |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + |
| + // Releasing it again. |
| + EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); |
| + EXPECT_FALSE(var->HasValidVarID()); |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + |
| + var = NULL; |
| + EXPECT_FALSE(var_tracker().GetVar(pp_var)); |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + another_var = NULL; |
| + EXPECT_FALSE(var_tracker().GetVar(pp_var)); |
| + EXPECT_EQ(0, mock_var_alive_count); |
| +} |
| + |
| +// Tests when the plugin is holding a ref to a PP_Var when the instance is |
| +// owned only by VarTracker. |
| +TEST_F(VarTrackerTest, ResourceRefWithoutVarRef) { |
| + // Make a PP_Var with one ref held by the plugin, and release the reference. |
| + scoped_refptr<MockStringVar> var(new MockStringVar(std::string("zzz"))); |
| + PP_Var pp_var = var->GetPPVar(); |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + var = NULL; |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + |
| + // The var is owned only by VarTracker. PP_Var must be still valid. |
| + EXPECT_TRUE(var_tracker().GetVar(pp_var)); |
| + |
| + var_tracker().ReleaseVar(pp_var); |
| + EXPECT_EQ(0, mock_var_alive_count); |
| + EXPECT_FALSE(var_tracker().GetVar(pp_var)); |
| +} |
| + |
| +// Tests on Var having type of PP_VARTYPE_OBJECT. |
| +TEST_F(VarTrackerTest, ObjectRef) { |
| + scoped_refptr<MockObjectVar> var(new MockObjectVar()); |
| + PP_Var pp_var = var->GetPPVar(); |
| + EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); |
| + EXPECT_FALSE(var->HasValidVarID()); |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + |
| + // Obtaining PP_Var ref again, and add ref from VarTracker. |
| + pp_var = var->GetPPVar(); |
| + EXPECT_TRUE(var->HasValidVarID()); |
| + EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID())); |
| + scoped_refptr<MockObjectVar> another_var = |
| + static_cast<MockObjectVar*>(var_tracker().GetVar(pp_var)); |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + |
| + // Releasing all references, then only VarTracker own the instance. |
| + var = NULL; |
| + EXPECT_TRUE(var_tracker().GetVar(pp_var)); |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + another_var = NULL; |
| + EXPECT_TRUE(var_tracker().GetVar(pp_var)); |
| + EXPECT_EQ(1, mock_var_alive_count); |
| + |
| + // Releasing resource reference. |
| + EXPECT_TRUE(var_tracker().ReleaseVar(pp_var)); |
| + EXPECT_EQ(0, mock_var_alive_count); |
| +} |
| + |
| +} // namespace ppapi |