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.
5 #include "ppapi/proxy/raw_var_data.h"
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/resource_var.h"
18 #include "ppapi/shared_impl/scoped_pp_var.h"
19 #include "ppapi/shared_impl/test_globals.h"
20 #include "ppapi/shared_impl/unittest_utils.h"
21 #include "ppapi/shared_impl/var.h"
22 #include "ppapi/shared_impl/var_tracker.h"
23 #include "testing/gtest/include/gtest/gtest.h"
30 void DefaultHandleWriter(IPC::Message
* m
, const SerializedHandle
& handle
) {
31 IPC::ParamTraits
<SerializedHandle
>::Write(m
, handle
);
34 class RawVarDataTest
: public testing::Test
{
39 // testing::Test implementation.
40 virtual void SetUp() {
41 ProxyLock::EnableLockingOnThreadForTest();
44 virtual void TearDown() {
45 ASSERT_TRUE(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().empty());
53 bool WriteAndRead(const PP_Var
& var
, PP_Var
* result
) {
54 PP_Instance dummy_instance
= 1234;
55 scoped_ptr
<RawVarDataGraph
> expected_data(RawVarDataGraph::Create(
56 var
, dummy_instance
));
60 expected_data
->Write(&m
, base::Bind(&DefaultHandleWriter
));
61 PickleIterator
iter(m
);
62 scoped_ptr
<RawVarDataGraph
> actual_data(RawVarDataGraph::Read(&m
, &iter
));
63 *result
= actual_data
->CreatePPVar(dummy_instance
);
67 // Assumes a ref for var.
68 bool WriteReadAndCompare(const PP_Var
& var
) {
69 ScopedPPVar
expected(ScopedPPVar::PassRef(), var
);
71 bool success
= WriteAndRead(expected
.get(), &result
);
74 ScopedPPVar
actual(ScopedPPVar::PassRef(), result
);
75 return TestEqual(expected
.get(), actual
.get());
80 TEST_F(RawVarDataTest
, SimpleTest
) {
81 EXPECT_TRUE(WriteReadAndCompare(PP_MakeUndefined()));
82 EXPECT_TRUE(WriteReadAndCompare(PP_MakeNull()));
83 EXPECT_TRUE(WriteReadAndCompare(PP_MakeInt32(100)));
84 EXPECT_TRUE(WriteReadAndCompare(PP_MakeBool(PP_TRUE
)));
85 EXPECT_TRUE(WriteReadAndCompare(PP_MakeDouble(53.75)));
87 object
.type
= PP_VARTYPE_OBJECT
;
88 object
.value
.as_id
= 10;
89 EXPECT_TRUE(WriteReadAndCompare(object
));
92 TEST_F(RawVarDataTest
, StringTest
) {
93 EXPECT_TRUE(WriteReadAndCompare(StringVar::StringToPPVar("")));
94 EXPECT_TRUE(WriteReadAndCompare(StringVar::StringToPPVar("hello world!")));
97 TEST_F(RawVarDataTest
, ArrayBufferTest
) {
98 std::string data
= "hello world!";
99 PP_Var var
= PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
100 data
.size(), data
.data());
101 EXPECT_TRUE(WriteReadAndCompare(var
));
102 var
= PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
103 0, static_cast<void*>(NULL
));
104 EXPECT_TRUE(WriteReadAndCompare(var
));
105 // TODO(raymes): add tests for shmem type array buffers.
108 TEST_F(RawVarDataTest
, DictionaryArrayTest
) {
110 scoped_refptr
<ArrayVar
> array(new ArrayVar
);
111 ScopedPPVar
release_array(ScopedPPVar::PassRef(), array
->GetPPVar());
112 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
116 // Array with primitives.
117 array
->Set(index
++, PP_MakeUndefined());
118 array
->Set(index
++, PP_MakeNull());
119 array
->Set(index
++, PP_MakeInt32(100));
120 array
->Set(index
++, PP_MakeBool(PP_FALSE
));
121 array
->Set(index
++, PP_MakeDouble(0.123));
122 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
124 // Array with 2 references to the same string.
125 ScopedPPVar
release_string(
126 ScopedPPVar::PassRef(), StringVar::StringToPPVar("abc"));
127 array
->Set(index
++, release_string
.get());
128 array
->Set(index
++, release_string
.get());
129 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
131 // Array with nested array that references the same string.
132 scoped_refptr
<ArrayVar
> array2(new ArrayVar
);
133 ScopedPPVar
release_array2(ScopedPPVar::PassRef(), array2
->GetPPVar());
134 array2
->Set(0, release_string
.get());
135 array
->Set(index
++, release_array2
.get());
136 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
139 scoped_refptr
<DictionaryVar
> dictionary(new DictionaryVar
);
140 ScopedPPVar
release_dictionary(ScopedPPVar::PassRef(),
141 dictionary
->GetPPVar());
142 EXPECT_TRUE(WriteReadAndCompare(dictionary
->GetPPVar()));
144 // Dictionary with primitives.
145 dictionary
->SetWithStringKey("1", PP_MakeUndefined());
146 dictionary
->SetWithStringKey("2", PP_MakeNull());
147 dictionary
->SetWithStringKey("3", PP_MakeInt32(-100));
148 dictionary
->SetWithStringKey("4", PP_MakeBool(PP_TRUE
));
149 dictionary
->SetWithStringKey("5", PP_MakeDouble(-103.52));
150 EXPECT_TRUE(WriteReadAndCompare(dictionary
->GetPPVar()));
152 // Dictionary with 2 references to the same string.
153 dictionary
->SetWithStringKey("6", release_string
.get());
154 dictionary
->SetWithStringKey("7", release_string
.get());
155 EXPECT_TRUE(WriteReadAndCompare(dictionary
->GetPPVar()));
157 // Dictionary with nested dictionary that references the same string.
158 scoped_refptr
<DictionaryVar
> dictionary2(new DictionaryVar
);
159 ScopedPPVar
release_dictionary2(ScopedPPVar::PassRef(),
160 dictionary2
->GetPPVar());
161 dictionary2
->SetWithStringKey("abc", release_string
.get());
162 dictionary
->SetWithStringKey("8", release_dictionary2
.get());
163 EXPECT_TRUE(WriteReadAndCompare(dictionary
->GetPPVar()));
165 // Array with dictionary.
166 array
->Set(index
++, release_dictionary
.get());
167 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
169 // Array with dictionary with array.
170 array2
->Set(0, PP_MakeInt32(100));
171 dictionary
->SetWithStringKey("9", release_array2
.get());
172 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
174 // Array <-> dictionary cycle.
175 dictionary
->SetWithStringKey("10", release_array
.get());
177 ASSERT_FALSE(WriteAndRead(release_dictionary
.get(), &result
));
179 // TODO(raymes): We need some better machinery for releasing vars with
180 // cycles. Remove the code below once we have that.
181 dictionary
->DeleteWithStringKey("10");
183 // Array with self references.
184 array
->Set(index
, release_array
.get());
185 ASSERT_FALSE(WriteAndRead(release_array
.get(), &result
));
186 // Break the self reference.
187 array
->Set(index
, PP_MakeUndefined());
190 TEST_F(RawVarDataTest
, ResourceTest
) {
191 // TODO(mgiuca): This test passes trivially, since GetVarTracker() returns a
192 // TestVarTracker which returns a null PP_Var.
193 ScopedPPVar
resource(
194 ScopedPPVar::PassRef(),
195 PpapiGlobals::Get()->GetVarTracker()->MakeResourcePPVar(34));
196 EXPECT_TRUE(WriteReadAndCompare(resource
.get()));
198 // TODO(mgiuca): Test a host resource with an IPC::Message. It is currently a
199 // checkfail to deserialize such a resource.