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() {
43 virtual void TearDown() {
44 ASSERT_TRUE(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().empty());
52 bool 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
));
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
);
66 // Assumes a ref for var.
67 bool WriteReadAndCompare(const PP_Var
& var
) {
68 ScopedPPVar
expected(ScopedPPVar::PassRef(), var
);
70 bool success
= WriteAndRead(expected
.get(), &result
);
73 ScopedPPVar
actual(ScopedPPVar::PassRef(), result
);
74 return TestEqual(expected
.get(), actual
.get(), true);
79 TEST_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)));
86 object
.type
= PP_VARTYPE_OBJECT
;
87 object
.value
.as_id
= 10;
88 EXPECT_TRUE(WriteReadAndCompare(object
));
91 TEST_F(RawVarDataTest
, StringTest
) {
92 EXPECT_TRUE(WriteReadAndCompare(StringVar::StringToPPVar("")));
93 EXPECT_TRUE(WriteReadAndCompare(StringVar::StringToPPVar("hello world!")));
96 TEST_F(RawVarDataTest
, ArrayBufferTest
) {
97 std::string data
= "hello world!";
98 PP_Var var
= PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
99 static_cast<uint32_t>(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.
107 TEST_F(RawVarDataTest
, DictionaryArrayTest
) {
109 scoped_refptr
<ArrayVar
> array(new ArrayVar
);
110 ScopedPPVar
release_array(ScopedPPVar::PassRef(), array
->GetPPVar());
111 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
115 // Array with primitives.
116 array
->Set(static_cast<uint32_t>(index
++), PP_MakeUndefined());
117 array
->Set(static_cast<uint32_t>(index
++), PP_MakeNull());
118 array
->Set(static_cast<uint32_t>(index
++), PP_MakeInt32(100));
119 array
->Set(static_cast<uint32_t>(index
++), PP_MakeBool(PP_FALSE
));
120 array
->Set(static_cast<uint32_t>(index
++), PP_MakeDouble(0.123));
121 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
123 // Array with 2 references to the same string.
124 ScopedPPVar
release_string(
125 ScopedPPVar::PassRef(), StringVar::StringToPPVar("abc"));
126 array
->Set(static_cast<uint32_t>(index
++), release_string
.get());
127 array
->Set(static_cast<uint32_t>(index
++), release_string
.get());
128 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
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(static_cast<uint32_t>(index
++), release_array2
.get());
135 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
138 scoped_refptr
<DictionaryVar
> dictionary(new DictionaryVar
);
139 ScopedPPVar
release_dictionary(ScopedPPVar::PassRef(),
140 dictionary
->GetPPVar());
141 EXPECT_TRUE(WriteReadAndCompare(dictionary
->GetPPVar()));
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()));
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()));
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()));
164 // Array with dictionary.
165 array
->Set(static_cast<uint32_t>(index
++), release_dictionary
.get());
166 EXPECT_TRUE(WriteReadAndCompare(array
->GetPPVar()));
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()));
173 // Array <-> dictionary cycle.
174 dictionary
->SetWithStringKey("10", release_array
.get());
176 ASSERT_FALSE(WriteAndRead(release_dictionary
.get(), &result
));
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");
182 // Array with self references.
183 array
->Set(static_cast<uint32_t>(index
), release_array
.get());
184 ASSERT_FALSE(WriteAndRead(release_array
.get(), &result
));
185 // Break the self reference.
186 array
->Set(static_cast<uint32_t>(index
), PP_MakeUndefined());
189 TEST_F(RawVarDataTest
, ResourceTest
) {
190 // TODO(mgiuca): This test passes trivially, since GetVarTracker() returns a
191 // TestVarTracker which returns a null PP_Var.
192 ScopedPPVar
resource(
193 ScopedPPVar::PassRef(),
194 PpapiGlobals::Get()->GetVarTracker()->MakeResourcePPVar(34));
195 EXPECT_TRUE(WriteReadAndCompare(resource
.get()));
197 // TODO(mgiuca): Test a host resource with an IPC::Message. It is currently a
198 // checkfail to deserialize such a resource.