raw_var_data_unittest.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
1// Copyright (c) 2012 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 "ppapi/proxy/raw_var_data.h" 6 7#include "base/logging.h" 8#include "base/memory/ref_counted.h" 9#include "base/memory/scoped_ptr.h" 10#include "base/values.h" 11#include "ppapi/c/pp_bool.h" 12#include "ppapi/c/pp_var.h" 13#include "ppapi/shared_impl/array_var.h" 14#include "ppapi/shared_impl/dictionary_var.h" 15#include "ppapi/shared_impl/ppapi_globals.h" 16#include "ppapi/shared_impl/proxy_lock.h" 17#include "ppapi/shared_impl/scoped_pp_var.h" 18#include "ppapi/shared_impl/test_globals.h" 19#include "ppapi/shared_impl/unittest_utils.h" 20#include "ppapi/shared_impl/var.h" 21#include "ppapi/shared_impl/var_tracker.h" 22#include "testing/gtest/include/gtest/gtest.h" 23 24namespace ppapi { 25namespace proxy { 26 27namespace { 28 29void DefaultHandleWriter(IPC::Message* m, const SerializedHandle& handle) { 30 IPC::ParamTraits<SerializedHandle>::Write(m, handle); 31} 32 33class RawVarDataTest : public testing::Test { 34 public: 35 RawVarDataTest() {} 36 ~RawVarDataTest() {} 37 38 // testing::Test implementation. 39 virtual void SetUp() { 40 ProxyLock::EnableLockingOnThreadForTest(); 41 ProxyLock::Acquire(); 42 } 43 virtual void TearDown() { 44 ASSERT_TRUE(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().empty()); 45 ProxyLock::Release(); 46 } 47 48 private: 49 TestGlobals globals_; 50}; 51 52bool WriteAndRead(const PP_Var& var, PP_Var* result) { 53 PP_Instance dummy_instance = 1234; 54 scoped_ptr<RawVarDataGraph> expected_data(RawVarDataGraph::Create( 55 var, dummy_instance)); 56 if (!expected_data) 57 return false; 58 IPC::Message m; 59 expected_data->Write(&m, base::Bind(&DefaultHandleWriter)); 60 PickleIterator iter(m); 61 scoped_ptr<RawVarDataGraph> actual_data(RawVarDataGraph::Read(&m, &iter)); 62 *result = actual_data->CreatePPVar(dummy_instance); 63 return true; 64} 65 66// Assumes a ref for var. 67bool WriteReadAndCompare(const PP_Var& var) { 68 ScopedPPVar expected(ScopedPPVar::PassRef(), var); 69 PP_Var result; 70 bool success = WriteAndRead(expected.get(), &result); 71 if (!success) 72 return false; 73 ScopedPPVar actual(ScopedPPVar::PassRef(), result); 74 return TestEqual(expected.get(), actual.get()); 75} 76 77} // namespace 78 79TEST_F(RawVarDataTest, SimpleTest) { 80 EXPECT_TRUE(WriteReadAndCompare(PP_MakeUndefined())); 81 EXPECT_TRUE(WriteReadAndCompare(PP_MakeNull())); 82 EXPECT_TRUE(WriteReadAndCompare(PP_MakeInt32(100))); 83 EXPECT_TRUE(WriteReadAndCompare(PP_MakeBool(PP_TRUE))); 84 EXPECT_TRUE(WriteReadAndCompare(PP_MakeDouble(53.75))); 85 PP_Var object; 86 object.type = PP_VARTYPE_OBJECT; 87 object.value.as_id = 10; 88 EXPECT_TRUE(WriteReadAndCompare(object)); 89} 90 91TEST_F(RawVarDataTest, StringTest) { 92 EXPECT_TRUE(WriteReadAndCompare(StringVar::StringToPPVar(""))); 93 EXPECT_TRUE(WriteReadAndCompare(StringVar::StringToPPVar("hello world!"))); 94} 95 96TEST_F(RawVarDataTest, ArrayBufferTest) { 97 std::string data = "hello world!"; 98 PP_Var var = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( 99 data.size(), data.data()); 100 EXPECT_TRUE(WriteReadAndCompare(var)); 101 var = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( 102 0, static_cast<void*>(NULL)); 103 EXPECT_TRUE(WriteReadAndCompare(var)); 104 // TODO(raymes): add tests for shmem type array buffers. 105} 106 107TEST_F(RawVarDataTest, DictionaryArrayTest) { 108 // Empty array. 109 scoped_refptr<ArrayVar> array(new ArrayVar); 110 ScopedPPVar release_array(ScopedPPVar::PassRef(), array->GetPPVar()); 111 EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar())); 112 113 size_t index = 0; 114 115 // Array with primitives. 116 array->Set(index++, PP_MakeUndefined()); 117 array->Set(index++, PP_MakeNull()); 118 array->Set(index++, PP_MakeInt32(100)); 119 array->Set(index++, PP_MakeBool(PP_FALSE)); 120 array->Set(index++, PP_MakeDouble(0.123)); 121 EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar())); 122 123 // Array with 2 references to the same string. 124 ScopedPPVar release_string( 125 ScopedPPVar::PassRef(), StringVar::StringToPPVar("abc")); 126 array->Set(index++, release_string.get()); 127 array->Set(index++, release_string.get()); 128 EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar())); 129 130 // Array with nested array that references the same string. 131 scoped_refptr<ArrayVar> array2(new ArrayVar); 132 ScopedPPVar release_array2(ScopedPPVar::PassRef(), array2->GetPPVar()); 133 array2->Set(0, release_string.get()); 134 array->Set(index++, release_array2.get()); 135 EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar())); 136 137 // Empty dictionary. 138 scoped_refptr<DictionaryVar> dictionary(new DictionaryVar); 139 ScopedPPVar release_dictionary(ScopedPPVar::PassRef(), 140 dictionary->GetPPVar()); 141 EXPECT_TRUE(WriteReadAndCompare(dictionary->GetPPVar())); 142 143 // Dictionary with primitives. 144 dictionary->SetWithStringKey("1", PP_MakeUndefined()); 145 dictionary->SetWithStringKey("2", PP_MakeNull()); 146 dictionary->SetWithStringKey("3", PP_MakeInt32(-100)); 147 dictionary->SetWithStringKey("4", PP_MakeBool(PP_TRUE)); 148 dictionary->SetWithStringKey("5", PP_MakeDouble(-103.52)); 149 EXPECT_TRUE(WriteReadAndCompare(dictionary->GetPPVar())); 150 151 // Dictionary with 2 references to the same string. 152 dictionary->SetWithStringKey("6", release_string.get()); 153 dictionary->SetWithStringKey("7", release_string.get()); 154 EXPECT_TRUE(WriteReadAndCompare(dictionary->GetPPVar())); 155 156 // Dictionary with nested dictionary that references the same string. 157 scoped_refptr<DictionaryVar> dictionary2(new DictionaryVar); 158 ScopedPPVar release_dictionary2(ScopedPPVar::PassRef(), 159 dictionary2->GetPPVar()); 160 dictionary2->SetWithStringKey("abc", release_string.get()); 161 dictionary->SetWithStringKey("8", release_dictionary2.get()); 162 EXPECT_TRUE(WriteReadAndCompare(dictionary->GetPPVar())); 163 164 // Array with dictionary. 165 array->Set(index++, release_dictionary.get()); 166 EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar())); 167 168 // Array with dictionary with array. 169 array2->Set(0, PP_MakeInt32(100)); 170 dictionary->SetWithStringKey("9", release_array2.get()); 171 EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar())); 172 173 // Array <-> dictionary cycle. 174 dictionary->SetWithStringKey("10", release_array.get()); 175 PP_Var result; 176 ASSERT_FALSE(WriteAndRead(release_dictionary.get(), &result)); 177 // Break the cycle. 178 // TODO(raymes): We need some better machinery for releasing vars with 179 // cycles. Remove the code below once we have that. 180 dictionary->DeleteWithStringKey("10"); 181 182 // Array with self references. 183 array->Set(index, release_array.get()); 184 ASSERT_FALSE(WriteAndRead(release_array.get(), &result)); 185 // Break the self reference. 186 array->Set(index, PP_MakeUndefined()); 187} 188 189} // namespace proxy 190} // namespace ppapi 191