Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(499)

Side by Side Diff: mojo/edk/js/tests/js_to_cpp_tests.cc

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/edk/js/tests/js_to_cpp.mojom ('k') | mojo/edk/js/tests/js_to_cpp_tests.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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 "base/at_exit.h"
6 #include "base/files/file_path.h"
7 #include "base/files/file_util.h"
8 #include "base/macros.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "gin/array_buffer.h"
13 #include "gin/public/isolate_holder.h"
14 #include "mojo/edk/js/mojo_runner_delegate.h"
15 #include "mojo/edk/js/tests/js_to_cpp.mojom.h"
16 #include "mojo/edk/test/test_utils.h"
17 #include "mojo/public/cpp/system/core.h"
18 #include "mojo/public/cpp/system/macros.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace mojo {
22 namespace js {
23
24 // Global value updated by some checks to prevent compilers from optimizing
25 // reads out of existence.
26 uint32 g_waste_accumulator = 0;
27
28 namespace {
29
30 // Negative numbers with different values in each byte, the last of
31 // which can survive promotion to double and back.
32 const int8 kExpectedInt8Value = -65;
33 const int16 kExpectedInt16Value = -16961;
34 const int32 kExpectedInt32Value = -1145258561;
35 const int64 kExpectedInt64Value = -77263311946305LL;
36
37 // Positive numbers with different values in each byte, the last of
38 // which can survive promotion to double and back.
39 const uint8 kExpectedUInt8Value = 65;
40 const uint16 kExpectedUInt16Value = 16961;
41 const uint32 kExpectedUInt32Value = 1145258561;
42 const uint64 kExpectedUInt64Value = 77263311946305LL;
43
44 // Double/float values, including special case constants.
45 const double kExpectedDoubleVal = 3.14159265358979323846;
46 const double kExpectedDoubleInf = std::numeric_limits<double>::infinity();
47 const double kExpectedDoubleNan = std::numeric_limits<double>::quiet_NaN();
48 const float kExpectedFloatVal = static_cast<float>(kExpectedDoubleVal);
49 const float kExpectedFloatInf = std::numeric_limits<float>::infinity();
50 const float kExpectedFloatNan = std::numeric_limits<float>::quiet_NaN();
51
52 // NaN has the property that it is not equal to itself.
53 #define EXPECT_NAN(x) EXPECT_NE(x, x)
54
55 void CheckDataPipe(MojoHandle data_pipe_handle) {
56 unsigned char buffer[100];
57 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
58 MojoResult result = MojoReadData(
59 data_pipe_handle, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE);
60 EXPECT_EQ(MOJO_RESULT_OK, result);
61 EXPECT_EQ(64u, buffer_size);
62 for (int i = 0; i < 64; ++i) {
63 EXPECT_EQ(i, buffer[i]);
64 }
65 }
66
67 void CheckMessagePipe(MojoHandle message_pipe_handle) {
68 unsigned char buffer[100];
69 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
70 MojoResult result = MojoReadMessage(
71 message_pipe_handle, buffer, &buffer_size, 0, 0, 0);
72 EXPECT_EQ(MOJO_RESULT_OK, result);
73 EXPECT_EQ(64u, buffer_size);
74 for (int i = 0; i < 64; ++i) {
75 EXPECT_EQ(255 - i, buffer[i]);
76 }
77 }
78
79 js_to_cpp::EchoArgsPtr BuildSampleEchoArgs() {
80 js_to_cpp::EchoArgsPtr args(js_to_cpp::EchoArgs::New());
81 args->si64 = kExpectedInt64Value;
82 args->si32 = kExpectedInt32Value;
83 args->si16 = kExpectedInt16Value;
84 args->si8 = kExpectedInt8Value;
85 args->ui64 = kExpectedUInt64Value;
86 args->ui32 = kExpectedUInt32Value;
87 args->ui16 = kExpectedUInt16Value;
88 args->ui8 = kExpectedUInt8Value;
89 args->float_val = kExpectedFloatVal;
90 args->float_inf = kExpectedFloatInf;
91 args->float_nan = kExpectedFloatNan;
92 args->double_val = kExpectedDoubleVal;
93 args->double_inf = kExpectedDoubleInf;
94 args->double_nan = kExpectedDoubleNan;
95 args->name = "coming";
96 Array<String> string_array(3);
97 string_array[0] = "one";
98 string_array[1] = "two";
99 string_array[2] = "three";
100 args->string_array = string_array.Pass();
101 return args.Pass();
102 }
103
104 void CheckSampleEchoArgs(const js_to_cpp::EchoArgs& arg) {
105 EXPECT_EQ(kExpectedInt64Value, arg.si64);
106 EXPECT_EQ(kExpectedInt32Value, arg.si32);
107 EXPECT_EQ(kExpectedInt16Value, arg.si16);
108 EXPECT_EQ(kExpectedInt8Value, arg.si8);
109 EXPECT_EQ(kExpectedUInt64Value, arg.ui64);
110 EXPECT_EQ(kExpectedUInt32Value, arg.ui32);
111 EXPECT_EQ(kExpectedUInt16Value, arg.ui16);
112 EXPECT_EQ(kExpectedUInt8Value, arg.ui8);
113 EXPECT_EQ(kExpectedFloatVal, arg.float_val);
114 EXPECT_EQ(kExpectedFloatInf, arg.float_inf);
115 EXPECT_NAN(arg.float_nan);
116 EXPECT_EQ(kExpectedDoubleVal, arg.double_val);
117 EXPECT_EQ(kExpectedDoubleInf, arg.double_inf);
118 EXPECT_NAN(arg.double_nan);
119 EXPECT_EQ(std::string("coming"), arg.name.get());
120 EXPECT_EQ(std::string("one"), arg.string_array[0].get());
121 EXPECT_EQ(std::string("two"), arg.string_array[1].get());
122 EXPECT_EQ(std::string("three"), arg.string_array[2].get());
123 CheckDataPipe(arg.data_handle.get().value());
124 CheckMessagePipe(arg.message_handle.get().value());
125 }
126
127 void CheckSampleEchoArgsList(const js_to_cpp::EchoArgsListPtr& list) {
128 if (list.is_null())
129 return;
130 CheckSampleEchoArgs(*list->item);
131 CheckSampleEchoArgsList(list->next);
132 }
133
134 // More forgiving checks are needed in the face of potentially corrupt
135 // messages. The values don't matter so long as all accesses are within
136 // bounds.
137 void CheckCorruptedString(const String& arg) {
138 if (arg.is_null())
139 return;
140 for (size_t i = 0; i < arg.size(); ++i)
141 g_waste_accumulator += arg[i];
142 }
143
144 void CheckCorruptedStringArray(const Array<String>& string_array) {
145 if (string_array.is_null())
146 return;
147 for (size_t i = 0; i < string_array.size(); ++i)
148 CheckCorruptedString(string_array[i]);
149 }
150
151 void CheckCorruptedDataPipe(MojoHandle data_pipe_handle) {
152 unsigned char buffer[100];
153 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
154 MojoResult result = MojoReadData(
155 data_pipe_handle, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE);
156 if (result != MOJO_RESULT_OK)
157 return;
158 for (uint32_t i = 0; i < buffer_size; ++i)
159 g_waste_accumulator += buffer[i];
160 }
161
162 void CheckCorruptedMessagePipe(MojoHandle message_pipe_handle) {
163 unsigned char buffer[100];
164 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
165 MojoResult result = MojoReadMessage(
166 message_pipe_handle, buffer, &buffer_size, 0, 0, 0);
167 if (result != MOJO_RESULT_OK)
168 return;
169 for (uint32_t i = 0; i < buffer_size; ++i)
170 g_waste_accumulator += buffer[i];
171 }
172
173 void CheckCorruptedEchoArgs(const js_to_cpp::EchoArgsPtr& arg) {
174 if (arg.is_null())
175 return;
176 CheckCorruptedString(arg->name);
177 CheckCorruptedStringArray(arg->string_array);
178 if (arg->data_handle.is_valid())
179 CheckCorruptedDataPipe(arg->data_handle.get().value());
180 if (arg->message_handle.is_valid())
181 CheckCorruptedMessagePipe(arg->message_handle.get().value());
182 }
183
184 void CheckCorruptedEchoArgsList(const js_to_cpp::EchoArgsListPtr& list) {
185 if (list.is_null())
186 return;
187 CheckCorruptedEchoArgs(list->item);
188 CheckCorruptedEchoArgsList(list->next);
189 }
190
191 // Base Provider implementation class. It's expected that tests subclass and
192 // override the appropriate Provider functions. When test is done quit the
193 // run_loop().
194 class CppSideConnection : public js_to_cpp::CppSide {
195 public:
196 CppSideConnection() :
197 run_loop_(NULL),
198 js_side_(NULL),
199 mishandled_messages_(0) {
200 }
201 ~CppSideConnection() override {}
202
203 void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
204 base::RunLoop* run_loop() { return run_loop_; }
205
206 void set_js_side(js_to_cpp::JsSide* js_side) { js_side_ = js_side; }
207 js_to_cpp::JsSide* js_side() { return js_side_; }
208
209 // js_to_cpp::CppSide:
210 void StartTest() override { NOTREACHED(); }
211
212 void TestFinished() override { NOTREACHED(); }
213
214 void PingResponse() override { mishandled_messages_ += 1; }
215
216 void EchoResponse(js_to_cpp::EchoArgsListPtr list) override {
217 mishandled_messages_ += 1;
218 }
219
220 void BitFlipResponse(js_to_cpp::EchoArgsListPtr list) override {
221 mishandled_messages_ += 1;
222 }
223
224 void BackPointerResponse(js_to_cpp::EchoArgsListPtr list) override {
225 mishandled_messages_ += 1;
226 }
227
228 protected:
229 base::RunLoop* run_loop_;
230 js_to_cpp::JsSide* js_side_;
231 int mishandled_messages_;
232
233 private:
234 DISALLOW_COPY_AND_ASSIGN(CppSideConnection);
235 };
236
237 // Trivial test to verify a message sent from JS is received.
238 class PingCppSideConnection : public CppSideConnection {
239 public:
240 PingCppSideConnection() : got_message_(false) {}
241 ~PingCppSideConnection() override {}
242
243 // js_to_cpp::CppSide:
244 void StartTest() override { js_side_->Ping(); }
245
246 void PingResponse() override {
247 got_message_ = true;
248 run_loop()->Quit();
249 }
250
251 bool DidSucceed() {
252 return got_message_ && !mishandled_messages_;
253 }
254
255 private:
256 bool got_message_;
257 DISALLOW_COPY_AND_ASSIGN(PingCppSideConnection);
258 };
259
260 // Test that parameters are passed with correct values.
261 class EchoCppSideConnection : public CppSideConnection {
262 public:
263 EchoCppSideConnection() :
264 message_count_(0),
265 termination_seen_(false) {
266 }
267 ~EchoCppSideConnection() override {}
268
269 // js_to_cpp::CppSide:
270 void StartTest() override {
271 js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgs());
272 }
273
274 void EchoResponse(js_to_cpp::EchoArgsListPtr list) override {
275 const js_to_cpp::EchoArgsPtr& special_arg = list->item;
276 message_count_ += 1;
277 EXPECT_EQ(-1, special_arg->si64);
278 EXPECT_EQ(-1, special_arg->si32);
279 EXPECT_EQ(-1, special_arg->si16);
280 EXPECT_EQ(-1, special_arg->si8);
281 EXPECT_EQ(std::string("going"), special_arg->name.To<std::string>());
282 CheckSampleEchoArgsList(list->next);
283 }
284
285 void TestFinished() override {
286 termination_seen_ = true;
287 run_loop()->Quit();
288 }
289
290 bool DidSucceed() {
291 return termination_seen_ &&
292 !mishandled_messages_ &&
293 message_count_ == kExpectedMessageCount;
294 }
295
296 private:
297 static const int kExpectedMessageCount = 10;
298 int message_count_;
299 bool termination_seen_;
300 DISALLOW_COPY_AND_ASSIGN(EchoCppSideConnection);
301 };
302
303 // Test that corrupted messages don't wreak havoc.
304 class BitFlipCppSideConnection : public CppSideConnection {
305 public:
306 BitFlipCppSideConnection() : termination_seen_(false) {}
307 ~BitFlipCppSideConnection() override {}
308
309 // js_to_cpp::CppSide:
310 void StartTest() override { js_side_->BitFlip(BuildSampleEchoArgs()); }
311
312 void BitFlipResponse(js_to_cpp::EchoArgsListPtr list) override {
313 CheckCorruptedEchoArgsList(list);
314 }
315
316 void TestFinished() override {
317 termination_seen_ = true;
318 run_loop()->Quit();
319 }
320
321 bool DidSucceed() {
322 return termination_seen_;
323 }
324
325 private:
326 bool termination_seen_;
327 DISALLOW_COPY_AND_ASSIGN(BitFlipCppSideConnection);
328 };
329
330 // Test that severely random messages don't wreak havoc.
331 class BackPointerCppSideConnection : public CppSideConnection {
332 public:
333 BackPointerCppSideConnection() : termination_seen_(false) {}
334 ~BackPointerCppSideConnection() override {}
335
336 // js_to_cpp::CppSide:
337 void StartTest() override { js_side_->BackPointer(BuildSampleEchoArgs()); }
338
339 void BackPointerResponse(js_to_cpp::EchoArgsListPtr list) override {
340 CheckCorruptedEchoArgsList(list);
341 }
342
343 void TestFinished() override {
344 termination_seen_ = true;
345 run_loop()->Quit();
346 }
347
348 bool DidSucceed() {
349 return termination_seen_;
350 }
351
352 private:
353 bool termination_seen_;
354 DISALLOW_COPY_AND_ASSIGN(BackPointerCppSideConnection);
355 };
356
357 } // namespace
358
359 class JsToCppTest : public testing::Test {
360 public:
361 JsToCppTest() {}
362
363 void RunTest(const std::string& test, CppSideConnection* cpp_side) {
364 cpp_side->set_run_loop(&run_loop_);
365
366 MessagePipe pipe;
367 js_to_cpp::JsSidePtr js_side =
368 MakeProxy<js_to_cpp::JsSide>(pipe.handle0.Pass());
369 js_side.set_client(cpp_side);
370
371 js_side.internal_state()->router_for_testing()->EnableTestingMode();
372
373 cpp_side->set_js_side(js_side.get());
374
375 gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
376 gin::ArrayBufferAllocator::SharedInstance());
377 gin::IsolateHolder instance;
378 MojoRunnerDelegate delegate;
379 gin::ShellRunner runner(&delegate, instance.isolate());
380 delegate.Start(&runner, pipe.handle1.release().value(), test);
381
382 run_loop_.Run();
383 }
384
385 private:
386 base::ShadowingAtExitManager at_exit_;
387 base::MessageLoop loop;
388 base::RunLoop run_loop_;
389
390 DISALLOW_COPY_AND_ASSIGN(JsToCppTest);
391 };
392
393 TEST_F(JsToCppTest, Ping) {
394 PingCppSideConnection cpp_side_connection;
395 RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
396 EXPECT_TRUE(cpp_side_connection.DidSucceed());
397 }
398
399 TEST_F(JsToCppTest, Echo) {
400 EchoCppSideConnection cpp_side_connection;
401 RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
402 EXPECT_TRUE(cpp_side_connection.DidSucceed());
403 }
404
405 TEST_F(JsToCppTest, BitFlip) {
406 BitFlipCppSideConnection cpp_side_connection;
407 RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
408 EXPECT_TRUE(cpp_side_connection.DidSucceed());
409 }
410
411 TEST_F(JsToCppTest, BackPointer) {
412 BackPointerCppSideConnection cpp_side_connection;
413 RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
414 EXPECT_TRUE(cpp_side_connection.DidSucceed());
415 }
416
417 } // namespace js
418 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/js/tests/js_to_cpp.mojom ('k') | mojo/edk/js/tests/js_to_cpp_tests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698