Home | History | Annotate | Download | only in shared_impl
      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 
     12 namespace ppapi {
     13 
     14 namespace {
     15 
     16 int mock_var_alive_count = 0;
     17 
     18 class 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 
     31 class 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 
     49 class 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.
     68 TEST_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 
     84 TEST_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.
    114 TEST_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.
    131 TEST_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