diff options
author | Hidehiko Abe <hidehiko@google.com> | 2018-04-24 02:15:00 +0900 |
---|---|---|
committer | Hidehiko Abe <hidehiko@google.com> | 2018-04-24 10:13:47 +0900 |
commit | 920588a1acdc4721abb713d8162010e4b85ae53e (patch) | |
tree | 5d0b02a305d2ce5e91eb915695a338dabff2ed6b /mojo/public/cpp/bindings/tests | |
parent | ca6c42abc66e142da1036f0061976d671862c457 (diff) | |
download | libmojo-920588a1acdc4721abb713d8162010e4b85ae53e.tar.gz |
Migrate libmojo repository into libchrome, part 2.HEADandroid-o-mr1-iot-release-smart-display-r9android-o-mr1-iot-release-smart-display-r8android-o-mr1-iot-release-smart-display-r5android-o-mr1-iot-release-smart-display-r40.1Jandroid-o-mr1-iot-release-smart-display-r4android-o-mr1-iot-release-smart-display-r39android-o-mr1-iot-release-smart-display-r30android-o-mr1-iot-release-smart-display-r3android-o-mr1-iot-release-smart-display-r22android-o-mr1-iot-release-smart-display-r14android-o-mr1-iot-release-smart-clock-r6android-o-mr1-iot-release-smart-clock-r2android-o-mr1-iot-release-smart-clock-fsiandroid-o-mr1-iot-release-smart-clock-fcsandroid-o-mr1-iot-release-cube_r2android-o-mr1-iot-release-cube-fsiandroid-o-mr1-iot-release-cube-fcsandroid-o-mr1-iot-release-1.0.8android-o-mr1-iot-release-1.0.7android-o-mr1-iot-release-1.0.5android-o-mr1-iot-release-1.0.4android-o-mr1-iot-release-1.0.3android-o-mr1-iot-release-1.0.2android-o-mr1-iot-release-1.0.14android-o-mr1-iot-release-1.0.13android-o-mr1-iot-release-1.0.12android-o-mr1-iot-release-1.0.10android-o-mr1-iot-release-1.0.1android-o-mr1-iot-release-1.0.0oreo-mr1-iot-releaseoreo-mr1-1.2-iot-releasemastermain
This CL moves following files.
- .gitignore
- Android.bp is merged into libchrome's Android.bp.
- base/android/*
- build/* except build_config.h which is exactly same with libchrome's.
- ipc/*
- mojo/*
- soong/* into libchrome_tools/
- third_party/{catapult,jinja2,markupsafe,ply}/*
- ui/gfx/{geometry,range}/mojo/*
Then removed following files:
- Android.bp
- CleanSpec.mk
- build/build_config.h
And added README.md to notify the migration.
Bug: 73606903
Test: Built locally. Ran on DUT.
Change-Id: I94aa1b43ff0854f48f30fdf03025bd1c8a346038
Diffstat (limited to 'mojo/public/cpp/bindings/tests')
67 files changed, 0 insertions, 14811 deletions
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn deleted file mode 100644 index 668ca6d..0000000 --- a/mojo/public/cpp/bindings/tests/BUILD.gn +++ /dev/null @@ -1,146 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("tests") { - testonly = true - - sources = [ - "associated_interface_unittest.cc", - "bind_task_runner_unittest.cc", - "binding_callback_unittest.cc", - "binding_set_unittest.cc", - "binding_unittest.cc", - "buffer_unittest.cc", - "connector_unittest.cc", - "constant_unittest.cc", - "container_test_util.cc", - "container_test_util.h", - "data_view_unittest.cc", - "equals_unittest.cc", - "handle_passing_unittest.cc", - "hash_unittest.cc", - "interface_ptr_unittest.cc", - "map_unittest.cc", - "message_queue.cc", - "message_queue.h", - "multiplex_router_unittest.cc", - "report_bad_message_unittest.cc", - "request_response_unittest.cc", - "router_test_util.cc", - "router_test_util.h", - "sample_service_unittest.cc", - "serialization_warning_unittest.cc", - "struct_unittest.cc", - "sync_method_unittest.cc", - "type_conversion_unittest.cc", - "union_unittest.cc", - "validation_context_unittest.cc", - "validation_unittest.cc", - "variant_test_util.h", - ] - - deps = [ - ":mojo_public_bindings_test_utils", - "//base/test:test_support", - "//mojo/edk/system", - "//mojo/public/cpp/bindings", - "//mojo/public/cpp/system", - "//mojo/public/cpp/test_support:test_utils", - "//mojo/public/interfaces/bindings/tests:test_associated_interfaces", - "//mojo/public/interfaces/bindings/tests:test_export_component", - "//mojo/public/interfaces/bindings/tests:test_export_component2", - "//mojo/public/interfaces/bindings/tests:test_exported_import", - "//mojo/public/interfaces/bindings/tests:test_interfaces", - "//mojo/public/interfaces/bindings/tests:test_struct_traits_interfaces", - "//testing/gtest", - ] - - data = [ - "//mojo/public/interfaces/bindings/tests/data/validation/", - ] - - if (is_ios) { - assert_no_deps = [ "//third_party/WebKit/*" ] - } else { - sources += [ - "pickle_unittest.cc", - "struct_traits_unittest.cc", - ] - - deps += [ "//mojo/public/interfaces/bindings/tests:test_interfaces_blink" ] - } -} - -if (!is_ios) { - source_set("for_blink_tests") { - testonly = true - - sources = [ - "container_test_util.cc", - "container_test_util.h", - "variant_test_util.h", - "wtf_hash_unittest.cc", - "wtf_map_unittest.cc", - "wtf_types_unittest.cc", - ] - - deps = [ - "//mojo/public/cpp/bindings", - "//mojo/public/cpp/system", - "//mojo/public/interfaces/bindings/tests:test_export_blink_component", - "//mojo/public/interfaces/bindings/tests:test_exported_import_blink", - "//mojo/public/interfaces/bindings/tests:test_interfaces", - "//mojo/public/interfaces/bindings/tests:test_interfaces_blink", - "//mojo/public/interfaces/bindings/tests:test_wtf_types", - "//mojo/public/interfaces/bindings/tests:test_wtf_types_blink", - "//testing/gtest", - ] - } -} - -source_set("struct_with_traits_impl") { - sources = [ - "struct_with_traits_impl.cc", - "struct_with_traits_impl.h", - ] - - deps = [ - "//base", - "//mojo/public/cpp/system:system", - ] -} - -source_set("perftests") { - testonly = true - - sources = [ - "bindings_perftest.cc", - ] - - if (!is_ios) { - sources += [ "e2e_perftest.cc" ] - } - - deps = [ - "//base/test:test_support", - "//mojo/edk/system", - "//mojo/edk/test:test_support", - "//mojo/public/cpp/bindings", - "//mojo/public/cpp/system", - "//mojo/public/cpp/test_support:test_utils", - "//mojo/public/interfaces/bindings/tests:test_interfaces", - "//testing/gtest", - ] -} - -source_set("mojo_public_bindings_test_utils") { - sources = [ - "validation_test_input_parser.cc", - "validation_test_input_parser.h", - ] - - deps = [ - "//mojo/public/c/system", - ] -} diff --git a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc deleted file mode 100644 index be225e4..0000000 --- a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc +++ /dev/null @@ -1,1189 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> -#include <algorithm> -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/callback_helpers.h" -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/threading/thread.h" -#include "base/threading/thread_task_runner_handle.h" -#include "mojo/public/cpp/bindings/associated_binding.h" -#include "mojo/public/cpp/bindings/associated_interface_ptr.h" -#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h" -#include "mojo/public/cpp/bindings/associated_interface_request.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/lib/multiplex_router.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h" -#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" -#include "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -using mojo::internal::MultiplexRouter; - -class IntegerSenderImpl : public IntegerSender { - public: - explicit IntegerSenderImpl(AssociatedInterfaceRequest<IntegerSender> request) - : binding_(this, std::move(request)) {} - - ~IntegerSenderImpl() override {} - - void set_notify_send_method_called( - const base::Callback<void(int32_t)>& callback) { - notify_send_method_called_ = callback; - } - - void Echo(int32_t value, const EchoCallback& callback) override { - callback.Run(value); - } - void Send(int32_t value) override { notify_send_method_called_.Run(value); } - - AssociatedBinding<IntegerSender>* binding() { return &binding_; } - - void set_connection_error_handler(const base::Closure& handler) { - binding_.set_connection_error_handler(handler); - } - - private: - AssociatedBinding<IntegerSender> binding_; - base::Callback<void(int32_t)> notify_send_method_called_; -}; - -class IntegerSenderConnectionImpl : public IntegerSenderConnection { - public: - explicit IntegerSenderConnectionImpl( - InterfaceRequest<IntegerSenderConnection> request) - : binding_(this, std::move(request)) {} - - ~IntegerSenderConnectionImpl() override {} - - void GetSender(AssociatedInterfaceRequest<IntegerSender> sender) override { - IntegerSenderImpl* sender_impl = new IntegerSenderImpl(std::move(sender)); - sender_impl->set_connection_error_handler( - base::Bind(&DeleteSender, sender_impl)); - } - - void AsyncGetSender(const AsyncGetSenderCallback& callback) override { - IntegerSenderAssociatedPtrInfo ptr_info; - auto request = MakeRequest(&ptr_info); - GetSender(std::move(request)); - callback.Run(std::move(ptr_info)); - } - - Binding<IntegerSenderConnection>* binding() { return &binding_; } - - private: - static void DeleteSender(IntegerSenderImpl* sender) { delete sender; } - - Binding<IntegerSenderConnection> binding_; -}; - -class AssociatedInterfaceTest : public testing::Test { - public: - AssociatedInterfaceTest() {} - ~AssociatedInterfaceTest() override { base::RunLoop().RunUntilIdle(); } - - void PumpMessages() { base::RunLoop().RunUntilIdle(); } - - template <typename T> - AssociatedInterfacePtrInfo<T> EmulatePassingAssociatedPtrInfo( - AssociatedInterfacePtrInfo<T> ptr_info, - scoped_refptr<MultiplexRouter> source, - scoped_refptr<MultiplexRouter> target) { - ScopedInterfaceEndpointHandle handle = ptr_info.PassHandle(); - CHECK(handle.pending_association()); - auto id = source->AssociateInterface(std::move(handle)); - return AssociatedInterfacePtrInfo<T>(target->CreateLocalEndpointHandle(id), - ptr_info.version()); - } - - void CreateRouterPair(scoped_refptr<MultiplexRouter>* router0, - scoped_refptr<MultiplexRouter>* router1) { - MessagePipe pipe; - *router0 = new MultiplexRouter(std::move(pipe.handle0), - MultiplexRouter::MULTI_INTERFACE, true, - base::ThreadTaskRunnerHandle::Get()); - *router1 = new MultiplexRouter(std::move(pipe.handle1), - MultiplexRouter::MULTI_INTERFACE, false, - base::ThreadTaskRunnerHandle::Get()); - } - - void CreateIntegerSenderWithExistingRouters( - scoped_refptr<MultiplexRouter> router0, - IntegerSenderAssociatedPtrInfo* ptr_info0, - scoped_refptr<MultiplexRouter> router1, - IntegerSenderAssociatedRequest* request1) { - *request1 = MakeRequest(ptr_info0); - *ptr_info0 = EmulatePassingAssociatedPtrInfo(std::move(*ptr_info0), router1, - router0); - } - - void CreateIntegerSender(IntegerSenderAssociatedPtrInfo* ptr_info, - IntegerSenderAssociatedRequest* request) { - scoped_refptr<MultiplexRouter> router0; - scoped_refptr<MultiplexRouter> router1; - CreateRouterPair(&router0, &router1); - CreateIntegerSenderWithExistingRouters(router1, ptr_info, router0, request); - } - - // Okay to call from any thread. - void QuitRunLoop(base::RunLoop* run_loop) { - if (loop_.task_runner()->BelongsToCurrentThread()) { - run_loop->Quit(); - } else { - loop_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&AssociatedInterfaceTest::QuitRunLoop, - base::Unretained(this), base::Unretained(run_loop))); - } - } - - private: - base::MessageLoop loop_; -}; - -void DoSetFlagAndRunClosure(bool* flag, const base::Closure& closure) { - *flag = true; - closure.Run(); -} - -void DoExpectValueSetFlagAndRunClosure(int32_t expected_value, - bool* flag, - const base::Closure& closure, - int32_t value) { - EXPECT_EQ(expected_value, value); - DoSetFlagAndRunClosure(flag, closure); -} - -base::Closure SetFlagAndRunClosure(bool* flag, const base::Closure& closure) { - return base::Bind(&DoSetFlagAndRunClosure, flag, closure); -} - -base::Callback<void(int32_t)> ExpectValueSetFlagAndRunClosure( - int32_t expected_value, - bool* flag, - const base::Closure& closure) { - return base::Bind( - &DoExpectValueSetFlagAndRunClosure, expected_value, flag, closure); -} - -void Fail() { - FAIL() << "Unexpected connection error"; -} - -TEST_F(AssociatedInterfaceTest, InterfacesAtBothEnds) { - // Bind to the same pipe two associated interfaces, whose implementation lives - // at different ends. Test that the two don't interfere with each other. - - scoped_refptr<MultiplexRouter> router0; - scoped_refptr<MultiplexRouter> router1; - CreateRouterPair(&router0, &router1); - - AssociatedInterfaceRequest<IntegerSender> request; - IntegerSenderAssociatedPtrInfo ptr_info; - CreateIntegerSenderWithExistingRouters(router1, &ptr_info, router0, &request); - - IntegerSenderImpl impl0(std::move(request)); - AssociatedInterfacePtr<IntegerSender> ptr0; - ptr0.Bind(std::move(ptr_info)); - - CreateIntegerSenderWithExistingRouters(router0, &ptr_info, router1, &request); - - IntegerSenderImpl impl1(std::move(request)); - AssociatedInterfacePtr<IntegerSender> ptr1; - ptr1.Bind(std::move(ptr_info)); - - base::RunLoop run_loop, run_loop2; - bool ptr0_callback_run = false; - ptr0->Echo(123, ExpectValueSetFlagAndRunClosure(123, &ptr0_callback_run, - run_loop.QuitClosure())); - - bool ptr1_callback_run = false; - ptr1->Echo(456, ExpectValueSetFlagAndRunClosure(456, &ptr1_callback_run, - run_loop2.QuitClosure())); - - run_loop.Run(); - run_loop2.Run(); - EXPECT_TRUE(ptr0_callback_run); - EXPECT_TRUE(ptr1_callback_run); - - bool ptr0_error_callback_run = false; - base::RunLoop run_loop3; - ptr0.set_connection_error_handler( - SetFlagAndRunClosure(&ptr0_error_callback_run, run_loop3.QuitClosure())); - - impl0.binding()->Close(); - run_loop3.Run(); - EXPECT_TRUE(ptr0_error_callback_run); - - bool impl1_error_callback_run = false; - base::RunLoop run_loop4; - impl1.binding()->set_connection_error_handler( - SetFlagAndRunClosure(&impl1_error_callback_run, run_loop4.QuitClosure())); - - ptr1.reset(); - run_loop4.Run(); - EXPECT_TRUE(impl1_error_callback_run); -} - -class TestSender { - public: - TestSender() - : sender_thread_("TestSender"), - next_sender_(nullptr), - max_value_to_send_(-1) { - sender_thread_.Start(); - } - - // The following three methods are called on the corresponding sender thread. - void SetUp(IntegerSenderAssociatedPtrInfo ptr_info, - TestSender* next_sender, - int32_t max_value_to_send) { - CHECK(sender_thread_.task_runner()->BelongsToCurrentThread()); - - ptr_.Bind(std::move(ptr_info)); - next_sender_ = next_sender ? next_sender : this; - max_value_to_send_ = max_value_to_send; - } - - void Send(int32_t value) { - CHECK(sender_thread_.task_runner()->BelongsToCurrentThread()); - - if (value > max_value_to_send_) - return; - - ptr_->Send(value); - - next_sender_->sender_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&TestSender::Send, base::Unretained(next_sender_), ++value)); - } - - void TearDown() { - CHECK(sender_thread_.task_runner()->BelongsToCurrentThread()); - - ptr_.reset(); - } - - base::Thread* sender_thread() { return &sender_thread_; } - - private: - base::Thread sender_thread_; - TestSender* next_sender_; - int32_t max_value_to_send_; - - AssociatedInterfacePtr<IntegerSender> ptr_; -}; - -class TestReceiver { - public: - TestReceiver() : receiver_thread_("TestReceiver"), expected_calls_(0) { - receiver_thread_.Start(); - } - - void SetUp(AssociatedInterfaceRequest<IntegerSender> request0, - AssociatedInterfaceRequest<IntegerSender> request1, - size_t expected_calls, - const base::Closure& notify_finish) { - CHECK(receiver_thread_.task_runner()->BelongsToCurrentThread()); - - impl0_.reset(new IntegerSenderImpl(std::move(request0))); - impl0_->set_notify_send_method_called( - base::Bind(&TestReceiver::SendMethodCalled, base::Unretained(this))); - impl1_.reset(new IntegerSenderImpl(std::move(request1))); - impl1_->set_notify_send_method_called( - base::Bind(&TestReceiver::SendMethodCalled, base::Unretained(this))); - - expected_calls_ = expected_calls; - notify_finish_ = notify_finish; - } - - void TearDown() { - CHECK(receiver_thread_.task_runner()->BelongsToCurrentThread()); - - impl0_.reset(); - impl1_.reset(); - } - - base::Thread* receiver_thread() { return &receiver_thread_; } - const std::vector<int32_t>& values() const { return values_; } - - private: - void SendMethodCalled(int32_t value) { - values_.push_back(value); - - if (values_.size() >= expected_calls_) - notify_finish_.Run(); - } - - base::Thread receiver_thread_; - size_t expected_calls_; - - std::unique_ptr<IntegerSenderImpl> impl0_; - std::unique_ptr<IntegerSenderImpl> impl1_; - - std::vector<int32_t> values_; - - base::Closure notify_finish_; -}; - -class NotificationCounter { - public: - NotificationCounter(size_t total_count, const base::Closure& notify_finish) - : total_count_(total_count), - current_count_(0), - notify_finish_(notify_finish) {} - - ~NotificationCounter() {} - - // Okay to call from any thread. - void OnGotNotification() { - bool finshed = false; - { - base::AutoLock locker(lock_); - CHECK_LT(current_count_, total_count_); - current_count_++; - finshed = current_count_ == total_count_; - } - - if (finshed) - notify_finish_.Run(); - } - - private: - base::Lock lock_; - const size_t total_count_; - size_t current_count_; - base::Closure notify_finish_; -}; - -TEST_F(AssociatedInterfaceTest, MultiThreadAccess) { - // Set up four associated interfaces on a message pipe. Use the inteface - // pointers on four threads in parallel; run the interface implementations on - // two threads. Test that multi-threaded access works. - - const int32_t kMaxValue = 1000; - MessagePipe pipe; - scoped_refptr<MultiplexRouter> router0; - scoped_refptr<MultiplexRouter> router1; - CreateRouterPair(&router0, &router1); - - AssociatedInterfaceRequest<IntegerSender> requests[4]; - IntegerSenderAssociatedPtrInfo ptr_infos[4]; - for (size_t i = 0; i < 4; ++i) { - CreateIntegerSenderWithExistingRouters(router1, &ptr_infos[i], router0, - &requests[i]); - } - - TestSender senders[4]; - for (size_t i = 0; i < 4; ++i) { - senders[i].sender_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&TestSender::SetUp, base::Unretained(&senders[i]), - base::Passed(&ptr_infos[i]), nullptr, - kMaxValue * (i + 1) / 4)); - } - - base::RunLoop run_loop; - TestReceiver receivers[2]; - NotificationCounter counter( - 2, base::Bind(&AssociatedInterfaceTest::QuitRunLoop, - base::Unretained(this), base::Unretained(&run_loop))); - for (size_t i = 0; i < 2; ++i) { - receivers[i].receiver_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&TestReceiver::SetUp, base::Unretained(&receivers[i]), - base::Passed(&requests[2 * i]), - base::Passed(&requests[2 * i + 1]), - static_cast<size_t>(kMaxValue / 2), - base::Bind(&NotificationCounter::OnGotNotification, - base::Unretained(&counter)))); - } - - for (size_t i = 0; i < 4; ++i) { - senders[i].sender_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&TestSender::Send, base::Unretained(&senders[i]), - kMaxValue * i / 4 + 1)); - } - - run_loop.Run(); - - for (size_t i = 0; i < 4; ++i) { - base::RunLoop run_loop; - senders[i].sender_thread()->task_runner()->PostTaskAndReply( - FROM_HERE, - base::Bind(&TestSender::TearDown, base::Unretained(&senders[i])), - base::Bind(&AssociatedInterfaceTest::QuitRunLoop, - base::Unretained(this), base::Unretained(&run_loop))); - run_loop.Run(); - } - - for (size_t i = 0; i < 2; ++i) { - base::RunLoop run_loop; - receivers[i].receiver_thread()->task_runner()->PostTaskAndReply( - FROM_HERE, - base::Bind(&TestReceiver::TearDown, base::Unretained(&receivers[i])), - base::Bind(&AssociatedInterfaceTest::QuitRunLoop, - base::Unretained(this), base::Unretained(&run_loop))); - run_loop.Run(); - } - - EXPECT_EQ(static_cast<size_t>(kMaxValue / 2), receivers[0].values().size()); - EXPECT_EQ(static_cast<size_t>(kMaxValue / 2), receivers[1].values().size()); - - std::vector<int32_t> all_values; - all_values.insert(all_values.end(), receivers[0].values().begin(), - receivers[0].values().end()); - all_values.insert(all_values.end(), receivers[1].values().begin(), - receivers[1].values().end()); - - std::sort(all_values.begin(), all_values.end()); - for (size_t i = 0; i < all_values.size(); ++i) - ASSERT_EQ(static_cast<int32_t>(i + 1), all_values[i]); -} - -TEST_F(AssociatedInterfaceTest, FIFO) { - // Set up four associated interfaces on a message pipe. Use the inteface - // pointers on four threads; run the interface implementations on two threads. - // Take turns to make calls using the four pointers. Test that FIFO-ness is - // preserved. - - const int32_t kMaxValue = 100; - MessagePipe pipe; - scoped_refptr<MultiplexRouter> router0; - scoped_refptr<MultiplexRouter> router1; - CreateRouterPair(&router0, &router1); - - AssociatedInterfaceRequest<IntegerSender> requests[4]; - IntegerSenderAssociatedPtrInfo ptr_infos[4]; - for (size_t i = 0; i < 4; ++i) { - CreateIntegerSenderWithExistingRouters(router1, &ptr_infos[i], router0, - &requests[i]); - } - - TestSender senders[4]; - for (size_t i = 0; i < 4; ++i) { - senders[i].sender_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&TestSender::SetUp, base::Unretained(&senders[i]), - base::Passed(&ptr_infos[i]), - base::Unretained(&senders[(i + 1) % 4]), kMaxValue)); - } - - base::RunLoop run_loop; - TestReceiver receivers[2]; - NotificationCounter counter( - 2, base::Bind(&AssociatedInterfaceTest::QuitRunLoop, - base::Unretained(this), base::Unretained(&run_loop))); - for (size_t i = 0; i < 2; ++i) { - receivers[i].receiver_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&TestReceiver::SetUp, base::Unretained(&receivers[i]), - base::Passed(&requests[2 * i]), - base::Passed(&requests[2 * i + 1]), - static_cast<size_t>(kMaxValue / 2), - base::Bind(&NotificationCounter::OnGotNotification, - base::Unretained(&counter)))); - } - - senders[0].sender_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&TestSender::Send, base::Unretained(&senders[0]), 1)); - - run_loop.Run(); - - for (size_t i = 0; i < 4; ++i) { - base::RunLoop run_loop; - senders[i].sender_thread()->task_runner()->PostTaskAndReply( - FROM_HERE, - base::Bind(&TestSender::TearDown, base::Unretained(&senders[i])), - base::Bind(&AssociatedInterfaceTest::QuitRunLoop, - base::Unretained(this), base::Unretained(&run_loop))); - run_loop.Run(); - } - - for (size_t i = 0; i < 2; ++i) { - base::RunLoop run_loop; - receivers[i].receiver_thread()->task_runner()->PostTaskAndReply( - FROM_HERE, - base::Bind(&TestReceiver::TearDown, base::Unretained(&receivers[i])), - base::Bind(&AssociatedInterfaceTest::QuitRunLoop, - base::Unretained(this), base::Unretained(&run_loop))); - run_loop.Run(); - } - - EXPECT_EQ(static_cast<size_t>(kMaxValue / 2), receivers[0].values().size()); - EXPECT_EQ(static_cast<size_t>(kMaxValue / 2), receivers[1].values().size()); - - for (size_t i = 0; i < 2; ++i) { - for (size_t j = 1; j < receivers[i].values().size(); ++j) - EXPECT_LT(receivers[i].values()[j - 1], receivers[i].values()[j]); - } -} - -void CaptureInt32(int32_t* storage, - const base::Closure& closure, - int32_t value) { - *storage = value; - closure.Run(); -} - -void CaptureSenderPtrInfo(IntegerSenderAssociatedPtr* storage, - const base::Closure& closure, - IntegerSenderAssociatedPtrInfo info) { - storage->Bind(std::move(info)); - closure.Run(); -} - -TEST_F(AssociatedInterfaceTest, PassAssociatedInterfaces) { - IntegerSenderConnectionPtr connection_ptr; - IntegerSenderConnectionImpl connection(MakeRequest(&connection_ptr)); - - IntegerSenderAssociatedPtr sender0; - connection_ptr->GetSender(MakeRequest(&sender0)); - - int32_t echoed_value = 0; - base::RunLoop run_loop; - sender0->Echo(123, base::Bind(&CaptureInt32, &echoed_value, - run_loop.QuitClosure())); - run_loop.Run(); - EXPECT_EQ(123, echoed_value); - - IntegerSenderAssociatedPtr sender1; - base::RunLoop run_loop2; - connection_ptr->AsyncGetSender( - base::Bind(&CaptureSenderPtrInfo, &sender1, run_loop2.QuitClosure())); - run_loop2.Run(); - EXPECT_TRUE(sender1); - - base::RunLoop run_loop3; - sender1->Echo(456, base::Bind(&CaptureInt32, &echoed_value, - run_loop3.QuitClosure())); - run_loop3.Run(); - EXPECT_EQ(456, echoed_value); -} - -TEST_F(AssociatedInterfaceTest, BindingWaitAndPauseWhenNoAssociatedInterfaces) { - IntegerSenderConnectionPtr connection_ptr; - IntegerSenderConnectionImpl connection(MakeRequest(&connection_ptr)); - - IntegerSenderAssociatedPtr sender0; - connection_ptr->GetSender(MakeRequest(&sender0)); - - EXPECT_FALSE(connection.binding()->HasAssociatedInterfaces()); - // There are no associated interfaces running on the pipe yet. It is okay to - // pause. - connection.binding()->PauseIncomingMethodCallProcessing(); - connection.binding()->ResumeIncomingMethodCallProcessing(); - - // There are no associated interfaces running on the pipe yet. It is okay to - // wait. - EXPECT_TRUE(connection.binding()->WaitForIncomingMethodCall()); - - // The previous wait has dispatched the GetSender request message, therefore - // an associated interface has been set up on the pipe. It is not allowed to - // wait or pause. - EXPECT_TRUE(connection.binding()->HasAssociatedInterfaces()); -} - -class PingServiceImpl : public PingService { - public: - explicit PingServiceImpl(PingServiceAssociatedRequest request) - : binding_(this, std::move(request)) {} - ~PingServiceImpl() override {} - - AssociatedBinding<PingService>& binding() { return binding_; } - - void set_ping_handler(const base::Closure& handler) { - ping_handler_ = handler; - } - - // PingService: - void Ping(const PingCallback& callback) override { - if (!ping_handler_.is_null()) - ping_handler_.Run(); - callback.Run(); - } - - private: - AssociatedBinding<PingService> binding_; - base::Closure ping_handler_; -}; - -class PingProviderImpl : public AssociatedPingProvider { - public: - explicit PingProviderImpl(AssociatedPingProviderRequest request) - : binding_(this, std::move(request)) {} - ~PingProviderImpl() override {} - - // AssociatedPingProvider: - void GetPing(PingServiceAssociatedRequest request) override { - ping_services_.emplace_back(new PingServiceImpl(std::move(request))); - - if (expected_bindings_count_ > 0 && - ping_services_.size() == expected_bindings_count_ && - !quit_waiting_.is_null()) { - expected_bindings_count_ = 0; - base::ResetAndReturn(&quit_waiting_).Run(); - } - } - - std::vector<std::unique_ptr<PingServiceImpl>>& ping_services() { - return ping_services_; - } - - void WaitForBindings(size_t count) { - DCHECK(quit_waiting_.is_null()); - - expected_bindings_count_ = count; - base::RunLoop loop; - quit_waiting_ = loop.QuitClosure(); - loop.Run(); - } - - private: - Binding<AssociatedPingProvider> binding_; - std::vector<std::unique_ptr<PingServiceImpl>> ping_services_; - size_t expected_bindings_count_ = 0; - base::Closure quit_waiting_; -}; - -class CallbackFilter : public MessageReceiver { - public: - explicit CallbackFilter(const base::Closure& callback) - : callback_(callback) {} - ~CallbackFilter() override {} - - static std::unique_ptr<CallbackFilter> Wrap(const base::Closure& callback) { - return base::MakeUnique<CallbackFilter>(callback); - } - - // MessageReceiver: - bool Accept(Message* message) override { - callback_.Run(); - return true; - } - - private: - const base::Closure callback_; -}; - -// Verifies that filters work as expected on associated bindings, i.e. that -// they're notified in order, before dispatch; and that each associated -// binding in a group operates with its own set of filters. -TEST_F(AssociatedInterfaceTest, BindingWithFilters) { - AssociatedPingProviderPtr provider; - PingProviderImpl provider_impl(MakeRequest(&provider)); - - PingServiceAssociatedPtr ping_a, ping_b; - provider->GetPing(MakeRequest(&ping_a)); - provider->GetPing(MakeRequest(&ping_b)); - provider_impl.WaitForBindings(2); - - ASSERT_EQ(2u, provider_impl.ping_services().size()); - PingServiceImpl& ping_a_impl = *provider_impl.ping_services()[0]; - PingServiceImpl& ping_b_impl = *provider_impl.ping_services()[1]; - - int a_status, b_status; - auto handler_helper = [] (int* a_status, int* b_status, int expected_a_status, - int new_a_status, int expected_b_status, - int new_b_status) { - EXPECT_EQ(expected_a_status, *a_status); - EXPECT_EQ(expected_b_status, *b_status); - *a_status = new_a_status; - *b_status = new_b_status; - }; - auto create_handler = [&] (int expected_a_status, int new_a_status, - int expected_b_status, int new_b_status) { - return base::Bind(handler_helper, &a_status, &b_status, expected_a_status, - new_a_status, expected_b_status, new_b_status); - }; - - ping_a_impl.binding().AddFilter( - CallbackFilter::Wrap(create_handler(0, 1, 0, 0))); - ping_a_impl.binding().AddFilter( - CallbackFilter::Wrap(create_handler(1, 2, 0, 0))); - ping_a_impl.set_ping_handler(create_handler(2, 3, 0, 0)); - - ping_b_impl.binding().AddFilter( - CallbackFilter::Wrap(create_handler(3, 3, 0, 1))); - ping_b_impl.binding().AddFilter( - CallbackFilter::Wrap(create_handler(3, 3, 1, 2))); - ping_b_impl.set_ping_handler(create_handler(3, 3, 2, 3)); - - for (int i = 0; i < 10; ++i) { - a_status = 0; - b_status = 0; - - { - base::RunLoop loop; - ping_a->Ping(loop.QuitClosure()); - loop.Run(); - } - - EXPECT_EQ(3, a_status); - EXPECT_EQ(0, b_status); - - { - base::RunLoop loop; - ping_b->Ping(loop.QuitClosure()); - loop.Run(); - } - - EXPECT_EQ(3, a_status); - EXPECT_EQ(3, b_status); - } -} - -TEST_F(AssociatedInterfaceTest, AssociatedPtrFlushForTesting) { - AssociatedInterfaceRequest<IntegerSender> request; - IntegerSenderAssociatedPtrInfo ptr_info; - CreateIntegerSender(&ptr_info, &request); - - IntegerSenderImpl impl0(std::move(request)); - AssociatedInterfacePtr<IntegerSender> ptr0; - ptr0.Bind(std::move(ptr_info)); - ptr0.set_connection_error_handler(base::Bind(&Fail)); - - bool ptr0_callback_run = false; - ptr0->Echo(123, ExpectValueSetFlagAndRunClosure( - 123, &ptr0_callback_run, base::Bind(&base::DoNothing))); - ptr0.FlushForTesting(); - EXPECT_TRUE(ptr0_callback_run); -} - -void SetBool(bool* value) { - *value = true; -} - -template <typename T> -void SetBoolWithUnusedParameter(bool* value, T unused) { - *value = true; -} - -TEST_F(AssociatedInterfaceTest, AssociatedPtrFlushForTestingWithClosedPeer) { - AssociatedInterfaceRequest<IntegerSender> request; - IntegerSenderAssociatedPtrInfo ptr_info; - CreateIntegerSender(&ptr_info, &request); - - AssociatedInterfacePtr<IntegerSender> ptr0; - ptr0.Bind(std::move(ptr_info)); - bool called = false; - ptr0.set_connection_error_handler(base::Bind(&SetBool, &called)); - request = nullptr; - - ptr0.FlushForTesting(); - EXPECT_TRUE(called); - ptr0.FlushForTesting(); -} - -TEST_F(AssociatedInterfaceTest, AssociatedBindingFlushForTesting) { - AssociatedInterfaceRequest<IntegerSender> request; - IntegerSenderAssociatedPtrInfo ptr_info; - CreateIntegerSender(&ptr_info, &request); - - IntegerSenderImpl impl0(std::move(request)); - impl0.set_connection_error_handler(base::Bind(&Fail)); - AssociatedInterfacePtr<IntegerSender> ptr0; - ptr0.Bind(std::move(ptr_info)); - - bool ptr0_callback_run = false; - ptr0->Echo(123, ExpectValueSetFlagAndRunClosure( - 123, &ptr0_callback_run, base::Bind(&base::DoNothing))); - // Because the flush is sent from the binding, it only guarantees that the - // request has been received, not the response. The second flush waits for the - // response to be received. - impl0.binding()->FlushForTesting(); - impl0.binding()->FlushForTesting(); - EXPECT_TRUE(ptr0_callback_run); -} - -TEST_F(AssociatedInterfaceTest, - AssociatedBindingFlushForTestingWithClosedPeer) { - scoped_refptr<MultiplexRouter> router0; - scoped_refptr<MultiplexRouter> router1; - CreateRouterPair(&router0, &router1); - - AssociatedInterfaceRequest<IntegerSender> request; - { - IntegerSenderAssociatedPtrInfo ptr_info; - CreateIntegerSenderWithExistingRouters(router1, &ptr_info, router0, - &request); - } - - IntegerSenderImpl impl(std::move(request)); - bool called = false; - impl.set_connection_error_handler(base::Bind(&SetBool, &called)); - impl.binding()->FlushForTesting(); - EXPECT_TRUE(called); - impl.binding()->FlushForTesting(); -} - -TEST_F(AssociatedInterfaceTest, BindingFlushForTesting) { - IntegerSenderConnectionPtr ptr; - IntegerSenderConnectionImpl impl(MakeRequest(&ptr)); - bool called = false; - ptr->AsyncGetSender(base::Bind( - &SetBoolWithUnusedParameter<IntegerSenderAssociatedPtrInfo>, &called)); - EXPECT_FALSE(called); - impl.binding()->set_connection_error_handler(base::Bind(&Fail)); - // Because the flush is sent from the binding, it only guarantees that the - // request has been received, not the response. The second flush waits for the - // response to be received. - impl.binding()->FlushForTesting(); - impl.binding()->FlushForTesting(); - EXPECT_TRUE(called); -} - -TEST_F(AssociatedInterfaceTest, BindingFlushForTestingWithClosedPeer) { - IntegerSenderConnectionPtr ptr; - IntegerSenderConnectionImpl impl(MakeRequest(&ptr)); - bool called = false; - impl.binding()->set_connection_error_handler(base::Bind(&SetBool, &called)); - ptr.reset(); - EXPECT_FALSE(called); - impl.binding()->FlushForTesting(); - EXPECT_TRUE(called); - impl.binding()->FlushForTesting(); -} - -TEST_F(AssociatedInterfaceTest, StrongBindingFlushForTesting) { - IntegerSenderConnectionPtr ptr; - auto binding = - MakeStrongBinding(base::MakeUnique<IntegerSenderConnectionImpl>( - IntegerSenderConnectionRequest{}), - MakeRequest(&ptr)); - bool called = false; - IntegerSenderAssociatedPtr sender_ptr; - ptr->GetSender(MakeRequest(&sender_ptr)); - sender_ptr->Echo(1, base::Bind(&SetBoolWithUnusedParameter<int>, &called)); - EXPECT_FALSE(called); - // Because the flush is sent from the binding, it only guarantees that the - // request has been received, not the response. The second flush waits for the - // response to be received. - ASSERT_TRUE(binding); - binding->FlushForTesting(); - ASSERT_TRUE(binding); - binding->FlushForTesting(); - EXPECT_TRUE(called); -} - -TEST_F(AssociatedInterfaceTest, StrongBindingFlushForTestingWithClosedPeer) { - IntegerSenderConnectionPtr ptr; - bool called = false; - auto binding = - MakeStrongBinding(base::MakeUnique<IntegerSenderConnectionImpl>( - IntegerSenderConnectionRequest{}), - MakeRequest(&ptr)); - binding->set_connection_error_handler(base::Bind(&SetBool, &called)); - ptr.reset(); - EXPECT_FALSE(called); - ASSERT_TRUE(binding); - binding->FlushForTesting(); - EXPECT_TRUE(called); - ASSERT_FALSE(binding); -} - -TEST_F(AssociatedInterfaceTest, PtrFlushForTesting) { - IntegerSenderConnectionPtr ptr; - IntegerSenderConnectionImpl impl(MakeRequest(&ptr)); - bool called = false; - ptr.set_connection_error_handler(base::Bind(&Fail)); - ptr->AsyncGetSender(base::Bind( - &SetBoolWithUnusedParameter<IntegerSenderAssociatedPtrInfo>, &called)); - EXPECT_FALSE(called); - ptr.FlushForTesting(); - EXPECT_TRUE(called); -} - -TEST_F(AssociatedInterfaceTest, PtrFlushForTestingWithClosedPeer) { - IntegerSenderConnectionPtr ptr; - MakeRequest(&ptr); - bool called = false; - ptr.set_connection_error_handler(base::Bind(&SetBool, &called)); - EXPECT_FALSE(called); - ptr.FlushForTesting(); - EXPECT_TRUE(called); - ptr.FlushForTesting(); -} - -TEST_F(AssociatedInterfaceTest, AssociatedBindingConnectionErrorWithReason) { - AssociatedInterfaceRequest<IntegerSender> request; - IntegerSenderAssociatedPtrInfo ptr_info; - CreateIntegerSender(&ptr_info, &request); - - IntegerSenderImpl impl(std::move(request)); - AssociatedInterfacePtr<IntegerSender> ptr; - ptr.Bind(std::move(ptr_info)); - - base::RunLoop run_loop; - impl.binding()->set_connection_error_with_reason_handler(base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(123u, custom_reason); - EXPECT_EQ("farewell", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - ptr.ResetWithReason(123u, "farewell"); - - run_loop.Run(); -} - -TEST_F(AssociatedInterfaceTest, - PendingAssociatedBindingConnectionErrorWithReason) { - // Test that AssociatedBinding is notified with connection error when the - // interface hasn't associated with a message pipe and the peer is closed. - - IntegerSenderAssociatedPtr ptr; - IntegerSenderImpl impl(MakeRequest(&ptr)); - - base::RunLoop run_loop; - impl.binding()->set_connection_error_with_reason_handler(base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(123u, custom_reason); - EXPECT_EQ("farewell", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - ptr.ResetWithReason(123u, "farewell"); - - run_loop.Run(); -} - -TEST_F(AssociatedInterfaceTest, AssociatedPtrConnectionErrorWithReason) { - AssociatedInterfaceRequest<IntegerSender> request; - IntegerSenderAssociatedPtrInfo ptr_info; - CreateIntegerSender(&ptr_info, &request); - - IntegerSenderImpl impl(std::move(request)); - AssociatedInterfacePtr<IntegerSender> ptr; - ptr.Bind(std::move(ptr_info)); - - base::RunLoop run_loop; - ptr.set_connection_error_with_reason_handler(base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(456u, custom_reason); - EXPECT_EQ("farewell", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - impl.binding()->CloseWithReason(456u, "farewell"); - - run_loop.Run(); -} - -TEST_F(AssociatedInterfaceTest, PendingAssociatedPtrConnectionErrorWithReason) { - // Test that AssociatedInterfacePtr is notified with connection error when the - // interface hasn't associated with a message pipe and the peer is closed. - - IntegerSenderAssociatedPtr ptr; - auto request = MakeRequest(&ptr); - - base::RunLoop run_loop; - ptr.set_connection_error_with_reason_handler(base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(456u, custom_reason); - EXPECT_EQ("farewell", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - request.ResetWithReason(456u, "farewell"); - - run_loop.Run(); -} - -TEST_F(AssociatedInterfaceTest, AssociatedRequestResetWithReason) { - AssociatedInterfaceRequest<IntegerSender> request; - IntegerSenderAssociatedPtrInfo ptr_info; - CreateIntegerSender(&ptr_info, &request); - - AssociatedInterfacePtr<IntegerSender> ptr; - ptr.Bind(std::move(ptr_info)); - - base::RunLoop run_loop; - ptr.set_connection_error_with_reason_handler(base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(789u, custom_reason); - EXPECT_EQ("long time no see", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - request.ResetWithReason(789u, "long time no see"); - - run_loop.Run(); -} - -TEST_F(AssociatedInterfaceTest, ThreadSafeAssociatedInterfacePtr) { - IntegerSenderConnectionPtr connection_ptr; - IntegerSenderConnectionImpl connection(MakeRequest(&connection_ptr)); - - IntegerSenderAssociatedPtr sender; - connection_ptr->GetSender(MakeRequest(&sender)); - - scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_sender = - ThreadSafeIntegerSenderAssociatedPtr::Create(std::move(sender)); - - { - // Test the thread safe pointer can be used from the interface ptr thread. - int32_t echoed_value = 0; - base::RunLoop run_loop; - (*thread_safe_sender) - ->Echo(123, base::Bind(&CaptureInt32, &echoed_value, - run_loop.QuitClosure())); - run_loop.Run(); - EXPECT_EQ(123, echoed_value); - } - - // Test the thread safe pointer can be used from another thread. - base::RunLoop run_loop; - base::Thread other_thread("service test thread"); - other_thread.Start(); - - auto run_method = base::Bind( - [](const scoped_refptr<base::TaskRunner>& main_task_runner, - const base::Closure& quit_closure, - const scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr>& - thread_safe_sender) { - auto done_callback = base::Bind( - [](const scoped_refptr<base::TaskRunner>& main_task_runner, - const base::Closure& quit_closure, - base::PlatformThreadId thread_id, int32_t result) { - EXPECT_EQ(123, result); - // Validate the callback is invoked on the calling thread. - EXPECT_EQ(thread_id, base::PlatformThread::CurrentId()); - // Notify the run_loop to quit. - main_task_runner->PostTask(FROM_HERE, quit_closure); - }); - (*thread_safe_sender) - ->Echo(123, - base::Bind(done_callback, main_task_runner, quit_closure, - base::PlatformThread::CurrentId())); - }, - base::SequencedTaskRunnerHandle::Get(), run_loop.QuitClosure(), - thread_safe_sender); - other_thread.message_loop()->task_runner()->PostTask(FROM_HERE, run_method); - - // Block until the method callback is called on the background thread. - run_loop.Run(); -} - -struct ForwarderTestContext { - IntegerSenderConnectionPtr connection_ptr; - std::unique_ptr<IntegerSenderConnectionImpl> interface_impl; - IntegerSenderAssociatedRequest sender_request; -}; - -TEST_F(AssociatedInterfaceTest, - ThreadSafeAssociatedInterfacePtrWithTaskRunner) { - // Start the thread from where we'll bind the interface pointer. - base::Thread other_thread("service test thread"); - other_thread.Start(); - const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner = - other_thread.message_loop()->task_runner(); - - ForwarderTestContext* context = new ForwarderTestContext(); - IntegerSenderAssociatedPtrInfo sender_info; - base::WaitableEvent sender_info_bound_event( - base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - auto setup = [](base::WaitableEvent* sender_info_bound_event, - IntegerSenderAssociatedPtrInfo* sender_info, - ForwarderTestContext* context) { - context->interface_impl = base::MakeUnique<IntegerSenderConnectionImpl>( - MakeRequest(&context->connection_ptr)); - - auto sender_request = MakeRequest(sender_info); - context->connection_ptr->GetSender(std::move(sender_request)); - - // Unblock the main thread as soon as |sender_info| is set. - sender_info_bound_event->Signal(); - }; - other_thread_task_runner->PostTask( - FROM_HERE, - base::Bind(setup, &sender_info_bound_event, &sender_info, context)); - sender_info_bound_event.Wait(); - - // Create a ThreadSafeAssociatedPtr that binds on the background thread and is - // associated with |connection_ptr| there. - scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_ptr = - ThreadSafeIntegerSenderAssociatedPtr::Create(std::move(sender_info), - other_thread_task_runner); - - // Issue a call on the thread-safe ptr immediately. Note that this may happen - // before the interface is bound on the background thread, and that must be - // OK. - { - auto echo_callback = - base::Bind([](const base::Closure& quit_closure, int32_t result) { - EXPECT_EQ(123, result); - quit_closure.Run(); - }); - base::RunLoop run_loop; - (*thread_safe_ptr) - ->Echo(123, base::Bind(echo_callback, run_loop.QuitClosure())); - - // Block until the method callback is called. - run_loop.Run(); - } - - other_thread_task_runner->DeleteSoon(FROM_HERE, context); - - // Reset the pointer now so the InterfacePtr associated resources can be - // deleted before the background thread's message loop is invalidated. - thread_safe_ptr = nullptr; -} - -class DiscardingAssociatedPingProviderProvider - : public AssociatedPingProviderProvider { - public: - void GetPingProvider( - AssociatedPingProviderAssociatedRequest request) override {} -}; - -TEST_F(AssociatedInterfaceTest, CloseWithoutBindingAssociatedRequest) { - DiscardingAssociatedPingProviderProvider ping_provider_provider; - mojo::Binding<AssociatedPingProviderProvider> binding( - &ping_provider_provider); - auto provider_provider = binding.CreateInterfacePtrAndBind(); - AssociatedPingProviderAssociatedPtr provider; - provider_provider->GetPingProvider(mojo::MakeRequest(&provider)); - PingServiceAssociatedPtr ping; - provider->GetPing(mojo::MakeRequest(&ping)); - base::RunLoop run_loop; - ping.set_connection_error_handler(run_loop.QuitClosure()); - run_loop.Run(); -} - -TEST_F(AssociatedInterfaceTest, GetIsolatedInterface) { - IntegerSenderAssociatedPtr sender; - GetIsolatedInterface(MakeRequest(&sender).PassHandle()); - sender->Send(42); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/bind_task_runner_unittest.cc b/mojo/public/cpp/bindings/tests/bind_task_runner_unittest.cc deleted file mode 100644 index 569eb51..0000000 --- a/mojo/public/cpp/bindings/tests/bind_task_runner_unittest.cc +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/message_loop/message_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/synchronization/lock.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/platform_thread.h" -#include "mojo/public/cpp/bindings/associated_binding.h" -#include "mojo/public/cpp/bindings/associated_interface_ptr.h" -#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h" -#include "mojo/public/cpp/bindings/associated_interface_request.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -class TestTaskRunner : public base::SingleThreadTaskRunner { - public: - TestTaskRunner() - : thread_id_(base::PlatformThread::CurrentRef()), - quit_called_(false), - task_ready_(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED) {} - - bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, - base::OnceClosure task, - base::TimeDelta delay) override { - NOTREACHED(); - return false; - } - - bool PostDelayedTask(const tracked_objects::Location& from_here, - base::OnceClosure task, - base::TimeDelta delay) override { - { - base::AutoLock locker(lock_); - tasks_.push(std::move(task)); - } - task_ready_.Signal(); - return true; - } - bool RunsTasksOnCurrentThread() const override { - return base::PlatformThread::CurrentRef() == thread_id_; - } - - // Only quits when Quit() is called. - void Run() { - DCHECK(RunsTasksOnCurrentThread()); - quit_called_ = false; - - while (true) { - { - base::AutoLock locker(lock_); - while (!tasks_.empty()) { - auto task = std::move(tasks_.front()); - tasks_.pop(); - - { - base::AutoUnlock unlocker(lock_); - std::move(task).Run(); - if (quit_called_) - return; - } - } - } - task_ready_.Wait(); - } - } - - void Quit() { - DCHECK(RunsTasksOnCurrentThread()); - quit_called_ = true; - } - - // Waits until one task is ready and runs it. - void RunOneTask() { - DCHECK(RunsTasksOnCurrentThread()); - - while (true) { - { - base::AutoLock locker(lock_); - if (!tasks_.empty()) { - auto task = std::move(tasks_.front()); - tasks_.pop(); - - { - base::AutoUnlock unlocker(lock_); - std::move(task).Run(); - return; - } - } - } - task_ready_.Wait(); - } - } - - private: - ~TestTaskRunner() override {} - - const base::PlatformThreadRef thread_id_; - bool quit_called_; - base::WaitableEvent task_ready_; - - // Protect |tasks_|. - base::Lock lock_; - std::queue<base::OnceClosure> tasks_; - - DISALLOW_COPY_AND_ASSIGN(TestTaskRunner); -}; - -template <typename BindingType, typename RequestType> -class IntegerSenderImpl : public IntegerSender { - public: - IntegerSenderImpl(RequestType request, - scoped_refptr<base::SingleThreadTaskRunner> runner) - : binding_(this, std::move(request), std::move(runner)) {} - - ~IntegerSenderImpl() override {} - - using EchoHandler = base::Callback<void(int32_t, const EchoCallback&)>; - - void set_echo_handler(const EchoHandler& handler) { echo_handler_ = handler; } - - void Echo(int32_t value, const EchoCallback& callback) override { - if (echo_handler_.is_null()) - callback.Run(value); - else - echo_handler_.Run(value, callback); - } - void Send(int32_t value) override { NOTREACHED(); } - - BindingType* binding() { return &binding_; } - - private: - BindingType binding_; - EchoHandler echo_handler_; -}; - -class IntegerSenderConnectionImpl : public IntegerSenderConnection { - public: - using SenderType = IntegerSenderImpl<AssociatedBinding<IntegerSender>, - IntegerSenderAssociatedRequest>; - - explicit IntegerSenderConnectionImpl( - IntegerSenderConnectionRequest request, - scoped_refptr<base::SingleThreadTaskRunner> runner, - scoped_refptr<base::SingleThreadTaskRunner> sender_runner) - : binding_(this, std::move(request), std::move(runner)), - sender_runner_(std::move(sender_runner)) {} - - ~IntegerSenderConnectionImpl() override {} - - void set_get_sender_notification(const base::Closure& notification) { - get_sender_notification_ = notification; - } - void GetSender(IntegerSenderAssociatedRequest sender) override { - sender_impl_.reset(new SenderType(std::move(sender), sender_runner_)); - get_sender_notification_.Run(); - } - - void AsyncGetSender(const AsyncGetSenderCallback& callback) override { - NOTREACHED(); - } - - Binding<IntegerSenderConnection>* binding() { return &binding_; } - - SenderType* sender_impl() { return sender_impl_.get(); } - - private: - Binding<IntegerSenderConnection> binding_; - std::unique_ptr<SenderType> sender_impl_; - scoped_refptr<base::SingleThreadTaskRunner> sender_runner_; - base::Closure get_sender_notification_; -}; - -class BindTaskRunnerTest : public testing::Test { - protected: - void SetUp() override { - binding_task_runner_ = scoped_refptr<TestTaskRunner>(new TestTaskRunner); - ptr_task_runner_ = scoped_refptr<TestTaskRunner>(new TestTaskRunner); - - auto request = MakeRequest(&ptr_, ptr_task_runner_); - impl_.reset(new ImplType(std::move(request), binding_task_runner_)); - } - - base::MessageLoop loop_; - scoped_refptr<TestTaskRunner> binding_task_runner_; - scoped_refptr<TestTaskRunner> ptr_task_runner_; - - IntegerSenderPtr ptr_; - using ImplType = - IntegerSenderImpl<Binding<IntegerSender>, IntegerSenderRequest>; - std::unique_ptr<ImplType> impl_; -}; - -class AssociatedBindTaskRunnerTest : public testing::Test { - protected: - void SetUp() override { - connection_binding_task_runner_ = - scoped_refptr<TestTaskRunner>(new TestTaskRunner); - connection_ptr_task_runner_ = - scoped_refptr<TestTaskRunner>(new TestTaskRunner); - sender_binding_task_runner_ = - scoped_refptr<TestTaskRunner>(new TestTaskRunner); - sender_ptr_task_runner_ = scoped_refptr<TestTaskRunner>(new TestTaskRunner); - - auto connection_request = - MakeRequest(&connection_ptr_, connection_ptr_task_runner_); - connection_impl_.reset(new IntegerSenderConnectionImpl( - std::move(connection_request), connection_binding_task_runner_, - sender_binding_task_runner_)); - - connection_impl_->set_get_sender_notification( - base::Bind(&AssociatedBindTaskRunnerTest::QuitTaskRunner, - base::Unretained(this))); - - connection_ptr_->GetSender( - MakeRequest(&sender_ptr_, sender_ptr_task_runner_)); - connection_binding_task_runner_->Run(); - } - - void QuitTaskRunner() { - connection_binding_task_runner_->Quit(); - } - - base::MessageLoop loop_; - scoped_refptr<TestTaskRunner> connection_binding_task_runner_; - scoped_refptr<TestTaskRunner> connection_ptr_task_runner_; - scoped_refptr<TestTaskRunner> sender_binding_task_runner_; - scoped_refptr<TestTaskRunner> sender_ptr_task_runner_; - - IntegerSenderConnectionPtr connection_ptr_; - std::unique_ptr<IntegerSenderConnectionImpl> connection_impl_; - IntegerSenderAssociatedPtr sender_ptr_; -}; - -void DoSetFlagAndQuitTaskRunner(bool* flag, - scoped_refptr<TestTaskRunner> task_runner) { - *flag = true; - if (task_runner) - task_runner->Quit(); -} - -void DoExpectValueSetFlagAndQuitTaskRunner( - int32_t expected_value, - bool* flag, - scoped_refptr<TestTaskRunner> task_runner, - int32_t value) { - EXPECT_EQ(expected_value, value); - DoSetFlagAndQuitTaskRunner(flag, task_runner); -} - -void DoExpectValueSetFlagForwardValueAndQuitTaskRunner( - int32_t expected_value, - bool* flag, - scoped_refptr<TestTaskRunner> task_runner, - int32_t value, - const IntegerSender::EchoCallback& callback) { - EXPECT_EQ(expected_value, value); - *flag = true; - callback.Run(value); - task_runner->Quit(); -} - -base::Closure SetFlagAndQuitTaskRunner( - bool* flag, - scoped_refptr<TestTaskRunner> task_runner) { - return base::Bind(&DoSetFlagAndQuitTaskRunner, flag, task_runner); -} - -base::Callback<void(int32_t)> ExpectValueSetFlagAndQuitTaskRunner( - int32_t expected_value, - bool* flag, - scoped_refptr<TestTaskRunner> task_runner) { - return base::Bind(&DoExpectValueSetFlagAndQuitTaskRunner, expected_value, - flag, task_runner); -} - -TEST_F(BindTaskRunnerTest, MethodCall) { - bool echo_called = false; - impl_->set_echo_handler( - base::Bind(&DoExpectValueSetFlagForwardValueAndQuitTaskRunner, - 1024, &echo_called, binding_task_runner_)); - bool echo_replied = false; - ptr_->Echo(1024, ExpectValueSetFlagAndQuitTaskRunner(1024, &echo_replied, - ptr_task_runner_)); - binding_task_runner_->Run(); - EXPECT_TRUE(echo_called); - ptr_task_runner_->Run(); - EXPECT_TRUE(echo_replied); -} - -TEST_F(BindTaskRunnerTest, BindingConnectionError) { - bool connection_error_called = false; - impl_->binding()->set_connection_error_handler( - SetFlagAndQuitTaskRunner(&connection_error_called, binding_task_runner_)); - ptr_.reset(); - binding_task_runner_->Run(); - EXPECT_TRUE(connection_error_called); -} - -TEST_F(BindTaskRunnerTest, PtrConnectionError) { - bool connection_error_called = false; - ptr_.set_connection_error_handler( - SetFlagAndQuitTaskRunner(&connection_error_called, ptr_task_runner_)); - impl_->binding()->Close(); - ptr_task_runner_->Run(); - EXPECT_TRUE(connection_error_called); -} - -void ExpectValueSetFlagAndForward(int32_t expected_value, - bool* flag, - int32_t value, - const IntegerSender::EchoCallback& callback) { - EXPECT_EQ(expected_value, value); - *flag = true; - callback.Run(value); -} - -TEST_F(AssociatedBindTaskRunnerTest, MethodCall) { - bool echo_called = false; - connection_impl_->sender_impl()->set_echo_handler( - base::Bind(&ExpectValueSetFlagAndForward, 1024, &echo_called)); - - bool echo_replied = false; - sender_ptr_->Echo( - 1024, ExpectValueSetFlagAndQuitTaskRunner(1024, &echo_replied, nullptr)); - - // The Echo request first arrives at the master endpoint's task runner, and - // then is forwarded to the associated endpoint's task runner. - connection_binding_task_runner_->RunOneTask(); - sender_binding_task_runner_->RunOneTask(); - EXPECT_TRUE(echo_called); - - // Similarly, the Echo response arrives at the master endpoint's task runner - // and then is forwarded to the associated endpoint's task runner. - connection_ptr_task_runner_->RunOneTask(); - sender_ptr_task_runner_->RunOneTask(); - EXPECT_TRUE(echo_replied); -} - -TEST_F(AssociatedBindTaskRunnerTest, BindingConnectionError) { - bool sender_impl_error = false; - connection_impl_->sender_impl()->binding()->set_connection_error_handler( - SetFlagAndQuitTaskRunner(&sender_impl_error, - sender_binding_task_runner_)); - bool connection_impl_error = false; - connection_impl_->binding()->set_connection_error_handler( - SetFlagAndQuitTaskRunner(&connection_impl_error, - connection_binding_task_runner_)); - bool sender_ptr_error = false; - sender_ptr_.set_connection_error_handler( - SetFlagAndQuitTaskRunner(&sender_ptr_error, sender_ptr_task_runner_)); - connection_ptr_.reset(); - sender_ptr_task_runner_->Run(); - EXPECT_TRUE(sender_ptr_error); - connection_binding_task_runner_->Run(); - EXPECT_TRUE(connection_impl_error); - sender_binding_task_runner_->Run(); - EXPECT_TRUE(sender_impl_error); -} - -TEST_F(AssociatedBindTaskRunnerTest, PtrConnectionError) { - bool sender_impl_error = false; - connection_impl_->sender_impl()->binding()->set_connection_error_handler( - SetFlagAndQuitTaskRunner(&sender_impl_error, - sender_binding_task_runner_)); - bool connection_ptr_error = false; - connection_ptr_.set_connection_error_handler( - SetFlagAndQuitTaskRunner(&connection_ptr_error, - connection_ptr_task_runner_)); - bool sender_ptr_error = false; - sender_ptr_.set_connection_error_handler( - SetFlagAndQuitTaskRunner(&sender_ptr_error, sender_ptr_task_runner_)); - connection_impl_->binding()->Close(); - sender_binding_task_runner_->Run(); - EXPECT_TRUE(sender_impl_error); - connection_ptr_task_runner_->Run(); - EXPECT_TRUE(connection_ptr_error); - sender_ptr_task_runner_->Run(); - EXPECT_TRUE(sender_ptr_error); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc b/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc deleted file mode 100644 index 43122ce..0000000 --- a/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stdint.h> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/test/gtest_util.h" -#include "build/build_config.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/interface_ptr.h" -#include "mojo/public/cpp/system/message_pipe.h" -#include "mojo/public/cpp/test_support/test_support.h" -#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -/////////////////////////////////////////////////////////////////////////////// -// -// The tests in this file are designed to test the interaction between a -// Callback and its associated Binding. If a Callback is deleted before -// being used we DCHECK fail--unless the associated Binding has already -// been closed or deleted. This contract must be explained to the Mojo -// application developer. For example it is the developer's responsibility to -// ensure that the Binding is destroyed before an unused Callback is destroyed. -// -/////////////////////////////////////////////////////////////////////////////// - -namespace mojo { -namespace test { -namespace { - -void SaveValue(int32_t* storage, const base::Closure& closure, int32_t value) { - *storage = value; - if (!closure.is_null()) - closure.Run(); -} - -base::Callback<void(int32_t)> BindValueSaver(int32_t* last_value_seen, - const base::Closure& closure) { - return base::Bind(&SaveValue, last_value_seen, closure); -} - -// An implementation of sample::Provider used on the server side. -// It only implements one of the methods: EchoInt(). -// All it does is save the values and Callbacks it sees. -class InterfaceImpl : public sample::Provider { - public: - InterfaceImpl() - : last_server_value_seen_(0), - callback_saved_(new EchoIntCallback) {} - - ~InterfaceImpl() override { - if (callback_saved_) { - delete callback_saved_; - } - } - - // Run's the callback previously saved from the last invocation - // of |EchoInt()|. - bool RunCallback() { - if (callback_saved_) { - callback_saved_->Run(last_server_value_seen_); - return true; - } - return false; - } - - // Delete's the previously saved callback. - void DeleteCallback() { - delete callback_saved_; - callback_saved_ = nullptr; - } - - // sample::Provider implementation - - // Saves its two input values in member variables and does nothing else. - void EchoInt(int32_t x, const EchoIntCallback& callback) override { - last_server_value_seen_ = x; - *callback_saved_ = callback; - if (!closure_.is_null()) { - closure_.Run(); - closure_.Reset(); - } - } - - void EchoString(const std::string& a, - const EchoStringCallback& callback) override { - CHECK(false) << "Not implemented."; - } - - void EchoStrings(const std::string& a, - const std::string& b, - const EchoStringsCallback& callback) override { - CHECK(false) << "Not implemented."; - } - - void EchoMessagePipeHandle( - ScopedMessagePipeHandle a, - const EchoMessagePipeHandleCallback& callback) override { - CHECK(false) << "Not implemented."; - } - - void EchoEnum(sample::Enum a, const EchoEnumCallback& callback) override { - CHECK(false) << "Not implemented."; - } - - void resetLastServerValueSeen() { last_server_value_seen_ = 0; } - - int32_t last_server_value_seen() const { return last_server_value_seen_; } - - void set_closure(const base::Closure& closure) { closure_ = closure; } - - private: - int32_t last_server_value_seen_; - EchoIntCallback* callback_saved_; - base::Closure closure_; -}; - -class BindingCallbackTest : public testing::Test { - public: - BindingCallbackTest() {} - ~BindingCallbackTest() override {} - - protected: - int32_t last_client_callback_value_seen_; - sample::ProviderPtr interface_ptr_; - - void PumpMessages() { base::RunLoop().RunUntilIdle(); } - - private: - base::MessageLoop loop_; -}; - -// Tests that the InterfacePtr and the Binding can communicate with each -// other normally. -TEST_F(BindingCallbackTest, Basic) { - // Create the ServerImpl and the Binding. - InterfaceImpl server_impl; - Binding<sample::Provider> binding(&server_impl, MakeRequest(&interface_ptr_)); - - // Initialize the test values. - server_impl.resetLastServerValueSeen(); - last_client_callback_value_seen_ = 0; - - // Invoke the Echo method. - base::RunLoop run_loop, run_loop2; - server_impl.set_closure(run_loop.QuitClosure()); - interface_ptr_->EchoInt( - 7, - BindValueSaver(&last_client_callback_value_seen_, - run_loop2.QuitClosure())); - run_loop.Run(); - - // Check that server saw the correct value, but the client has not yet. - EXPECT_EQ(7, server_impl.last_server_value_seen()); - EXPECT_EQ(0, last_client_callback_value_seen_); - - // Now run the Callback. - server_impl.RunCallback(); - run_loop2.Run(); - - // Check that the client has now seen the correct value. - EXPECT_EQ(7, last_client_callback_value_seen_); - - // Initialize the test values again. - server_impl.resetLastServerValueSeen(); - last_client_callback_value_seen_ = 0; - - // Invoke the Echo method again. - base::RunLoop run_loop3, run_loop4; - server_impl.set_closure(run_loop3.QuitClosure()); - interface_ptr_->EchoInt( - 13, - BindValueSaver(&last_client_callback_value_seen_, - run_loop4.QuitClosure())); - run_loop3.Run(); - - // Check that server saw the correct value, but the client has not yet. - EXPECT_EQ(13, server_impl.last_server_value_seen()); - EXPECT_EQ(0, last_client_callback_value_seen_); - - // Now run the Callback again. - server_impl.RunCallback(); - run_loop4.Run(); - - // Check that the client has now seen the correct value again. - EXPECT_EQ(13, last_client_callback_value_seen_); -} - -// Tests that running the Callback after the Binding has been deleted -// results in a clean failure. -TEST_F(BindingCallbackTest, DeleteBindingThenRunCallback) { - // Create the ServerImpl. - InterfaceImpl server_impl; - base::RunLoop run_loop; - { - // Create the binding in an inner scope so it can be deleted first. - Binding<sample::Provider> binding(&server_impl, - MakeRequest(&interface_ptr_)); - interface_ptr_.set_connection_error_handler(run_loop.QuitClosure()); - - // Initialize the test values. - server_impl.resetLastServerValueSeen(); - last_client_callback_value_seen_ = 0; - - // Invoke the Echo method. - base::RunLoop run_loop2; - server_impl.set_closure(run_loop2.QuitClosure()); - interface_ptr_->EchoInt( - 7, - BindValueSaver(&last_client_callback_value_seen_, base::Closure())); - run_loop2.Run(); - } - // The binding has now been destroyed and the pipe is closed. - - // Check that server saw the correct value, but the client has not yet. - EXPECT_EQ(7, server_impl.last_server_value_seen()); - EXPECT_EQ(0, last_client_callback_value_seen_); - - // Now try to run the Callback. This should do nothing since the pipe - // is closed. - EXPECT_TRUE(server_impl.RunCallback()); - PumpMessages(); - - // Check that the client has still not seen the correct value. - EXPECT_EQ(0, last_client_callback_value_seen_); - - // Attempt to invoke the method again and confirm that an error was - // encountered. - interface_ptr_->EchoInt( - 13, - BindValueSaver(&last_client_callback_value_seen_, base::Closure())); - run_loop.Run(); - EXPECT_TRUE(interface_ptr_.encountered_error()); -} - -// Tests that deleting a Callback without running it after the corresponding -// binding has already been deleted does not result in a crash. -TEST_F(BindingCallbackTest, DeleteBindingThenDeleteCallback) { - // Create the ServerImpl. - InterfaceImpl server_impl; - { - // Create the binding in an inner scope so it can be deleted first. - Binding<sample::Provider> binding(&server_impl, - MakeRequest(&interface_ptr_)); - - // Initialize the test values. - server_impl.resetLastServerValueSeen(); - last_client_callback_value_seen_ = 0; - - // Invoke the Echo method. - base::RunLoop run_loop; - server_impl.set_closure(run_loop.QuitClosure()); - interface_ptr_->EchoInt( - 7, - BindValueSaver(&last_client_callback_value_seen_, base::Closure())); - run_loop.Run(); - } - // The binding has now been destroyed and the pipe is closed. - - // Check that server saw the correct value, but the client has not yet. - EXPECT_EQ(7, server_impl.last_server_value_seen()); - EXPECT_EQ(0, last_client_callback_value_seen_); - - // Delete the callback without running it. This should not - // cause a problem because the insfrastructure can detect that the - // binding has already been destroyed and the pipe is closed. - server_impl.DeleteCallback(); -} - -// Tests that closing a Binding allows us to delete a callback -// without running it without encountering a crash. -TEST_F(BindingCallbackTest, CloseBindingBeforeDeletingCallback) { - // Create the ServerImpl and the Binding. - InterfaceImpl server_impl; - Binding<sample::Provider> binding(&server_impl, MakeRequest(&interface_ptr_)); - - // Initialize the test values. - server_impl.resetLastServerValueSeen(); - last_client_callback_value_seen_ = 0; - - // Invoke the Echo method. - base::RunLoop run_loop; - server_impl.set_closure(run_loop.QuitClosure()); - interface_ptr_->EchoInt( - 7, - BindValueSaver(&last_client_callback_value_seen_, base::Closure())); - run_loop.Run(); - - // Check that server saw the correct value, but the client has not yet. - EXPECT_EQ(7, server_impl.last_server_value_seen()); - EXPECT_EQ(0, last_client_callback_value_seen_); - - // Now close the Binding. - binding.Close(); - - // Delete the callback without running it. This should not - // cause a crash because the insfrastructure can detect that the - // binding has already been closed. - server_impl.DeleteCallback(); - - // Check that the client has still not seen the correct value. - EXPECT_EQ(0, last_client_callback_value_seen_); -} - -// Tests that deleting a Callback without using it before the -// Binding has been destroyed or closed results in a DCHECK. -TEST_F(BindingCallbackTest, DeleteCallbackBeforeBindingDeathTest) { - // Create the ServerImpl and the Binding. - InterfaceImpl server_impl; - Binding<sample::Provider> binding(&server_impl, MakeRequest(&interface_ptr_)); - - // Initialize the test values. - server_impl.resetLastServerValueSeen(); - last_client_callback_value_seen_ = 0; - - // Invoke the Echo method. - base::RunLoop run_loop; - server_impl.set_closure(run_loop.QuitClosure()); - interface_ptr_->EchoInt( - 7, - BindValueSaver(&last_client_callback_value_seen_, base::Closure())); - run_loop.Run(); - - // Check that server saw the correct value, but the client has not yet. - EXPECT_EQ(7, server_impl.last_server_value_seen()); - EXPECT_EQ(0, last_client_callback_value_seen_); - - EXPECT_DCHECK_DEATH(server_impl.DeleteCallback()); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/binding_set_unittest.cc b/mojo/public/cpp/bindings/tests/binding_set_unittest.cc deleted file mode 100644 index 07acfbe..0000000 --- a/mojo/public/cpp/bindings/tests/binding_set_unittest.cc +++ /dev/null @@ -1,416 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> -#include <utility> - -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "mojo/public/cpp/bindings/associated_binding_set.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "mojo/public/cpp/bindings/strong_binding_set.h" -#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" -#include "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -class BindingSetTest : public testing::Test { - public: - BindingSetTest() {} - ~BindingSetTest() override {} - - base::MessageLoop& loop() { return loop_; } - - private: - base::MessageLoop loop_; - - DISALLOW_COPY_AND_ASSIGN(BindingSetTest); -}; - -template <typename BindingSetType, typename ContextType> -void ExpectContextHelper(BindingSetType* binding_set, - ContextType expected_context) { - EXPECT_EQ(expected_context, binding_set->dispatch_context()); -} - -template <typename BindingSetType, typename ContextType> -base::Closure ExpectContext(BindingSetType* binding_set, - ContextType expected_context) { - return base::Bind( - &ExpectContextHelper<BindingSetType, ContextType>, binding_set, - expected_context); -} - -base::Closure Sequence(const base::Closure& first, - const base::Closure& second) { - return base::Bind( - [] (const base::Closure& first, const base::Closure& second) { - first.Run(); - second.Run(); - }, first, second); -} - -class PingImpl : public PingService { - public: - PingImpl() {} - ~PingImpl() override {} - - void set_ping_handler(const base::Closure& handler) { - ping_handler_ = handler; - } - - private: - // PingService: - void Ping(const PingCallback& callback) override { - if (!ping_handler_.is_null()) - ping_handler_.Run(); - callback.Run(); - } - - base::Closure ping_handler_; -}; - -TEST_F(BindingSetTest, BindingSetContext) { - PingImpl impl; - - BindingSet<PingService, int> bindings; - PingServicePtr ping_a, ping_b; - bindings.AddBinding(&impl, MakeRequest(&ping_a), 1); - bindings.AddBinding(&impl, MakeRequest(&ping_b), 2); - - { - impl.set_ping_handler(ExpectContext(&bindings, 1)); - base::RunLoop loop; - ping_a->Ping(loop.QuitClosure()); - loop.Run(); - } - - { - impl.set_ping_handler(ExpectContext(&bindings, 2)); - base::RunLoop loop; - ping_b->Ping(loop.QuitClosure()); - loop.Run(); - } - - { - base::RunLoop loop; - bindings.set_connection_error_handler( - Sequence(ExpectContext(&bindings, 1), loop.QuitClosure())); - ping_a.reset(); - loop.Run(); - } - - { - base::RunLoop loop; - bindings.set_connection_error_handler( - Sequence(ExpectContext(&bindings, 2), loop.QuitClosure())); - ping_b.reset(); - loop.Run(); - } - - EXPECT_TRUE(bindings.empty()); -} - -TEST_F(BindingSetTest, BindingSetConnectionErrorWithReason) { - PingImpl impl; - PingServicePtr ptr; - BindingSet<PingService> bindings; - bindings.AddBinding(&impl, MakeRequest(&ptr)); - - base::RunLoop run_loop; - bindings.set_connection_error_with_reason_handler(base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(1024u, custom_reason); - EXPECT_EQ("bye", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - ptr.ResetWithReason(1024u, "bye"); -} - -class PingProviderImpl : public AssociatedPingProvider, public PingService { - public: - PingProviderImpl() {} - ~PingProviderImpl() override {} - - void set_new_ping_context(int context) { new_ping_context_ = context; } - - void set_new_ping_handler(const base::Closure& handler) { - new_ping_handler_ = handler; - } - - void set_ping_handler(const base::Closure& handler) { - ping_handler_ = handler; - } - - AssociatedBindingSet<PingService, int>& ping_bindings() { - return ping_bindings_; - } - - private: - // AssociatedPingProvider: - void GetPing(PingServiceAssociatedRequest request) override { - ping_bindings_.AddBinding(this, std::move(request), new_ping_context_); - if (!new_ping_handler_.is_null()) - new_ping_handler_.Run(); - } - - // PingService: - void Ping(const PingCallback& callback) override { - if (!ping_handler_.is_null()) - ping_handler_.Run(); - callback.Run(); - } - - AssociatedBindingSet<PingService, int> ping_bindings_; - int new_ping_context_ = -1; - base::Closure ping_handler_; - base::Closure new_ping_handler_; -}; - -TEST_F(BindingSetTest, AssociatedBindingSetContext) { - AssociatedPingProviderPtr provider; - PingProviderImpl impl; - Binding<AssociatedPingProvider> binding(&impl, MakeRequest(&provider)); - - PingServiceAssociatedPtr ping_a; - { - base::RunLoop loop; - impl.set_new_ping_context(1); - impl.set_new_ping_handler(loop.QuitClosure()); - provider->GetPing(MakeRequest(&ping_a)); - loop.Run(); - } - - PingServiceAssociatedPtr ping_b; - { - base::RunLoop loop; - impl.set_new_ping_context(2); - impl.set_new_ping_handler(loop.QuitClosure()); - provider->GetPing(MakeRequest(&ping_b)); - loop.Run(); - } - - { - impl.set_ping_handler(ExpectContext(&impl.ping_bindings(), 1)); - base::RunLoop loop; - ping_a->Ping(loop.QuitClosure()); - loop.Run(); - } - - { - impl.set_ping_handler(ExpectContext(&impl.ping_bindings(), 2)); - base::RunLoop loop; - ping_b->Ping(loop.QuitClosure()); - loop.Run(); - } - - { - base::RunLoop loop; - impl.ping_bindings().set_connection_error_handler( - Sequence(ExpectContext(&impl.ping_bindings(), 1), loop.QuitClosure())); - ping_a.reset(); - loop.Run(); - } - - { - base::RunLoop loop; - impl.ping_bindings().set_connection_error_handler( - Sequence(ExpectContext(&impl.ping_bindings(), 2), loop.QuitClosure())); - ping_b.reset(); - loop.Run(); - } - - EXPECT_TRUE(impl.ping_bindings().empty()); -} - -TEST_F(BindingSetTest, MasterInterfaceBindingSetContext) { - AssociatedPingProviderPtr provider_a, provider_b; - PingProviderImpl impl; - BindingSet<AssociatedPingProvider, int> bindings; - - bindings.AddBinding(&impl, MakeRequest(&provider_a), 1); - bindings.AddBinding(&impl, MakeRequest(&provider_b), 2); - - { - PingServiceAssociatedPtr ping; - base::RunLoop loop; - impl.set_new_ping_handler( - Sequence(ExpectContext(&bindings, 1), loop.QuitClosure())); - provider_a->GetPing(MakeRequest(&ping)); - loop.Run(); - } - - { - PingServiceAssociatedPtr ping; - base::RunLoop loop; - impl.set_new_ping_handler( - Sequence(ExpectContext(&bindings, 2), loop.QuitClosure())); - provider_b->GetPing(MakeRequest(&ping)); - loop.Run(); - } - - { - base::RunLoop loop; - bindings.set_connection_error_handler( - Sequence(ExpectContext(&bindings, 1), loop.QuitClosure())); - provider_a.reset(); - loop.Run(); - } - - { - base::RunLoop loop; - bindings.set_connection_error_handler( - Sequence(ExpectContext(&bindings, 2), loop.QuitClosure())); - provider_b.reset(); - loop.Run(); - } - - EXPECT_TRUE(bindings.empty()); -} - -TEST_F(BindingSetTest, PreDispatchHandler) { - PingImpl impl; - - BindingSet<PingService, int> bindings; - PingServicePtr ping_a, ping_b; - bindings.AddBinding(&impl, MakeRequest(&ping_a), 1); - bindings.AddBinding(&impl, MakeRequest(&ping_b), 2); - - { - bindings.set_pre_dispatch_handler(base::Bind([] (const int& context) { - EXPECT_EQ(1, context); - })); - base::RunLoop loop; - ping_a->Ping(loop.QuitClosure()); - loop.Run(); - } - - { - bindings.set_pre_dispatch_handler(base::Bind([] (const int& context) { - EXPECT_EQ(2, context); - })); - base::RunLoop loop; - ping_b->Ping(loop.QuitClosure()); - loop.Run(); - } - - { - base::RunLoop loop; - bindings.set_pre_dispatch_handler( - base::Bind([](base::RunLoop* loop, const int& context) { - EXPECT_EQ(1, context); - loop->Quit(); - }, &loop)); - ping_a.reset(); - loop.Run(); - } - - { - base::RunLoop loop; - bindings.set_pre_dispatch_handler( - base::Bind([](base::RunLoop* loop, const int& context) { - EXPECT_EQ(2, context); - loop->Quit(); - }, &loop)); - ping_b.reset(); - loop.Run(); - } - - EXPECT_TRUE(bindings.empty()); -} - -TEST_F(BindingSetTest, AssociatedBindingSetConnectionErrorWithReason) { - AssociatedPingProviderPtr master_ptr; - PingProviderImpl master_impl; - Binding<AssociatedPingProvider> master_binding(&master_impl, &master_ptr); - - base::RunLoop run_loop; - master_impl.ping_bindings().set_connection_error_with_reason_handler( - base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(2048u, custom_reason); - EXPECT_EQ("bye", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - PingServiceAssociatedPtr ptr; - master_ptr->GetPing(MakeRequest(&ptr)); - - ptr.ResetWithReason(2048u, "bye"); - - run_loop.Run(); -} - -class PingInstanceCounter : public PingService { - public: - PingInstanceCounter() { ++instance_count; } - ~PingInstanceCounter() override { --instance_count; } - - void Ping(const PingCallback& callback) override {} - - static int instance_count; -}; -int PingInstanceCounter::instance_count = 0; - -TEST_F(BindingSetTest, StrongBinding_Destructor) { - PingServicePtr ping_a, ping_b; - auto bindings = base::MakeUnique<StrongBindingSet<PingService>>(); - - bindings->AddBinding(base::MakeUnique<PingInstanceCounter>(), - mojo::MakeRequest(&ping_a)); - EXPECT_EQ(1, PingInstanceCounter::instance_count); - - bindings->AddBinding(base::MakeUnique<PingInstanceCounter>(), - mojo::MakeRequest(&ping_b)); - EXPECT_EQ(2, PingInstanceCounter::instance_count); - - bindings.reset(); - EXPECT_EQ(0, PingInstanceCounter::instance_count); -} - -TEST_F(BindingSetTest, StrongBinding_ConnectionError) { - PingServicePtr ping_a, ping_b; - StrongBindingSet<PingService> bindings; - bindings.AddBinding(base::MakeUnique<PingInstanceCounter>(), - mojo::MakeRequest(&ping_a)); - bindings.AddBinding(base::MakeUnique<PingInstanceCounter>(), - mojo::MakeRequest(&ping_b)); - EXPECT_EQ(2, PingInstanceCounter::instance_count); - - ping_a.reset(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1, PingInstanceCounter::instance_count); - - ping_b.reset(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(0, PingInstanceCounter::instance_count); -} - -TEST_F(BindingSetTest, StrongBinding_RemoveBinding) { - PingServicePtr ping_a, ping_b; - StrongBindingSet<PingService> bindings; - BindingId binding_id_a = bindings.AddBinding( - base::MakeUnique<PingInstanceCounter>(), mojo::MakeRequest(&ping_a)); - BindingId binding_id_b = bindings.AddBinding( - base::MakeUnique<PingInstanceCounter>(), mojo::MakeRequest(&ping_b)); - EXPECT_EQ(2, PingInstanceCounter::instance_count); - - EXPECT_TRUE(bindings.RemoveBinding(binding_id_a)); - EXPECT_EQ(1, PingInstanceCounter::instance_count); - - EXPECT_TRUE(bindings.RemoveBinding(binding_id_b)); - EXPECT_EQ(0, PingInstanceCounter::instance_count); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/binding_unittest.cc b/mojo/public/cpp/bindings/tests/binding_unittest.cc deleted file mode 100644 index e76993b..0000000 --- a/mojo/public/cpp/bindings/tests/binding_unittest.cc +++ /dev/null @@ -1,611 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Note: This file tests both binding.h (mojo::Binding) and strong_binding.h -// (mojo::StrongBinding). - -#include "mojo/public/cpp/bindings/binding.h" - -#include <stdint.h> -#include <utility> - -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" -#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" -#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -class BindingTestBase : public testing::Test { - public: - BindingTestBase() {} - ~BindingTestBase() override {} - - base::MessageLoop& loop() { return loop_; } - - private: - base::MessageLoop loop_; - - DISALLOW_COPY_AND_ASSIGN(BindingTestBase); -}; - -class ServiceImpl : public sample::Service { - public: - explicit ServiceImpl(bool* was_deleted = nullptr) - : was_deleted_(was_deleted) {} - ~ServiceImpl() override { - if (was_deleted_) - *was_deleted_ = true; - } - - private: - // sample::Service implementation - void Frobinate(sample::FooPtr foo, - BazOptions options, - sample::PortPtr port, - const FrobinateCallback& callback) override { - callback.Run(1); - } - void GetPort(InterfaceRequest<sample::Port> port) override {} - - bool* const was_deleted_; - - DISALLOW_COPY_AND_ASSIGN(ServiceImpl); -}; - -template <typename... Args> -void DoSetFlagAndRunClosure(bool* flag, - const base::Closure& closure, - Args... args) { - *flag = true; - if (!closure.is_null()) - closure.Run(); -} - -template <typename... Args> -base::Callback<void(Args...)> SetFlagAndRunClosure( - bool* flag, - const base::Closure& callback = base::Closure()) { - return base::Bind(&DoSetFlagAndRunClosure<Args...>, flag, callback); -} - -// BindingTest ----------------------------------------------------------------- - -using BindingTest = BindingTestBase; - -TEST_F(BindingTest, Close) { - bool called = false; - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - base::RunLoop run_loop; - ptr.set_connection_error_handler( - SetFlagAndRunClosure(&called, run_loop.QuitClosure())); - ServiceImpl impl; - Binding<sample::Service> binding(&impl, std::move(request)); - - binding.Close(); - EXPECT_FALSE(called); - run_loop.Run(); - EXPECT_TRUE(called); -} - -// Tests that destroying a mojo::Binding closes the bound message pipe handle. -TEST_F(BindingTest, DestroyClosesMessagePipe) { - bool encountered_error = false; - ServiceImpl impl; - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - base::RunLoop run_loop; - ptr.set_connection_error_handler( - SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure())); - bool called = false; - base::RunLoop run_loop2; - { - Binding<sample::Service> binding(&impl, std::move(request)); - ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, - SetFlagAndRunClosure<int32_t>(&called, - run_loop2.QuitClosure())); - run_loop2.Run(); - EXPECT_TRUE(called); - EXPECT_FALSE(encountered_error); - } - // Now that the Binding is out of scope we should detect an error on the other - // end of the pipe. - run_loop.Run(); - EXPECT_TRUE(encountered_error); - - // And calls should fail. - called = false; - ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, - SetFlagAndRunClosure<int32_t>(&called, - run_loop2.QuitClosure())); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(called); -} - -// Tests that the binding's connection error handler gets called when the other -// end is closed. -TEST_F(BindingTest, ConnectionError) { - bool called = false; - { - ServiceImpl impl; - sample::ServicePtr ptr; - Binding<sample::Service> binding(&impl, MakeRequest(&ptr)); - base::RunLoop run_loop; - binding.set_connection_error_handler( - SetFlagAndRunClosure(&called, run_loop.QuitClosure())); - ptr.reset(); - EXPECT_FALSE(called); - run_loop.Run(); - EXPECT_TRUE(called); - // We want to make sure that it isn't called again during destruction. - called = false; - } - EXPECT_FALSE(called); -} - -// Tests that calling Close doesn't result in the connection error handler being -// called. -TEST_F(BindingTest, CloseDoesntCallConnectionErrorHandler) { - ServiceImpl impl; - sample::ServicePtr ptr; - Binding<sample::Service> binding(&impl, MakeRequest(&ptr)); - bool called = false; - binding.set_connection_error_handler(SetFlagAndRunClosure(&called)); - binding.Close(); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(called); - - // We can also close the other end, and the error handler still won't be - // called. - ptr.reset(); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(called); -} - -class ServiceImplWithBinding : public ServiceImpl { - public: - ServiceImplWithBinding(bool* was_deleted, - const base::Closure& closure, - InterfaceRequest<sample::Service> request) - : ServiceImpl(was_deleted), - binding_(this, std::move(request)), - closure_(closure) { - binding_.set_connection_error_handler( - base::Bind(&ServiceImplWithBinding::OnConnectionError, - base::Unretained(this))); - } - - private: - ~ServiceImplWithBinding() override{ - closure_.Run(); - } - - void OnConnectionError() { delete this; } - - Binding<sample::Service> binding_; - base::Closure closure_; - - DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding); -}; - -// Tests that the binding may be deleted in the connection error handler. -TEST_F(BindingTest, SelfDeleteOnConnectionError) { - bool was_deleted = false; - sample::ServicePtr ptr; - // This should delete itself on connection error. - base::RunLoop run_loop; - new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(), - MakeRequest(&ptr)); - ptr.reset(); - EXPECT_FALSE(was_deleted); - run_loop.Run(); - EXPECT_TRUE(was_deleted); -} - -// Tests that explicitly calling Unbind followed by rebinding works. -TEST_F(BindingTest, Unbind) { - ServiceImpl impl; - sample::ServicePtr ptr; - Binding<sample::Service> binding(&impl, MakeRequest(&ptr)); - - bool called = false; - base::RunLoop run_loop; - ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, - SetFlagAndRunClosure<int32_t>(&called, - run_loop.QuitClosure())); - run_loop.Run(); - EXPECT_TRUE(called); - - called = false; - auto request = binding.Unbind(); - EXPECT_FALSE(binding.is_bound()); - // All calls should fail when not bound... - ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, - SetFlagAndRunClosure<int32_t>(&called, - run_loop.QuitClosure())); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(called); - - called = false; - binding.Bind(std::move(request)); - EXPECT_TRUE(binding.is_bound()); - // ...and should succeed again when the rebound. - base::RunLoop run_loop2; - ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, - SetFlagAndRunClosure<int32_t>(&called, - run_loop2.QuitClosure())); - run_loop2.Run(); - EXPECT_TRUE(called); -} - -class IntegerAccessorImpl : public sample::IntegerAccessor { - public: - IntegerAccessorImpl() {} - ~IntegerAccessorImpl() override {} - - private: - // sample::IntegerAccessor implementation. - void GetInteger(const GetIntegerCallback& callback) override { - callback.Run(1, sample::Enum::VALUE); - } - void SetInteger(int64_t data, sample::Enum type) override {} - - DISALLOW_COPY_AND_ASSIGN(IntegerAccessorImpl); -}; - -TEST_F(BindingTest, SetInterfacePtrVersion) { - IntegerAccessorImpl impl; - sample::IntegerAccessorPtr ptr; - Binding<sample::IntegerAccessor> binding(&impl, &ptr); - EXPECT_EQ(3u, ptr.version()); -} - -TEST_F(BindingTest, PauseResume) { - bool called = false; - base::RunLoop run_loop; - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - ServiceImpl impl; - Binding<sample::Service> binding(&impl, std::move(request)); - binding.PauseIncomingMethodCallProcessing(); - ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, - SetFlagAndRunClosure<int32_t>(&called, - run_loop.QuitClosure())); - EXPECT_FALSE(called); - base::RunLoop().RunUntilIdle(); - // Frobinate() should not be called as the binding is paused. - EXPECT_FALSE(called); - - // Resume the binding, which should trigger processing. - binding.ResumeIncomingMethodCallProcessing(); - run_loop.Run(); - EXPECT_TRUE(called); -} - -// Verifies the connection error handler is not run while a binding is paused. -TEST_F(BindingTest, ErrorHandleNotRunWhilePaused) { - bool called = false; - base::RunLoop run_loop; - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - ServiceImpl impl; - Binding<sample::Service> binding(&impl, std::move(request)); - binding.set_connection_error_handler( - SetFlagAndRunClosure(&called, run_loop.QuitClosure())); - binding.PauseIncomingMethodCallProcessing(); - - ptr.reset(); - base::RunLoop().RunUntilIdle(); - // The connection error handle should not be called as the binding is paused. - EXPECT_FALSE(called); - - // Resume the binding, which should trigger the error handler. - binding.ResumeIncomingMethodCallProcessing(); - run_loop.Run(); - EXPECT_TRUE(called); -} - -class PingServiceImpl : public test::PingService { - public: - PingServiceImpl() {} - ~PingServiceImpl() override {} - - // test::PingService: - void Ping(const PingCallback& callback) override { - if (!ping_handler_.is_null()) - ping_handler_.Run(); - callback.Run(); - } - - void set_ping_handler(const base::Closure& handler) { - ping_handler_ = handler; - } - - private: - base::Closure ping_handler_; - - DISALLOW_COPY_AND_ASSIGN(PingServiceImpl); -}; - -class CallbackFilter : public MessageReceiver { - public: - explicit CallbackFilter(const base::Closure& callback) - : callback_(callback) {} - ~CallbackFilter() override {} - - static std::unique_ptr<CallbackFilter> Wrap(const base::Closure& callback) { - return base::MakeUnique<CallbackFilter>(callback); - } - - // MessageReceiver: - bool Accept(Message* message) override { - callback_.Run(); - return true; - } - - private: - const base::Closure callback_; -}; - -// Verifies that message filters are notified in the order they were added and -// are always notified before a message is dispatched. -TEST_F(BindingTest, MessageFilter) { - test::PingServicePtr ptr; - PingServiceImpl impl; - mojo::Binding<test::PingService> binding(&impl, MakeRequest(&ptr)); - - int status = 0; - auto handler_helper = [] (int* status, int expected_status, int new_status) { - EXPECT_EQ(expected_status, *status); - *status = new_status; - }; - auto create_handler = [&] (int expected_status, int new_status) { - return base::Bind(handler_helper, &status, expected_status, new_status); - }; - - binding.AddFilter(CallbackFilter::Wrap(create_handler(0, 1))); - binding.AddFilter(CallbackFilter::Wrap(create_handler(1, 2))); - impl.set_ping_handler(create_handler(2, 3)); - - for (int i = 0; i < 10; ++i) { - status = 0; - base::RunLoop loop; - ptr->Ping(loop.QuitClosure()); - loop.Run(); - EXPECT_EQ(3, status); - } -} - -void Fail() { - FAIL() << "Unexpected connection error"; -} - -TEST_F(BindingTest, FlushForTesting) { - bool called = false; - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - ServiceImpl impl; - Binding<sample::Service> binding(&impl, std::move(request)); - binding.set_connection_error_handler(base::Bind(&Fail)); - - ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, - SetFlagAndRunClosure<int32_t>(&called)); - EXPECT_FALSE(called); - // Because the flush is sent from the binding, it only guarantees that the - // request has been received, not the response. The second flush waits for the - // response to be received. - binding.FlushForTesting(); - binding.FlushForTesting(); - EXPECT_TRUE(called); -} - -TEST_F(BindingTest, FlushForTestingWithClosedPeer) { - bool called = false; - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - ServiceImpl impl; - Binding<sample::Service> binding(&impl, std::move(request)); - binding.set_connection_error_handler(SetFlagAndRunClosure(&called)); - ptr.reset(); - - EXPECT_FALSE(called); - binding.FlushForTesting(); - EXPECT_TRUE(called); - binding.FlushForTesting(); -} - -TEST_F(BindingTest, ConnectionErrorWithReason) { - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - ServiceImpl impl; - Binding<sample::Service> binding(&impl, std::move(request)); - - base::RunLoop run_loop; - binding.set_connection_error_with_reason_handler(base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(1234u, custom_reason); - EXPECT_EQ("hello", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - ptr.ResetWithReason(1234u, "hello"); - - run_loop.Run(); -} - -template <typename T> -struct WeakPtrImplRefTraits { - using PointerType = base::WeakPtr<T>; - - static bool IsNull(const base::WeakPtr<T>& ptr) { return !ptr; } - static T* GetRawPointer(base::WeakPtr<T>* ptr) { return ptr->get(); } -}; - -template <typename T> -using WeakBinding = Binding<T, WeakPtrImplRefTraits<T>>; - -TEST_F(BindingTest, CustomImplPointerType) { - PingServiceImpl impl; - base::WeakPtrFactory<test::PingService> weak_factory(&impl); - - test::PingServicePtr proxy; - WeakBinding<test::PingService> binding(weak_factory.GetWeakPtr(), - MakeRequest(&proxy)); - - { - // Ensure the binding is functioning. - base::RunLoop run_loop; - proxy->Ping(run_loop.QuitClosure()); - run_loop.Run(); - } - - { - // Attempt to dispatch another message after the WeakPtr is invalidated. - base::Closure assert_not_reached = base::Bind([] { NOTREACHED(); }); - impl.set_ping_handler(assert_not_reached); - proxy->Ping(assert_not_reached); - - // The binding will close its end of the pipe which will trigger a - // connection error on |proxy|. - base::RunLoop run_loop; - proxy.set_connection_error_handler(run_loop.QuitClosure()); - weak_factory.InvalidateWeakPtrs(); - run_loop.Run(); - } -} - -// StrongBindingTest ----------------------------------------------------------- - -using StrongBindingTest = BindingTestBase; - -// Tests that destroying a mojo::StrongBinding closes the bound message pipe -// handle but does *not* destroy the implementation object. -TEST_F(StrongBindingTest, DestroyClosesMessagePipe) { - base::RunLoop run_loop; - bool encountered_error = false; - bool was_deleted = false; - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - ptr.set_connection_error_handler( - SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure())); - bool called = false; - base::RunLoop run_loop2; - - auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted), - std::move(request)); - ptr->Frobinate( - nullptr, sample::Service::BazOptions::REGULAR, nullptr, - SetFlagAndRunClosure<int32_t>(&called, run_loop2.QuitClosure())); - run_loop2.Run(); - EXPECT_TRUE(called); - EXPECT_FALSE(encountered_error); - binding->Close(); - - // Now that the StrongBinding is closed we should detect an error on the other - // end of the pipe. - run_loop.Run(); - EXPECT_TRUE(encountered_error); - - // Destroying the StrongBinding also destroys the impl. - ASSERT_TRUE(was_deleted); -} - -// Tests the typical case, where the implementation object owns the -// StrongBinding (and should be destroyed on connection error). -TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) { - sample::ServicePtr ptr; - bool was_deleted = false; - // Will delete itself. - base::RunLoop run_loop; - new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(), - MakeRequest(&ptr)); - - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(was_deleted); - - ptr.reset(); - EXPECT_FALSE(was_deleted); - run_loop.Run(); - EXPECT_TRUE(was_deleted); -} - -TEST_F(StrongBindingTest, FlushForTesting) { - bool called = false; - bool was_deleted = false; - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted), - std::move(request)); - binding->set_connection_error_handler(base::Bind(&Fail)); - - ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, - SetFlagAndRunClosure<int32_t>(&called)); - EXPECT_FALSE(called); - // Because the flush is sent from the binding, it only guarantees that the - // request has been received, not the response. The second flush waits for the - // response to be received. - ASSERT_TRUE(binding); - binding->FlushForTesting(); - ASSERT_TRUE(binding); - binding->FlushForTesting(); - EXPECT_TRUE(called); - EXPECT_FALSE(was_deleted); - ptr.reset(); - ASSERT_TRUE(binding); - binding->set_connection_error_handler(base::Closure()); - binding->FlushForTesting(); - EXPECT_TRUE(was_deleted); -} - -TEST_F(StrongBindingTest, FlushForTestingWithClosedPeer) { - bool called = false; - bool was_deleted = false; - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted), - std::move(request)); - binding->set_connection_error_handler(SetFlagAndRunClosure(&called)); - ptr.reset(); - - EXPECT_FALSE(called); - EXPECT_FALSE(was_deleted); - ASSERT_TRUE(binding); - binding->FlushForTesting(); - EXPECT_TRUE(called); - EXPECT_TRUE(was_deleted); - ASSERT_FALSE(binding); -} - -TEST_F(StrongBindingTest, ConnectionErrorWithReason) { - sample::ServicePtr ptr; - auto request = MakeRequest(&ptr); - auto binding = - MakeStrongBinding(base::MakeUnique<ServiceImpl>(), std::move(request)); - base::RunLoop run_loop; - binding->set_connection_error_with_reason_handler(base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(5678u, custom_reason); - EXPECT_EQ("hello", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - ptr.ResetWithReason(5678u, "hello"); - - run_loop.Run(); -} - -} // namespace -} // mojo diff --git a/mojo/public/cpp/bindings/tests/bindings_perftest.cc b/mojo/public/cpp/bindings/tests/bindings_perftest.cc deleted file mode 100644 index 65b3c8c..0000000 --- a/mojo/public/cpp/bindings/tests/bindings_perftest.cc +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <utility> - -#include "base/bind.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/interface_endpoint_client.h" -#include "mojo/public/cpp/bindings/lib/message_builder.h" -#include "mojo/public/cpp/bindings/lib/multiplex_router.h" -#include "mojo/public/cpp/bindings/message.h" -#include "mojo/public/cpp/test_support/test_support.h" -#include "mojo/public/cpp/test_support/test_utils.h" -#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -const double kMojoTicksPerSecond = 1000000.0; - -double MojoTicksToSeconds(MojoTimeTicks ticks) { - return ticks / kMojoTicksPerSecond; -} - -class PingServiceImpl : public test::PingService { - public: - PingServiceImpl() {} - ~PingServiceImpl() override {} - - // |PingService| methods: - void Ping(const PingCallback& callback) override; - - private: - DISALLOW_COPY_AND_ASSIGN(PingServiceImpl); -}; - -void PingServiceImpl::Ping(const PingCallback& callback) { - callback.Run(); -} - -class PingPongTest { - public: - explicit PingPongTest(test::PingServicePtr service); - - void Run(unsigned int iterations); - - private: - void OnPingDone(); - - test::PingServicePtr service_; - unsigned int iterations_to_run_; - unsigned int current_iterations_; - - base::Closure quit_closure_; - - DISALLOW_COPY_AND_ASSIGN(PingPongTest); -}; - -PingPongTest::PingPongTest(test::PingServicePtr service) - : service_(std::move(service)) {} - -void PingPongTest::Run(unsigned int iterations) { - iterations_to_run_ = iterations; - current_iterations_ = 0; - - base::RunLoop run_loop; - quit_closure_ = run_loop.QuitClosure(); - service_->Ping(base::Bind(&PingPongTest::OnPingDone, base::Unretained(this))); - run_loop.Run(); -} - -void PingPongTest::OnPingDone() { - current_iterations_++; - if (current_iterations_ >= iterations_to_run_) { - quit_closure_.Run(); - return; - } - - service_->Ping(base::Bind(&PingPongTest::OnPingDone, base::Unretained(this))); -} - -struct BoundPingService { - BoundPingService() : binding(&impl) { binding.Bind(MakeRequest(&service)); } - - PingServiceImpl impl; - test::PingServicePtr service; - Binding<test::PingService> binding; -}; - -class MojoBindingsPerftest : public testing::Test { - public: - MojoBindingsPerftest() {} - - protected: - base::MessageLoop loop_; -}; - -TEST_F(MojoBindingsPerftest, InProcessPingPong) { - test::PingServicePtr service; - PingServiceImpl impl; - Binding<test::PingService> binding(&impl, MakeRequest(&service)); - PingPongTest test(std::move(service)); - - { - const unsigned int kIterations = 100000; - const MojoTimeTicks start_time = MojoGetTimeTicksNow(); - test.Run(kIterations); - const MojoTimeTicks end_time = MojoGetTimeTicksNow(); - test::LogPerfResult( - "InProcessPingPong", "0_Inactive", - kIterations / MojoTicksToSeconds(end_time - start_time), - "pings/second"); - } - - { - const size_t kNumInactiveServices = 1000; - BoundPingService* inactive_services = - new BoundPingService[kNumInactiveServices]; - - const unsigned int kIterations = 10000; - const MojoTimeTicks start_time = MojoGetTimeTicksNow(); - test.Run(kIterations); - const MojoTimeTicks end_time = MojoGetTimeTicksNow(); - test::LogPerfResult( - "InProcessPingPong", "1000_Inactive", - kIterations / MojoTicksToSeconds(end_time - start_time), - "pings/second"); - - delete[] inactive_services; - } -} - -class PingPongPaddle : public MessageReceiverWithResponderStatus { - public: - PingPongPaddle(MessageReceiver* sender) : sender_(sender) {} - - void set_sender(MessageReceiver* sender) { sender_ = sender; } - - bool Accept(Message* message) override { - uint32_t count = message->header()->name; - if (!quit_closure_.is_null()) { - count++; - if (count >= expected_count_) { - end_time_ = base::TimeTicks::Now(); - quit_closure_.Run(); - return true; - } - } - - internal::MessageBuilder builder(count, 0, 8, 0); - bool result = sender_->Accept(builder.message()); - DCHECK(result); - return true; - } - - bool AcceptWithResponder( - Message* message, - std::unique_ptr<MessageReceiverWithStatus> responder) override { - NOTREACHED(); - return true; - } - - base::TimeDelta Serve(uint32_t expected_count) { - base::RunLoop run_loop; - - expected_count_ = expected_count; - quit_closure_ = run_loop.QuitClosure(); - - start_time_ = base::TimeTicks::Now(); - internal::MessageBuilder builder(0, 0, 8, 0); - bool result = sender_->Accept(builder.message()); - DCHECK(result); - - run_loop.Run(); - - return end_time_ - start_time_; - } - - private: - base::TimeTicks start_time_; - base::TimeTicks end_time_; - uint32_t expected_count_ = 0; - MessageReceiver* sender_; - base::Closure quit_closure_; -}; - -TEST_F(MojoBindingsPerftest, MultiplexRouterPingPong) { - MessagePipe pipe; - scoped_refptr<internal::MultiplexRouter> router0( - new internal::MultiplexRouter(std::move(pipe.handle0), - internal::MultiplexRouter::SINGLE_INTERFACE, - true, base::ThreadTaskRunnerHandle::Get())); - scoped_refptr<internal::MultiplexRouter> router1( - new internal::MultiplexRouter( - std::move(pipe.handle1), internal::MultiplexRouter::SINGLE_INTERFACE, - false, base::ThreadTaskRunnerHandle::Get())); - - PingPongPaddle paddle0(nullptr); - PingPongPaddle paddle1(nullptr); - - InterfaceEndpointClient client0( - router0->CreateLocalEndpointHandle(kMasterInterfaceId), &paddle0, nullptr, - false, base::ThreadTaskRunnerHandle::Get(), 0u); - InterfaceEndpointClient client1( - router1->CreateLocalEndpointHandle(kMasterInterfaceId), &paddle1, nullptr, - false, base::ThreadTaskRunnerHandle::Get(), 0u); - - paddle0.set_sender(&client0); - paddle1.set_sender(&client1); - - static const uint32_t kWarmUpIterations = 1000; - static const uint32_t kTestIterations = 1000000; - - paddle0.Serve(kWarmUpIterations); - - base::TimeDelta duration = paddle0.Serve(kTestIterations); - - test::LogPerfResult("MultiplexRouterPingPong", nullptr, - kTestIterations / duration.InSecondsF(), "pings/second"); -} - -class CounterReceiver : public MessageReceiverWithResponderStatus { - public: - bool Accept(Message* message) override { - counter_++; - return true; - } - - bool AcceptWithResponder( - Message* message, - std::unique_ptr<MessageReceiverWithStatus> responder) override { - NOTREACHED(); - return true; - } - - uint32_t counter() const { return counter_; } - - void Reset() { counter_ = 0; } - - private: - uint32_t counter_ = 0; -}; - -TEST_F(MojoBindingsPerftest, MultiplexRouterDispatchCost) { - MessagePipe pipe; - scoped_refptr<internal::MultiplexRouter> router(new internal::MultiplexRouter( - std::move(pipe.handle0), internal::MultiplexRouter::SINGLE_INTERFACE, - true, base::ThreadTaskRunnerHandle::Get())); - CounterReceiver receiver; - InterfaceEndpointClient client( - router->CreateLocalEndpointHandle(kMasterInterfaceId), &receiver, nullptr, - false, base::ThreadTaskRunnerHandle::Get(), 0u); - - static const uint32_t kIterations[] = {1000, 3000000}; - - for (size_t i = 0; i < 2; ++i) { - receiver.Reset(); - base::TimeTicks start_time = base::TimeTicks::Now(); - for (size_t j = 0; j < kIterations[i]; ++j) { - internal::MessageBuilder builder(0, 0, 8, 0); - bool result = - router->SimulateReceivingMessageForTesting(builder.message()); - DCHECK(result); - } - - base::TimeTicks end_time = base::TimeTicks::Now(); - base::TimeDelta duration = end_time - start_time; - CHECK_EQ(kIterations[i], receiver.counter()); - - if (i == 1) { - test::LogPerfResult("MultiplexRouterDispatchCost", nullptr, - kIterations[i] / duration.InSecondsF(), - "times/second"); - } - } -} - -} // namespace -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/blink_typemaps.gni b/mojo/public/cpp/bindings/tests/blink_typemaps.gni deleted file mode 100644 index b71dcf8..0000000 --- a/mojo/public/cpp/bindings/tests/blink_typemaps.gni +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -typemaps = [ - "//mojo/public/cpp/bindings/tests/rect_blink.typemap", - "//mojo/public/cpp/bindings/tests/test_native_types_blink.typemap", -] diff --git a/mojo/public/cpp/bindings/tests/buffer_unittest.cc b/mojo/public/cpp/bindings/tests/buffer_unittest.cc deleted file mode 100644 index d75bdd0..0000000 --- a/mojo/public/cpp/bindings/tests/buffer_unittest.cc +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> - -#include <limits> - -#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" -#include "mojo/public/cpp/bindings/lib/serialization_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -bool IsZero(void* p_buf, size_t size) { - char* buf = reinterpret_cast<char*>(p_buf); - for (size_t i = 0; i < size; ++i) { - if (buf[i] != 0) - return false; - } - return true; -} - -// Tests that FixedBuffer allocates memory aligned to 8 byte boundaries. -TEST(FixedBufferTest, Alignment) { - internal::FixedBufferForTesting buf(internal::Align(10) * 2); - ASSERT_EQ(buf.size(), 16u * 2); - - void* a = buf.Allocate(10); - ASSERT_TRUE(a); - EXPECT_TRUE(IsZero(a, 10)); - EXPECT_EQ(0, reinterpret_cast<ptrdiff_t>(a) % 8); - - void* b = buf.Allocate(10); - ASSERT_TRUE(b); - EXPECT_TRUE(IsZero(b, 10)); - EXPECT_EQ(0, reinterpret_cast<ptrdiff_t>(b) % 8); - - // Any more allocations would result in an assert, but we can't test that. -} - -// Tests that FixedBufferForTesting::Leak passes ownership to the caller. -TEST(FixedBufferTest, Leak) { - void* ptr = nullptr; - void* buf_ptr = nullptr; - { - internal::FixedBufferForTesting buf(8); - ASSERT_EQ(8u, buf.size()); - - ptr = buf.Allocate(8); - ASSERT_TRUE(ptr); - buf_ptr = buf.Leak(); - - // The buffer should point to the first element allocated. - // TODO(mpcomplete): Is this a reasonable expectation? - EXPECT_EQ(ptr, buf_ptr); - - // The FixedBufferForTesting should be empty now. - EXPECT_EQ(0u, buf.size()); - EXPECT_FALSE(buf.Leak()); - } - - // Since we called Leak, ptr is still writable after FixedBufferForTesting - // went out of scope. - memset(ptr, 1, 8); - free(buf_ptr); -} - -#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) -TEST(FixedBufferTest, TooBig) { - internal::FixedBufferForTesting buf(24); - - // A little bit too large. - EXPECT_EQ(reinterpret_cast<void*>(0), buf.Allocate(32)); - - // Move the cursor forward. - EXPECT_NE(reinterpret_cast<void*>(0), buf.Allocate(16)); - - // A lot too large. - EXPECT_EQ(reinterpret_cast<void*>(0), - buf.Allocate(std::numeric_limits<size_t>::max() - 1024u)); - - // A lot too large, leading to possible integer overflow. - EXPECT_EQ(reinterpret_cast<void*>(0), - buf.Allocate(std::numeric_limits<size_t>::max() - 8u)); -} -#endif - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/chromium_typemaps.gni b/mojo/public/cpp/bindings/tests/chromium_typemaps.gni deleted file mode 100644 index 1da7cbf..0000000 --- a/mojo/public/cpp/bindings/tests/chromium_typemaps.gni +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -typemaps = [ - "//mojo/public/cpp/bindings/tests/rect_chromium.typemap", - "//mojo/public/cpp/bindings/tests/struct_with_traits.typemap", - "//mojo/public/cpp/bindings/tests/test_native_types_chromium.typemap", -] diff --git a/mojo/public/cpp/bindings/tests/connector_unittest.cc b/mojo/public/cpp/bindings/tests/connector_unittest.cc deleted file mode 100644 index 74ecb7a..0000000 --- a/mojo/public/cpp/bindings/tests/connector_unittest.cc +++ /dev/null @@ -1,599 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/connector.h" - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/callback_helpers.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/threading/thread.h" -#include "base/threading/thread_task_runner_handle.h" -#include "mojo/public/cpp/bindings/lib/message_builder.h" -#include "mojo/public/cpp/bindings/tests/message_queue.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -class MessageAccumulator : public MessageReceiver { - public: - MessageAccumulator() {} - explicit MessageAccumulator(const base::Closure& closure) - : closure_(closure) {} - - bool Accept(Message* message) override { - queue_.Push(message); - if (!closure_.is_null()) - base::ResetAndReturn(&closure_).Run(); - return true; - } - - bool IsEmpty() const { return queue_.IsEmpty(); } - - void Pop(Message* message) { queue_.Pop(message); } - - void set_closure(const base::Closure& closure) { closure_ = closure; } - - size_t size() const { return queue_.size(); } - - private: - MessageQueue queue_; - base::Closure closure_; -}; - -class ConnectorDeletingMessageAccumulator : public MessageAccumulator { - public: - ConnectorDeletingMessageAccumulator(Connector** connector) - : connector_(connector) {} - - bool Accept(Message* message) override { - delete *connector_; - *connector_ = nullptr; - return MessageAccumulator::Accept(message); - } - - private: - Connector** connector_; -}; - -class ReentrantMessageAccumulator : public MessageAccumulator { - public: - ReentrantMessageAccumulator(Connector* connector) - : connector_(connector), number_of_calls_(0) {} - - bool Accept(Message* message) override { - if (!MessageAccumulator::Accept(message)) - return false; - number_of_calls_++; - if (number_of_calls_ == 1) { - return connector_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); - } - return true; - } - - int number_of_calls() { return number_of_calls_; } - - private: - Connector* connector_; - int number_of_calls_; -}; - -class ConnectorTest : public testing::Test { - public: - ConnectorTest() {} - - void SetUp() override { - CreateMessagePipe(nullptr, &handle0_, &handle1_); - } - - void TearDown() override {} - - void AllocMessage(const char* text, Message* message) { - size_t payload_size = strlen(text) + 1; // Plus null terminator. - internal::MessageBuilder builder(1, 0, payload_size, 0); - memcpy(builder.buffer()->Allocate(payload_size), text, payload_size); - - *message = std::move(*builder.message()); - } - - protected: - ScopedMessagePipeHandle handle0_; - ScopedMessagePipeHandle handle1_; - - private: - base::MessageLoop loop_; -}; - -TEST_F(ConnectorTest, Basic) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - const char kText[] = "hello world"; - - Message message; - AllocMessage(kText, &message); - - connector0.Accept(&message); - - base::RunLoop run_loop; - MessageAccumulator accumulator(run_loop.QuitClosure()); - connector1.set_incoming_receiver(&accumulator); - - run_loop.Run(); - - ASSERT_FALSE(accumulator.IsEmpty()); - - Message message_received; - accumulator.Pop(&message_received); - - EXPECT_EQ( - std::string(kText), - std::string(reinterpret_cast<const char*>(message_received.payload()))); -} - -TEST_F(ConnectorTest, Basic_Synchronous) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - const char kText[] = "hello world"; - - Message message; - AllocMessage(kText, &message); - - connector0.Accept(&message); - - MessageAccumulator accumulator; - connector1.set_incoming_receiver(&accumulator); - - connector1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); - - ASSERT_FALSE(accumulator.IsEmpty()); - - Message message_received; - accumulator.Pop(&message_received); - - EXPECT_EQ( - std::string(kText), - std::string(reinterpret_cast<const char*>(message_received.payload()))); -} - -TEST_F(ConnectorTest, Basic_EarlyIncomingReceiver) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - base::RunLoop run_loop; - MessageAccumulator accumulator(run_loop.QuitClosure()); - connector1.set_incoming_receiver(&accumulator); - - const char kText[] = "hello world"; - - Message message; - AllocMessage(kText, &message); - - connector0.Accept(&message); - - run_loop.Run(); - - ASSERT_FALSE(accumulator.IsEmpty()); - - Message message_received; - accumulator.Pop(&message_received); - - EXPECT_EQ( - std::string(kText), - std::string(reinterpret_cast<const char*>(message_received.payload()))); -} - -TEST_F(ConnectorTest, Basic_TwoMessages) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - const char* kText[] = {"hello", "world"}; - - for (size_t i = 0; i < arraysize(kText); ++i) { - Message message; - AllocMessage(kText[i], &message); - - connector0.Accept(&message); - } - - MessageAccumulator accumulator; - connector1.set_incoming_receiver(&accumulator); - - for (size_t i = 0; i < arraysize(kText); ++i) { - if (accumulator.IsEmpty()) { - base::RunLoop run_loop; - accumulator.set_closure(run_loop.QuitClosure()); - run_loop.Run(); - } - ASSERT_FALSE(accumulator.IsEmpty()); - - Message message_received; - accumulator.Pop(&message_received); - - EXPECT_EQ( - std::string(kText[i]), - std::string(reinterpret_cast<const char*>(message_received.payload()))); - } -} - -TEST_F(ConnectorTest, Basic_TwoMessages_Synchronous) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - const char* kText[] = {"hello", "world"}; - - for (size_t i = 0; i < arraysize(kText); ++i) { - Message message; - AllocMessage(kText[i], &message); - - connector0.Accept(&message); - } - - MessageAccumulator accumulator; - connector1.set_incoming_receiver(&accumulator); - - connector1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); - - ASSERT_FALSE(accumulator.IsEmpty()); - - Message message_received; - accumulator.Pop(&message_received); - - EXPECT_EQ( - std::string(kText[0]), - std::string(reinterpret_cast<const char*>(message_received.payload()))); - - ASSERT_TRUE(accumulator.IsEmpty()); -} - -TEST_F(ConnectorTest, WriteToClosedPipe) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - const char kText[] = "hello world"; - - Message message; - AllocMessage(kText, &message); - - // Close the other end of the pipe. - handle1_.reset(); - - // Not observed yet because we haven't spun the message loop yet. - EXPECT_FALSE(connector0.encountered_error()); - - // Write failures are not reported. - bool ok = connector0.Accept(&message); - EXPECT_TRUE(ok); - - // Still not observed. - EXPECT_FALSE(connector0.encountered_error()); - - // Spin the message loop, and then we should start observing the closed pipe. - base::RunLoop run_loop; - connector0.set_connection_error_handler(run_loop.QuitClosure()); - run_loop.Run(); - - EXPECT_TRUE(connector0.encountered_error()); -} - -TEST_F(ConnectorTest, MessageWithHandles) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - const char kText[] = "hello world"; - - Message message1; - AllocMessage(kText, &message1); - - MessagePipe pipe; - message1.mutable_handles()->push_back(pipe.handle0.release()); - - connector0.Accept(&message1); - - // The message should have been transferred, releasing the handles. - EXPECT_TRUE(message1.handles()->empty()); - - base::RunLoop run_loop; - MessageAccumulator accumulator(run_loop.QuitClosure()); - connector1.set_incoming_receiver(&accumulator); - - run_loop.Run(); - - ASSERT_FALSE(accumulator.IsEmpty()); - - Message message_received; - accumulator.Pop(&message_received); - - EXPECT_EQ( - std::string(kText), - std::string(reinterpret_cast<const char*>(message_received.payload()))); - ASSERT_EQ(1U, message_received.handles()->size()); - - // Now send a message to the transferred handle and confirm it's sent through - // to the orginal pipe. - // TODO(vtl): Do we need a better way of "downcasting" the handle types? - ScopedMessagePipeHandle smph; - smph.reset(MessagePipeHandle(message_received.handles()->front().value())); - message_received.mutable_handles()->front() = Handle(); - // |smph| now owns this handle. - - Connector connector_received(std::move(smph), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector connector_original(std::move(pipe.handle1), - Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - Message message2; - AllocMessage(kText, &message2); - - connector_received.Accept(&message2); - base::RunLoop run_loop2; - MessageAccumulator accumulator2(run_loop2.QuitClosure()); - connector_original.set_incoming_receiver(&accumulator2); - run_loop2.Run(); - - ASSERT_FALSE(accumulator2.IsEmpty()); - - accumulator2.Pop(&message_received); - - EXPECT_EQ( - std::string(kText), - std::string(reinterpret_cast<const char*>(message_received.payload()))); -} - -TEST_F(ConnectorTest, WaitForIncomingMessageWithError) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - // Close the other end of the pipe. - handle1_.reset(); - ASSERT_FALSE(connector0.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE)); -} - -TEST_F(ConnectorTest, WaitForIncomingMessageWithDeletion) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector* connector1 = - new Connector(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - const char kText[] = "hello world"; - - Message message; - AllocMessage(kText, &message); - - connector0.Accept(&message); - - ConnectorDeletingMessageAccumulator accumulator(&connector1); - connector1->set_incoming_receiver(&accumulator); - - connector1->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); - - ASSERT_FALSE(connector1); - ASSERT_FALSE(accumulator.IsEmpty()); - - Message message_received; - accumulator.Pop(&message_received); - - EXPECT_EQ( - std::string(kText), - std::string(reinterpret_cast<const char*>(message_received.payload()))); -} - -TEST_F(ConnectorTest, WaitForIncomingMessageWithReentrancy) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - const char* kText[] = {"hello", "world"}; - - for (size_t i = 0; i < arraysize(kText); ++i) { - Message message; - AllocMessage(kText[i], &message); - - connector0.Accept(&message); - } - - ReentrantMessageAccumulator accumulator(&connector1); - connector1.set_incoming_receiver(&accumulator); - - for (size_t i = 0; i < arraysize(kText); ++i) { - if (accumulator.IsEmpty()) { - base::RunLoop run_loop; - accumulator.set_closure(run_loop.QuitClosure()); - run_loop.Run(); - } - ASSERT_FALSE(accumulator.IsEmpty()); - - Message message_received; - accumulator.Pop(&message_received); - - EXPECT_EQ( - std::string(kText[i]), - std::string(reinterpret_cast<const char*>(message_received.payload()))); - } - - ASSERT_EQ(2, accumulator.number_of_calls()); -} - -void ForwardErrorHandler(bool* called, const base::Closure& callback) { - *called = true; - callback.Run(); -} - -TEST_F(ConnectorTest, RaiseError) { - base::RunLoop run_loop, run_loop2; - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - bool error_handler_called0 = false; - connector0.set_connection_error_handler( - base::Bind(&ForwardErrorHandler, &error_handler_called0, - run_loop.QuitClosure())); - - Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - bool error_handler_called1 = false; - connector1.set_connection_error_handler( - base::Bind(&ForwardErrorHandler, &error_handler_called1, - run_loop2.QuitClosure())); - - const char kText[] = "hello world"; - - Message message; - AllocMessage(kText, &message); - - connector0.Accept(&message); - connector0.RaiseError(); - - base::RunLoop run_loop3; - MessageAccumulator accumulator(run_loop3.QuitClosure()); - connector1.set_incoming_receiver(&accumulator); - - run_loop3.Run(); - - // Messages sent prior to RaiseError() still arrive at the other end. - ASSERT_FALSE(accumulator.IsEmpty()); - - Message message_received; - accumulator.Pop(&message_received); - - EXPECT_EQ( - std::string(kText), - std::string(reinterpret_cast<const char*>(message_received.payload()))); - - run_loop.Run(); - run_loop2.Run(); - - // Connection error handler is called at both sides. - EXPECT_TRUE(error_handler_called0); - EXPECT_TRUE(error_handler_called1); - - // The error flag is set at both sides. - EXPECT_TRUE(connector0.encountered_error()); - EXPECT_TRUE(connector1.encountered_error()); - - // The message pipe handle is valid at both sides. - EXPECT_TRUE(connector0.is_valid()); - EXPECT_TRUE(connector1.is_valid()); -} - -void PauseConnectorAndRunClosure(Connector* connector, - const base::Closure& closure) { - connector->PauseIncomingMethodCallProcessing(); - closure.Run(); -} - -TEST_F(ConnectorTest, PauseWithQueuedMessages) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - const char kText[] = "hello world"; - - // Queue up two messages. - Message message; - AllocMessage(kText, &message); - connector0.Accept(&message); - AllocMessage(kText, &message); - connector0.Accept(&message); - - base::RunLoop run_loop; - // Configure the accumulator such that it pauses after the first message is - // received. - MessageAccumulator accumulator( - base::Bind(&PauseConnectorAndRunClosure, &connector1, - run_loop.QuitClosure())); - connector1.set_incoming_receiver(&accumulator); - - run_loop.Run(); - - // As we paused after the first message we should only have gotten one - // message. - ASSERT_EQ(1u, accumulator.size()); -} - -void AccumulateWithNestedLoop(MessageAccumulator* accumulator, - const base::Closure& closure) { - base::RunLoop nested_run_loop; - base::MessageLoop::ScopedNestableTaskAllower allow( - base::MessageLoop::current()); - accumulator->set_closure(nested_run_loop.QuitClosure()); - nested_run_loop.Run(); - closure.Run(); -} - -TEST_F(ConnectorTest, ProcessWhenNested) { - Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()); - - const char kText[] = "hello world"; - - // Queue up two messages. - Message message; - AllocMessage(kText, &message); - connector0.Accept(&message); - AllocMessage(kText, &message); - connector0.Accept(&message); - - base::RunLoop run_loop; - MessageAccumulator accumulator; - // When the accumulator gets the first message it spins a nested message - // loop. The loop is quit when another message is received. - accumulator.set_closure(base::Bind(&AccumulateWithNestedLoop, &accumulator, - run_loop.QuitClosure())); - connector1.set_incoming_receiver(&accumulator); - - run_loop.Run(); - - ASSERT_EQ(2u, accumulator.size()); -} - -TEST_F(ConnectorTest, DestroyOnDifferentThreadAfterClose) { - std::unique_ptr<Connector> connector( - new Connector(std::move(handle0_), Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get())); - - connector->CloseMessagePipe(); - - base::Thread another_thread("ThreadForDestroyingConnector"); - another_thread.Start(); - - base::RunLoop run_loop; - another_thread.task_runner()->PostTaskAndReply( - FROM_HERE, - base::Bind( - [](std::unique_ptr<Connector> connector) { connector.reset(); }, - base::Passed(std::move(connector))), - run_loop.QuitClosure()); - - run_loop.Run(); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/constant_unittest.cc b/mojo/public/cpp/bindings/tests/constant_unittest.cc deleted file mode 100644 index caa6464..0000000 --- a/mojo/public/cpp/bindings/tests/constant_unittest.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <cmath> - -#include "base/strings/string_piece.h" -#include "mojo/public/interfaces/bindings/tests/test_constants.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { - -TEST(ConstantTest, GlobalConstants) { - // Compile-time constants. - static_assert(kBoolValue == true, ""); - static_assert(kInt8Value == -2, ""); - static_assert(kUint8Value == 128U, ""); - static_assert(kInt16Value == -233, ""); - static_assert(kUint16Value == 44204U, ""); - static_assert(kInt32Value == -44204, ""); - static_assert(kUint32Value == 4294967295U, ""); - static_assert(kInt64Value == -9223372036854775807, ""); - static_assert(kUint64Value == 9999999999999999999ULL, ""); - static_assert(kDoubleValue == 3.14159, ""); - static_assert(kFloatValue == 2.71828f, ""); - - EXPECT_EQ(base::StringPiece(kStringValue), "test string contents"); - EXPECT_TRUE(std::isnan(kDoubleNaN)); - EXPECT_TRUE(std::isinf(kDoubleInfinity)); - EXPECT_TRUE(std::isinf(kDoubleNegativeInfinity)); - EXPECT_NE(kDoubleInfinity, kDoubleNegativeInfinity); - EXPECT_TRUE(std::isnan(kFloatNaN)); - EXPECT_TRUE(std::isinf(kFloatInfinity)); - EXPECT_TRUE(std::isinf(kFloatNegativeInfinity)); - EXPECT_NE(kFloatInfinity, kFloatNegativeInfinity); -} - -TEST(ConstantTest, StructConstants) { - // Compile-time constants. - static_assert(StructWithConstants::kInt8Value == 5U, ""); - static_assert(StructWithConstants::kFloatValue == 765.432f, ""); - - EXPECT_EQ(base::StringPiece(StructWithConstants::kStringValue), - "struct test string contents"); -} - -TEST(ConstantTest, InterfaceConstants) { - // Compile-time constants. - static_assert(InterfaceWithConstants::kUint32Value == 20100722, ""); - static_assert(InterfaceWithConstants::kDoubleValue == 12.34567, ""); - - EXPECT_EQ(base::StringPiece(InterfaceWithConstants::kStringValue), - "interface test string contents"); - EXPECT_EQ(base::StringPiece(InterfaceWithConstants::Name_), - "mojo::test::InterfaceWithConstants"); -} - -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/container_test_util.cc b/mojo/public/cpp/bindings/tests/container_test_util.cc deleted file mode 100644 index a53d351..0000000 --- a/mojo/public/cpp/bindings/tests/container_test_util.cc +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> - -#include "mojo/public/cpp/bindings/tests/container_test_util.h" - -namespace mojo { - -size_t CopyableType::num_instances_ = 0; -size_t MoveOnlyType::num_instances_ = 0; - -CopyableType::CopyableType() : copied_(false), ptr_(this) { - num_instances_++; -} - -CopyableType::CopyableType(const CopyableType& other) - : copied_(true), ptr_(other.ptr()) { - num_instances_++; -} - -CopyableType& CopyableType::operator=(const CopyableType& other) { - copied_ = true; - ptr_ = other.ptr(); - return *this; -} - -CopyableType::~CopyableType() { - num_instances_--; -} - -MoveOnlyType::MoveOnlyType() : moved_(false), ptr_(this) { - num_instances_++; -} - -MoveOnlyType::MoveOnlyType(MoveOnlyType&& other) - : moved_(true), ptr_(other.ptr()) { - num_instances_++; -} - -MoveOnlyType& MoveOnlyType::operator=(MoveOnlyType&& other) { - moved_ = true; - ptr_ = other.ptr(); - return *this; -} - -MoveOnlyType::~MoveOnlyType() { - num_instances_--; -} - -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/container_test_util.h b/mojo/public/cpp/bindings/tests/container_test_util.h deleted file mode 100644 index f709c15..0000000 --- a/mojo/public/cpp/bindings/tests/container_test_util.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_CONTAINER_TEST_UTIL_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_CONTAINER_TEST_UTIL_H_ - -#include <stddef.h> - -#include "base/macros.h" - -namespace mojo { - -class CopyableType { - public: - CopyableType(); - CopyableType(const CopyableType& other); - CopyableType& operator=(const CopyableType& other); - ~CopyableType(); - - bool copied() const { return copied_; } - static size_t num_instances() { return num_instances_; } - CopyableType* ptr() const { return ptr_; } - void ResetCopied() { copied_ = false; } - - private: - bool copied_; - static size_t num_instances_; - CopyableType* ptr_; -}; - -class MoveOnlyType { - public: - typedef MoveOnlyType Data_; - MoveOnlyType(); - MoveOnlyType(MoveOnlyType&& other); - MoveOnlyType& operator=(MoveOnlyType&& other); - ~MoveOnlyType(); - - bool moved() const { return moved_; } - static size_t num_instances() { return num_instances_; } - MoveOnlyType* ptr() const { return ptr_; } - void ResetMoved() { moved_ = false; } - - private: - bool moved_; - static size_t num_instances_; - MoveOnlyType* ptr_; - - DISALLOW_COPY_AND_ASSIGN(MoveOnlyType); -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_CONTAINER_TEST_UTIL_H_ diff --git a/mojo/public/cpp/bindings/tests/data_view_unittest.cc b/mojo/public/cpp/bindings/tests/data_view_unittest.cc deleted file mode 100644 index 0ebfda5..0000000 --- a/mojo/public/cpp/bindings/tests/data_view_unittest.cc +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> -#include <string> -#include <unordered_map> -#include <vector> - -#include "base/message_loop/message_loop.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" -#include "mojo/public/cpp/bindings/lib/serialization.h" -#include "mojo/public/interfaces/bindings/tests/test_data_view.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace data_view { -namespace { - -class DataViewTest : public testing::Test { - private: - base::MessageLoop message_loop_; -}; - -struct DataViewHolder { - std::unique_ptr<TestStructDataView> data_view; - std::unique_ptr<mojo::internal::FixedBufferForTesting> buf; - mojo::internal::SerializationContext context; -}; - -std::unique_ptr<DataViewHolder> SerializeTestStruct(TestStructPtr input) { - std::unique_ptr<DataViewHolder> result(new DataViewHolder); - - size_t size = mojo::internal::PrepareToSerialize<TestStructDataView>( - input, &result->context); - - result->buf.reset(new mojo::internal::FixedBufferForTesting(size)); - internal::TestStruct_Data* data = nullptr; - mojo::internal::Serialize<TestStructDataView>(input, result->buf.get(), &data, - &result->context); - - result->data_view.reset(new TestStructDataView(data, &result->context)); - return result; -} - -class TestInterfaceImpl : public TestInterface { - public: - explicit TestInterfaceImpl(TestInterfaceRequest request) - : binding_(this, std::move(request)) {} - ~TestInterfaceImpl() override {} - - // TestInterface implementation: - void Echo(int32_t value, const EchoCallback& callback) override { - callback.Run(value); - } - - private: - Binding<TestInterface> binding_; -}; - -} // namespace - -TEST_F(DataViewTest, String) { - TestStructPtr obj(TestStruct::New()); - obj->f_string = "hello"; - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - StringDataView string_data_view; - data_view.GetFStringDataView(&string_data_view); - - ASSERT_FALSE(string_data_view.is_null()); - EXPECT_EQ(std::string("hello"), - std::string(string_data_view.storage(), string_data_view.size())); -} - -TEST_F(DataViewTest, NestedStruct) { - TestStructPtr obj(TestStruct::New()); - obj->f_struct = NestedStruct::New(); - obj->f_struct->f_int32 = 42; - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - NestedStructDataView struct_data_view; - data_view.GetFStructDataView(&struct_data_view); - - ASSERT_FALSE(struct_data_view.is_null()); - EXPECT_EQ(42, struct_data_view.f_int32()); -} - -TEST_F(DataViewTest, NativeStruct) { - TestStructPtr obj(TestStruct::New()); - obj->f_native_struct = NativeStruct::New(); - obj->f_native_struct->data = std::vector<uint8_t>({3, 2, 1}); - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - NativeStructDataView struct_data_view; - data_view.GetFNativeStructDataView(&struct_data_view); - - ASSERT_FALSE(struct_data_view.is_null()); - ASSERT_EQ(3u, struct_data_view.size()); - EXPECT_EQ(3, struct_data_view[0]); - EXPECT_EQ(2, struct_data_view[1]); - EXPECT_EQ(1, struct_data_view[2]); - EXPECT_EQ(3, *struct_data_view.data()); -} - -TEST_F(DataViewTest, BoolArray) { - TestStructPtr obj(TestStruct::New()); - obj->f_bool_array = {true, false}; - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - ArrayDataView<bool> array_data_view; - data_view.GetFBoolArrayDataView(&array_data_view); - - ASSERT_FALSE(array_data_view.is_null()); - ASSERT_EQ(2u, array_data_view.size()); - EXPECT_TRUE(array_data_view[0]); - EXPECT_FALSE(array_data_view[1]); -} - -TEST_F(DataViewTest, IntegerArray) { - TestStructPtr obj(TestStruct::New()); - obj->f_int32_array = {1024, 128}; - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - ArrayDataView<int32_t> array_data_view; - data_view.GetFInt32ArrayDataView(&array_data_view); - - ASSERT_FALSE(array_data_view.is_null()); - ASSERT_EQ(2u, array_data_view.size()); - EXPECT_EQ(1024, array_data_view[0]); - EXPECT_EQ(128, array_data_view[1]); - EXPECT_EQ(1024, *array_data_view.data()); -} - -TEST_F(DataViewTest, EnumArray) { - TestStructPtr obj(TestStruct::New()); - obj->f_enum_array = {TestEnum::VALUE_1, TestEnum::VALUE_0}; - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - ArrayDataView<TestEnum> array_data_view; - data_view.GetFEnumArrayDataView(&array_data_view); - - ASSERT_FALSE(array_data_view.is_null()); - ASSERT_EQ(2u, array_data_view.size()); - EXPECT_EQ(TestEnum::VALUE_1, array_data_view[0]); - EXPECT_EQ(TestEnum::VALUE_0, array_data_view[1]); - EXPECT_EQ(TestEnum::VALUE_0, *(array_data_view.data() + 1)); - - TestEnum output; - ASSERT_TRUE(array_data_view.Read(0, &output)); - EXPECT_EQ(TestEnum::VALUE_1, output); -} - -TEST_F(DataViewTest, InterfaceArray) { - TestInterfacePtr ptr; - TestInterfaceImpl impl(MakeRequest(&ptr)); - - TestStructPtr obj(TestStruct::New()); - obj->f_interface_array.push_back(std::move(ptr)); - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - ArrayDataView<TestInterfacePtrDataView> array_data_view; - data_view.GetFInterfaceArrayDataView(&array_data_view); - - ASSERT_FALSE(array_data_view.is_null()); - ASSERT_EQ(1u, array_data_view.size()); - - TestInterfacePtr ptr2 = array_data_view.Take<TestInterfacePtr>(0); - ASSERT_TRUE(ptr2); - int32_t result = 0; - ASSERT_TRUE(ptr2->Echo(42, &result)); - EXPECT_EQ(42, result); -} - -TEST_F(DataViewTest, NestedArray) { - TestStructPtr obj(TestStruct::New()); - obj->f_nested_array = {{3, 4}, {2}}; - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - ArrayDataView<ArrayDataView<int32_t>> array_data_view; - data_view.GetFNestedArrayDataView(&array_data_view); - - ASSERT_FALSE(array_data_view.is_null()); - ASSERT_EQ(2u, array_data_view.size()); - - ArrayDataView<int32_t> nested_array_data_view; - array_data_view.GetDataView(0, &nested_array_data_view); - ASSERT_FALSE(nested_array_data_view.is_null()); - ASSERT_EQ(2u, nested_array_data_view.size()); - EXPECT_EQ(4, nested_array_data_view[1]); - - std::vector<int32_t> vec; - ASSERT_TRUE(array_data_view.Read(1, &vec)); - ASSERT_EQ(1u, vec.size()); - EXPECT_EQ(2, vec[0]); -} - -TEST_F(DataViewTest, StructArray) { - NestedStructPtr nested_struct(NestedStruct::New()); - nested_struct->f_int32 = 42; - - TestStructPtr obj(TestStruct::New()); - obj->f_struct_array.push_back(std::move(nested_struct)); - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - ArrayDataView<NestedStructDataView> array_data_view; - data_view.GetFStructArrayDataView(&array_data_view); - - ASSERT_FALSE(array_data_view.is_null()); - ASSERT_EQ(1u, array_data_view.size()); - - NestedStructDataView struct_data_view; - array_data_view.GetDataView(0, &struct_data_view); - ASSERT_FALSE(struct_data_view.is_null()); - EXPECT_EQ(42, struct_data_view.f_int32()); - - NestedStructPtr nested_struct2; - ASSERT_TRUE(array_data_view.Read(0, &nested_struct2)); - ASSERT_TRUE(nested_struct2); - EXPECT_EQ(42, nested_struct2->f_int32); -} - -TEST_F(DataViewTest, Map) { - TestStructPtr obj(TestStruct::New()); - obj->f_map["1"] = 1; - obj->f_map["2"] = 2; - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - MapDataView<StringDataView, int32_t> map_data_view; - data_view.GetFMapDataView(&map_data_view); - - ASSERT_FALSE(map_data_view.is_null()); - ASSERT_EQ(2u, map_data_view.size()); - - ASSERT_FALSE(map_data_view.keys().is_null()); - ASSERT_EQ(2u, map_data_view.keys().size()); - - ASSERT_FALSE(map_data_view.values().is_null()); - ASSERT_EQ(2u, map_data_view.values().size()); - - std::vector<std::string> keys; - ASSERT_TRUE(map_data_view.ReadKeys(&keys)); - std::vector<int32_t> values; - ASSERT_TRUE(map_data_view.ReadValues(&values)); - - std::unordered_map<std::string, int32_t> map; - for (size_t i = 0; i < 2; ++i) - map[keys[i]] = values[i]; - - EXPECT_EQ(1, map["1"]); - EXPECT_EQ(2, map["2"]); -} - -TEST_F(DataViewTest, UnionArray) { - TestUnionPtr union_ptr(TestUnion::New()); - union_ptr->set_f_int32(1024); - - TestStructPtr obj(TestStruct::New()); - obj->f_union_array.push_back(std::move(union_ptr)); - - auto data_view_holder = SerializeTestStruct(std::move(obj)); - auto& data_view = *data_view_holder->data_view; - - ArrayDataView<TestUnionDataView> array_data_view; - data_view.GetFUnionArrayDataView(&array_data_view); - ASSERT_FALSE(array_data_view.is_null()); - ASSERT_EQ(1u, array_data_view.size()); - - TestUnionDataView union_data_view; - array_data_view.GetDataView(0, &union_data_view); - ASSERT_FALSE(union_data_view.is_null()); - - TestUnionPtr union_ptr2; - ASSERT_TRUE(array_data_view.Read(0, &union_ptr2)); - ASSERT_TRUE(union_ptr2->is_f_int32()); - EXPECT_EQ(1024, union_ptr2->get_f_int32()); -} - -} // namespace data_view -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/e2e_perftest.cc b/mojo/public/cpp/bindings/tests/e2e_perftest.cc deleted file mode 100644 index bc69e0f..0000000 --- a/mojo/public/cpp/bindings/tests/e2e_perftest.cc +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/strings/stringprintf.h" -#include "base/test/perf_time_logger.h" -#include "base/threading/thread_task_runner_handle.h" -#include "mojo/edk/embedder/embedder.h" -#include "mojo/edk/test/mojo_test_base.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -class EchoServiceImpl : public test::EchoService { - public: - explicit EchoServiceImpl(const base::Closure& quit_closure); - ~EchoServiceImpl() override; - - // |EchoService| methods: - void Echo(const std::string& test_data, - const EchoCallback& callback) override; - - private: - const base::Closure quit_closure_; -}; - -EchoServiceImpl::EchoServiceImpl(const base::Closure& quit_closure) - : quit_closure_(quit_closure) {} - -EchoServiceImpl::~EchoServiceImpl() { - quit_closure_.Run(); -} - -void EchoServiceImpl::Echo(const std::string& test_data, - const EchoCallback& callback) { - callback.Run(test_data); -} - -class PingPongTest { - public: - explicit PingPongTest(test::EchoServicePtr service); - - void RunTest(int iterations, int batch_size, int message_size); - - private: - void DoPing(); - void OnPingDone(const std::string& reply); - - test::EchoServicePtr service_; - const base::Callback<void(const std::string&)> ping_done_callback_; - - int iterations_; - int batch_size_; - std::string message_; - - int current_iterations_; - int calls_outstanding_; - - base::Closure quit_closure_; -}; - -PingPongTest::PingPongTest(test::EchoServicePtr service) - : service_(std::move(service)), - ping_done_callback_( - base::Bind(&PingPongTest::OnPingDone, base::Unretained(this))) {} - -void PingPongTest::RunTest(int iterations, int batch_size, int message_size) { - iterations_ = iterations; - batch_size_ = batch_size; - message_ = std::string(message_size, 'a'); - current_iterations_ = 0; - calls_outstanding_ = 0; - - base::MessageLoop::current()->SetNestableTasksAllowed(true); - base::RunLoop run_loop; - quit_closure_ = run_loop.QuitClosure(); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&PingPongTest::DoPing, base::Unretained(this))); - run_loop.Run(); -} - -void PingPongTest::DoPing() { - DCHECK_EQ(0, calls_outstanding_); - current_iterations_++; - if (current_iterations_ > iterations_) { - quit_closure_.Run(); - return; - } - - calls_outstanding_ = batch_size_; - for (int i = 0; i < batch_size_; i++) { - service_->Echo(message_, ping_done_callback_); - } -} - -void PingPongTest::OnPingDone(const std::string& reply) { - DCHECK_GT(calls_outstanding_, 0); - calls_outstanding_--; - - if (!calls_outstanding_) - DoPing(); -} - -class MojoE2EPerftest : public edk::test::MojoTestBase { - public: - void RunTestOnTaskRunner(base::TaskRunner* runner, - MojoHandle client_mp, - const std::string& test_name) { - if (runner == base::ThreadTaskRunnerHandle::Get().get()) { - RunTests(client_mp, test_name); - } else { - base::RunLoop run_loop; - runner->PostTaskAndReply( - FROM_HERE, base::Bind(&MojoE2EPerftest::RunTests, - base::Unretained(this), client_mp, test_name), - run_loop.QuitClosure()); - run_loop.Run(); - } - } - - protected: - base::MessageLoop message_loop_; - - private: - void RunTests(MojoHandle client_mp, const std::string& test_name) { - const int kMessages = 10000; - const int kBatchSizes[] = {1, 10, 100}; - const int kMessageSizes[] = {8, 64, 512, 4096, 65536}; - - test::EchoServicePtr service; - service.Bind(InterfacePtrInfo<test::EchoService>( - ScopedMessagePipeHandle(MessagePipeHandle(client_mp)), - service.version())); - PingPongTest test(std::move(service)); - - for (int batch_size : kBatchSizes) { - for (int message_size : kMessageSizes) { - int num_messages = kMessages; - if (message_size == 65536) - num_messages /= 10; - std::string sub_test_name = base::StringPrintf( - "%s/%dx%d/%dbytes", test_name.c_str(), num_messages / batch_size, - batch_size, message_size); - base::PerfTimeLogger timer(sub_test_name.c_str()); - test.RunTest(num_messages / batch_size, batch_size, message_size); - } - } - } -}; - -void CreateAndRunService(InterfaceRequest<test::EchoService> request, - const base::Closure& cb) { - MakeStrongBinding(base::MakeUnique<EchoServiceImpl>(cb), std::move(request)); -} - -DEFINE_TEST_CLIENT_TEST_WITH_PIPE(PingService, MojoE2EPerftest, mp) { - MojoHandle service_mp; - EXPECT_EQ("hello", ReadMessageWithHandles(mp, &service_mp, 1)); - - InterfaceRequest<test::EchoService> request; - request.Bind(ScopedMessagePipeHandle(MessagePipeHandle(service_mp))); - base::RunLoop run_loop; - edk::GetIOTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&CreateAndRunService, base::Passed(&request), - base::Bind(base::IgnoreResult(&base::TaskRunner::PostTask), - message_loop_.task_runner(), FROM_HERE, - run_loop.QuitClosure()))); - run_loop.Run(); -} - -TEST_F(MojoE2EPerftest, MultiProcessEchoMainThread) { - RUN_CHILD_ON_PIPE(PingService, mp) - MojoHandle client_mp, service_mp; - CreateMessagePipe(&client_mp, &service_mp); - WriteMessageWithHandles(mp, "hello", &service_mp, 1); - RunTestOnTaskRunner(message_loop_.task_runner().get(), client_mp, - "MultiProcessEchoMainThread"); - END_CHILD() -} - -TEST_F(MojoE2EPerftest, MultiProcessEchoIoThread) { - RUN_CHILD_ON_PIPE(PingService, mp) - MojoHandle client_mp, service_mp; - CreateMessagePipe(&client_mp, &service_mp); - WriteMessageWithHandles(mp, "hello", &service_mp, 1); - RunTestOnTaskRunner(edk::GetIOTaskRunner().get(), client_mp, - "MultiProcessEchoIoThread"); - END_CHILD() -} - -} // namespace -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/equals_unittest.cc b/mojo/public/cpp/bindings/tests/equals_unittest.cc deleted file mode 100644 index 6483baf..0000000 --- a/mojo/public/cpp/bindings/tests/equals_unittest.cc +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <utility> - -#include "base/message_loop/message_loop.h" -#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { - -namespace { - -RectPtr CreateRect() { - return Rect::New(1, 2, 3, 4); -} - -using EqualsTest = testing::Test; - -} // namespace - -TEST_F(EqualsTest, NullStruct) { - RectPtr r1; - RectPtr r2; - EXPECT_TRUE(r1.Equals(r2)); - EXPECT_TRUE(r2.Equals(r1)); - - r1 = CreateRect(); - EXPECT_FALSE(r1.Equals(r2)); - EXPECT_FALSE(r2.Equals(r1)); -} - -TEST_F(EqualsTest, Struct) { - RectPtr r1(CreateRect()); - RectPtr r2(r1.Clone()); - EXPECT_TRUE(r1.Equals(r2)); - r2->y = 1; - EXPECT_FALSE(r1.Equals(r2)); - r2.reset(); - EXPECT_FALSE(r1.Equals(r2)); -} - -TEST_F(EqualsTest, StructNested) { - RectPairPtr p1(RectPair::New(CreateRect(), CreateRect())); - RectPairPtr p2(p1.Clone()); - EXPECT_TRUE(p1.Equals(p2)); - p2->second->width = 0; - EXPECT_FALSE(p1.Equals(p2)); - p2->second.reset(); - EXPECT_FALSE(p1.Equals(p2)); -} - -TEST_F(EqualsTest, Array) { - std::vector<RectPtr> rects; - rects.push_back(CreateRect()); - NamedRegionPtr n1(NamedRegion::New(std::string("n1"), std::move(rects))); - NamedRegionPtr n2(n1.Clone()); - EXPECT_TRUE(n1.Equals(n2)); - - n2->rects = base::nullopt; - EXPECT_FALSE(n1.Equals(n2)); - n2->rects.emplace(); - EXPECT_FALSE(n1.Equals(n2)); - - n2->rects->push_back(CreateRect()); - n2->rects->push_back(CreateRect()); - EXPECT_FALSE(n1.Equals(n2)); - - n2->rects->resize(1); - (*n2->rects)[0]->width = 0; - EXPECT_FALSE(n1.Equals(n2)); - - (*n2->rects)[0] = CreateRect(); - EXPECT_TRUE(n1.Equals(n2)); -} - -TEST_F(EqualsTest, InterfacePtr) { - base::MessageLoop message_loop; - - SomeInterfacePtr inf1; - SomeInterfacePtr inf2; - - EXPECT_TRUE(inf1.Equals(inf1)); - EXPECT_TRUE(inf1.Equals(inf2)); - - auto inf1_request = MakeRequest(&inf1); - ALLOW_UNUSED_LOCAL(inf1_request); - - EXPECT_TRUE(inf1.Equals(inf1)); - EXPECT_FALSE(inf1.Equals(inf2)); - - auto inf2_request = MakeRequest(&inf2); - ALLOW_UNUSED_LOCAL(inf2_request); - - EXPECT_FALSE(inf1.Equals(inf2)); -} - -TEST_F(EqualsTest, InterfaceRequest) { - base::MessageLoop message_loop; - - InterfaceRequest<SomeInterface> req1; - InterfaceRequest<SomeInterface> req2; - - EXPECT_TRUE(req1.Equals(req1)); - EXPECT_TRUE(req1.Equals(req2)); - - SomeInterfacePtr inf1; - req1 = MakeRequest(&inf1); - - EXPECT_TRUE(req1.Equals(req1)); - EXPECT_FALSE(req1.Equals(req2)); - - SomeInterfacePtr inf2; - req2 = MakeRequest(&inf2); - - EXPECT_FALSE(req1.Equals(req2)); -} - -} // test -} // mojo diff --git a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc deleted file mode 100644 index ef977af..0000000 --- a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stdint.h> -#include <utility> - -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/public/cpp/system/wait.h" -#include "mojo/public/cpp/test_support/test_utils.h" -#include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -const char kText1[] = "hello"; -const char kText2[] = "world"; - -void RecordString(std::string* storage, - const base::Closure& closure, - const std::string& str) { - *storage = str; - closure.Run(); -} - -base::Callback<void(const std::string&)> MakeStringRecorder( - std::string* storage, - const base::Closure& closure) { - return base::Bind(&RecordString, storage, closure); -} - -class ImportedInterfaceImpl : public imported::ImportedInterface { - public: - ImportedInterfaceImpl( - InterfaceRequest<imported::ImportedInterface> request, - const base::Closure& closure) - : binding_(this, std::move(request)), closure_(closure) {} - - void DoSomething() override { - do_something_count_++; - closure_.Run(); - } - - static int do_something_count() { return do_something_count_; } - - private: - static int do_something_count_; - Binding<ImportedInterface> binding_; - base::Closure closure_; -}; -int ImportedInterfaceImpl::do_something_count_ = 0; - -class SampleNamedObjectImpl : public sample::NamedObject { - public: - SampleNamedObjectImpl() {} - - void SetName(const std::string& name) override { name_ = name; } - - void GetName(const GetNameCallback& callback) override { - callback.Run(name_); - } - - private: - std::string name_; -}; - -class SampleFactoryImpl : public sample::Factory { - public: - explicit SampleFactoryImpl(InterfaceRequest<sample::Factory> request) - : binding_(this, std::move(request)) {} - - void DoStuff(sample::RequestPtr request, - ScopedMessagePipeHandle pipe, - const DoStuffCallback& callback) override { - std::string text1; - if (pipe.is_valid()) - EXPECT_TRUE(ReadTextMessage(pipe.get(), &text1)); - - std::string text2; - if (request->pipe.is_valid()) { - EXPECT_TRUE(ReadTextMessage(request->pipe.get(), &text2)); - - // Ensure that simply accessing request->pipe does not close it. - EXPECT_TRUE(request->pipe.is_valid()); - } - - ScopedMessagePipeHandle pipe0; - if (!text2.empty()) { - CreateMessagePipe(nullptr, &pipe0, &pipe1_); - EXPECT_TRUE(WriteTextMessage(pipe1_.get(), text2)); - } - - sample::ResponsePtr response(sample::Response::New(2, std::move(pipe0))); - callback.Run(std::move(response), text1); - - if (request->obj) - request->obj->DoSomething(); - } - - void DoStuff2(ScopedDataPipeConsumerHandle pipe, - const DoStuff2Callback& callback) override { - // Read the data from the pipe, writing the response (as a string) to - // DidStuff2(). - ASSERT_TRUE(pipe.is_valid()); - uint32_t data_size = 0; - - MojoHandleSignalsState state; - ASSERT_EQ(MOJO_RESULT_OK, - mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE, &state)); - ASSERT_TRUE(state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); - ASSERT_EQ(MOJO_RESULT_OK, - ReadDataRaw( - pipe.get(), nullptr, &data_size, MOJO_READ_DATA_FLAG_QUERY)); - ASSERT_NE(0, static_cast<int>(data_size)); - char data[64]; - ASSERT_LT(static_cast<int>(data_size), 64); - ASSERT_EQ( - MOJO_RESULT_OK, - ReadDataRaw( - pipe.get(), data, &data_size, MOJO_READ_DATA_FLAG_ALL_OR_NONE)); - - callback.Run(data); - } - - void CreateNamedObject( - InterfaceRequest<sample::NamedObject> object_request) override { - EXPECT_TRUE(object_request.is_pending()); - MakeStrongBinding(base::MakeUnique<SampleNamedObjectImpl>(), - std::move(object_request)); - } - - // These aren't called or implemented, but exist here to test that the - // methods are generated with the correct argument types for imported - // interfaces. - void RequestImportedInterface( - InterfaceRequest<imported::ImportedInterface> imported, - const RequestImportedInterfaceCallback& callback) override {} - void TakeImportedInterface( - imported::ImportedInterfacePtr imported, - const TakeImportedInterfaceCallback& callback) override {} - - private: - ScopedMessagePipeHandle pipe1_; - Binding<sample::Factory> binding_; -}; - -class HandlePassingTest : public testing::Test { - public: - HandlePassingTest() {} - - void TearDown() override { PumpMessages(); } - - void PumpMessages() { base::RunLoop().RunUntilIdle(); } - - private: - base::MessageLoop loop_; -}; - -void DoStuff(bool* got_response, - std::string* got_text_reply, - const base::Closure& closure, - sample::ResponsePtr response, - const std::string& text_reply) { - *got_text_reply = text_reply; - - if (response->pipe.is_valid()) { - std::string text2; - EXPECT_TRUE(ReadTextMessage(response->pipe.get(), &text2)); - - // Ensure that simply accessing response.pipe does not close it. - EXPECT_TRUE(response->pipe.is_valid()); - - EXPECT_EQ(std::string(kText2), text2); - - // Do some more tests of handle passing: - ScopedMessagePipeHandle p = std::move(response->pipe); - EXPECT_TRUE(p.is_valid()); - EXPECT_FALSE(response->pipe.is_valid()); - } - - *got_response = true; - closure.Run(); -} - -void DoStuff2(bool* got_response, - std::string* got_text_reply, - const base::Closure& closure, - const std::string& text_reply) { - *got_response = true; - *got_text_reply = text_reply; - closure.Run(); -} - -TEST_F(HandlePassingTest, Basic) { - sample::FactoryPtr factory; - SampleFactoryImpl factory_impl(MakeRequest(&factory)); - - MessagePipe pipe0; - EXPECT_TRUE(WriteTextMessage(pipe0.handle1.get(), kText1)); - - MessagePipe pipe1; - EXPECT_TRUE(WriteTextMessage(pipe1.handle1.get(), kText2)); - - imported::ImportedInterfacePtr imported; - base::RunLoop run_loop; - ImportedInterfaceImpl imported_impl(MakeRequest(&imported), - run_loop.QuitClosure()); - - sample::RequestPtr request(sample::Request::New( - 1, std::move(pipe1.handle0), base::nullopt, std::move(imported))); - bool got_response = false; - std::string got_text_reply; - base::RunLoop run_loop2; - factory->DoStuff(std::move(request), std::move(pipe0.handle0), - base::Bind(&DoStuff, &got_response, &got_text_reply, - run_loop2.QuitClosure())); - - EXPECT_FALSE(got_response); - int count_before = ImportedInterfaceImpl::do_something_count(); - - run_loop.Run(); - run_loop2.Run(); - - EXPECT_TRUE(got_response); - EXPECT_EQ(kText1, got_text_reply); - EXPECT_EQ(1, ImportedInterfaceImpl::do_something_count() - count_before); -} - -TEST_F(HandlePassingTest, PassInvalid) { - sample::FactoryPtr factory; - SampleFactoryImpl factory_impl(MakeRequest(&factory)); - - sample::RequestPtr request( - sample::Request::New(1, ScopedMessagePipeHandle(), base::nullopt, - imported::ImportedInterfacePtr())); - bool got_response = false; - std::string got_text_reply; - base::RunLoop run_loop; - factory->DoStuff(std::move(request), ScopedMessagePipeHandle(), - base::Bind(&DoStuff, &got_response, &got_text_reply, - run_loop.QuitClosure())); - - EXPECT_FALSE(got_response); - - run_loop.Run(); - - EXPECT_TRUE(got_response); -} - -// Verifies DataPipeConsumer can be passed and read from. -TEST_F(HandlePassingTest, DataPipe) { - sample::FactoryPtr factory; - SampleFactoryImpl factory_impl(MakeRequest(&factory)); - - // Writes a string to a data pipe and passes the data pipe (consumer) to the - // factory. - ScopedDataPipeProducerHandle producer_handle; - ScopedDataPipeConsumerHandle consumer_handle; - MojoCreateDataPipeOptions options = {sizeof(MojoCreateDataPipeOptions), - MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, - 1, - 1024}; - ASSERT_EQ(MOJO_RESULT_OK, - CreateDataPipe(&options, &producer_handle, &consumer_handle)); - std::string expected_text_reply = "got it"; - // +1 for \0. - uint32_t data_size = static_cast<uint32_t>(expected_text_reply.size() + 1); - ASSERT_EQ(MOJO_RESULT_OK, - WriteDataRaw(producer_handle.get(), - expected_text_reply.c_str(), - &data_size, - MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); - - bool got_response = false; - std::string got_text_reply; - base::RunLoop run_loop; - factory->DoStuff2(std::move(consumer_handle), - base::Bind(&DoStuff2, &got_response, &got_text_reply, - run_loop.QuitClosure())); - - EXPECT_FALSE(got_response); - - run_loop.Run(); - - EXPECT_TRUE(got_response); - EXPECT_EQ(expected_text_reply, got_text_reply); -} - -TEST_F(HandlePassingTest, PipesAreClosed) { - sample::FactoryPtr factory; - SampleFactoryImpl factory_impl(MakeRequest(&factory)); - - MessagePipe extra_pipe; - - MojoHandle handle0_value = extra_pipe.handle0.get().value(); - MojoHandle handle1_value = extra_pipe.handle1.get().value(); - - { - std::vector<ScopedMessagePipeHandle> pipes(2); - pipes[0] = std::move(extra_pipe.handle0); - pipes[1] = std::move(extra_pipe.handle1); - - sample::RequestPtr request(sample::Request::New()); - request->more_pipes = std::move(pipes); - - factory->DoStuff(std::move(request), ScopedMessagePipeHandle(), - sample::Factory::DoStuffCallback()); - } - - // We expect the pipes to have been closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle0_value)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle1_value)); -} - -TEST_F(HandlePassingTest, CreateNamedObject) { - sample::FactoryPtr factory; - SampleFactoryImpl factory_impl(MakeRequest(&factory)); - - sample::NamedObjectPtr object1; - EXPECT_FALSE(object1); - - InterfaceRequest<sample::NamedObject> object1_request(&object1); - EXPECT_TRUE(object1_request.is_pending()); - factory->CreateNamedObject(std::move(object1_request)); - EXPECT_FALSE(object1_request.is_pending()); // We've passed the request. - - ASSERT_TRUE(object1); - object1->SetName("object1"); - - sample::NamedObjectPtr object2; - factory->CreateNamedObject(MakeRequest(&object2)); - object2->SetName("object2"); - - base::RunLoop run_loop, run_loop2; - std::string name1; - object1->GetName(MakeStringRecorder(&name1, run_loop.QuitClosure())); - - std::string name2; - object2->GetName(MakeStringRecorder(&name2, run_loop2.QuitClosure())); - - run_loop.Run(); - run_loop2.Run(); - - EXPECT_EQ(std::string("object1"), name1); - EXPECT_EQ(std::string("object2"), name2); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/hash_unittest.cc b/mojo/public/cpp/bindings/tests/hash_unittest.cc deleted file mode 100644 index 9ce1f5b..0000000 --- a/mojo/public/cpp/bindings/tests/hash_unittest.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/lib/hash_util.h" - -#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -using HashTest = testing::Test; - -TEST_F(HashTest, NestedStruct) { - // Just check that this template instantiation compiles. - ASSERT_EQ( - ::mojo::internal::Hash(::mojo::internal::kHashSeed, - SimpleNestedStruct::New(ContainsOther::New(1))), - ::mojo::internal::Hash(::mojo::internal::kHashSeed, - SimpleNestedStruct::New(ContainsOther::New(1)))); -} - -TEST_F(HashTest, UnmappedNativeStruct) { - // Just check that this template instantiation compiles. - ASSERT_EQ(::mojo::internal::Hash(::mojo::internal::kHashSeed, - UnmappedNativeStruct::New()), - ::mojo::internal::Hash(::mojo::internal::kHashSeed, - UnmappedNativeStruct::New())); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc deleted file mode 100644 index 431a844..0000000 --- a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc +++ /dev/null @@ -1,937 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stdint.h> -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/threading/thread.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h" -#include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h" -#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" -#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" -#include "mojo/public/interfaces/bindings/tests/scoping.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -typedef base::Callback<void(double)> CalcCallback; - -class MathCalculatorImpl : public math::Calculator { - public: - explicit MathCalculatorImpl(InterfaceRequest<math::Calculator> request) - : total_(0.0), binding_(this, std::move(request)) {} - ~MathCalculatorImpl() override {} - - void Clear(const CalcCallback& callback) override { - total_ = 0.0; - callback.Run(total_); - } - - void Add(double value, const CalcCallback& callback) override { - total_ += value; - callback.Run(total_); - } - - void Multiply(double value, const CalcCallback& callback) override { - total_ *= value; - callback.Run(total_); - } - - Binding<math::Calculator>* binding() { return &binding_; } - - private: - double total_; - Binding<math::Calculator> binding_; -}; - -class MathCalculatorUI { - public: - explicit MathCalculatorUI(math::CalculatorPtr calculator) - : calculator_(std::move(calculator)), - output_(0.0) {} - - bool encountered_error() const { return calculator_.encountered_error(); } - void set_connection_error_handler(const base::Closure& closure) { - calculator_.set_connection_error_handler(closure); - } - - void Add(double value, const base::Closure& closure) { - calculator_->Add( - value, - base::Bind(&MathCalculatorUI::Output, base::Unretained(this), closure)); - } - - void Multiply(double value, const base::Closure& closure) { - calculator_->Multiply( - value, - base::Bind(&MathCalculatorUI::Output, base::Unretained(this), closure)); - } - - double GetOutput() const { return output_; } - - math::CalculatorPtr& GetInterfacePtr() { return calculator_; } - - private: - void Output(const base::Closure& closure, double output) { - output_ = output; - if (!closure.is_null()) - closure.Run(); - } - - math::CalculatorPtr calculator_; - double output_; - base::Closure closure_; -}; - -class SelfDestructingMathCalculatorUI { - public: - explicit SelfDestructingMathCalculatorUI(math::CalculatorPtr calculator) - : calculator_(std::move(calculator)), nesting_level_(0) { - ++num_instances_; - } - - void BeginTest(bool nested, const base::Closure& closure) { - nesting_level_ = nested ? 2 : 1; - calculator_->Add( - 1.0, - base::Bind(&SelfDestructingMathCalculatorUI::Output, - base::Unretained(this), closure)); - } - - static int num_instances() { return num_instances_; } - - void Output(const base::Closure& closure, double value) { - if (--nesting_level_ > 0) { - // Add some more and wait for re-entrant call to Output! - calculator_->Add( - 1.0, - base::Bind(&SelfDestructingMathCalculatorUI::Output, - base::Unretained(this), closure)); - } else { - closure.Run(); - delete this; - } - } - - private: - ~SelfDestructingMathCalculatorUI() { --num_instances_; } - - math::CalculatorPtr calculator_; - int nesting_level_; - static int num_instances_; -}; - -// static -int SelfDestructingMathCalculatorUI::num_instances_ = 0; - -class ReentrantServiceImpl : public sample::Service { - public: - ~ReentrantServiceImpl() override {} - - explicit ReentrantServiceImpl(InterfaceRequest<sample::Service> request) - : call_depth_(0), - max_call_depth_(0), - binding_(this, std::move(request)) {} - - int max_call_depth() { return max_call_depth_; } - - void Frobinate(sample::FooPtr foo, - sample::Service::BazOptions baz, - sample::PortPtr port, - const sample::Service::FrobinateCallback& callback) override { - max_call_depth_ = std::max(++call_depth_, max_call_depth_); - if (call_depth_ == 1) { - EXPECT_TRUE(binding_.WaitForIncomingMethodCall()); - } - call_depth_--; - callback.Run(5); - } - - void GetPort(mojo::InterfaceRequest<sample::Port> port) override {} - - private: - int call_depth_; - int max_call_depth_; - Binding<sample::Service> binding_; -}; - -class IntegerAccessorImpl : public sample::IntegerAccessor { - public: - IntegerAccessorImpl() : integer_(0) {} - ~IntegerAccessorImpl() override {} - - int64_t integer() const { return integer_; } - - void set_closure(const base::Closure& closure) { closure_ = closure; } - - private: - // sample::IntegerAccessor implementation. - void GetInteger(const GetIntegerCallback& callback) override { - callback.Run(integer_, sample::Enum::VALUE); - } - void SetInteger(int64_t data, sample::Enum type) override { - integer_ = data; - if (!closure_.is_null()) { - closure_.Run(); - closure_.Reset(); - } - } - - int64_t integer_; - base::Closure closure_; -}; - -class InterfacePtrTest : public testing::Test { - public: - InterfacePtrTest() {} - ~InterfacePtrTest() override { base::RunLoop().RunUntilIdle(); } - - void PumpMessages() { base::RunLoop().RunUntilIdle(); } - - private: - base::MessageLoop loop_; -}; - -void SetFlagAndRunClosure(bool* flag, const base::Closure& closure) { - *flag = true; - closure.Run(); -} - -void IgnoreValueAndRunClosure(const base::Closure& closure, int32_t value) { - closure.Run(); -} - -void ExpectValueAndRunClosure(uint32_t expected_value, - const base::Closure& closure, - uint32_t value) { - EXPECT_EQ(expected_value, value); - closure.Run(); -} - -TEST_F(InterfacePtrTest, IsBound) { - math::CalculatorPtr calc; - EXPECT_FALSE(calc.is_bound()); - MathCalculatorImpl calc_impl(MakeRequest(&calc)); - EXPECT_TRUE(calc.is_bound()); -} - -TEST_F(InterfacePtrTest, EndToEnd) { - math::CalculatorPtr calc; - MathCalculatorImpl calc_impl(MakeRequest(&calc)); - - // Suppose this is instantiated in a process that has pipe1_. - MathCalculatorUI calculator_ui(std::move(calc)); - - base::RunLoop run_loop, run_loop2; - calculator_ui.Add(2.0, run_loop.QuitClosure()); - calculator_ui.Multiply(5.0, run_loop2.QuitClosure()); - run_loop.Run(); - run_loop2.Run(); - - EXPECT_EQ(10.0, calculator_ui.GetOutput()); -} - -TEST_F(InterfacePtrTest, EndToEnd_Synchronous) { - math::CalculatorPtr calc; - MathCalculatorImpl calc_impl(MakeRequest(&calc)); - - // Suppose this is instantiated in a process that has pipe1_. - MathCalculatorUI calculator_ui(std::move(calc)); - - EXPECT_EQ(0.0, calculator_ui.GetOutput()); - - base::RunLoop run_loop; - calculator_ui.Add(2.0, run_loop.QuitClosure()); - EXPECT_EQ(0.0, calculator_ui.GetOutput()); - calc_impl.binding()->WaitForIncomingMethodCall(); - run_loop.Run(); - EXPECT_EQ(2.0, calculator_ui.GetOutput()); - - base::RunLoop run_loop2; - calculator_ui.Multiply(5.0, run_loop2.QuitClosure()); - EXPECT_EQ(2.0, calculator_ui.GetOutput()); - calc_impl.binding()->WaitForIncomingMethodCall(); - run_loop2.Run(); - EXPECT_EQ(10.0, calculator_ui.GetOutput()); -} - -TEST_F(InterfacePtrTest, Movable) { - math::CalculatorPtr a; - math::CalculatorPtr b; - MathCalculatorImpl calc_impl(MakeRequest(&b)); - - EXPECT_TRUE(!a); - EXPECT_FALSE(!b); - - a = std::move(b); - - EXPECT_FALSE(!a); - EXPECT_TRUE(!b); -} - -TEST_F(InterfacePtrTest, Resettable) { - math::CalculatorPtr a; - - EXPECT_TRUE(!a); - - MessagePipe pipe; - - // Save this so we can test it later. - Handle handle = pipe.handle0.get(); - - a = MakeProxy( - InterfacePtrInfo<math::Calculator>(std::move(pipe.handle0), 0u)); - - EXPECT_FALSE(!a); - - a.reset(); - - EXPECT_TRUE(!a); - EXPECT_FALSE(a.internal_state()->is_bound()); - - // Test that handle was closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle)); -} - -TEST_F(InterfacePtrTest, BindInvalidHandle) { - math::CalculatorPtr ptr; - EXPECT_FALSE(ptr.get()); - EXPECT_FALSE(ptr); - - ptr.Bind(InterfacePtrInfo<math::Calculator>()); - EXPECT_FALSE(ptr.get()); - EXPECT_FALSE(ptr); -} - -TEST_F(InterfacePtrTest, EncounteredError) { - math::CalculatorPtr proxy; - MathCalculatorImpl calc_impl(MakeRequest(&proxy)); - - MathCalculatorUI calculator_ui(std::move(proxy)); - - base::RunLoop run_loop; - calculator_ui.Add(2.0, run_loop.QuitClosure()); - run_loop.Run(); - EXPECT_EQ(2.0, calculator_ui.GetOutput()); - EXPECT_FALSE(calculator_ui.encountered_error()); - - calculator_ui.Multiply(5.0, base::Closure()); - EXPECT_FALSE(calculator_ui.encountered_error()); - - // Close the server. - calc_impl.binding()->Close(); - - // The state change isn't picked up locally yet. - base::RunLoop run_loop2; - calculator_ui.set_connection_error_handler(run_loop2.QuitClosure()); - EXPECT_FALSE(calculator_ui.encountered_error()); - - run_loop2.Run(); - - // OK, now we see the error. - EXPECT_TRUE(calculator_ui.encountered_error()); -} - -TEST_F(InterfacePtrTest, EncounteredErrorCallback) { - math::CalculatorPtr proxy; - MathCalculatorImpl calc_impl(MakeRequest(&proxy)); - - bool encountered_error = false; - base::RunLoop run_loop; - proxy.set_connection_error_handler( - base::Bind(&SetFlagAndRunClosure, &encountered_error, - run_loop.QuitClosure())); - - MathCalculatorUI calculator_ui(std::move(proxy)); - - base::RunLoop run_loop2; - calculator_ui.Add(2.0, run_loop2.QuitClosure()); - run_loop2.Run(); - EXPECT_EQ(2.0, calculator_ui.GetOutput()); - EXPECT_FALSE(calculator_ui.encountered_error()); - - calculator_ui.Multiply(5.0, base::Closure()); - EXPECT_FALSE(calculator_ui.encountered_error()); - - // Close the server. - calc_impl.binding()->Close(); - - // The state change isn't picked up locally yet. - EXPECT_FALSE(calculator_ui.encountered_error()); - - run_loop.Run(); - - // OK, now we see the error. - EXPECT_TRUE(calculator_ui.encountered_error()); - - // We should have also been able to observe the error through the error - // handler. - EXPECT_TRUE(encountered_error); -} - -TEST_F(InterfacePtrTest, DestroyInterfacePtrOnMethodResponse) { - math::CalculatorPtr proxy; - MathCalculatorImpl calc_impl(MakeRequest(&proxy)); - - EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); - - SelfDestructingMathCalculatorUI* impl = - new SelfDestructingMathCalculatorUI(std::move(proxy)); - base::RunLoop run_loop; - impl->BeginTest(false, run_loop.QuitClosure()); - run_loop.Run(); - - EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); -} - -TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnMethodResponse) { - math::CalculatorPtr proxy; - MathCalculatorImpl calc_impl(MakeRequest(&proxy)); - - EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); - - SelfDestructingMathCalculatorUI* impl = - new SelfDestructingMathCalculatorUI(std::move(proxy)); - base::RunLoop run_loop; - impl->BeginTest(true, run_loop.QuitClosure()); - run_loop.Run(); - - EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); -} - -TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) { - sample::ServicePtr proxy; - ReentrantServiceImpl impl(MakeRequest(&proxy)); - - base::RunLoop run_loop, run_loop2; - proxy->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, - base::Bind(&IgnoreValueAndRunClosure, - run_loop.QuitClosure())); - proxy->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, - base::Bind(&IgnoreValueAndRunClosure, - run_loop2.QuitClosure())); - - run_loop.Run(); - run_loop2.Run(); - - EXPECT_EQ(2, impl.max_call_depth()); -} - -TEST_F(InterfacePtrTest, QueryVersion) { - IntegerAccessorImpl impl; - sample::IntegerAccessorPtr ptr; - Binding<sample::IntegerAccessor> binding(&impl, MakeRequest(&ptr)); - - EXPECT_EQ(0u, ptr.version()); - - base::RunLoop run_loop; - ptr.QueryVersion(base::Bind(&ExpectValueAndRunClosure, 3u, - run_loop.QuitClosure())); - run_loop.Run(); - - EXPECT_EQ(3u, ptr.version()); -} - -TEST_F(InterfacePtrTest, RequireVersion) { - IntegerAccessorImpl impl; - sample::IntegerAccessorPtr ptr; - Binding<sample::IntegerAccessor> binding(&impl, MakeRequest(&ptr)); - - EXPECT_EQ(0u, ptr.version()); - - ptr.RequireVersion(1u); - EXPECT_EQ(1u, ptr.version()); - base::RunLoop run_loop; - impl.set_closure(run_loop.QuitClosure()); - ptr->SetInteger(123, sample::Enum::VALUE); - run_loop.Run(); - EXPECT_FALSE(ptr.encountered_error()); - EXPECT_EQ(123, impl.integer()); - - ptr.RequireVersion(3u); - EXPECT_EQ(3u, ptr.version()); - base::RunLoop run_loop2; - impl.set_closure(run_loop2.QuitClosure()); - ptr->SetInteger(456, sample::Enum::VALUE); - run_loop2.Run(); - EXPECT_FALSE(ptr.encountered_error()); - EXPECT_EQ(456, impl.integer()); - - // Require a version that is not supported by the impl side. - ptr.RequireVersion(4u); - // This value is set to the input of RequireVersion() synchronously. - EXPECT_EQ(4u, ptr.version()); - base::RunLoop run_loop3; - ptr.set_connection_error_handler(run_loop3.QuitClosure()); - ptr->SetInteger(789, sample::Enum::VALUE); - run_loop3.Run(); - EXPECT_TRUE(ptr.encountered_error()); - // The call to SetInteger() after RequireVersion(4u) is ignored. - EXPECT_EQ(456, impl.integer()); -} - -class StrongMathCalculatorImpl : public math::Calculator { - public: - StrongMathCalculatorImpl(bool* destroyed) : destroyed_(destroyed) {} - ~StrongMathCalculatorImpl() override { *destroyed_ = true; } - - // math::Calculator implementation. - void Clear(const CalcCallback& callback) override { callback.Run(total_); } - - void Add(double value, const CalcCallback& callback) override { - total_ += value; - callback.Run(total_); - } - - void Multiply(double value, const CalcCallback& callback) override { - total_ *= value; - callback.Run(total_); - } - - private: - double total_ = 0.0; - bool* destroyed_; -}; - -TEST(StrongConnectorTest, Math) { - base::MessageLoop loop; - - bool error_received = false; - bool destroyed = false; - math::CalculatorPtr calc; - base::RunLoop run_loop; - - auto binding = - MakeStrongBinding(base::MakeUnique<StrongMathCalculatorImpl>(&destroyed), - MakeRequest(&calc)); - binding->set_connection_error_handler(base::Bind( - &SetFlagAndRunClosure, &error_received, run_loop.QuitClosure())); - - { - // Suppose this is instantiated in a process that has the other end of the - // message pipe. - MathCalculatorUI calculator_ui(std::move(calc)); - - base::RunLoop run_loop, run_loop2; - calculator_ui.Add(2.0, run_loop.QuitClosure()); - calculator_ui.Multiply(5.0, run_loop2.QuitClosure()); - run_loop.Run(); - run_loop2.Run(); - - EXPECT_EQ(10.0, calculator_ui.GetOutput()); - EXPECT_FALSE(error_received); - EXPECT_FALSE(destroyed); - } - // Destroying calculator_ui should close the pipe and generate an error on the - // other - // end which will destroy the instance since it is strongly bound. - - run_loop.Run(); - EXPECT_TRUE(error_received); - EXPECT_TRUE(destroyed); -} - -class WeakMathCalculatorImpl : public math::Calculator { - public: - WeakMathCalculatorImpl(ScopedMessagePipeHandle handle, - bool* error_received, - bool* destroyed, - const base::Closure& closure) - : error_received_(error_received), - destroyed_(destroyed), - closure_(closure), - binding_(this, std::move(handle)) { - binding_.set_connection_error_handler( - base::Bind(&SetFlagAndRunClosure, error_received_, closure_)); - } - ~WeakMathCalculatorImpl() override { *destroyed_ = true; } - - void Clear(const CalcCallback& callback) override { callback.Run(total_); } - - void Add(double value, const CalcCallback& callback) override { - total_ += value; - callback.Run(total_); - } - - void Multiply(double value, const CalcCallback& callback) override { - total_ *= value; - callback.Run(total_); - } - - private: - double total_ = 0.0; - bool* error_received_; - bool* destroyed_; - base::Closure closure_; - - Binding<math::Calculator> binding_; -}; - -TEST(WeakConnectorTest, Math) { - base::MessageLoop loop; - - bool error_received = false; - bool destroyed = false; - MessagePipe pipe; - base::RunLoop run_loop; - WeakMathCalculatorImpl impl(std::move(pipe.handle0), &error_received, - &destroyed, run_loop.QuitClosure()); - - math::CalculatorPtr calc; - calc.Bind(InterfacePtrInfo<math::Calculator>(std::move(pipe.handle1), 0u)); - - { - // Suppose this is instantiated in a process that has the other end of the - // message pipe. - MathCalculatorUI calculator_ui(std::move(calc)); - - base::RunLoop run_loop, run_loop2; - calculator_ui.Add(2.0, run_loop.QuitClosure()); - calculator_ui.Multiply(5.0, run_loop2.QuitClosure()); - run_loop.Run(); - run_loop2.Run(); - - EXPECT_EQ(10.0, calculator_ui.GetOutput()); - EXPECT_FALSE(error_received); - EXPECT_FALSE(destroyed); - // Destroying calculator_ui should close the pipe and generate an error on - // the other - // end which will destroy the instance since it is strongly bound. - } - - run_loop.Run(); - EXPECT_TRUE(error_received); - EXPECT_FALSE(destroyed); -} - -class CImpl : public C { - public: - CImpl(bool* d_called, const base::Closure& closure) - : d_called_(d_called), closure_(closure) {} - ~CImpl() override {} - - private: - void D() override { - *d_called_ = true; - closure_.Run(); - } - - bool* d_called_; - base::Closure closure_; -}; - -class BImpl : public B { - public: - BImpl(bool* d_called, const base::Closure& closure) - : d_called_(d_called), closure_(closure) {} - ~BImpl() override {} - - private: - void GetC(InterfaceRequest<C> c) override { - MakeStrongBinding(base::MakeUnique<CImpl>(d_called_, closure_), - std::move(c)); - } - - bool* d_called_; - base::Closure closure_; -}; - -class AImpl : public A { - public: - AImpl(InterfaceRequest<A> request, const base::Closure& closure) - : d_called_(false), binding_(this, std::move(request)), - closure_(closure) {} - ~AImpl() override {} - - bool d_called() const { return d_called_; } - - private: - void GetB(InterfaceRequest<B> b) override { - MakeStrongBinding(base::MakeUnique<BImpl>(&d_called_, closure_), - std::move(b)); - } - - bool d_called_; - Binding<A> binding_; - base::Closure closure_; -}; - -TEST_F(InterfacePtrTest, Scoping) { - APtr a; - base::RunLoop run_loop; - AImpl a_impl(MakeRequest(&a), run_loop.QuitClosure()); - - EXPECT_FALSE(a_impl.d_called()); - - { - BPtr b; - a->GetB(MakeRequest(&b)); - CPtr c; - b->GetC(MakeRequest(&c)); - c->D(); - } - - // While B & C have fallen out of scope, the pipes will remain until they are - // flushed. - EXPECT_FALSE(a_impl.d_called()); - run_loop.Run(); - EXPECT_TRUE(a_impl.d_called()); -} - -class PingTestImpl : public sample::PingTest { - public: - explicit PingTestImpl(InterfaceRequest<sample::PingTest> request) - : binding_(this, std::move(request)) {} - ~PingTestImpl() override {} - - private: - // sample::PingTest: - void Ping(const PingCallback& callback) override { callback.Run(); } - - Binding<sample::PingTest> binding_; -}; - -// Tests that FuseProxy does what it's supposed to do. -TEST_F(InterfacePtrTest, Fusion) { - sample::PingTestPtr proxy; - PingTestImpl impl(MakeRequest(&proxy)); - - // Create another PingTest pipe. - sample::PingTestPtr ptr; - sample::PingTestRequest request(&ptr); - - // Fuse the new pipe to the one hanging off |impl|. - EXPECT_TRUE(FuseInterface(std::move(request), proxy.PassInterface())); - - // Ping! - bool called = false; - base::RunLoop loop; - ptr->Ping(base::Bind(&SetFlagAndRunClosure, &called, loop.QuitClosure())); - loop.Run(); - EXPECT_TRUE(called); -} - -void Fail() { - FAIL() << "Unexpected connection error"; -} - -TEST_F(InterfacePtrTest, FlushForTesting) { - math::CalculatorPtr calc; - MathCalculatorImpl calc_impl(MakeRequest(&calc)); - calc.set_connection_error_handler(base::Bind(&Fail)); - - MathCalculatorUI calculator_ui(std::move(calc)); - - calculator_ui.Add(2.0, base::Bind(&base::DoNothing)); - calculator_ui.GetInterfacePtr().FlushForTesting(); - EXPECT_EQ(2.0, calculator_ui.GetOutput()); - - calculator_ui.Multiply(5.0, base::Bind(&base::DoNothing)); - calculator_ui.GetInterfacePtr().FlushForTesting(); - - EXPECT_EQ(10.0, calculator_ui.GetOutput()); -} - -void SetBool(bool* value) { - *value = true; -} - -TEST_F(InterfacePtrTest, FlushForTestingWithClosedPeer) { - math::CalculatorPtr calc; - MakeRequest(&calc); - bool called = false; - calc.set_connection_error_handler(base::Bind(&SetBool, &called)); - calc.FlushForTesting(); - EXPECT_TRUE(called); - calc.FlushForTesting(); -} - -TEST_F(InterfacePtrTest, ConnectionErrorWithReason) { - math::CalculatorPtr calc; - MathCalculatorImpl calc_impl(MakeRequest(&calc)); - - base::RunLoop run_loop; - calc.set_connection_error_with_reason_handler(base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(42u, custom_reason); - EXPECT_EQ("hey", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - calc_impl.binding()->CloseWithReason(42u, "hey"); - - run_loop.Run(); -} - -TEST_F(InterfacePtrTest, InterfaceRequestResetWithReason) { - math::CalculatorPtr calc; - auto request = MakeRequest(&calc); - - base::RunLoop run_loop; - calc.set_connection_error_with_reason_handler(base::Bind( - [](const base::Closure& quit_closure, uint32_t custom_reason, - const std::string& description) { - EXPECT_EQ(88u, custom_reason); - EXPECT_EQ("greetings", description); - quit_closure.Run(); - }, - run_loop.QuitClosure())); - - request.ResetWithReason(88u, "greetings"); - - run_loop.Run(); -} - -TEST_F(InterfacePtrTest, CallbackIsPassedInterfacePtr) { - sample::PingTestPtr ptr; - sample::PingTestRequest request(&ptr); - - base::RunLoop run_loop; - - // Make a call with the proxy's lifetime bound to the response callback. - sample::PingTest* raw_proxy = ptr.get(); - ptr.set_connection_error_handler(run_loop.QuitClosure()); - raw_proxy->Ping( - base::Bind([](sample::PingTestPtr ptr) {}, base::Passed(&ptr))); - - // Trigger an error on |ptr|. This will ultimately lead to the proxy's - // response callbacks being destroyed, which will in turn lead to the proxy - // being destroyed. This should not crash. - request.PassMessagePipe(); - run_loop.Run(); -} - -TEST_F(InterfacePtrTest, ConnectionErrorHandlerOwnsInterfacePtr) { - sample::PingTestPtr* ptr = new sample::PingTestPtr; - sample::PingTestRequest request(ptr); - - base::RunLoop run_loop; - - // Make a call with |ptr|'s lifetime bound to the connection error handler - // callback. - ptr->set_connection_error_handler(base::Bind( - [](const base::Closure& quit, sample::PingTestPtr* ptr) { - ptr->reset(); - quit.Run(); - }, - run_loop.QuitClosure(), base::Owned(ptr))); - - // Trigger an error on |ptr|. In the error handler |ptr| is reset. This - // shouldn't immediately destroy the callback (and |ptr| that it owns), before - // the callback is completed. - request.PassMessagePipe(); - run_loop.Run(); -} - -TEST_F(InterfacePtrTest, ThreadSafeInterfacePointer) { - math::CalculatorPtr ptr; - MathCalculatorImpl calc_impl(MakeRequest(&ptr)); - scoped_refptr<math::ThreadSafeCalculatorPtr> thread_safe_ptr = - math::ThreadSafeCalculatorPtr::Create(std::move(ptr)); - - base::RunLoop run_loop; - - // Create and start the thread from where we'll call the interface pointer. - base::Thread other_thread("service test thread"); - other_thread.Start(); - - auto run_method = base::Bind( - [](const scoped_refptr<base::TaskRunner>& main_task_runner, - const base::Closure& quit_closure, - const scoped_refptr<math::ThreadSafeCalculatorPtr>& thread_safe_ptr) { - auto calc_callback = base::Bind( - [](const scoped_refptr<base::TaskRunner>& main_task_runner, - const base::Closure& quit_closure, - base::PlatformThreadId thread_id, - double result) { - EXPECT_EQ(123, result); - // Validate the callback is invoked on the calling thread. - EXPECT_EQ(thread_id, base::PlatformThread::CurrentId()); - // Notify the run_loop to quit. - main_task_runner->PostTask(FROM_HERE, quit_closure); - }); - (*thread_safe_ptr)->Add( - 123, base::Bind(calc_callback, main_task_runner, quit_closure, - base::PlatformThread::CurrentId())); - }, - base::SequencedTaskRunnerHandle::Get(), run_loop.QuitClosure(), - thread_safe_ptr); - other_thread.message_loop()->task_runner()->PostTask(FROM_HERE, run_method); - - // Block until the method callback is called on the background thread. - run_loop.Run(); -} - -TEST_F(InterfacePtrTest, ThreadSafeInterfacePointerWithTaskRunner) { - // Create and start the thread from where we'll bind the interface pointer. - base::Thread other_thread("service test thread"); - other_thread.Start(); - const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner = - other_thread.message_loop()->task_runner(); - - math::CalculatorPtr ptr; - math::CalculatorRequest request(&ptr); - - // Create a ThreadSafeInterfacePtr that we'll bind from a different thread. - scoped_refptr<math::ThreadSafeCalculatorPtr> thread_safe_ptr = - math::ThreadSafeCalculatorPtr::Create(ptr.PassInterface(), - other_thread_task_runner); - ASSERT_TRUE(thread_safe_ptr); - - MathCalculatorImpl* math_calc_impl = nullptr; - { - base::RunLoop run_loop; - auto run_method = base::Bind( - [](const scoped_refptr<base::TaskRunner>& main_task_runner, - const base::Closure& quit_closure, - const scoped_refptr<math::ThreadSafeCalculatorPtr>& thread_safe_ptr, - math::CalculatorRequest request, - MathCalculatorImpl** math_calc_impl) { - math::CalculatorPtr ptr; - // In real life, the implementation would have a legitimate owner. - *math_calc_impl = new MathCalculatorImpl(std::move(request)); - main_task_runner->PostTask(FROM_HERE, quit_closure); - }, - base::SequencedTaskRunnerHandle::Get(), run_loop.QuitClosure(), - thread_safe_ptr, base::Passed(&request), &math_calc_impl); - other_thread.message_loop()->task_runner()->PostTask(FROM_HERE, run_method); - run_loop.Run(); - } - - { - // The interface ptr is bound, we can call methods on it. - auto calc_callback = - base::Bind([](const base::Closure& quit_closure, double result) { - EXPECT_EQ(123, result); - quit_closure.Run(); - }); - base::RunLoop run_loop; - (*thread_safe_ptr) - ->Add(123, base::Bind(calc_callback, run_loop.QuitClosure())); - // Block until the method callback is called. - run_loop.Run(); - } - - other_thread_task_runner->DeleteSoon(FROM_HERE, math_calc_impl); - - // Reset the pointer now so the InterfacePtr associated resources can be - // deleted before the background thread's message loop is invalidated. - thread_safe_ptr = nullptr; -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/map_unittest.cc b/mojo/public/cpp/bindings/tests/map_unittest.cc deleted file mode 100644 index 8d630a5..0000000 --- a/mojo/public/cpp/bindings/tests/map_unittest.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> -#include <unordered_map> -#include <utility> - -#include "mojo/public/cpp/bindings/tests/rect_chromium.h" -#include "mojo/public/interfaces/bindings/tests/rect.mojom.h" -#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -TEST(MapTest, StructKey) { - std::unordered_map<RectPtr, int32_t> map; - map.insert(std::make_pair(Rect::New(1, 2, 3, 4), 123)); - - RectPtr key = Rect::New(1, 2, 3, 4); - ASSERT_NE(map.end(), map.find(key)); - ASSERT_EQ(123, map.find(key)->second); - - map.erase(key); - ASSERT_EQ(0u, map.size()); -} - -TEST(MapTest, TypemappedStructKey) { - std::unordered_map<ContainsHashablePtr, int32_t> map; - map.insert( - std::make_pair(ContainsHashable::New(RectChromium(1, 2, 3, 4)), 123)); - - ContainsHashablePtr key = ContainsHashable::New(RectChromium(1, 2, 3, 4)); - ASSERT_NE(map.end(), map.find(key)); - ASSERT_EQ(123, map.find(key)->second); - - map.erase(key); - ASSERT_EQ(0u, map.size()); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/message_queue.cc b/mojo/public/cpp/bindings/tests/message_queue.cc deleted file mode 100644 index 32ed763..0000000 --- a/mojo/public/cpp/bindings/tests/message_queue.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/tests/message_queue.h" - -#include "base/logging.h" -#include "mojo/public/cpp/bindings/message.h" - -namespace mojo { -namespace test { - -MessageQueue::MessageQueue() { -} - -MessageQueue::~MessageQueue() { -} - -bool MessageQueue::IsEmpty() const { - return queue_.empty(); -} - -void MessageQueue::Push(Message* message) { - queue_.emplace(std::move(*message)); -} - -void MessageQueue::Pop(Message* message) { - DCHECK(!queue_.empty()); - *message = std::move(queue_.front()); - Pop(); -} - -void MessageQueue::Pop() { - DCHECK(!queue_.empty()); - queue_.pop(); -} - -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/message_queue.h b/mojo/public/cpp/bindings/tests/message_queue.h deleted file mode 100644 index 8f13f7a..0000000 --- a/mojo/public/cpp/bindings/tests/message_queue.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_MESSAGE_QUEUE_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_MESSAGE_QUEUE_H_ - -#include <queue> - -#include "base/macros.h" -#include "mojo/public/cpp/bindings/message.h" - -namespace mojo { -namespace test { - -// A queue for Message objects. -class MessageQueue { - public: - MessageQueue(); - ~MessageQueue(); - - bool IsEmpty() const; - - // This method copies the message data and steals ownership of its handles. - void Push(Message* message); - - // Removes the next message from the queue, copying its data and transferring - // ownership of its handles to the given |message|. - void Pop(Message* message); - - size_t size() const { return queue_.size(); } - - private: - void Pop(); - - std::queue<Message> queue_; - - DISALLOW_COPY_AND_ASSIGN(MessageQueue); -}; - -} // namespace test -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_MESSAGE_QUEUE_H_ diff --git a/mojo/public/cpp/bindings/tests/mojo_test_blink_export.h b/mojo/public/cpp/bindings/tests/mojo_test_blink_export.h deleted file mode 100644 index b3bbe27..0000000 --- a/mojo/public/cpp/bindings/tests/mojo_test_blink_export.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_BLINK_EXPORT_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_BLINK_EXPORT_H_ - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -#if defined(MOJO_TEST_BLINK_IMPLEMENTATION) -#define MOJO_TEST_BLINK_EXPORT __declspec(dllexport) -#else -#define MOJO_TEST_BLINK_EXPORT __declspec(dllimport) -#endif // defined(MOJO_TEST_BLINK_IMPLEMENTATION) - -#else // defined(WIN32) -#if defined(MOJO_TEST_BLINK_IMPLEMENTATION) -#define MOJO_TEST_BLINK_EXPORT __attribute__((visibility("default"))) -#else -#define MOJO_TEST_BLINK_EXPORT -#endif -#endif - -#else // defined(COMPONENT_BUILD) -#define MOJO_TEST_BLINK_EXPORT -#endif - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_BLINK_EXPORT_H_ diff --git a/mojo/public/cpp/bindings/tests/mojo_test_export.h b/mojo/public/cpp/bindings/tests/mojo_test_export.h deleted file mode 100644 index a48a1ba..0000000 --- a/mojo/public/cpp/bindings/tests/mojo_test_export.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_EXPORT_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_EXPORT_H_ - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -#if defined(MOJO_TEST_IMPLEMENTATION) -#define MOJO_TEST_EXPORT __declspec(dllexport) -#else -#define MOJO_TEST_EXPORT __declspec(dllimport) -#endif // defined(MOJO_TEST_IMPLEMENTATION) - -#else // defined(WIN32) -#if defined(MOJO_TEST_IMPLEMENTATION) -#define MOJO_TEST_EXPORT __attribute__((visibility("default"))) -#else -#define MOJO_TEST_EXPORT -#endif -#endif - -#else // defined(COMPONENT_BUILD) -#define MOJO_TEST_EXPORT -#endif - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_MOJO_TEST_EXPORT_H_ diff --git a/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc b/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc deleted file mode 100644 index 8950928..0000000 --- a/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc +++ /dev/null @@ -1,314 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/lib/multiplex_router.h" - -#include <utility> - -#include "base/bind.h" -#include "base/memory/ptr_util.h" -#include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/threading/thread_task_runner_handle.h" -#include "mojo/public/cpp/bindings/interface_endpoint_client.h" -#include "mojo/public/cpp/bindings/message.h" -#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" -#include "mojo/public/cpp/bindings/tests/message_queue.h" -#include "mojo/public/cpp/bindings/tests/router_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -using mojo::internal::MultiplexRouter; - -class MultiplexRouterTest : public testing::Test { - public: - MultiplexRouterTest() {} - - void SetUp() override { - MessagePipe pipe; - router0_ = new MultiplexRouter(std::move(pipe.handle0), - MultiplexRouter::MULTI_INTERFACE, false, - base::ThreadTaskRunnerHandle::Get()); - router1_ = new MultiplexRouter(std::move(pipe.handle1), - MultiplexRouter::MULTI_INTERFACE, true, - base::ThreadTaskRunnerHandle::Get()); - ScopedInterfaceEndpointHandle::CreatePairPendingAssociation(&endpoint0_, - &endpoint1_); - auto id = router0_->AssociateInterface(std::move(endpoint1_)); - endpoint1_ = router1_->CreateLocalEndpointHandle(id); - } - - void TearDown() override {} - - void PumpMessages() { base::RunLoop().RunUntilIdle(); } - - protected: - scoped_refptr<MultiplexRouter> router0_; - scoped_refptr<MultiplexRouter> router1_; - ScopedInterfaceEndpointHandle endpoint0_; - ScopedInterfaceEndpointHandle endpoint1_; - - private: - base::MessageLoop loop_; -}; - -TEST_F(MultiplexRouterTest, BasicRequestResponse) { - InterfaceEndpointClient client0(std::move(endpoint0_), nullptr, - base::MakeUnique<PassThroughFilter>(), false, - base::ThreadTaskRunnerHandle::Get(), 0u); - ResponseGenerator generator; - InterfaceEndpointClient client1(std::move(endpoint1_), &generator, - base::MakeUnique<PassThroughFilter>(), false, - base::ThreadTaskRunnerHandle::Get(), 0u); - - Message request; - AllocRequestMessage(1, "hello", &request); - - MessageQueue message_queue; - base::RunLoop run_loop; - client0.AcceptWithResponder( - &request, base::MakeUnique<MessageAccumulator>(&message_queue, - run_loop.QuitClosure())); - - run_loop.Run(); - - EXPECT_FALSE(message_queue.IsEmpty()); - - Message response; - message_queue.Pop(&response); - - EXPECT_EQ(std::string("hello world!"), - std::string(reinterpret_cast<const char*>(response.payload()))); - - // Send a second message on the pipe. - Message request2; - AllocRequestMessage(1, "hello again", &request2); - - base::RunLoop run_loop2; - client0.AcceptWithResponder( - &request2, base::MakeUnique<MessageAccumulator>(&message_queue, - run_loop2.QuitClosure())); - - run_loop2.Run(); - - EXPECT_FALSE(message_queue.IsEmpty()); - - message_queue.Pop(&response); - - EXPECT_EQ(std::string("hello again world!"), - std::string(reinterpret_cast<const char*>(response.payload()))); -} - -TEST_F(MultiplexRouterTest, BasicRequestResponse_Synchronous) { - InterfaceEndpointClient client0(std::move(endpoint0_), nullptr, - base::MakeUnique<PassThroughFilter>(), false, - base::ThreadTaskRunnerHandle::Get(), 0u); - ResponseGenerator generator; - InterfaceEndpointClient client1(std::move(endpoint1_), &generator, - base::MakeUnique<PassThroughFilter>(), false, - base::ThreadTaskRunnerHandle::Get(), 0u); - - Message request; - AllocRequestMessage(1, "hello", &request); - - MessageQueue message_queue; - client0.AcceptWithResponder( - &request, base::MakeUnique<MessageAccumulator>(&message_queue)); - - router1_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); - router0_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); - - EXPECT_FALSE(message_queue.IsEmpty()); - - Message response; - message_queue.Pop(&response); - - EXPECT_EQ(std::string("hello world!"), - std::string(reinterpret_cast<const char*>(response.payload()))); - - // Send a second message on the pipe. - Message request2; - AllocRequestMessage(1, "hello again", &request2); - - client0.AcceptWithResponder( - &request2, base::MakeUnique<MessageAccumulator>(&message_queue)); - - router1_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); - router0_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); - - EXPECT_FALSE(message_queue.IsEmpty()); - - message_queue.Pop(&response); - - EXPECT_EQ(std::string("hello again world!"), - std::string(reinterpret_cast<const char*>(response.payload()))); -} - -// Tests MultiplexRouter using the LazyResponseGenerator. The responses will not -// be sent until after the requests have been accepted. -TEST_F(MultiplexRouterTest, LazyResponses) { - InterfaceEndpointClient client0( - std::move(endpoint0_), nullptr, base::WrapUnique(new PassThroughFilter()), - false, base::ThreadTaskRunnerHandle::Get(), 0u); - base::RunLoop run_loop; - LazyResponseGenerator generator(run_loop.QuitClosure()); - InterfaceEndpointClient client1(std::move(endpoint1_), &generator, - base::WrapUnique(new PassThroughFilter()), - false, base::ThreadTaskRunnerHandle::Get(), - 0u); - - Message request; - AllocRequestMessage(1, "hello", &request); - - MessageQueue message_queue; - base::RunLoop run_loop2; - client0.AcceptWithResponder( - &request, base::MakeUnique<MessageAccumulator>(&message_queue, - run_loop2.QuitClosure())); - run_loop.Run(); - - // The request has been received but the response has not been sent yet. - EXPECT_TRUE(message_queue.IsEmpty()); - - // Send the response. - EXPECT_TRUE(generator.responder_is_valid()); - generator.CompleteWithResponse(); - run_loop2.Run(); - - // Check the response. - EXPECT_FALSE(message_queue.IsEmpty()); - Message response; - message_queue.Pop(&response); - EXPECT_EQ(std::string("hello world!"), - std::string(reinterpret_cast<const char*>(response.payload()))); - - // Send a second message on the pipe. - base::RunLoop run_loop3; - generator.set_closure(run_loop3.QuitClosure()); - Message request2; - AllocRequestMessage(1, "hello again", &request2); - - base::RunLoop run_loop4; - client0.AcceptWithResponder( - &request2, base::MakeUnique<MessageAccumulator>(&message_queue, - run_loop4.QuitClosure())); - run_loop3.Run(); - - // The request has been received but the response has not been sent yet. - EXPECT_TRUE(message_queue.IsEmpty()); - - // Send the second response. - EXPECT_TRUE(generator.responder_is_valid()); - generator.CompleteWithResponse(); - run_loop4.Run(); - - // Check the second response. - EXPECT_FALSE(message_queue.IsEmpty()); - message_queue.Pop(&response); - EXPECT_EQ(std::string("hello again world!"), - std::string(reinterpret_cast<const char*>(response.payload()))); -} - -void ForwardErrorHandler(bool* called, const base::Closure& callback) { - *called = true; - callback.Run(); -} - -// Tests that if the receiving application destroys the responder_ without -// sending a response, then we trigger connection error at both sides. Moreover, -// both sides still appear to have a valid message pipe handle bound. -TEST_F(MultiplexRouterTest, MissingResponses) { - base::RunLoop run_loop0, run_loop1; - InterfaceEndpointClient client0( - std::move(endpoint0_), nullptr, base::WrapUnique(new PassThroughFilter()), - false, base::ThreadTaskRunnerHandle::Get(), 0u); - bool error_handler_called0 = false; - client0.set_connection_error_handler( - base::Bind(&ForwardErrorHandler, &error_handler_called0, - run_loop0.QuitClosure())); - - base::RunLoop run_loop3; - LazyResponseGenerator generator(run_loop3.QuitClosure()); - InterfaceEndpointClient client1(std::move(endpoint1_), &generator, - base::WrapUnique(new PassThroughFilter()), - false, base::ThreadTaskRunnerHandle::Get(), - 0u); - bool error_handler_called1 = false; - client1.set_connection_error_handler( - base::Bind(&ForwardErrorHandler, &error_handler_called1, - run_loop1.QuitClosure())); - - Message request; - AllocRequestMessage(1, "hello", &request); - - MessageQueue message_queue; - client0.AcceptWithResponder( - &request, base::MakeUnique<MessageAccumulator>(&message_queue)); - run_loop3.Run(); - - // The request has been received but no response has been sent. - EXPECT_TRUE(message_queue.IsEmpty()); - - // Destroy the responder MessagerReceiver but don't send any response. - generator.CompleteWithoutResponse(); - run_loop0.Run(); - run_loop1.Run(); - - // Check that no response was received. - EXPECT_TRUE(message_queue.IsEmpty()); - - // Connection error handler is called at both sides. - EXPECT_TRUE(error_handler_called0); - EXPECT_TRUE(error_handler_called1); - - // The error flag is set at both sides. - EXPECT_TRUE(client0.encountered_error()); - EXPECT_TRUE(client1.encountered_error()); - - // The message pipe handle is valid at both sides. - EXPECT_TRUE(router0_->is_valid()); - EXPECT_TRUE(router1_->is_valid()); -} - -TEST_F(MultiplexRouterTest, LateResponse) { - // Test that things won't blow up if we try to send a message to a - // MessageReceiver, which was given to us via AcceptWithResponder, - // after the router has gone away. - - base::RunLoop run_loop; - LazyResponseGenerator generator(run_loop.QuitClosure()); - { - InterfaceEndpointClient client0( - std::move(endpoint0_), nullptr, base::MakeUnique<PassThroughFilter>(), - false, base::ThreadTaskRunnerHandle::Get(), 0u); - InterfaceEndpointClient client1(std::move(endpoint1_), &generator, - base::MakeUnique<PassThroughFilter>(), - false, base::ThreadTaskRunnerHandle::Get(), - 0u); - - Message request; - AllocRequestMessage(1, "hello", &request); - - MessageQueue message_queue; - client0.AcceptWithResponder( - &request, base::MakeUnique<MessageAccumulator>(&message_queue)); - - run_loop.Run(); - - EXPECT_TRUE(generator.has_responder()); - } - - EXPECT_FALSE(generator.responder_is_valid()); - generator.CompleteWithResponse(); // This should end up doing nothing. -} - -// TODO(yzshen): add more tests. - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/pickle_unittest.cc b/mojo/public/cpp/bindings/tests/pickle_unittest.cc deleted file mode 100644 index a5947ce..0000000 --- a/mojo/public/cpp/bindings/tests/pickle_unittest.cc +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "mojo/public/cpp/bindings/tests/pickled_types_blink.h" -#include "mojo/public/cpp/bindings/tests/pickled_types_chromium.h" -#include "mojo/public/cpp/bindings/tests/variant_test_util.h" -#include "mojo/public/interfaces/bindings/tests/test_native_types.mojom-blink.h" -#include "mojo/public/interfaces/bindings/tests/test_native_types.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -template <typename T> -void DoExpectResult(int foo, int bar, const base::Closure& callback, T actual) { - EXPECT_EQ(foo, actual.foo()); - EXPECT_EQ(bar, actual.bar()); - callback.Run(); -} - -template <typename T> -base::Callback<void(T)> ExpectResult(const T& t, - const base::Closure& callback) { - return base::Bind(&DoExpectResult<T>, t.foo(), t.bar(), callback); -} - -template <typename T> -void DoFail(const std::string& reason, T) { - EXPECT_TRUE(false) << reason; -} - -template <typename T> -base::Callback<void(T)> Fail(const std::string& reason) { - return base::Bind(&DoFail<T>, reason); -} - -template <typename T> -void DoExpectEnumResult(T expected, const base::Closure& callback, T actual) { - EXPECT_EQ(expected, actual); - callback.Run(); -} - -template <typename T> -base::Callback<void(T)> ExpectEnumResult(T t, const base::Closure& callback) { - return base::Bind(&DoExpectEnumResult<T>, t, callback); -} - -template <typename T> -void DoEnumFail(const std::string& reason, T) { - EXPECT_TRUE(false) << reason; -} - -template <typename T> -base::Callback<void(T)> EnumFail(const std::string& reason) { - return base::Bind(&DoEnumFail<T>, reason); -} - -template <typename T> -void ExpectError(InterfacePtr<T>* proxy, const base::Closure& callback) { - proxy->set_connection_error_handler(callback); -} - -template <typename Func, typename Arg> -void RunSimpleLambda(Func func, Arg arg) { func(std::move(arg)); } - -template <typename Arg, typename Func> -base::Callback<void(Arg)> BindSimpleLambda(Func func) { - return base::Bind(&RunSimpleLambda<Func, Arg>, func); -} - -// This implements the generated Chromium variant of PicklePasser. -class ChromiumPicklePasserImpl : public PicklePasser { - public: - ChromiumPicklePasserImpl() {} - - // mojo::test::PicklePasser: - void PassPickledStruct(PickledStructChromium pickle, - const PassPickledStructCallback& callback) override { - callback.Run(std::move(pickle)); - } - - void PassPickledEnum(PickledEnumChromium pickle, - const PassPickledEnumCallback& callback) override { - callback.Run(pickle); - } - - void PassPickleContainer( - PickleContainerPtr container, - const PassPickleContainerCallback& callback) override { - callback.Run(std::move(container)); - } - - void PassPickles(std::vector<PickledStructChromium> pickles, - const PassPicklesCallback& callback) override { - callback.Run(std::move(pickles)); - } - - void PassPickleArrays( - std::vector<std::vector<PickledStructChromium>> pickle_arrays, - const PassPickleArraysCallback& callback) override { - callback.Run(std::move(pickle_arrays)); - } -}; - -// This implements the generated Blink variant of PicklePasser. -class BlinkPicklePasserImpl : public blink::PicklePasser { - public: - BlinkPicklePasserImpl() {} - - // mojo::test::blink::PicklePasser: - void PassPickledStruct(PickledStructBlink pickle, - const PassPickledStructCallback& callback) override { - callback.Run(std::move(pickle)); - } - - void PassPickledEnum(PickledEnumBlink pickle, - const PassPickledEnumCallback& callback) override { - callback.Run(pickle); - } - - void PassPickleContainer( - blink::PickleContainerPtr container, - const PassPickleContainerCallback& callback) override { - callback.Run(std::move(container)); - } - - void PassPickles(WTF::Vector<PickledStructBlink> pickles, - const PassPicklesCallback& callback) override { - callback.Run(std::move(pickles)); - } - - void PassPickleArrays( - WTF::Vector<WTF::Vector<PickledStructBlink>> pickle_arrays, - const PassPickleArraysCallback& callback) override { - callback.Run(std::move(pickle_arrays)); - } -}; - -// A test which runs both Chromium and Blink implementations of the -// PicklePasser service. -class PickleTest : public testing::Test { - public: - PickleTest() {} - - template <typename ProxyType = PicklePasser> - InterfacePtr<ProxyType> ConnectToChromiumService() { - InterfacePtr<ProxyType> proxy; - InterfaceRequest<ProxyType> request(&proxy); - chromium_bindings_.AddBinding( - &chromium_service_, - ConvertInterfaceRequest<PicklePasser>(std::move(request))); - return proxy; - } - - template <typename ProxyType = blink::PicklePasser> - InterfacePtr<ProxyType> ConnectToBlinkService() { - InterfacePtr<ProxyType> proxy; - InterfaceRequest<ProxyType> request(&proxy); - blink_bindings_.AddBinding( - &blink_service_, - ConvertInterfaceRequest<blink::PicklePasser>(std::move(request))); - return proxy; - } - - private: - base::MessageLoop loop_; - ChromiumPicklePasserImpl chromium_service_; - BindingSet<PicklePasser> chromium_bindings_; - BlinkPicklePasserImpl blink_service_; - BindingSet<blink::PicklePasser> blink_bindings_; -}; - -} // namespace - -TEST_F(PickleTest, ChromiumProxyToChromiumService) { - auto chromium_proxy = ConnectToChromiumService(); - { - base::RunLoop loop; - chromium_proxy->PassPickledStruct( - PickledStructChromium(1, 2), - ExpectResult(PickledStructChromium(1, 2), loop.QuitClosure())); - loop.Run(); - } - { - base::RunLoop loop; - chromium_proxy->PassPickledStruct( - PickledStructChromium(4, 5), - ExpectResult(PickledStructChromium(4, 5), loop.QuitClosure())); - loop.Run(); - } - - { - base::RunLoop loop; - chromium_proxy->PassPickledEnum( - PickledEnumChromium::VALUE_1, - ExpectEnumResult(PickledEnumChromium::VALUE_1, loop.QuitClosure())); - loop.Run(); - } -} - -TEST_F(PickleTest, ChromiumProxyToBlinkService) { - auto chromium_proxy = ConnectToBlinkService<PicklePasser>(); - { - base::RunLoop loop; - chromium_proxy->PassPickledStruct( - PickledStructChromium(1, 2), - ExpectResult(PickledStructChromium(1, 2), loop.QuitClosure())); - loop.Run(); - } - { - base::RunLoop loop; - chromium_proxy->PassPickledStruct( - PickledStructChromium(4, 5), - ExpectResult(PickledStructChromium(4, 5), loop.QuitClosure())); - loop.Run(); - } - // The Blink service should drop our connection because the - // PickledStructBlink ParamTraits deserializer rejects negative values. - { - base::RunLoop loop; - chromium_proxy->PassPickledStruct( - PickledStructChromium(-1, -1), - Fail<PickledStructChromium>("Blink service should reject this.")); - ExpectError(&chromium_proxy, loop.QuitClosure()); - loop.Run(); - } - - chromium_proxy = ConnectToBlinkService<PicklePasser>(); - { - base::RunLoop loop; - chromium_proxy->PassPickledEnum( - PickledEnumChromium::VALUE_0, - ExpectEnumResult(PickledEnumChromium::VALUE_0, loop.QuitClosure())); - loop.Run(); - } - - // The Blink service should drop our connection because the - // PickledEnumBlink ParamTraits deserializer rejects this value. - { - base::RunLoop loop; - chromium_proxy->PassPickledEnum( - PickledEnumChromium::VALUE_2, - EnumFail<PickledEnumChromium>("Blink service should reject this.")); - ExpectError(&chromium_proxy, loop.QuitClosure()); - loop.Run(); - } -} - -TEST_F(PickleTest, BlinkProxyToBlinkService) { - auto blink_proxy = ConnectToBlinkService(); - { - base::RunLoop loop; - blink_proxy->PassPickledStruct( - PickledStructBlink(1, 1), - ExpectResult(PickledStructBlink(1, 1), loop.QuitClosure())); - loop.Run(); - } - - { - base::RunLoop loop; - blink_proxy->PassPickledEnum( - PickledEnumBlink::VALUE_0, - ExpectEnumResult(PickledEnumBlink::VALUE_0, loop.QuitClosure())); - loop.Run(); - } -} - -TEST_F(PickleTest, BlinkProxyToChromiumService) { - auto blink_proxy = ConnectToChromiumService<blink::PicklePasser>(); - { - base::RunLoop loop; - blink_proxy->PassPickledStruct( - PickledStructBlink(1, 1), - ExpectResult(PickledStructBlink(1, 1), loop.QuitClosure())); - loop.Run(); - } - - { - base::RunLoop loop; - blink_proxy->PassPickledEnum( - PickledEnumBlink::VALUE_1, - ExpectEnumResult(PickledEnumBlink::VALUE_1, loop.QuitClosure())); - loop.Run(); - } -} - -TEST_F(PickleTest, PickleArray) { - auto proxy = ConnectToChromiumService(); - auto pickles = std::vector<PickledStructChromium>(2); - pickles[0].set_foo(1); - pickles[0].set_bar(2); - pickles[0].set_baz(100); - pickles[1].set_foo(3); - pickles[1].set_bar(4); - pickles[1].set_baz(100); - { - base::RunLoop run_loop; - // Verify that the array of pickled structs can be serialized and - // deserialized intact. This ensures that the ParamTraits are actually used - // rather than doing a byte-for-byte copy of the element data, beacuse the - // |baz| field should never be serialized. - proxy->PassPickles(std::move(pickles), - BindSimpleLambda<std::vector<PickledStructChromium>>( - [&](std::vector<PickledStructChromium> passed) { - ASSERT_EQ(2u, passed.size()); - EXPECT_EQ(1, passed[0].foo()); - EXPECT_EQ(2, passed[0].bar()); - EXPECT_EQ(0, passed[0].baz()); - EXPECT_EQ(3, passed[1].foo()); - EXPECT_EQ(4, passed[1].bar()); - EXPECT_EQ(0, passed[1].baz()); - run_loop.Quit(); - })); - run_loop.Run(); - } -} - -TEST_F(PickleTest, PickleArrayArray) { - auto proxy = ConnectToChromiumService(); - auto pickle_arrays = std::vector<std::vector<PickledStructChromium>>(2); - for (size_t i = 0; i < 2; ++i) - pickle_arrays[i] = std::vector<PickledStructChromium>(2); - - pickle_arrays[0][0].set_foo(1); - pickle_arrays[0][0].set_bar(2); - pickle_arrays[0][0].set_baz(100); - pickle_arrays[0][1].set_foo(3); - pickle_arrays[0][1].set_bar(4); - pickle_arrays[0][1].set_baz(100); - pickle_arrays[1][0].set_foo(5); - pickle_arrays[1][0].set_bar(6); - pickle_arrays[1][0].set_baz(100); - pickle_arrays[1][1].set_foo(7); - pickle_arrays[1][1].set_bar(8); - pickle_arrays[1][1].set_baz(100); - { - base::RunLoop run_loop; - // Verify that the array-of-arrays serializes and deserializes properly. - proxy->PassPickleArrays( - std::move(pickle_arrays), - BindSimpleLambda<std::vector<std::vector<PickledStructChromium>>>( - [&](std::vector<std::vector<PickledStructChromium>> passed) { - ASSERT_EQ(2u, passed.size()); - ASSERT_EQ(2u, passed[0].size()); - ASSERT_EQ(2u, passed[1].size()); - EXPECT_EQ(1, passed[0][0].foo()); - EXPECT_EQ(2, passed[0][0].bar()); - EXPECT_EQ(0, passed[0][0].baz()); - EXPECT_EQ(3, passed[0][1].foo()); - EXPECT_EQ(4, passed[0][1].bar()); - EXPECT_EQ(0, passed[0][1].baz()); - EXPECT_EQ(5, passed[1][0].foo()); - EXPECT_EQ(6, passed[1][0].bar()); - EXPECT_EQ(0, passed[1][0].baz()); - EXPECT_EQ(7, passed[1][1].foo()); - EXPECT_EQ(8, passed[1][1].bar()); - EXPECT_EQ(0, passed[1][1].baz()); - run_loop.Quit(); - })); - run_loop.Run(); - } -} - -TEST_F(PickleTest, PickleContainer) { - auto proxy = ConnectToChromiumService(); - PickleContainerPtr pickle_container = PickleContainer::New(); - pickle_container->f_struct.set_foo(42); - pickle_container->f_struct.set_bar(43); - pickle_container->f_struct.set_baz(44); - pickle_container->f_enum = PickledEnumChromium::VALUE_1; - EXPECT_TRUE(pickle_container.Equals(pickle_container)); - EXPECT_FALSE(pickle_container.Equals(PickleContainer::New())); - { - base::RunLoop run_loop; - proxy->PassPickleContainer(std::move(pickle_container), - BindSimpleLambda<PickleContainerPtr>( - [&](PickleContainerPtr passed) { - ASSERT_FALSE(passed.is_null()); - EXPECT_EQ(42, passed->f_struct.foo()); - EXPECT_EQ(43, passed->f_struct.bar()); - EXPECT_EQ(0, passed->f_struct.baz()); - EXPECT_EQ(PickledEnumChromium::VALUE_1, - passed->f_enum); - run_loop.Quit(); - })); - run_loop.Run(); - } -} - -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/pickled_types_blink.cc b/mojo/public/cpp/bindings/tests/pickled_types_blink.cc deleted file mode 100644 index 7e55650..0000000 --- a/mojo/public/cpp/bindings/tests/pickled_types_blink.cc +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/tests/pickled_types_blink.h" - -#include "base/logging.h" -#include "base/pickle.h" - -namespace mojo { -namespace test { - -PickledStructBlink::PickledStructBlink() {} - -PickledStructBlink::PickledStructBlink(int foo, int bar) - : foo_(foo), bar_(bar) { - DCHECK_GE(foo_, 0); - DCHECK_GE(bar_, 0); -} - -PickledStructBlink::~PickledStructBlink() {} - -} // namespace test -} // namespace mojo - -namespace IPC { - -void ParamTraits<mojo::test::PickledStructBlink>::GetSize( - base::PickleSizer* sizer, - const param_type& p) { - sizer->AddInt(); - sizer->AddInt(); -} - -void ParamTraits<mojo::test::PickledStructBlink>::Write(base::Pickle* m, - const param_type& p) { - m->WriteInt(p.foo()); - m->WriteInt(p.bar()); -} - -bool ParamTraits<mojo::test::PickledStructBlink>::Read( - const base::Pickle* m, - base::PickleIterator* iter, - param_type* p) { - int foo, bar; - if (!iter->ReadInt(&foo) || !iter->ReadInt(&bar) || foo < 0 || bar < 0) - return false; - - p->set_foo(foo); - p->set_bar(bar); - return true; -} - -#include "ipc/param_traits_size_macros.h" -IPC_ENUM_TRAITS_MAX_VALUE(mojo::test::PickledEnumBlink, - mojo::test::PickledEnumBlink::VALUE_1) -#include "ipc/param_traits_write_macros.h" -IPC_ENUM_TRAITS_MAX_VALUE(mojo::test::PickledEnumBlink, - mojo::test::PickledEnumBlink::VALUE_1) -#include "ipc/param_traits_read_macros.h" -IPC_ENUM_TRAITS_MAX_VALUE(mojo::test::PickledEnumBlink, - mojo::test::PickledEnumBlink::VALUE_1) -#include "ipc/param_traits_log_macros.h" -IPC_ENUM_TRAITS_MAX_VALUE(mojo::test::PickledEnumBlink, - mojo::test::PickledEnumBlink::VALUE_1) - -} // namespace IPC diff --git a/mojo/public/cpp/bindings/tests/pickled_types_blink.h b/mojo/public/cpp/bindings/tests/pickled_types_blink.h deleted file mode 100644 index 37e9e70..0000000 --- a/mojo/public/cpp/bindings/tests/pickled_types_blink.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_PICKLED_TYPES_BLINK_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_PICKLED_TYPES_BLINK_H_ - -#include <stddef.h> - -#include <string> - -#include "base/logging.h" -#include "base/macros.h" -#include "ipc/ipc_message_macros.h" -#include "ipc/ipc_param_traits.h" - -namespace base { -class Pickle; -class PickleIterator; -class PickleSizer; -} - -namespace mojo { -namespace test { - -// Implementation of types with IPC::ParamTraits for consumers in Blink. - -enum class PickledEnumBlink { VALUE_0, VALUE_1 }; - -// To make things slightly more interesting, this variation of the type doesn't -// support negative values. It'll DCHECK if you try to construct it with any, -// and it will fail deserialization if negative values are decoded. -class PickledStructBlink { - public: - PickledStructBlink(); - PickledStructBlink(int foo, int bar); - PickledStructBlink(PickledStructBlink&& other) = default; - ~PickledStructBlink(); - - PickledStructBlink& operator=(PickledStructBlink&& other) = default; - - int foo() const { return foo_; } - void set_foo(int foo) { - DCHECK_GE(foo, 0); - foo_ = foo; - } - - int bar() const { return bar_; } - void set_bar(int bar) { - DCHECK_GE(bar, 0); - bar_ = bar; - } - - // The |baz| field should never be serialized. - int baz() const { return baz_; } - void set_baz(int baz) { baz_ = baz; } - - private: - int foo_ = 0; - int bar_ = 0; - int baz_ = 0; - - DISALLOW_COPY_AND_ASSIGN(PickledStructBlink); -}; - -} // namespace test -} // namespace mojo - -namespace IPC { - -template <> -struct ParamTraits<mojo::test::PickledStructBlink> { - using param_type = mojo::test::PickledStructBlink; - - static void GetSize(base::PickleSizer* sizer, const param_type& p); - static void Write(base::Pickle* m, const param_type& p); - static bool Read(const base::Pickle* m, - base::PickleIterator* iter, - param_type* r); - static void Log(const param_type& p, std::string* l) {} -}; - -} // namespace IPC - -IPC_ENUM_TRAITS_MAX_VALUE(mojo::test::PickledEnumBlink, - mojo::test::PickledEnumBlink::VALUE_1) - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_PICKLED_TYPES_BLINK_H_ diff --git a/mojo/public/cpp/bindings/tests/pickled_types_chromium.cc b/mojo/public/cpp/bindings/tests/pickled_types_chromium.cc deleted file mode 100644 index 9957c9a..0000000 --- a/mojo/public/cpp/bindings/tests/pickled_types_chromium.cc +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/tests/pickled_types_chromium.h" - -#include "base/pickle.h" - -namespace mojo { -namespace test { - -PickledStructChromium::PickledStructChromium() {} - -PickledStructChromium::PickledStructChromium(int foo, int bar) - : foo_(foo), bar_(bar) {} - -PickledStructChromium::~PickledStructChromium() {} - -bool operator==(const PickledStructChromium& a, - const PickledStructChromium& b) { - return a.foo() == b.foo() && a.bar() == b.bar() && a.baz() == b.baz(); -} - -} // namespace test -} // namespace mojo - -namespace IPC { - -void ParamTraits<mojo::test::PickledStructChromium>::GetSize( - base::PickleSizer* sizer, - const param_type& p) { - sizer->AddInt(); - sizer->AddInt(); -} - -void ParamTraits<mojo::test::PickledStructChromium>::Write( - base::Pickle* m, - const param_type& p) { - m->WriteInt(p.foo()); - m->WriteInt(p.bar()); -} - -bool ParamTraits<mojo::test::PickledStructChromium>::Read( - const base::Pickle* m, - base::PickleIterator* iter, - param_type* p) { - int foo, bar; - if (!iter->ReadInt(&foo) || !iter->ReadInt(&bar)) - return false; - - p->set_foo(foo); - p->set_bar(bar); - return true; -} - -#include "ipc/param_traits_size_macros.h" -IPC_ENUM_TRAITS_MAX_VALUE(mojo::test::PickledEnumChromium, - mojo::test::PickledEnumChromium::VALUE_2) -#include "ipc/param_traits_write_macros.h" -IPC_ENUM_TRAITS_MAX_VALUE(mojo::test::PickledEnumChromium, - mojo::test::PickledEnumChromium::VALUE_2) -#include "ipc/param_traits_read_macros.h" -IPC_ENUM_TRAITS_MAX_VALUE(mojo::test::PickledEnumChromium, - mojo::test::PickledEnumChromium::VALUE_2) -#include "ipc/param_traits_log_macros.h" -IPC_ENUM_TRAITS_MAX_VALUE(mojo::test::PickledEnumChromium, - mojo::test::PickledEnumChromium::VALUE_2) - -} // namespace IPC diff --git a/mojo/public/cpp/bindings/tests/pickled_types_chromium.h b/mojo/public/cpp/bindings/tests/pickled_types_chromium.h deleted file mode 100644 index d9287b6..0000000 --- a/mojo/public/cpp/bindings/tests/pickled_types_chromium.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_PICKLED_TYPES_CHROMIUM_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_PICKLED_TYPES_CHROMIUM_H_ - -#include <stddef.h> - -#include <string> - -#include "base/macros.h" -#include "ipc/ipc_message_macros.h" -#include "ipc/ipc_param_traits.h" - -namespace base { -class Pickle; -class PickleIterator; -class PickleSizer; -} - -namespace mojo { -namespace test { - -// Implementation of types with IPC::ParamTraits for consumers in the greater -// Chromium tree. - -enum class PickledEnumChromium { VALUE_0, VALUE_1, VALUE_2 }; - -class PickledStructChromium { - public: - PickledStructChromium(); - PickledStructChromium(int foo, int bar); - PickledStructChromium(PickledStructChromium&& other) = default; - ~PickledStructChromium(); - - PickledStructChromium& operator=(PickledStructChromium&& other) = default; - - int foo() const { return foo_; } - void set_foo(int foo) { foo_ = foo; } - - int bar() const { return bar_; } - void set_bar(int bar) { bar_ = bar; } - - // The |baz| field should never be serialized. - int baz() const { return baz_; } - void set_baz(int baz) { baz_ = baz; } - - private: - int foo_ = 0; - int bar_ = 0; - int baz_ = 0; - - DISALLOW_COPY_AND_ASSIGN(PickledStructChromium); -}; - -bool operator==(const PickledStructChromium& a, const PickledStructChromium& b); - -} // namespace test -} // namespace mojo - -namespace IPC { - -template <> -struct ParamTraits<mojo::test::PickledStructChromium> { - using param_type = mojo::test::PickledStructChromium; - - static void GetSize(base::PickleSizer* sizer, const param_type& p); - static void Write(base::Pickle* m, const param_type& p); - static bool Read(const base::Pickle* m, - base::PickleIterator* iter, - param_type* r); - static void Log(const param_type& p, std::string* l) {} -}; - -} // namespace IPC - -IPC_ENUM_TRAITS_MAX_VALUE(mojo::test::PickledEnumChromium, - mojo::test::PickledEnumChromium::VALUE_2) - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_PICKLED_TYPES_CHROMIUM_H_ diff --git a/mojo/public/cpp/bindings/tests/rect_blink.h b/mojo/public/cpp/bindings/tests/rect_blink.h deleted file mode 100644 index 7335989..0000000 --- a/mojo/public/cpp/bindings/tests/rect_blink.h +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_BLINK_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_BLINK_H_ - -#include "base/logging.h" - -namespace mojo { -namespace test { - -// An implementation of a hypothetical Rect type specifically for consumers in -// in Blink. Unlike the Chromium variant (see rect_chromium.h) this does not -// support negative origin coordinates and is not copyable. -class RectBlink { - public: - RectBlink() {} - RectBlink(int x, int y, int width, int height) : - x_(x), y_(y), width_(width), height_(height) { - DCHECK_GE(x_, 0); - DCHECK_GE(y_, 0); - DCHECK_GE(width_, 0); - DCHECK_GE(height_, 0); - } - ~RectBlink() {} - - int x() const { return x_; } - void setX(int x) { - DCHECK_GE(x, 0); - x_ = x; - } - - int y() const { return y_; } - void setY(int y) { - DCHECK_GE(y, 0); - y_ = y; - } - - int width() const { return width_; } - void setWidth(int width) { - DCHECK_GE(width, 0); - width_ = width; - } - - int height() const { return height_; } - void setHeight(int height) { - DCHECK_GE(height, 0); - height_ = height; - } - - int computeArea() const { return width_ * height_; } - - bool operator==(const RectBlink& other) const { - return (x() == other.x() && y() == other.y() && width() == other.width() && - height() == other.height()); - } - bool operator!=(const RectBlink& other) const { return !(*this == other); } - - private: - int x_ = 0; - int y_ = 0; - int width_ = 0; - int height_ = 0; -}; - -} // namespace test -} // namespace mojo - -namespace std { - -template <> -struct hash<mojo::test::RectBlink> { - size_t operator()(const mojo::test::RectBlink& value) { - // Terrible hash function: - return (std::hash<int>()(value.x()) ^ std::hash<int>()(value.y()) ^ - std::hash<int>()(value.width()) ^ std::hash<int>()(value.height())); - } -}; - -} // namespace std - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_BLINK_H_ diff --git a/mojo/public/cpp/bindings/tests/rect_blink.typemap b/mojo/public/cpp/bindings/tests/rect_blink.typemap deleted file mode 100644 index 657ea1a..0000000 --- a/mojo/public/cpp/bindings/tests/rect_blink.typemap +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//mojo/public/interfaces/bindings/tests/rect.mojom" -public_headers = [ - "//mojo/public/cpp/bindings/tests/rect_blink.h", - "//mojo/public/cpp/bindings/tests/shared_rect.h", -] -traits_headers = [ - "//mojo/public/cpp/bindings/tests/rect_blink_traits.h", - "//mojo/public/cpp/bindings/tests/shared_rect_traits.h", -] - -type_mappings = [ - "mojo.test.TypemappedRect=mojo::test::RectBlink[hashable]", - "mojo.test.SharedTypemappedRect=mojo::test::SharedRect", -] diff --git a/mojo/public/cpp/bindings/tests/rect_blink_traits.h b/mojo/public/cpp/bindings/tests/rect_blink_traits.h deleted file mode 100644 index 7258739..0000000 --- a/mojo/public/cpp/bindings/tests/rect_blink_traits.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_BLINK_TRAITS_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_BLINK_TRAITS_H_ - -#include "mojo/public/cpp/bindings/struct_traits.h" -#include "mojo/public/cpp/bindings/tests/rect_blink.h" -#include "mojo/public/interfaces/bindings/tests/rect.mojom-blink.h" - -namespace mojo { - -template <> -struct StructTraits<test::TypemappedRectDataView, test::RectBlink> { - static int x(const test::RectBlink& r) { return r.x(); } - static int y(const test::RectBlink& r) { return r.y(); } - static int width(const test::RectBlink& r) { return r.width(); } - static int height(const test::RectBlink& r) { return r.height(); } - - static bool Read(test::TypemappedRectDataView r, test::RectBlink* out) { - if (r.x() < 0 || r.y() < 0 || r.width() < 0 || r.height() < 0) { - return false; - } - out->setX(r.x()); - out->setY(r.y()); - out->setWidth(r.width()); - out->setHeight(r.height()); - return true; - } -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_BLINK_TRAITS_H_ diff --git a/mojo/public/cpp/bindings/tests/rect_chromium.h b/mojo/public/cpp/bindings/tests/rect_chromium.h deleted file mode 100644 index d2e0a3e..0000000 --- a/mojo/public/cpp/bindings/tests/rect_chromium.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_CHROMIUM_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_CHROMIUM_H_ - -#include "base/logging.h" - -namespace mojo { -namespace test { - -// An implementation of a hypothetical Rect type specifically for consumers in -// in Chromium. -class RectChromium { - public: - RectChromium() {} - RectChromium(const RectChromium& other) - : x_(other.x_), - y_(other.y_), - width_(other.width_), - height_(other.height_) {} - RectChromium(int x, int y, int width, int height) : - x_(x), y_(y), width_(width), height_(height) { - DCHECK_GE(width_, 0); - DCHECK_GE(height_, 0); - } - ~RectChromium() {} - - RectChromium& operator=(const RectChromium& other) { - x_ = other.x_; - y_ = other.y_; - width_ = other.width_; - height_ = other.height_; - return *this; - } - - int x() const { return x_; } - void set_x(int x) { x_ = x; } - - int y() const { return y_; } - void set_y(int y) { y_ = y; } - - int width() const { return width_; } - void set_width(int width) { - DCHECK_GE(width, 0); - width_ = width; - } - - int height() const { return height_; } - void set_height(int height) { - DCHECK_GE(height, 0); - height_ = height; - } - - int GetArea() const { return width_ * height_; } - - bool operator==(const RectChromium& other) const { - return (x() == other.x() && y() == other.y() && width() == other.width() && - height() == other.height()); - } - bool operator!=(const RectChromium& other) const { return !(*this == other); } - - private: - int x_ = 0; - int y_ = 0; - int width_ = 0; - int height_ = 0; -}; - -} // namespace test -} // namespace mojo - -namespace std { - -template <> -struct hash<mojo::test::RectChromium> { - size_t operator()(const mojo::test::RectChromium& value) { - // Terrible hash function: - return (std::hash<int>()(value.x()) ^ std::hash<int>()(value.y()) ^ - std::hash<int>()(value.width()) ^ std::hash<int>()(value.height())); - } -}; - -} // namespace std - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_CHROMIUM_H_ diff --git a/mojo/public/cpp/bindings/tests/rect_chromium.typemap b/mojo/public/cpp/bindings/tests/rect_chromium.typemap deleted file mode 100644 index 7e5df84..0000000 --- a/mojo/public/cpp/bindings/tests/rect_chromium.typemap +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//mojo/public/interfaces/bindings/tests/rect.mojom" -public_headers = [ - "//mojo/public/cpp/bindings/tests/rect_chromium.h", - "//mojo/public/cpp/bindings/tests/shared_rect.h", -] -traits_headers = [ - "//mojo/public/cpp/bindings/tests/rect_chromium_traits.h", - "//mojo/public/cpp/bindings/tests/shared_rect_traits.h", -] - -type_mappings = [ - "mojo.test.TypemappedRect=mojo::test::RectChromium[hashable]", - "mojo.test.SharedTypemappedRect=mojo::test::SharedRect", -] diff --git a/mojo/public/cpp/bindings/tests/rect_chromium_traits.h b/mojo/public/cpp/bindings/tests/rect_chromium_traits.h deleted file mode 100644 index b446d7d..0000000 --- a/mojo/public/cpp/bindings/tests/rect_chromium_traits.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_CHROMIUM_TRAITS_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_CHROMIUM_TRAITS_H_ - -#include "mojo/public/cpp/bindings/struct_traits.h" -#include "mojo/public/cpp/bindings/tests/rect_chromium.h" -#include "mojo/public/interfaces/bindings/tests/rect.mojom.h" - -namespace mojo { - -template <> -struct StructTraits<test::TypemappedRectDataView, test::RectChromium> { - static int x(const test::RectChromium& r) { return r.x(); } - static int y(const test::RectChromium& r) { return r.y(); } - static int width(const test::RectChromium& r) { return r.width(); } - static int height(const test::RectChromium& r) { return r.height(); } - - static bool Read(test::TypemappedRectDataView r, test::RectChromium* out) { - if (r.width() < 0 || r.height() < 0) - return false; - out->set_x(r.x()); - out->set_y(r.y()); - out->set_width(r.width()); - out->set_height(r.height()); - return true; - } -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_RECT_CHROMIUM_TRAITS_H_ diff --git a/mojo/public/cpp/bindings/tests/report_bad_message_unittest.cc b/mojo/public/cpp/bindings/tests/report_bad_message_unittest.cc deleted file mode 100644 index 1bf3f7a..0000000 --- a/mojo/public/cpp/bindings/tests/report_bad_message_unittest.cc +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/bind.h" -#include "base/callback.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "mojo/edk/embedder/embedder.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/message.h" -#include "mojo/public/interfaces/bindings/tests/test_bad_messages.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -class TestBadMessagesImpl : public TestBadMessages { - public: - TestBadMessagesImpl() : binding_(this) {} - ~TestBadMessagesImpl() override {} - - void BindImpl(TestBadMessagesRequest request) { - binding_.Bind(std::move(request)); - } - - const ReportBadMessageCallback& bad_message_callback() { - return bad_message_callback_; - } - - private: - // TestBadMessages: - void RejectEventually(const RejectEventuallyCallback& callback) override { - bad_message_callback_ = GetBadMessageCallback(); - callback.Run(); - } - - void RequestResponse(const RequestResponseCallback& callback) override { - callback.Run(); - } - - void RejectSync(const RejectSyncCallback& callback) override { - callback.Run(); - ReportBadMessage("go away"); - } - - void RequestResponseSync( - const RequestResponseSyncCallback& callback) override { - callback.Run(); - } - - ReportBadMessageCallback bad_message_callback_; - mojo::Binding<TestBadMessages> binding_; - - DISALLOW_COPY_AND_ASSIGN(TestBadMessagesImpl); -}; - -class ReportBadMessageTest : public testing::Test { - public: - ReportBadMessageTest() {} - - void SetUp() override { - mojo::edk::SetDefaultProcessErrorCallback( - base::Bind(&ReportBadMessageTest::OnProcessError, - base::Unretained(this))); - - impl_.BindImpl(MakeRequest(&proxy_)); - } - - void TearDown() override { - mojo::edk::SetDefaultProcessErrorCallback( - mojo::edk::ProcessErrorCallback()); - } - - TestBadMessages* proxy() { return proxy_.get(); } - - TestBadMessagesImpl* impl() { return &impl_; } - - void SetErrorHandler(const base::Closure& handler) { - error_handler_ = handler; - } - - private: - void OnProcessError(const std::string& error) { - if (!error_handler_.is_null()) - error_handler_.Run(); - } - - TestBadMessagesPtr proxy_; - TestBadMessagesImpl impl_; - base::Closure error_handler_; - base::MessageLoop message_loop; -}; - -TEST_F(ReportBadMessageTest, Request) { - // Verify that basic immediate error reporting works. - bool error = false; - SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error)); - EXPECT_TRUE(proxy()->RejectSync()); - EXPECT_TRUE(error); -} - -TEST_F(ReportBadMessageTest, RequestAsync) { - bool error = false; - SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error)); - - // This should capture a bad message reporting callback in the impl. - base::RunLoop loop; - proxy()->RejectEventually(loop.QuitClosure()); - loop.Run(); - - EXPECT_FALSE(error); - - // Now we can run the callback and it should trigger a bad message report. - DCHECK(!impl()->bad_message_callback().is_null()); - impl()->bad_message_callback().Run("bad!"); - EXPECT_TRUE(error); -} - -TEST_F(ReportBadMessageTest, Response) { - bool error = false; - SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error)); - - base::RunLoop loop; - proxy()->RequestResponse( - base::Bind([] (const base::Closure& quit) { - // Report a bad message inside the response callback. This should - // trigger the error handler. - ReportBadMessage("no way!"); - quit.Run(); - }, - loop.QuitClosure())); - loop.Run(); - - EXPECT_TRUE(error); -} - -TEST_F(ReportBadMessageTest, ResponseAsync) { - bool error = false; - SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error)); - - ReportBadMessageCallback bad_message_callback; - base::RunLoop loop; - proxy()->RequestResponse( - base::Bind([] (const base::Closure& quit, - ReportBadMessageCallback* callback) { - // Capture the bad message callback inside the response callback. - *callback = GetBadMessageCallback(); - quit.Run(); - }, - loop.QuitClosure(), &bad_message_callback)); - loop.Run(); - - EXPECT_FALSE(error); - - // Invoking this callback should report a bad message and trigger the error - // handler immediately. - bad_message_callback.Run("this message is bad and should feel bad"); - EXPECT_TRUE(error); -} - -TEST_F(ReportBadMessageTest, ResponseSync) { - bool error = false; - SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error)); - - SyncMessageResponseContext context; - proxy()->RequestResponseSync(); - - EXPECT_FALSE(error); - context.ReportBadMessage("i don't like this response"); - EXPECT_TRUE(error); -} - -TEST_F(ReportBadMessageTest, ResponseSyncDeferred) { - bool error = false; - SetErrorHandler(base::Bind([] (bool* flag) { *flag = true; }, &error)); - - ReportBadMessageCallback bad_message_callback; - { - SyncMessageResponseContext context; - proxy()->RequestResponseSync(); - bad_message_callback = context.GetBadMessageCallback(); - } - - EXPECT_FALSE(error); - bad_message_callback.Run("nope nope nope"); - EXPECT_TRUE(error); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/request_response_unittest.cc b/mojo/public/cpp/bindings/tests/request_response_unittest.cc deleted file mode 100644 index 43b8f0d..0000000 --- a/mojo/public/cpp/bindings/tests/request_response_unittest.cc +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stdint.h> -#include <utility> - -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/test_support/test_utils.h" -#include "mojo/public/interfaces/bindings/tests/sample_import.mojom.h" -#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -class ProviderImpl : public sample::Provider { - public: - explicit ProviderImpl(InterfaceRequest<sample::Provider> request) - : binding_(this, std::move(request)) {} - - void EchoString(const std::string& a, - const EchoStringCallback& callback) override { - EchoStringCallback callback_copy; - // Make sure operator= is used. - callback_copy = callback; - callback_copy.Run(a); - } - - void EchoStrings(const std::string& a, - const std::string& b, - const EchoStringsCallback& callback) override { - callback.Run(a, b); - } - - void EchoMessagePipeHandle( - ScopedMessagePipeHandle a, - const EchoMessagePipeHandleCallback& callback) override { - callback.Run(std::move(a)); - } - - void EchoEnum(sample::Enum a, const EchoEnumCallback& callback) override { - callback.Run(a); - } - - void EchoInt(int32_t a, const EchoIntCallback& callback) override { - callback.Run(a); - } - - Binding<sample::Provider> binding_; -}; - -void RecordString(std::string* storage, - const base::Closure& closure, - const std::string& str) { - *storage = str; - closure.Run(); -} - -void RecordStrings(std::string* storage, - const base::Closure& closure, - const std::string& a, - const std::string& b) { - *storage = a + b; - closure.Run(); -} - -void WriteToMessagePipe(const char* text, - const base::Closure& closure, - ScopedMessagePipeHandle handle) { - WriteTextMessage(handle.get(), text); - closure.Run(); -} - -void RecordEnum(sample::Enum* storage, - const base::Closure& closure, - sample::Enum value) { - *storage = value; - closure.Run(); -} - -class RequestResponseTest : public testing::Test { - public: - RequestResponseTest() {} - ~RequestResponseTest() override { base::RunLoop().RunUntilIdle(); } - - void PumpMessages() { base::RunLoop().RunUntilIdle(); } - - private: - base::MessageLoop loop_; -}; - -TEST_F(RequestResponseTest, EchoString) { - sample::ProviderPtr provider; - ProviderImpl provider_impl(MakeRequest(&provider)); - - std::string buf; - base::RunLoop run_loop; - provider->EchoString("hello", - base::Bind(&RecordString, &buf, run_loop.QuitClosure())); - - run_loop.Run(); - - EXPECT_EQ(std::string("hello"), buf); -} - -TEST_F(RequestResponseTest, EchoStrings) { - sample::ProviderPtr provider; - ProviderImpl provider_impl(MakeRequest(&provider)); - - std::string buf; - base::RunLoop run_loop; - provider->EchoStrings("hello", " world", base::Bind(&RecordStrings, &buf, - run_loop.QuitClosure())); - - run_loop.Run(); - - EXPECT_EQ(std::string("hello world"), buf); -} - -TEST_F(RequestResponseTest, EchoMessagePipeHandle) { - sample::ProviderPtr provider; - ProviderImpl provider_impl(MakeRequest(&provider)); - - MessagePipe pipe2; - base::RunLoop run_loop; - provider->EchoMessagePipeHandle( - std::move(pipe2.handle1), - base::Bind(&WriteToMessagePipe, "hello", run_loop.QuitClosure())); - - run_loop.Run(); - - std::string value; - ReadTextMessage(pipe2.handle0.get(), &value); - - EXPECT_EQ(std::string("hello"), value); -} - -TEST_F(RequestResponseTest, EchoEnum) { - sample::ProviderPtr provider; - ProviderImpl provider_impl(MakeRequest(&provider)); - - sample::Enum value; - base::RunLoop run_loop; - provider->EchoEnum(sample::Enum::VALUE, - base::Bind(&RecordEnum, &value, run_loop.QuitClosure())); - run_loop.Run(); - - EXPECT_EQ(sample::Enum::VALUE, value); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/router_test_util.cc b/mojo/public/cpp/bindings/tests/router_test_util.cc deleted file mode 100644 index 9bab1cb..0000000 --- a/mojo/public/cpp/bindings/tests/router_test_util.cc +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/tests/router_test_util.h" - -#include <stddef.h> -#include <stdint.h> -#include <string.h> - -#include "mojo/public/cpp/bindings/lib/message_builder.h" -#include "mojo/public/cpp/bindings/tests/message_queue.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { - -void AllocRequestMessage(uint32_t name, const char* text, Message* message) { - size_t payload_size = strlen(text) + 1; // Plus null terminator. - internal::MessageBuilder builder(name, Message::kFlagExpectsResponse, - payload_size, 0); - memcpy(builder.buffer()->Allocate(payload_size), text, payload_size); - *message = std::move(*builder.message()); -} - -void AllocResponseMessage(uint32_t name, - const char* text, - uint64_t request_id, - Message* message) { - size_t payload_size = strlen(text) + 1; // Plus null terminator. - internal::MessageBuilder builder(name, Message::kFlagIsResponse, payload_size, - 0); - builder.message()->set_request_id(request_id); - memcpy(builder.buffer()->Allocate(payload_size), text, payload_size); - *message = std::move(*builder.message()); -} - -MessageAccumulator::MessageAccumulator(MessageQueue* queue, - const base::Closure& closure) - : queue_(queue), closure_(closure) {} - -MessageAccumulator::~MessageAccumulator() {} - -bool MessageAccumulator::Accept(Message* message) { - queue_->Push(message); - if (!closure_.is_null()) { - closure_.Run(); - closure_.Reset(); - } - return true; -} - -ResponseGenerator::ResponseGenerator() {} - -bool ResponseGenerator::Accept(Message* message) { - return false; -} - -bool ResponseGenerator::AcceptWithResponder( - Message* message, - std::unique_ptr<MessageReceiverWithStatus> responder) { - EXPECT_TRUE(message->has_flag(Message::kFlagExpectsResponse)); - - bool result = SendResponse(message->name(), message->request_id(), - reinterpret_cast<const char*>(message->payload()), - responder.get()); - EXPECT_TRUE(responder->IsValid()); - return result; -} - -bool ResponseGenerator::SendResponse(uint32_t name, - uint64_t request_id, - const char* request_string, - MessageReceiver* responder) { - Message response; - std::string response_string(request_string); - response_string += " world!"; - AllocResponseMessage(name, response_string.c_str(), request_id, &response); - - return responder->Accept(&response); -} - -LazyResponseGenerator::LazyResponseGenerator(const base::Closure& closure) - : responder_(nullptr), name_(0), request_id_(0), closure_(closure) {} - -LazyResponseGenerator::~LazyResponseGenerator() = default; - -bool LazyResponseGenerator::AcceptWithResponder( - Message* message, - std::unique_ptr<MessageReceiverWithStatus> responder) { - name_ = message->name(); - request_id_ = message->request_id(); - request_string_ = - std::string(reinterpret_cast<const char*>(message->payload())); - responder_ = std::move(responder); - if (!closure_.is_null()) { - closure_.Run(); - closure_.Reset(); - } - return true; -} - -void LazyResponseGenerator::Complete(bool send_response) { - if (send_response) { - SendResponse(name_, request_id_, request_string_.c_str(), responder_.get()); - } - responder_ = nullptr; -} - -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/router_test_util.h b/mojo/public/cpp/bindings/tests/router_test_util.h deleted file mode 100644 index dd6aff6..0000000 --- a/mojo/public/cpp/bindings/tests/router_test_util.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_ROUTER_TEST_UTIL_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_ROUTER_TEST_UTIL_H_ - -#include <stdint.h> - -#include <string> - -#include "base/callback.h" -#include "mojo/public/cpp/bindings/message.h" - -namespace mojo { -namespace test { - -class MessageQueue; - -void AllocRequestMessage(uint32_t name, const char* text, Message* message); -void AllocResponseMessage(uint32_t name, - const char* text, - uint64_t request_id, - Message* message); - -class MessageAccumulator : public MessageReceiver { - public: - MessageAccumulator(MessageQueue* queue, - const base::Closure& closure = base::Closure()); - ~MessageAccumulator() override; - - bool Accept(Message* message) override; - - private: - MessageQueue* queue_; - base::Closure closure_; -}; - -class ResponseGenerator : public MessageReceiverWithResponderStatus { - public: - ResponseGenerator(); - - bool Accept(Message* message) override; - - bool AcceptWithResponder( - Message* message, - std::unique_ptr<MessageReceiverWithStatus> responder) override; - bool SendResponse(uint32_t name, - uint64_t request_id, - const char* request_string, - MessageReceiver* responder); -}; - -class LazyResponseGenerator : public ResponseGenerator { - public: - explicit LazyResponseGenerator( - const base::Closure& closure = base::Closure()); - - ~LazyResponseGenerator() override; - - bool AcceptWithResponder( - Message* message, - std::unique_ptr<MessageReceiverWithStatus> responder) override; - - bool has_responder() const { return !!responder_; } - - bool responder_is_valid() const { return responder_->IsValid(); } - - void set_closure(const base::Closure& closure) { closure_ = closure; } - - // Sends the response and delete the responder. - void CompleteWithResponse() { Complete(true); } - - // Deletes the responder without sending a response. - void CompleteWithoutResponse() { Complete(false); } - - private: - // Completes the request handling by deleting responder_. Optionally - // also sends a response. - void Complete(bool send_response); - - std::unique_ptr<MessageReceiverWithStatus> responder_; - uint32_t name_; - uint64_t request_id_; - std::string request_string_; - base::Closure closure_; -}; - -} // namespace test -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_ROUTER_TEST_UTIL_H_ diff --git a/mojo/public/cpp/bindings/tests/sample_service_unittest.cc b/mojo/public/cpp/bindings/tests/sample_service_unittest.cc deleted file mode 100644 index 1f95a27..0000000 --- a/mojo/public/cpp/bindings/tests/sample_service_unittest.cc +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> -#include <algorithm> -#include <ostream> -#include <string> -#include <utility> - -#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { - -template <> -struct TypeConverter<int32_t, sample::BarPtr> { - static int32_t Convert(const sample::BarPtr& bar) { - return static_cast<int32_t>(bar->alpha) << 16 | - static_cast<int32_t>(bar->beta) << 8 | - static_cast<int32_t>(bar->gamma); - } -}; - -} // namespace mojo - -namespace sample { -namespace { - -// Set this variable to true to print the message in hex. -bool g_dump_message_as_hex = false; - -// Set this variable to true to print the message in human readable form. -bool g_dump_message_as_text = false; - -// Make a sample |Foo|. -FooPtr MakeFoo() { - std::string name("foopy"); - - BarPtr bar(Bar::New(20, 40, 60, Bar::Type::VERTICAL)); - - std::vector<BarPtr> extra_bars(3); - for (size_t i = 0; i < extra_bars.size(); ++i) { - Bar::Type type = i % 2 == 0 ? Bar::Type::VERTICAL : Bar::Type::HORIZONTAL; - uint8_t base = static_cast<uint8_t>(i * 100); - extra_bars[i] = Bar::New(base, base + 20, base + 40, type); - } - - std::vector<uint8_t> data(10); - for (size_t i = 0; i < data.size(); ++i) - data[i] = static_cast<uint8_t>(data.size() - i); - - std::vector<mojo::ScopedDataPipeConsumerHandle> input_streams(2); - std::vector<mojo::ScopedDataPipeProducerHandle> output_streams(2); - for (size_t i = 0; i < input_streams.size(); ++i) { - MojoCreateDataPipeOptions options; - options.struct_size = sizeof(MojoCreateDataPipeOptions); - options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; - options.element_num_bytes = 1; - options.capacity_num_bytes = 1024; - mojo::ScopedDataPipeProducerHandle producer; - mojo::ScopedDataPipeConsumerHandle consumer; - mojo::CreateDataPipe(&options, &producer, &consumer); - input_streams[i] = std::move(consumer); - output_streams[i] = std::move(producer); - } - - std::vector<std::vector<bool>> array_of_array_of_bools(2); - for (size_t i = 0; i < 2; ++i) { - std::vector<bool> array_of_bools(2); - for (size_t j = 0; j < 2; ++j) - array_of_bools[j] = j; - array_of_array_of_bools[i] = std::move(array_of_bools); - } - - mojo::MessagePipe pipe; - return Foo::New(name, 1, 2, false, true, false, std::move(bar), - std::move(extra_bars), std::move(data), - std::move(pipe.handle1), std::move(input_streams), - std::move(output_streams), std::move(array_of_array_of_bools), - base::nullopt, base::nullopt); -} - -// Check that the given |Foo| is identical to the one made by |MakeFoo()|. -void CheckFoo(const Foo& foo) { - const std::string kName("foopy"); - EXPECT_EQ(kName.size(), foo.name.size()); - for (size_t i = 0; i < std::min(kName.size(), foo.name.size()); i++) { - // Test both |operator[]| and |at|. - EXPECT_EQ(kName[i], foo.name.at(i)) << i; - EXPECT_EQ(kName[i], foo.name[i]) << i; - } - EXPECT_EQ(kName, foo.name); - - EXPECT_EQ(1, foo.x); - EXPECT_EQ(2, foo.y); - EXPECT_FALSE(foo.a); - EXPECT_TRUE(foo.b); - EXPECT_FALSE(foo.c); - - EXPECT_EQ(20, foo.bar->alpha); - EXPECT_EQ(40, foo.bar->beta); - EXPECT_EQ(60, foo.bar->gamma); - EXPECT_EQ(Bar::Type::VERTICAL, foo.bar->type); - - EXPECT_EQ(3u, foo.extra_bars->size()); - for (size_t i = 0; i < foo.extra_bars->size(); i++) { - uint8_t base = static_cast<uint8_t>(i * 100); - Bar::Type type = i % 2 == 0 ? Bar::Type::VERTICAL : Bar::Type::HORIZONTAL; - EXPECT_EQ(base, (*foo.extra_bars)[i]->alpha) << i; - EXPECT_EQ(base + 20, (*foo.extra_bars)[i]->beta) << i; - EXPECT_EQ(base + 40, (*foo.extra_bars)[i]->gamma) << i; - EXPECT_EQ(type, (*foo.extra_bars)[i]->type) << i; - } - - EXPECT_EQ(10u, foo.data->size()); - for (size_t i = 0; i < foo.data->size(); ++i) { - EXPECT_EQ(static_cast<uint8_t>(foo.data->size() - i), (*foo.data)[i]) << i; - } - - EXPECT_TRUE(foo.input_streams); - EXPECT_EQ(2u, foo.input_streams->size()); - - EXPECT_TRUE(foo.output_streams); - EXPECT_EQ(2u, foo.output_streams->size()); - - EXPECT_EQ(2u, foo.array_of_array_of_bools->size()); - for (size_t i = 0; i < foo.array_of_array_of_bools->size(); ++i) { - EXPECT_EQ(2u, (*foo.array_of_array_of_bools)[i].size()); - for (size_t j = 0; j < (*foo.array_of_array_of_bools)[i].size(); ++j) { - EXPECT_EQ(bool(j), (*foo.array_of_array_of_bools)[i][j]); - } - } -} - -void PrintSpacer(int depth) { - for (int i = 0; i < depth; ++i) - std::cout << " "; -} - -void Print(int depth, const char* name, bool value) { - PrintSpacer(depth); - std::cout << name << ": " << (value ? "true" : "false") << std::endl; -} - -void Print(int depth, const char* name, int32_t value) { - PrintSpacer(depth); - std::cout << name << ": " << value << std::endl; -} - -void Print(int depth, const char* name, uint8_t value) { - PrintSpacer(depth); - std::cout << name << ": " << uint32_t(value) << std::endl; -} - -template <typename H> -void Print(int depth, - const char* name, - const mojo::ScopedHandleBase<H>& value) { - PrintSpacer(depth); - std::cout << name << ": 0x" << std::hex << value.get().value() << std::endl; -} - -void Print(int depth, const char* name, const std::string& str) { - PrintSpacer(depth); - std::cout << name << ": \"" << str << "\"" << std::endl; -} - -void Print(int depth, const char* name, const BarPtr& bar) { - PrintSpacer(depth); - std::cout << name << ":" << std::endl; - if (!bar.is_null()) { - ++depth; - Print(depth, "alpha", bar->alpha); - Print(depth, "beta", bar->beta); - Print(depth, "gamma", bar->gamma); - Print(depth, "packed", bar.To<int32_t>()); - --depth; - } -} - -template <typename T> -void Print(int depth, const char* name, const std::vector<T>& array) { - PrintSpacer(depth); - std::cout << name << ":" << std::endl; - ++depth; - for (size_t i = 0; i < array.size(); ++i) { - std::stringstream buf; - buf << i; - Print(depth, buf.str().data(), array.at(i)); - } - --depth; -} - -template <typename T> -void Print(int depth, - const char* name, - const base::Optional<std::vector<T>>& array) { - if (array) - Print(depth, name, *array); - else - Print(depth, name, std::vector<T>()); -} - -void Print(int depth, const char* name, const FooPtr& foo) { - PrintSpacer(depth); - std::cout << name << ":" << std::endl; - if (!foo.is_null()) { - ++depth; - Print(depth, "name", foo->name); - Print(depth, "x", foo->x); - Print(depth, "y", foo->y); - Print(depth, "a", foo->a); - Print(depth, "b", foo->b); - Print(depth, "c", foo->c); - Print(depth, "bar", foo->bar); - Print(depth, "extra_bars", foo->extra_bars); - Print(depth, "data", foo->data); - Print(depth, "source", foo->source); - Print(depth, "input_streams", foo->input_streams); - Print(depth, "output_streams", foo->output_streams); - Print(depth, "array_of_array_of_bools", foo->array_of_array_of_bools); - --depth; - } -} - -void DumpHex(const uint8_t* bytes, uint32_t num_bytes) { - for (uint32_t i = 0; i < num_bytes; ++i) { - std::cout << std::setw(2) << std::setfill('0') << std::hex - << uint32_t(bytes[i]); - - if (i % 16 == 15) { - std::cout << std::endl; - continue; - } - - if (i % 2 == 1) - std::cout << " "; - if (i % 8 == 7) - std::cout << " "; - } -} - -class ServiceImpl : public Service { - public: - void Frobinate(FooPtr foo, - BazOptions baz, - PortPtr port, - const Service::FrobinateCallback& callback) override { - // Users code goes here to handle the incoming Frobinate message. - - // We mainly check that we're given the expected arguments. - EXPECT_FALSE(foo.is_null()); - if (!foo.is_null()) - CheckFoo(*foo); - EXPECT_EQ(BazOptions::EXTRA, baz); - - if (g_dump_message_as_text) { - // Also dump the Foo structure and all of its members. - std::cout << "Frobinate:" << std::endl; - int depth = 1; - Print(depth, "foo", foo); - Print(depth, "baz", static_cast<int32_t>(baz)); - Print(depth, "port", port.get()); - } - callback.Run(5); - } - - void GetPort(mojo::InterfaceRequest<Port> port_request) override {} -}; - -class ServiceProxyImpl : public ServiceProxy { - public: - explicit ServiceProxyImpl(mojo::MessageReceiverWithResponder* receiver) - : ServiceProxy(receiver) {} -}; - -class SimpleMessageReceiver : public mojo::MessageReceiverWithResponder { - public: - bool Accept(mojo::Message* message) override { - // Imagine some IPC happened here. - - if (g_dump_message_as_hex) { - DumpHex(reinterpret_cast<const uint8_t*>(message->data()), - message->data_num_bytes()); - } - - // In the receiving process, an implementation of ServiceStub is known to - // the system. It receives the incoming message. - ServiceImpl impl; - - ServiceStub<> stub; - stub.set_sink(&impl); - return stub.Accept(message); - } - - bool AcceptWithResponder( - mojo::Message* message, - std::unique_ptr<mojo::MessageReceiver> responder) override { - return false; - } -}; - -using BindingsSampleTest = testing::Test; - -TEST_F(BindingsSampleTest, Basic) { - SimpleMessageReceiver receiver; - - // User has a proxy to a Service somehow. - Service* service = new ServiceProxyImpl(&receiver); - - // User constructs a message to send. - - // Notice that it doesn't matter in what order the structs / arrays are - // allocated. Here, the various members of Foo are allocated before Foo is - // allocated. - - FooPtr foo = MakeFoo(); - CheckFoo(*foo); - - PortPtr port; - service->Frobinate(std::move(foo), Service::BazOptions::EXTRA, - std::move(port), Service::FrobinateCallback()); - - delete service; -} - -TEST_F(BindingsSampleTest, DefaultValues) { - DefaultsTestPtr defaults(DefaultsTest::New()); - EXPECT_EQ(-12, defaults->a0); - EXPECT_EQ(kTwelve, defaults->a1); - EXPECT_EQ(1234, defaults->a2); - EXPECT_EQ(34567U, defaults->a3); - EXPECT_EQ(123456, defaults->a4); - EXPECT_EQ(3456789012U, defaults->a5); - EXPECT_EQ(-111111111111LL, defaults->a6); - EXPECT_EQ(9999999999999999999ULL, defaults->a7); - EXPECT_EQ(0x12345, defaults->a8); - EXPECT_EQ(-0x12345, defaults->a9); - EXPECT_EQ(1234, defaults->a10); - EXPECT_TRUE(defaults->a11); - EXPECT_FALSE(defaults->a12); - EXPECT_FLOAT_EQ(123.25f, defaults->a13); - EXPECT_DOUBLE_EQ(1234567890.123, defaults->a14); - EXPECT_DOUBLE_EQ(1E10, defaults->a15); - EXPECT_DOUBLE_EQ(-1.2E+20, defaults->a16); - EXPECT_DOUBLE_EQ(1.23E-20, defaults->a17); - EXPECT_TRUE(defaults->a18.empty()); - EXPECT_TRUE(defaults->a19.empty()); - EXPECT_EQ(Bar::Type::BOTH, defaults->a20); - EXPECT_TRUE(defaults->a21.is_null()); - ASSERT_FALSE(defaults->a22.is_null()); - EXPECT_EQ(imported::Shape::RECTANGLE, defaults->a22->shape); - EXPECT_EQ(imported::Color::BLACK, defaults->a22->color); - EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, defaults->a23); - EXPECT_EQ(0x123456789, defaults->a24); - EXPECT_EQ(-0x123456789, defaults->a25); -} - -} // namespace -} // namespace sample diff --git a/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc b/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc deleted file mode 100644 index 275f10f..0000000 --- a/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Serialization warnings are only recorded when DLOG is enabled. -#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) - -#include <stddef.h> -#include <utility> - -#include "mojo/public/cpp/bindings/lib/array_internal.h" -#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" -#include "mojo/public/cpp/bindings/lib/serialization.h" -#include "mojo/public/cpp/bindings/lib/validation_errors.h" -#include "mojo/public/cpp/system/message_pipe.h" -#include "mojo/public/interfaces/bindings/tests/serialization_test_structs.mojom.h" -#include "mojo/public/interfaces/bindings/tests/test_unions.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -using mojo::internal::ContainerValidateParams; - -// Creates an array of arrays of handles (2 X 3) for testing. -std::vector<base::Optional<std::vector<ScopedHandle>>> -CreateTestNestedHandleArray() { - std::vector<base::Optional<std::vector<ScopedHandle>>> array(2); - for (size_t i = 0; i < array.size(); ++i) { - std::vector<ScopedHandle> nested_array(3); - for (size_t j = 0; j < nested_array.size(); ++j) { - MessagePipe pipe; - nested_array[j] = ScopedHandle::From(std::move(pipe.handle1)); - } - array[i].emplace(std::move(nested_array)); - } - - return array; -} - -class SerializationWarningTest : public testing::Test { - public: - ~SerializationWarningTest() override {} - - protected: - template <typename T> - void TestWarning(T obj, mojo::internal::ValidationError expected_warning) { - using MojomType = typename T::Struct::DataView; - - warning_observer_.set_last_warning(mojo::internal::VALIDATION_ERROR_NONE); - - mojo::internal::SerializationContext context; - mojo::internal::FixedBufferForTesting buf( - mojo::internal::PrepareToSerialize<MojomType>(obj, &context)); - typename mojo::internal::MojomTypeTraits<MojomType>::Data* data; - mojo::internal::Serialize<MojomType>(obj, &buf, &data, &context); - - EXPECT_EQ(expected_warning, warning_observer_.last_warning()); - } - - template <typename MojomType, typename T> - void TestArrayWarning(T obj, - mojo::internal::ValidationError expected_warning, - const ContainerValidateParams* validate_params) { - warning_observer_.set_last_warning(mojo::internal::VALIDATION_ERROR_NONE); - - mojo::internal::SerializationContext context; - mojo::internal::FixedBufferForTesting buf( - mojo::internal::PrepareToSerialize<MojomType>(obj, &context)); - typename mojo::internal::MojomTypeTraits<MojomType>::Data* data; - mojo::internal::Serialize<MojomType>(obj, &buf, &data, validate_params, - &context); - - EXPECT_EQ(expected_warning, warning_observer_.last_warning()); - } - - template <typename T> - void TestUnionWarning(T obj, - mojo::internal::ValidationError expected_warning) { - using MojomType = typename T::Struct::DataView; - - warning_observer_.set_last_warning(mojo::internal::VALIDATION_ERROR_NONE); - - mojo::internal::SerializationContext context; - mojo::internal::FixedBufferForTesting buf( - mojo::internal::PrepareToSerialize<MojomType>(obj, false, &context)); - typename mojo::internal::MojomTypeTraits<MojomType>::Data* data; - mojo::internal::Serialize<MojomType>(obj, &buf, &data, false, &context); - - EXPECT_EQ(expected_warning, warning_observer_.last_warning()); - } - - mojo::internal::SerializationWarningObserverForTesting warning_observer_; -}; - -TEST_F(SerializationWarningTest, HandleInStruct) { - Struct2Ptr test_struct(Struct2::New()); - EXPECT_FALSE(test_struct->hdl.is_valid()); - - TestWarning(std::move(test_struct), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE); - - test_struct = Struct2::New(); - MessagePipe pipe; - test_struct->hdl = ScopedHandle::From(std::move(pipe.handle1)); - - TestWarning(std::move(test_struct), mojo::internal::VALIDATION_ERROR_NONE); -} - -TEST_F(SerializationWarningTest, StructInStruct) { - Struct3Ptr test_struct(Struct3::New()); - EXPECT_TRUE(!test_struct->struct_1); - - TestWarning(std::move(test_struct), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); - - test_struct = Struct3::New(); - test_struct->struct_1 = Struct1::New(); - - TestWarning(std::move(test_struct), mojo::internal::VALIDATION_ERROR_NONE); -} - -TEST_F(SerializationWarningTest, ArrayOfStructsInStruct) { - Struct4Ptr test_struct(Struct4::New()); - test_struct->data.resize(1); - - TestWarning(std::move(test_struct), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); - - test_struct = Struct4::New(); - test_struct->data.resize(0); - - TestWarning(std::move(test_struct), mojo::internal::VALIDATION_ERROR_NONE); - - test_struct = Struct4::New(); - test_struct->data.resize(1); - test_struct->data[0] = Struct1::New(); - - TestWarning(std::move(test_struct), mojo::internal::VALIDATION_ERROR_NONE); -} - -TEST_F(SerializationWarningTest, FixedArrayOfStructsInStruct) { - Struct5Ptr test_struct(Struct5::New()); - test_struct->pair.resize(1); - test_struct->pair[0] = Struct1::New(); - - TestWarning(std::move(test_struct), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER); - - test_struct = Struct5::New(); - test_struct->pair.resize(2); - test_struct->pair[0] = Struct1::New(); - test_struct->pair[1] = Struct1::New(); - - TestWarning(std::move(test_struct), mojo::internal::VALIDATION_ERROR_NONE); -} - -TEST_F(SerializationWarningTest, ArrayOfArraysOfHandles) { - using MojomType = ArrayDataView<ArrayDataView<ScopedHandle>>; - auto test_array = CreateTestNestedHandleArray(); - test_array[0] = base::nullopt; - (*test_array[1])[0] = ScopedHandle(); - - ContainerValidateParams validate_params_0( - 0, true, new ContainerValidateParams(0, true, nullptr)); - TestArrayWarning<MojomType>(std::move(test_array), - mojo::internal::VALIDATION_ERROR_NONE, - &validate_params_0); - - test_array = CreateTestNestedHandleArray(); - test_array[0] = base::nullopt; - ContainerValidateParams validate_params_1( - 0, false, new ContainerValidateParams(0, true, nullptr)); - TestArrayWarning<MojomType>( - std::move(test_array), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, - &validate_params_1); - - test_array = CreateTestNestedHandleArray(); - (*test_array[1])[0] = ScopedHandle(); - ContainerValidateParams validate_params_2( - 0, true, new ContainerValidateParams(0, false, nullptr)); - TestArrayWarning<MojomType>( - std::move(test_array), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, - &validate_params_2); -} - -TEST_F(SerializationWarningTest, ArrayOfStrings) { - using MojomType = ArrayDataView<StringDataView>; - - std::vector<std::string> test_array(3); - for (size_t i = 0; i < test_array.size(); ++i) - test_array[i] = "hello"; - - ContainerValidateParams validate_params_0( - 0, true, new ContainerValidateParams(0, false, nullptr)); - TestArrayWarning<MojomType>(std::move(test_array), - mojo::internal::VALIDATION_ERROR_NONE, - &validate_params_0); - - std::vector<base::Optional<std::string>> optional_test_array(3); - ContainerValidateParams validate_params_1( - 0, false, new ContainerValidateParams(0, false, nullptr)); - TestArrayWarning<MojomType>( - std::move(optional_test_array), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, - &validate_params_1); - - test_array = std::vector<std::string>(2); - ContainerValidateParams validate_params_2( - 3, true, new ContainerValidateParams(0, false, nullptr)); - TestArrayWarning<MojomType>( - std::move(test_array), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, - &validate_params_2); -} - -TEST_F(SerializationWarningTest, StructInUnion) { - DummyStructPtr dummy(nullptr); - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_dummy(std::move(dummy)); - - TestUnionWarning(std::move(obj), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); -} - -TEST_F(SerializationWarningTest, UnionInUnion) { - PodUnionPtr pod(nullptr); - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_pod_union(std::move(pod)); - - TestUnionWarning(std::move(obj), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); -} - -TEST_F(SerializationWarningTest, HandleInUnion) { - ScopedMessagePipeHandle pipe; - HandleUnionPtr handle(HandleUnion::New()); - handle->set_f_message_pipe(std::move(pipe)); - - TestUnionWarning(std::move(handle), - mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE); -} - -} // namespace -} // namespace test -} // namespace mojo - -#endif diff --git a/mojo/public/cpp/bindings/tests/shared_rect.h b/mojo/public/cpp/bindings/tests/shared_rect.h deleted file mode 100644 index c0a4771..0000000 --- a/mojo/public/cpp/bindings/tests/shared_rect.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_H_ - -#include "base/logging.h" - -namespace mojo { -namespace test { - -// An implementation of a hypothetical Rect type specifically for consumers in -// both Chromium and Blink. -class SharedRect { - public: - SharedRect() {} - SharedRect(int x, int y, int width, int height) - : x_(x), y_(y), width_(width), height_(height) {} - - int x() const { return x_; } - void set_x(int x) { x_ = x; } - - int y() const { return y_; } - void set_y(int y) { y_ = y; } - - int width() const { return width_; } - void set_width(int width) { width_ = width; } - - int height() const { return height_; } - void set_height(int height) { height_ = height; } - - private: - int x_ = 0; - int y_ = 0; - int width_ = 0; - int height_ = 0; -}; - -} // namespace test -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_H_ diff --git a/mojo/public/cpp/bindings/tests/shared_rect_traits.h b/mojo/public/cpp/bindings/tests/shared_rect_traits.h deleted file mode 100644 index bbf04d5..0000000 --- a/mojo/public/cpp/bindings/tests/shared_rect_traits.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_TRAITS_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_TRAITS_H_ - -#include "mojo/public/cpp/bindings/struct_traits.h" -#include "mojo/public/cpp/bindings/tests/shared_rect.h" -#include "mojo/public/interfaces/bindings/tests/rect.mojom-shared.h" - -namespace mojo { - -template <> -struct StructTraits<test::SharedTypemappedRectDataView, test::SharedRect> { - static int x(const test::SharedRect& r) { return r.x(); } - static int y(const test::SharedRect& r) { return r.y(); } - static int width(const test::SharedRect& r) { return r.width(); } - static int height(const test::SharedRect& r) { return r.height(); } - - static bool Read(test::SharedTypemappedRectDataView r, - test::SharedRect* out) { - out->set_x(r.x()); - out->set_y(r.y()); - out->set_width(r.width()); - out->set_height(r.height()); - return true; - } -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_SHARED_RECT_TRAITS_H_ diff --git a/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc b/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc deleted file mode 100644 index 77b448a..0000000 --- a/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc +++ /dev/null @@ -1,553 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "mojo/public/cpp/bindings/tests/rect_blink.h" -#include "mojo/public/cpp/bindings/tests/rect_chromium.h" -#include "mojo/public/cpp/bindings/tests/struct_with_traits_impl.h" -#include "mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h" -#include "mojo/public/cpp/bindings/tests/variant_test_util.h" -#include "mojo/public/cpp/system/wait.h" -#include "mojo/public/interfaces/bindings/tests/struct_with_traits.mojom.h" -#include "mojo/public/interfaces/bindings/tests/test_native_types.mojom-blink.h" -#include "mojo/public/interfaces/bindings/tests/test_native_types.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -template <typename T> -void DoExpectResult(const T& expected, - const base::Closure& callback, - const T& actual) { - EXPECT_EQ(expected.x(), actual.x()); - EXPECT_EQ(expected.y(), actual.y()); - EXPECT_EQ(expected.width(), actual.width()); - EXPECT_EQ(expected.height(), actual.height()); - callback.Run(); -} - -template <typename T> -base::Callback<void(const T&)> ExpectResult(const T& r, - const base::Closure& callback) { - return base::Bind(&DoExpectResult<T>, r, callback); -} - -template <typename T> -void DoFail(const std::string& reason, const T&) { - EXPECT_TRUE(false) << reason; -} - -template <typename T> -base::Callback<void(const T&)> Fail(const std::string& reason) { - return base::Bind(&DoFail<T>, reason); -} - -template <typename T> -void ExpectError(InterfacePtr<T> *proxy, const base::Closure& callback) { - proxy->set_connection_error_handler(callback); -} - -// This implements the generated Chromium variant of RectService. -class ChromiumRectServiceImpl : public RectService { - public: - ChromiumRectServiceImpl() {} - - // mojo::test::RectService: - void AddRect(const RectChromium& r) override { - if (r.GetArea() > largest_rect_.GetArea()) - largest_rect_ = r; - } - - void GetLargestRect(const GetLargestRectCallback& callback) override { - callback.Run(largest_rect_); - } - - void PassSharedRect(const SharedRect& r, - const PassSharedRectCallback& callback) override { - callback.Run(r); - } - - private: - RectChromium largest_rect_; -}; - -// This implements the generated Blink variant of RectService. -class BlinkRectServiceImpl : public blink::RectService { - public: - BlinkRectServiceImpl() {} - - // mojo::test::blink::RectService: - void AddRect(const RectBlink& r) override { - if (r.computeArea() > largest_rect_.computeArea()) { - largest_rect_.setX(r.x()); - largest_rect_.setY(r.y()); - largest_rect_.setWidth(r.width()); - largest_rect_.setHeight(r.height()); - } - } - - void GetLargestRect(const GetLargestRectCallback& callback) override { - callback.Run(largest_rect_); - } - - void PassSharedRect(const SharedRect& r, - const PassSharedRectCallback& callback) override { - callback.Run(r); - } - - private: - RectBlink largest_rect_; -}; - -// A test which runs both Chromium and Blink implementations of a RectService. -class StructTraitsTest : public testing::Test, - public TraitsTestService { - public: - StructTraitsTest() {} - - protected: - void BindToChromiumService(RectServiceRequest request) { - chromium_bindings_.AddBinding(&chromium_service_, std::move(request)); - } - void BindToChromiumService(blink::RectServiceRequest request) { - chromium_bindings_.AddBinding( - &chromium_service_, - ConvertInterfaceRequest<RectService>(std::move(request))); - } - - void BindToBlinkService(blink::RectServiceRequest request) { - blink_bindings_.AddBinding(&blink_service_, std::move(request)); - } - void BindToBlinkService(RectServiceRequest request) { - blink_bindings_.AddBinding( - &blink_service_, - ConvertInterfaceRequest<blink::RectService>(std::move(request))); - } - - TraitsTestServicePtr GetTraitsTestProxy() { - return traits_test_bindings_.CreateInterfacePtrAndBind(this); - } - - private: - // TraitsTestService: - void EchoStructWithTraits( - const StructWithTraitsImpl& s, - const EchoStructWithTraitsCallback& callback) override { - callback.Run(s); - } - - void EchoTrivialStructWithTraits( - TrivialStructWithTraitsImpl s, - const EchoTrivialStructWithTraitsCallback& callback) override { - callback.Run(s); - } - - void EchoMoveOnlyStructWithTraits( - MoveOnlyStructWithTraitsImpl s, - const EchoMoveOnlyStructWithTraitsCallback& callback) override { - callback.Run(std::move(s)); - } - - void EchoNullableMoveOnlyStructWithTraits( - base::Optional<MoveOnlyStructWithTraitsImpl> s, - const EchoNullableMoveOnlyStructWithTraitsCallback& callback) override { - callback.Run(std::move(s)); - } - - void EchoEnumWithTraits(EnumWithTraitsImpl e, - const EchoEnumWithTraitsCallback& callback) override { - callback.Run(e); - } - - void EchoStructWithTraitsForUniquePtr( - std::unique_ptr<int> e, - const EchoStructWithTraitsForUniquePtrCallback& callback) override { - callback.Run(std::move(e)); - } - - void EchoNullableStructWithTraitsForUniquePtr( - std::unique_ptr<int> e, - const EchoNullableStructWithTraitsForUniquePtrCallback& callback) - override { - callback.Run(std::move(e)); - } - - void EchoUnionWithTraits( - std::unique_ptr<test::UnionWithTraitsBase> u, - const EchoUnionWithTraitsCallback& callback) override { - callback.Run(std::move(u)); - } - - base::MessageLoop loop_; - - ChromiumRectServiceImpl chromium_service_; - BindingSet<RectService> chromium_bindings_; - - BlinkRectServiceImpl blink_service_; - BindingSet<blink::RectService> blink_bindings_; - - BindingSet<TraitsTestService> traits_test_bindings_; -}; - -} // namespace - -TEST_F(StructTraitsTest, ChromiumProxyToChromiumService) { - RectServicePtr chromium_proxy; - BindToChromiumService(MakeRequest(&chromium_proxy)); - { - base::RunLoop loop; - chromium_proxy->AddRect(RectChromium(1, 1, 4, 5)); - chromium_proxy->AddRect(RectChromium(-1, -1, 2, 2)); - chromium_proxy->GetLargestRect( - ExpectResult(RectChromium(1, 1, 4, 5), loop.QuitClosure())); - loop.Run(); - } - { - base::RunLoop loop; - chromium_proxy->PassSharedRect( - {1, 2, 3, 4}, - ExpectResult(SharedRect({1, 2, 3, 4}), loop.QuitClosure())); - loop.Run(); - } -} - -TEST_F(StructTraitsTest, ChromiumToBlinkService) { - RectServicePtr chromium_proxy; - BindToBlinkService(MakeRequest(&chromium_proxy)); - { - base::RunLoop loop; - chromium_proxy->AddRect(RectChromium(1, 1, 4, 5)); - chromium_proxy->AddRect(RectChromium(2, 2, 5, 5)); - chromium_proxy->GetLargestRect( - ExpectResult(RectChromium(2, 2, 5, 5), loop.QuitClosure())); - loop.Run(); - } - { - base::RunLoop loop; - chromium_proxy->PassSharedRect( - {1, 2, 3, 4}, - ExpectResult(SharedRect({1, 2, 3, 4}), loop.QuitClosure())); - loop.Run(); - } - // The Blink service should drop our connection because RectBlink's - // deserializer rejects negative origins. - { - base::RunLoop loop; - ExpectError(&chromium_proxy, loop.QuitClosure()); - chromium_proxy->AddRect(RectChromium(-1, -1, 2, 2)); - chromium_proxy->GetLargestRect( - Fail<RectChromium>("The pipe should have been closed.")); - loop.Run(); - } -} - -TEST_F(StructTraitsTest, BlinkProxyToBlinkService) { - blink::RectServicePtr blink_proxy; - BindToBlinkService(MakeRequest(&blink_proxy)); - { - base::RunLoop loop; - blink_proxy->AddRect(RectBlink(1, 1, 4, 5)); - blink_proxy->AddRect(RectBlink(10, 10, 20, 20)); - blink_proxy->GetLargestRect( - ExpectResult(RectBlink(10, 10, 20, 20), loop.QuitClosure())); - loop.Run(); - } - { - base::RunLoop loop; - blink_proxy->PassSharedRect( - {4, 3, 2, 1}, - ExpectResult(SharedRect({4, 3, 2, 1}), loop.QuitClosure())); - loop.Run(); - } -} - -TEST_F(StructTraitsTest, BlinkProxyToChromiumService) { - blink::RectServicePtr blink_proxy; - BindToChromiumService(MakeRequest(&blink_proxy)); - { - base::RunLoop loop; - blink_proxy->AddRect(RectBlink(1, 1, 4, 5)); - blink_proxy->AddRect(RectBlink(10, 10, 2, 2)); - blink_proxy->GetLargestRect( - ExpectResult(RectBlink(1, 1, 4, 5), loop.QuitClosure())); - loop.Run(); - } - { - base::RunLoop loop; - blink_proxy->PassSharedRect( - {4, 3, 2, 1}, - ExpectResult(SharedRect({4, 3, 2, 1}), loop.QuitClosure())); - loop.Run(); - } -} - -void ExpectStructWithTraits(const StructWithTraitsImpl& expected, - const base::Closure& closure, - const StructWithTraitsImpl& passed) { - EXPECT_EQ(expected.get_enum(), passed.get_enum()); - EXPECT_EQ(expected.get_bool(), passed.get_bool()); - EXPECT_EQ(expected.get_uint32(), passed.get_uint32()); - EXPECT_EQ(expected.get_uint64(), passed.get_uint64()); - EXPECT_EQ(expected.get_string(), passed.get_string()); - EXPECT_EQ(expected.get_string_array(), passed.get_string_array()); - EXPECT_EQ(expected.get_struct(), passed.get_struct()); - EXPECT_EQ(expected.get_struct_array(), passed.get_struct_array()); - EXPECT_EQ(expected.get_struct_map(), passed.get_struct_map()); - closure.Run(); -} - -TEST_F(StructTraitsTest, EchoStructWithTraits) { - StructWithTraitsImpl input; - input.set_enum(EnumWithTraitsImpl::CUSTOM_VALUE_1); - input.set_bool(true); - input.set_uint32(7); - input.set_uint64(42); - input.set_string("hello world!"); - input.get_mutable_string_array().assign({"hello", "world!"}); - input.get_mutable_string_set().insert("hello"); - input.get_mutable_string_set().insert("world!"); - input.get_mutable_struct().value = 42; - input.get_mutable_struct_array().resize(2); - input.get_mutable_struct_array()[0].value = 1; - input.get_mutable_struct_array()[1].value = 2; - input.get_mutable_struct_map()["hello"] = NestedStructWithTraitsImpl(1024); - input.get_mutable_struct_map()["world"] = NestedStructWithTraitsImpl(2048); - - base::RunLoop loop; - TraitsTestServicePtr proxy = GetTraitsTestProxy(); - - proxy->EchoStructWithTraits( - input, - base::Bind(&ExpectStructWithTraits, input, loop.QuitClosure())); - loop.Run(); -} - -TEST_F(StructTraitsTest, CloneStructWithTraitsContainer) { - StructWithTraitsContainerPtr container = StructWithTraitsContainer::New(); - container->f_struct.set_uint32(7); - container->f_struct.set_uint64(42); - StructWithTraitsContainerPtr cloned_container = container.Clone(); - EXPECT_EQ(7u, cloned_container->f_struct.get_uint32()); - EXPECT_EQ(42u, cloned_container->f_struct.get_uint64()); -} - -void ExpectTrivialStructWithTraits(TrivialStructWithTraitsImpl expected, - const base::Closure& closure, - TrivialStructWithTraitsImpl passed) { - EXPECT_EQ(expected.value, passed.value); - closure.Run(); -} - -TEST_F(StructTraitsTest, EchoTrivialStructWithTraits) { - TrivialStructWithTraitsImpl input; - input.value = 42; - - base::RunLoop loop; - TraitsTestServicePtr proxy = GetTraitsTestProxy(); - - proxy->EchoTrivialStructWithTraits( - input, - base::Bind(&ExpectTrivialStructWithTraits, input, loop.QuitClosure())); - loop.Run(); -} - -void CaptureMessagePipe(ScopedMessagePipeHandle* storage, - const base::Closure& closure, - MoveOnlyStructWithTraitsImpl passed) { - storage->reset(MessagePipeHandle( - passed.get_mutable_handle().release().value())); - closure.Run(); -} - -TEST_F(StructTraitsTest, EchoMoveOnlyStructWithTraits) { - MessagePipe mp; - MoveOnlyStructWithTraitsImpl input; - input.get_mutable_handle().reset(mp.handle0.release()); - - base::RunLoop loop; - TraitsTestServicePtr proxy = GetTraitsTestProxy(); - - ScopedMessagePipeHandle received; - proxy->EchoMoveOnlyStructWithTraits( - std::move(input), - base::Bind(&CaptureMessagePipe, &received, loop.QuitClosure())); - loop.Run(); - - ASSERT_TRUE(received.is_valid()); - - // Verify that the message pipe handle is correctly passed. - const char kHello[] = "hello"; - const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); - EXPECT_EQ(MOJO_RESULT_OK, - WriteMessageRaw(mp.handle1.get(), kHello, kHelloSize, nullptr, 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - - EXPECT_EQ(MOJO_RESULT_OK, Wait(received.get(), MOJO_HANDLE_SIGNAL_READABLE)); - - char buffer[10] = {0}; - uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); - EXPECT_EQ(MOJO_RESULT_OK, - ReadMessageRaw(received.get(), buffer, &buffer_size, nullptr, - nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kHelloSize, buffer_size); - EXPECT_STREQ(kHello, buffer); -} - -void CaptureNullableMoveOnlyStructWithTraitsImpl( - base::Optional<MoveOnlyStructWithTraitsImpl>* storage, - const base::Closure& closure, - base::Optional<MoveOnlyStructWithTraitsImpl> passed) { - *storage = std::move(passed); - closure.Run(); -} - -TEST_F(StructTraitsTest, EchoNullableMoveOnlyStructWithTraits) { - base::RunLoop loop; - TraitsTestServicePtr proxy = GetTraitsTestProxy(); - - base::Optional<MoveOnlyStructWithTraitsImpl> received; - proxy->EchoNullableMoveOnlyStructWithTraits( - base::nullopt, base::Bind(&CaptureNullableMoveOnlyStructWithTraitsImpl, - &received, loop.QuitClosure())); - loop.Run(); - - EXPECT_FALSE(received); -} - -void ExpectEnumWithTraits(EnumWithTraitsImpl expected_value, - const base::Closure& closure, - EnumWithTraitsImpl value) { - EXPECT_EQ(expected_value, value); - closure.Run(); -} - -TEST_F(StructTraitsTest, EchoEnumWithTraits) { - base::RunLoop loop; - TraitsTestServicePtr proxy = GetTraitsTestProxy(); - - proxy->EchoEnumWithTraits( - EnumWithTraitsImpl::CUSTOM_VALUE_1, - base::Bind(&ExpectEnumWithTraits, EnumWithTraitsImpl::CUSTOM_VALUE_1, - loop.QuitClosure())); - loop.Run(); -} - -TEST_F(StructTraitsTest, SerializeStructWithTraits) { - StructWithTraitsImpl input; - input.set_enum(EnumWithTraitsImpl::CUSTOM_VALUE_1); - input.set_bool(true); - input.set_uint32(7); - input.set_uint64(42); - input.set_string("hello world!"); - input.get_mutable_string_array().assign({ "hello", "world!" }); - input.get_mutable_string_set().insert("hello"); - input.get_mutable_string_set().insert("world!"); - input.get_mutable_struct().value = 42; - input.get_mutable_struct_array().resize(2); - input.get_mutable_struct_array()[0].value = 1; - input.get_mutable_struct_array()[1].value = 2; - input.get_mutable_struct_map()["hello"] = NestedStructWithTraitsImpl(1024); - input.get_mutable_struct_map()["world"] = NestedStructWithTraitsImpl(2048); - - auto data = StructWithTraits::Serialize(&input); - StructWithTraitsImpl output; - ASSERT_TRUE(StructWithTraits::Deserialize(std::move(data), &output)); - - EXPECT_EQ(input.get_enum(), output.get_enum()); - EXPECT_EQ(input.get_bool(), output.get_bool()); - EXPECT_EQ(input.get_uint32(), output.get_uint32()); - EXPECT_EQ(input.get_uint64(), output.get_uint64()); - EXPECT_EQ(input.get_string(), output.get_string()); - EXPECT_EQ(input.get_string_array(), output.get_string_array()); - EXPECT_EQ(input.get_string_set(), output.get_string_set()); - EXPECT_EQ(input.get_struct(), output.get_struct()); - EXPECT_EQ(input.get_struct_array(), output.get_struct_array()); - EXPECT_EQ(input.get_struct_map(), output.get_struct_map()); -} - -void ExpectUniquePtr(std::unique_ptr<int> expected, - const base::Closure& closure, - std::unique_ptr<int> value) { - ASSERT_EQ(!expected, !value); - if (expected) - EXPECT_EQ(*expected, *value); - closure.Run(); -} - -TEST_F(StructTraitsTest, TypemapUniquePtr) { - TraitsTestServicePtr proxy = GetTraitsTestProxy(); - - { - base::RunLoop loop; - proxy->EchoStructWithTraitsForUniquePtr( - base::MakeUnique<int>(12345), - base::Bind(&ExpectUniquePtr, base::Passed(base::MakeUnique<int>(12345)), - loop.QuitClosure())); - loop.Run(); - } - { - base::RunLoop loop; - proxy->EchoNullableStructWithTraitsForUniquePtr( - nullptr, base::Bind(&ExpectUniquePtr, nullptr, loop.QuitClosure())); - loop.Run(); - } -} - -TEST_F(StructTraitsTest, EchoUnionWithTraits) { - TraitsTestServicePtr proxy = GetTraitsTestProxy(); - - { - std::unique_ptr<test::UnionWithTraitsBase> input( - new test::UnionWithTraitsInt32(1234)); - base::RunLoop loop; - proxy->EchoUnionWithTraits( - std::move(input), - base::Bind( - [](const base::Closure& quit_closure, - std::unique_ptr<test::UnionWithTraitsBase> passed) { - ASSERT_EQ(test::UnionWithTraitsBase::Type::INT32, passed->type()); - EXPECT_EQ(1234, - static_cast<test::UnionWithTraitsInt32*>(passed.get()) - ->value()); - quit_closure.Run(); - - }, - loop.QuitClosure())); - loop.Run(); - } - - { - std::unique_ptr<test::UnionWithTraitsBase> input( - new test::UnionWithTraitsStruct(4321)); - base::RunLoop loop; - proxy->EchoUnionWithTraits( - std::move(input), - base::Bind( - [](const base::Closure& quit_closure, - std::unique_ptr<test::UnionWithTraitsBase> passed) { - ASSERT_EQ(test::UnionWithTraitsBase::Type::STRUCT, - passed->type()); - EXPECT_EQ(4321, - static_cast<test::UnionWithTraitsStruct*>(passed.get()) - ->get_struct() - .value); - quit_closure.Run(); - - }, - loop.QuitClosure())); - loop.Run(); - } -} - -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/struct_unittest.cc b/mojo/public/cpp/bindings/tests/struct_unittest.cc deleted file mode 100644 index a687052..0000000 --- a/mojo/public/cpp/bindings/tests/struct_unittest.cc +++ /dev/null @@ -1,526 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> -#include <string.h> -#include <utility> - -#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" -#include "mojo/public/cpp/system/message_pipe.h" -#include "mojo/public/interfaces/bindings/tests/test_export2.mojom.h" -#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -RectPtr MakeRect(int32_t factor = 1) { - return Rect::New(1 * factor, 2 * factor, 10 * factor, 20 * factor); -} - -void CheckRect(const Rect& rect, int32_t factor = 1) { - EXPECT_EQ(1 * factor, rect.x); - EXPECT_EQ(2 * factor, rect.y); - EXPECT_EQ(10 * factor, rect.width); - EXPECT_EQ(20 * factor, rect.height); -} - -MultiVersionStructPtr MakeMultiVersionStruct() { - MessagePipe pipe; - return MultiVersionStruct::New(123, MakeRect(5), std::string("hello"), - std::vector<int8_t>{10, 9, 8}, - std::move(pipe.handle0), false, 42); -} - -template <typename U, typename T> -U SerializeAndDeserialize(T input) { - using InputMojomType = typename T::Struct::DataView; - using OutputMojomType = typename U::Struct::DataView; - - using InputDataType = - typename mojo::internal::MojomTypeTraits<InputMojomType>::Data*; - using OutputDataType = - typename mojo::internal::MojomTypeTraits<OutputMojomType>::Data*; - - mojo::internal::SerializationContext context; - size_t size = - mojo::internal::PrepareToSerialize<InputMojomType>(input, &context); - mojo::internal::FixedBufferForTesting buf(size + 32); - InputDataType data; - mojo::internal::Serialize<InputMojomType>(input, &buf, &data, &context); - - // Set the subsequent area to a special value, so that we can find out if we - // mistakenly access the area. - void* subsequent_area = buf.Allocate(32); - memset(subsequent_area, 0xAA, 32); - - OutputDataType output_data = reinterpret_cast<OutputDataType>(data); - - U output; - mojo::internal::Deserialize<OutputMojomType>(output_data, &output, &context); - return std::move(output); -} - -using StructTest = testing::Test; - -} // namespace - -TEST_F(StructTest, Rect) { - RectPtr rect; - EXPECT_TRUE(rect.is_null()); - EXPECT_TRUE(!rect); - EXPECT_FALSE(rect); - - rect = nullptr; - EXPECT_TRUE(rect.is_null()); - EXPECT_TRUE(!rect); - EXPECT_FALSE(rect); - - rect = MakeRect(); - EXPECT_FALSE(rect.is_null()); - EXPECT_FALSE(!rect); - EXPECT_TRUE(rect); - - RectPtr null_rect = nullptr; - EXPECT_TRUE(null_rect.is_null()); - EXPECT_TRUE(!null_rect); - EXPECT_FALSE(null_rect); - - CheckRect(*rect); -} - -TEST_F(StructTest, Clone) { - NamedRegionPtr region; - - NamedRegionPtr clone_region = region.Clone(); - EXPECT_TRUE(clone_region.is_null()); - - region = NamedRegion::New(); - clone_region = region.Clone(); - EXPECT_FALSE(clone_region->name); - EXPECT_FALSE(clone_region->rects); - - region->name.emplace("hello world"); - clone_region = region.Clone(); - EXPECT_EQ(region->name, clone_region->name); - - region->rects.emplace(2); - (*region->rects)[1] = MakeRect(); - clone_region = region.Clone(); - EXPECT_EQ(2u, clone_region->rects->size()); - EXPECT_TRUE((*clone_region->rects)[0].is_null()); - CheckRect(*(*clone_region->rects)[1]); - - // NoDefaultFieldValues contains handles, so Clone() is not available, but - // NoDefaultFieldValuesPtr should still compile. - NoDefaultFieldValuesPtr no_default_field_values(NoDefaultFieldValues::New()); - EXPECT_FALSE(no_default_field_values->f13.is_valid()); -} - -// Serialization test of a struct with no pointer or handle members. -TEST_F(StructTest, Serialization_Basic) { - RectPtr rect(MakeRect()); - - size_t size = mojo::internal::PrepareToSerialize<RectDataView>(rect, nullptr); - EXPECT_EQ(8U + 16U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::Rect_Data* data; - mojo::internal::Serialize<RectDataView>(rect, &buf, &data, nullptr); - - RectPtr rect2; - mojo::internal::Deserialize<RectDataView>(data, &rect2, nullptr); - - CheckRect(*rect2); -} - -// Construction of a struct with struct pointers from null. -TEST_F(StructTest, Construction_StructPointers) { - RectPairPtr pair; - EXPECT_TRUE(pair.is_null()); - - pair = RectPair::New(); - EXPECT_FALSE(pair.is_null()); - EXPECT_TRUE(pair->first.is_null()); - EXPECT_TRUE(pair->first.is_null()); - - pair = nullptr; - EXPECT_TRUE(pair.is_null()); -} - -// Serialization test of a struct with struct pointers. -TEST_F(StructTest, Serialization_StructPointers) { - RectPairPtr pair(RectPair::New(MakeRect(), MakeRect())); - - size_t size = - mojo::internal::PrepareToSerialize<RectPairDataView>(pair, nullptr); - EXPECT_EQ(8U + 16U + 2 * (8U + 16U), size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::RectPair_Data* data; - mojo::internal::Serialize<RectPairDataView>(pair, &buf, &data, nullptr); - - RectPairPtr pair2; - mojo::internal::Deserialize<RectPairDataView>(data, &pair2, nullptr); - - CheckRect(*pair2->first); - CheckRect(*pair2->second); -} - -// Serialization test of a struct with an array member. -TEST_F(StructTest, Serialization_ArrayPointers) { - std::vector<RectPtr> rects; - for (size_t i = 0; i < 4; ++i) - rects.push_back(MakeRect(static_cast<int32_t>(i) + 1)); - - NamedRegionPtr region( - NamedRegion::New(std::string("region"), std::move(rects))); - - size_t size = - mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, nullptr); - EXPECT_EQ(8U + // header - 8U + // name pointer - 8U + // rects pointer - 8U + // name header - 8U + // name payload (rounded up) - 8U + // rects header - 4 * 8U + // rects payload (four pointers) - 4 * (8U + // rect header - 16U), // rect payload (four ints) - size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::NamedRegion_Data* data; - mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, nullptr); - - NamedRegionPtr region2; - mojo::internal::Deserialize<NamedRegionDataView>(data, ®ion2, nullptr); - - EXPECT_EQ("region", *region2->name); - - EXPECT_EQ(4U, region2->rects->size()); - for (size_t i = 0; i < region2->rects->size(); ++i) - CheckRect(*(*region2->rects)[i], static_cast<int32_t>(i) + 1); -} - -// Serialization test of a struct with null array pointers. -TEST_F(StructTest, Serialization_NullArrayPointers) { - NamedRegionPtr region(NamedRegion::New()); - EXPECT_FALSE(region->name); - EXPECT_FALSE(region->rects); - - size_t size = - mojo::internal::PrepareToSerialize<NamedRegionDataView>(region, nullptr); - EXPECT_EQ(8U + // header - 8U + // name pointer - 8U, // rects pointer - size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::NamedRegion_Data* data; - mojo::internal::Serialize<NamedRegionDataView>(region, &buf, &data, nullptr); - - NamedRegionPtr region2; - mojo::internal::Deserialize<NamedRegionDataView>(data, ®ion2, nullptr); - - EXPECT_FALSE(region2->name); - EXPECT_FALSE(region2->rects); -} - -// Tests deserializing structs as a newer version. -TEST_F(StructTest, Versioning_OldToNew) { - { - MultiVersionStructV0Ptr input(MultiVersionStructV0::New(123)); - MultiVersionStructPtr expected_output(MultiVersionStruct::New(123)); - - MultiVersionStructPtr output = - SerializeAndDeserialize<MultiVersionStructPtr>(std::move(input)); - EXPECT_TRUE(output); - EXPECT_TRUE(output->Equals(*expected_output)); - } - - { - MultiVersionStructV1Ptr input(MultiVersionStructV1::New(123, MakeRect(5))); - MultiVersionStructPtr expected_output( - MultiVersionStruct::New(123, MakeRect(5))); - - MultiVersionStructPtr output = - SerializeAndDeserialize<MultiVersionStructPtr>(std::move(input)); - EXPECT_TRUE(output); - EXPECT_TRUE(output->Equals(*expected_output)); - } - - { - MultiVersionStructV3Ptr input( - MultiVersionStructV3::New(123, MakeRect(5), std::string("hello"))); - MultiVersionStructPtr expected_output( - MultiVersionStruct::New(123, MakeRect(5), std::string("hello"))); - - MultiVersionStructPtr output = - SerializeAndDeserialize<MultiVersionStructPtr>(std::move(input)); - EXPECT_TRUE(output); - EXPECT_TRUE(output->Equals(*expected_output)); - } - - { - MultiVersionStructV5Ptr input(MultiVersionStructV5::New( - 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8})); - MultiVersionStructPtr expected_output(MultiVersionStruct::New( - 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8})); - - MultiVersionStructPtr output = - SerializeAndDeserialize<MultiVersionStructPtr>(std::move(input)); - EXPECT_TRUE(output); - EXPECT_TRUE(output->Equals(*expected_output)); - } - - { - MessagePipe pipe; - MultiVersionStructV7Ptr input(MultiVersionStructV7::New( - 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8}, - std::move(pipe.handle0), false)); - - MultiVersionStructPtr expected_output(MultiVersionStruct::New( - 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8})); - // Save the raw handle value separately so that we can compare later. - MojoHandle expected_handle = input->f_message_pipe.get().value(); - - MultiVersionStructPtr output = - SerializeAndDeserialize<MultiVersionStructPtr>(std::move(input)); - EXPECT_TRUE(output); - EXPECT_EQ(expected_handle, output->f_message_pipe.get().value()); - output->f_message_pipe.reset(); - EXPECT_TRUE(output->Equals(*expected_output)); - } -} - -// Tests deserializing structs as an older version. -TEST_F(StructTest, Versioning_NewToOld) { - { - MultiVersionStructPtr input = MakeMultiVersionStruct(); - MultiVersionStructV7Ptr expected_output(MultiVersionStructV7::New( - 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8})); - // Save the raw handle value separately so that we can compare later. - MojoHandle expected_handle = input->f_message_pipe.get().value(); - - MultiVersionStructV7Ptr output = - SerializeAndDeserialize<MultiVersionStructV7Ptr>(std::move(input)); - EXPECT_TRUE(output); - EXPECT_EQ(expected_handle, output->f_message_pipe.get().value()); - output->f_message_pipe.reset(); - EXPECT_TRUE(output->Equals(*expected_output)); - } - - { - MultiVersionStructPtr input = MakeMultiVersionStruct(); - MultiVersionStructV5Ptr expected_output(MultiVersionStructV5::New( - 123, MakeRect(5), std::string("hello"), std::vector<int8_t>{10, 9, 8})); - - MultiVersionStructV5Ptr output = - SerializeAndDeserialize<MultiVersionStructV5Ptr>(std::move(input)); - EXPECT_TRUE(output); - EXPECT_TRUE(output->Equals(*expected_output)); - } - - { - MultiVersionStructPtr input = MakeMultiVersionStruct(); - MultiVersionStructV3Ptr expected_output( - MultiVersionStructV3::New(123, MakeRect(5), std::string("hello"))); - - MultiVersionStructV3Ptr output = - SerializeAndDeserialize<MultiVersionStructV3Ptr>(std::move(input)); - EXPECT_TRUE(output); - EXPECT_TRUE(output->Equals(*expected_output)); - } - - { - MultiVersionStructPtr input = MakeMultiVersionStruct(); - MultiVersionStructV1Ptr expected_output( - MultiVersionStructV1::New(123, MakeRect(5))); - - MultiVersionStructV1Ptr output = - SerializeAndDeserialize<MultiVersionStructV1Ptr>(std::move(input)); - EXPECT_TRUE(output); - EXPECT_TRUE(output->Equals(*expected_output)); - } - - { - MultiVersionStructPtr input = MakeMultiVersionStruct(); - MultiVersionStructV0Ptr expected_output(MultiVersionStructV0::New(123)); - - MultiVersionStructV0Ptr output = - SerializeAndDeserialize<MultiVersionStructV0Ptr>(std::move(input)); - EXPECT_TRUE(output); - EXPECT_TRUE(output->Equals(*expected_output)); - } -} - -// Serialization test for native struct. -TEST_F(StructTest, Serialization_NativeStruct) { - using Data = mojo::internal::NativeStruct_Data; - { - // Serialization of a null native struct. - NativeStructPtr native; - size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>( - native, nullptr); - EXPECT_EQ(0u, size); - mojo::internal::FixedBufferForTesting buf(size); - - Data* data = nullptr; - mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf, - &data, nullptr); - - EXPECT_EQ(nullptr, data); - - NativeStructPtr output_native; - mojo::internal::Deserialize<NativeStructDataView>(data, &output_native, - nullptr); - EXPECT_TRUE(output_native.is_null()); - } - - { - // Serialization of a native struct with null data. - NativeStructPtr native(NativeStruct::New()); - size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>( - native, nullptr); - EXPECT_EQ(0u, size); - mojo::internal::FixedBufferForTesting buf(size); - - Data* data = nullptr; - mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf, - &data, nullptr); - - EXPECT_EQ(nullptr, data); - - NativeStructPtr output_native; - mojo::internal::Deserialize<NativeStructDataView>(data, &output_native, - nullptr); - EXPECT_TRUE(output_native.is_null()); - } - - { - NativeStructPtr native(NativeStruct::New()); - native->data = std::vector<uint8_t>{'X', 'Y'}; - - size_t size = mojo::internal::PrepareToSerialize<NativeStructDataView>( - native, nullptr); - EXPECT_EQ(16u, size); - mojo::internal::FixedBufferForTesting buf(size); - - Data* data = nullptr; - mojo::internal::Serialize<NativeStructDataView>(std::move(native), &buf, - &data, nullptr); - - EXPECT_NE(nullptr, data); - - NativeStructPtr output_native; - mojo::internal::Deserialize<NativeStructDataView>(data, &output_native, - nullptr); - ASSERT_TRUE(output_native); - ASSERT_FALSE(output_native->data->empty()); - EXPECT_EQ(2u, output_native->data->size()); - EXPECT_EQ('X', (*output_native->data)[0]); - EXPECT_EQ('Y', (*output_native->data)[1]); - } -} - -TEST_F(StructTest, Serialization_PublicAPI) { - { - // A null struct pointer. - RectPtr null_struct; - auto data = Rect::Serialize(&null_struct); - EXPECT_TRUE(data.empty()); - - // Initialize it to non-null. - RectPtr output(Rect::New()); - ASSERT_TRUE(Rect::Deserialize(data, &output)); - EXPECT_TRUE(output.is_null()); - } - - { - // A struct with no fields. - EmptyStructPtr empty_struct(EmptyStruct::New()); - auto data = EmptyStruct::Serialize(&empty_struct); - EXPECT_FALSE(data.empty()); - - EmptyStructPtr output; - ASSERT_TRUE(EmptyStruct::Deserialize(data, &output)); - EXPECT_FALSE(output.is_null()); - } - - { - // A simple struct. - RectPtr rect = MakeRect(); - RectPtr cloned_rect = rect.Clone(); - auto data = Rect::Serialize(&rect); - - RectPtr output; - ASSERT_TRUE(Rect::Deserialize(data, &output)); - EXPECT_TRUE(output.Equals(cloned_rect)); - } - - { - // A struct containing other objects. - std::vector<RectPtr> rects; - for (size_t i = 0; i < 3; ++i) - rects.push_back(MakeRect(static_cast<int32_t>(i) + 1)); - NamedRegionPtr region( - NamedRegion::New(std::string("region"), std::move(rects))); - - NamedRegionPtr cloned_region = region.Clone(); - auto data = NamedRegion::Serialize(®ion); - - // Make sure that the serialized result gets pointers encoded properly. - auto cloned_data = data; - NamedRegionPtr output; - ASSERT_TRUE(NamedRegion::Deserialize(cloned_data, &output)); - EXPECT_TRUE(output.Equals(cloned_region)); - } - - { - // Deserialization failure. - RectPtr rect = MakeRect(); - auto data = Rect::Serialize(&rect); - - NamedRegionPtr output; - EXPECT_FALSE(NamedRegion::Deserialize(data, &output)); - } - - { - // A struct from another component. - auto pair = test_export2::StringPair::New("hello", "world"); - auto data = test_export2::StringPair::Serialize(&pair); - - test_export2::StringPairPtr output; - ASSERT_TRUE(test_export2::StringPair::Deserialize(data, &output)); - EXPECT_TRUE(output.Equals(pair)); - } -} - -TEST_F(StructTest, VersionedStructConstructor) { - auto reordered = ReorderedStruct::New(123, 456, 789); - EXPECT_EQ(123, reordered->a); - EXPECT_EQ(456, reordered->b); - EXPECT_EQ(789, reordered->c); - - reordered = ReorderedStruct::New(123, 456); - EXPECT_EQ(123, reordered->a); - EXPECT_EQ(6, reordered->b); - EXPECT_EQ(456, reordered->c); - - reordered = ReorderedStruct::New(123); - EXPECT_EQ(3, reordered->a); - EXPECT_EQ(6, reordered->b); - EXPECT_EQ(123, reordered->c); - - reordered = ReorderedStruct::New(); - EXPECT_EQ(3, reordered->a); - EXPECT_EQ(6, reordered->b); - EXPECT_EQ(1, reordered->c); -} - -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits.typemap b/mojo/public/cpp/bindings/tests/struct_with_traits.typemap deleted file mode 100644 index 752ce44..0000000 --- a/mojo/public/cpp/bindings/tests/struct_with_traits.typemap +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//mojo/public/interfaces/bindings/tests/struct_with_traits.mojom" -public_headers = - [ "//mojo/public/cpp/bindings/tests/struct_with_traits_impl.h" ] -traits_headers = - [ "//mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h" ] -sources = [ - "//mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.cc", -] -deps = [ - "//mojo/public/cpp/bindings/tests:struct_with_traits_impl", - "//mojo/public/cpp/system:system", -] - -type_mappings = [ - "mojo.test.EnumWithTraits=mojo::test::EnumWithTraitsImpl", - "mojo.test.StructWithTraits=mojo::test::StructWithTraitsImpl", - "mojo.test.NestedStructWithTraits=mojo::test::NestedStructWithTraitsImpl", - "mojo.test.TrivialStructWithTraits=mojo::test::TrivialStructWithTraitsImpl[copyable_pass_by_value]", - "mojo.test.MoveOnlyStructWithTraits=mojo::test::MoveOnlyStructWithTraitsImpl[move_only]", - "mojo.test.StructWithTraitsForUniquePtr=std::unique_ptr<int>[move_only,nullable_is_same_type]", - "mojo.test.UnionWithTraits=std::unique_ptr<mojo::test::UnionWithTraitsBase>[move_only,nullable_is_same_type]", -] diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc b/mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc deleted file mode 100644 index cbdd4bf..0000000 --- a/mojo/public/cpp/bindings/tests/struct_with_traits_impl.cc +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/tests/struct_with_traits_impl.h" - -namespace mojo { -namespace test { - -NestedStructWithTraitsImpl::NestedStructWithTraitsImpl() {} -NestedStructWithTraitsImpl::NestedStructWithTraitsImpl(int32_t in_value) - : value(in_value) {} - -StructWithTraitsImpl::StructWithTraitsImpl() {} - -StructWithTraitsImpl::~StructWithTraitsImpl() {} - -StructWithTraitsImpl::StructWithTraitsImpl(const StructWithTraitsImpl& other) = - default; - -MoveOnlyStructWithTraitsImpl::MoveOnlyStructWithTraitsImpl() {} - -MoveOnlyStructWithTraitsImpl::MoveOnlyStructWithTraitsImpl( - MoveOnlyStructWithTraitsImpl&& other) = default; - -MoveOnlyStructWithTraitsImpl::~MoveOnlyStructWithTraitsImpl() {} - -MoveOnlyStructWithTraitsImpl& MoveOnlyStructWithTraitsImpl::operator=( - MoveOnlyStructWithTraitsImpl&& other) = default; - -UnionWithTraitsInt32::~UnionWithTraitsInt32() {} - -UnionWithTraitsStruct::~UnionWithTraitsStruct() {} - -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits_impl.h b/mojo/public/cpp/bindings/tests/struct_with_traits_impl.h deleted file mode 100644 index 7b007cc..0000000 --- a/mojo/public/cpp/bindings/tests/struct_with_traits_impl.h +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_STRUCT_WITH_TRAITS_IMPL_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_STRUCT_WITH_TRAITS_IMPL_H_ - -#include <stdint.h> - -#include <map> -#include <set> -#include <string> -#include <vector> - -#include "base/strings/string_piece.h" -#include "mojo/public/cpp/system/handle.h" - -namespace mojo { -namespace test { - -struct NestedStructWithTraitsImpl { - public: - NestedStructWithTraitsImpl(); - explicit NestedStructWithTraitsImpl(int32_t in_value); - - bool operator==(const NestedStructWithTraitsImpl& other) const { - return value == other.value; - } - - int32_t value = 0; -}; - -enum class EnumWithTraitsImpl { CUSTOM_VALUE_0 = 10, CUSTOM_VALUE_1 = 11 }; - -// A type which knows how to look like a mojo::test::StructWithTraits mojom type -// by way of mojo::StructTraits. -class StructWithTraitsImpl { - public: - StructWithTraitsImpl(); - ~StructWithTraitsImpl(); - - StructWithTraitsImpl(const StructWithTraitsImpl& other); - - void set_enum(EnumWithTraitsImpl value) { enum_ = value; } - EnumWithTraitsImpl get_enum() const { return enum_; } - - void set_bool(bool value) { bool_ = value; } - bool get_bool() const { return bool_; } - - void set_uint32(uint32_t value) { uint32_ = value; } - uint32_t get_uint32() const { return uint32_; } - - void set_uint64(uint64_t value) { uint64_ = value; } - uint64_t get_uint64() const { return uint64_; } - - void set_string(std::string value) { string_ = value; } - base::StringPiece get_string_as_string_piece() const { return string_; } - const std::string& get_string() const { return string_; } - - const std::vector<std::string>& get_string_array() const { - return string_array_; - } - std::vector<std::string>& get_mutable_string_array() { return string_array_; } - - const std::set<std::string>& get_string_set() const { - return string_set_; - } - std::set<std::string>& get_mutable_string_set() { return string_set_; } - - const NestedStructWithTraitsImpl& get_struct() const { return struct_; } - NestedStructWithTraitsImpl& get_mutable_struct() { return struct_; } - - const std::vector<NestedStructWithTraitsImpl>& get_struct_array() const { - return struct_array_; - } - std::vector<NestedStructWithTraitsImpl>& get_mutable_struct_array() { - return struct_array_; - } - - const std::map<std::string, NestedStructWithTraitsImpl>& get_struct_map() - const { - return struct_map_; - } - std::map<std::string, NestedStructWithTraitsImpl>& get_mutable_struct_map() { - return struct_map_; - } - - private: - EnumWithTraitsImpl enum_ = EnumWithTraitsImpl::CUSTOM_VALUE_0; - bool bool_ = false; - uint32_t uint32_ = 0; - uint64_t uint64_ = 0; - std::string string_; - std::vector<std::string> string_array_; - std::set<std::string> string_set_; - NestedStructWithTraitsImpl struct_; - std::vector<NestedStructWithTraitsImpl> struct_array_; - std::map<std::string, NestedStructWithTraitsImpl> struct_map_; -}; - -// A type which knows how to look like a mojo::test::TrivialStructWithTraits -// mojom type by way of mojo::StructTraits. -struct TrivialStructWithTraitsImpl { - int32_t value; -}; - -// A type which knows how to look like a mojo::test::MoveOnlyStructWithTraits -// mojom type by way of mojo::StructTraits. -class MoveOnlyStructWithTraitsImpl { - public: - MoveOnlyStructWithTraitsImpl(); - MoveOnlyStructWithTraitsImpl(MoveOnlyStructWithTraitsImpl&& other); - ~MoveOnlyStructWithTraitsImpl(); - - ScopedHandle& get_mutable_handle() { return handle_; } - - MoveOnlyStructWithTraitsImpl& operator=(MoveOnlyStructWithTraitsImpl&& other); - - private: - ScopedHandle handle_; - DISALLOW_COPY_AND_ASSIGN(MoveOnlyStructWithTraitsImpl); -}; - -class UnionWithTraitsBase { - public: - enum class Type { INT32, STRUCT }; - - virtual ~UnionWithTraitsBase() {} - - Type type() const { return type_; } - - protected: - Type type_ = Type::INT32; -}; - -class UnionWithTraitsInt32 : public UnionWithTraitsBase { - public: - UnionWithTraitsInt32() {} - explicit UnionWithTraitsInt32(int32_t value) : value_(value) {} - - ~UnionWithTraitsInt32() override; - - int32_t value() const { return value_; } - void set_value(int32_t value) { value_ = value; } - - private: - int32_t value_ = 0; -}; - -class UnionWithTraitsStruct : public UnionWithTraitsBase { - public: - UnionWithTraitsStruct() { type_ = Type::STRUCT; } - explicit UnionWithTraitsStruct(int32_t value) : struct_(value) { - type_ = Type::STRUCT; - } - ~UnionWithTraitsStruct() override; - - NestedStructWithTraitsImpl& get_mutable_struct() { return struct_; } - const NestedStructWithTraitsImpl& get_struct() const { return struct_; } - - private: - NestedStructWithTraitsImpl struct_; -}; - -} // namespace test -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_STRUCT_WITH_TRAITS_IMPL_H_ diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.cc b/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.cc deleted file mode 100644 index 6b770b1..0000000 --- a/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.cc +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h" - -namespace mojo { -namespace { - -struct Context { - int32_t value; -}; - -} // namespace - -// static -void* StructTraits<test::NestedStructWithTraitsDataView, - test::NestedStructWithTraitsImpl>:: - SetUpContext(const test::NestedStructWithTraitsImpl& input) { - Context* context = new Context; - context->value = input.value; - return context; -} - -// static -void StructTraits<test::NestedStructWithTraitsDataView, - test::NestedStructWithTraitsImpl>:: - TearDownContext(const test::NestedStructWithTraitsImpl& input, - void* context) { - Context* context_obj = static_cast<Context*>(context); - CHECK_EQ(context_obj->value, input.value); - delete context_obj; -} - -// static -int32_t StructTraits<test::NestedStructWithTraitsDataView, - test::NestedStructWithTraitsImpl>:: - value(const test::NestedStructWithTraitsImpl& input, void* context) { - Context* context_obj = static_cast<Context*>(context); - CHECK_EQ(context_obj->value, input.value); - return input.value; -} - -// static -bool StructTraits<test::NestedStructWithTraitsDataView, - test::NestedStructWithTraitsImpl>:: - Read(test::NestedStructWithTraits::DataView data, - test::NestedStructWithTraitsImpl* output) { - output->value = data.value(); - return true; -} - -test::EnumWithTraits -EnumTraits<test::EnumWithTraits, test::EnumWithTraitsImpl>::ToMojom( - test::EnumWithTraitsImpl input) { - switch (input) { - case test::EnumWithTraitsImpl::CUSTOM_VALUE_0: - return test::EnumWithTraits::VALUE_0; - case test::EnumWithTraitsImpl::CUSTOM_VALUE_1: - return test::EnumWithTraits::VALUE_1; - }; - - NOTREACHED(); - return test::EnumWithTraits::VALUE_0; -} - -bool EnumTraits<test::EnumWithTraits, test::EnumWithTraitsImpl>::FromMojom( - test::EnumWithTraits input, - test::EnumWithTraitsImpl* output) { - switch (input) { - case test::EnumWithTraits::VALUE_0: - *output = test::EnumWithTraitsImpl::CUSTOM_VALUE_0; - return true; - case test::EnumWithTraits::VALUE_1: - *output = test::EnumWithTraitsImpl::CUSTOM_VALUE_1; - return true; - }; - - return false; -} - -// static -bool StructTraits<test::StructWithTraitsDataView, test::StructWithTraitsImpl>:: - Read(test::StructWithTraits::DataView data, - test::StructWithTraitsImpl* out) { - test::EnumWithTraitsImpl f_enum; - if (!data.ReadFEnum(&f_enum)) - return false; - out->set_enum(f_enum); - - out->set_bool(data.f_bool()); - out->set_uint32(data.f_uint32()); - out->set_uint64(data.f_uint64()); - - base::StringPiece f_string; - std::string f_string2; - if (!data.ReadFString(&f_string) || !data.ReadFString2(&f_string2) || - f_string != f_string2) { - return false; - } - out->set_string(f_string2); - - if (!data.ReadFStringArray(&out->get_mutable_string_array())) - return false; - - // We can't deserialize as a std::set, so we have to manually copy from the - // data view. - ArrayDataView<StringDataView> string_set_data_view; - data.GetFStringSetDataView(&string_set_data_view); - for (size_t i = 0; i < string_set_data_view.size(); ++i) { - std::string value; - string_set_data_view.Read(i, &value); - out->get_mutable_string_set().insert(value); - } - - if (!data.ReadFStruct(&out->get_mutable_struct())) - return false; - - if (!data.ReadFStructArray(&out->get_mutable_struct_array())) - return false; - - if (!data.ReadFStructMap(&out->get_mutable_struct_map())) - return false; - - return true; -} - -// static -bool StructTraits<test::MoveOnlyStructWithTraitsDataView, - test::MoveOnlyStructWithTraitsImpl>:: - Read(test::MoveOnlyStructWithTraits::DataView data, - test::MoveOnlyStructWithTraitsImpl* out) { - out->get_mutable_handle() = data.TakeFHandle(); - return true; -} - -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h b/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h deleted file mode 100644 index adcad8a..0000000 --- a/mojo/public/cpp/bindings/tests/struct_with_traits_impl_traits.h +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_STRUCT_WITH_TRAITS_IMPL_TRAITS_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_STRUCT_WITH_TRAITS_IMPL_TRAITS_H_ - -#include <stdint.h> - -#include <string> -#include <vector> - -#include "base/strings/string_piece.h" -#include "mojo/public/cpp/bindings/struct_traits.h" -#include "mojo/public/cpp/bindings/tests/struct_with_traits_impl.h" -#include "mojo/public/interfaces/bindings/tests/struct_with_traits.mojom.h" - -namespace mojo { - -template <> -struct StructTraits<test::NestedStructWithTraitsDataView, - test::NestedStructWithTraitsImpl> { - static void* SetUpContext(const test::NestedStructWithTraitsImpl& input); - static void TearDownContext(const test::NestedStructWithTraitsImpl& input, - void* context); - - static int32_t value(const test::NestedStructWithTraitsImpl& input, - void* context); - - static bool Read(test::NestedStructWithTraitsDataView data, - test::NestedStructWithTraitsImpl* output); -}; - -template <> -struct EnumTraits<test::EnumWithTraits, test::EnumWithTraitsImpl> { - static test::EnumWithTraits ToMojom(test::EnumWithTraitsImpl input); - static bool FromMojom(test::EnumWithTraits input, - test::EnumWithTraitsImpl* output); -}; - -template <> -struct StructTraits<test::StructWithTraitsDataView, - test::StructWithTraitsImpl> { - // Deserialization to test::StructTraitsImpl. - static bool Read(test::StructWithTraitsDataView data, - test::StructWithTraitsImpl* out); - - // Fields in test::StructWithTraits. - // See src/mojo/public/interfaces/bindings/tests/struct_with_traits.mojom. - static test::EnumWithTraitsImpl f_enum( - const test::StructWithTraitsImpl& value) { - return value.get_enum(); - } - - static bool f_bool(const test::StructWithTraitsImpl& value) { - return value.get_bool(); - } - - static uint32_t f_uint32(const test::StructWithTraitsImpl& value) { - return value.get_uint32(); - } - - static uint64_t f_uint64(const test::StructWithTraitsImpl& value) { - return value.get_uint64(); - } - - static base::StringPiece f_string(const test::StructWithTraitsImpl& value) { - return value.get_string_as_string_piece(); - } - - static const std::string& f_string2(const test::StructWithTraitsImpl& value) { - return value.get_string(); - } - - static const std::vector<std::string>& f_string_array( - const test::StructWithTraitsImpl& value) { - return value.get_string_array(); - } - - static const std::set<std::string>& f_string_set( - const test::StructWithTraitsImpl& value) { - return value.get_string_set(); - } - - static const test::NestedStructWithTraitsImpl& f_struct( - const test::StructWithTraitsImpl& value) { - return value.get_struct(); - } - - static const std::vector<test::NestedStructWithTraitsImpl>& f_struct_array( - const test::StructWithTraitsImpl& value) { - return value.get_struct_array(); - } - - static const std::map<std::string, test::NestedStructWithTraitsImpl>& - f_struct_map(const test::StructWithTraitsImpl& value) { - return value.get_struct_map(); - } -}; - -template <> -struct StructTraits<test::TrivialStructWithTraitsDataView, - test::TrivialStructWithTraitsImpl> { - // Deserialization to test::TrivialStructTraitsImpl. - static bool Read(test::TrivialStructWithTraitsDataView data, - test::TrivialStructWithTraitsImpl* out) { - out->value = data.value(); - return true; - } - - // Fields in test::TrivialStructWithTraits. - // See src/mojo/public/interfaces/bindings/tests/struct_with_traits.mojom. - static int32_t value(test::TrivialStructWithTraitsImpl& input) { - return input.value; - } -}; - -template <> -struct StructTraits<test::MoveOnlyStructWithTraitsDataView, - test::MoveOnlyStructWithTraitsImpl> { - // Deserialization to test::MoveOnlyStructTraitsImpl. - static bool Read(test::MoveOnlyStructWithTraitsDataView data, - test::MoveOnlyStructWithTraitsImpl* out); - - // Fields in test::MoveOnlyStructWithTraits. - // See src/mojo/public/interfaces/bindings/tests/struct_with_traits.mojom. - static ScopedHandle f_handle(test::MoveOnlyStructWithTraitsImpl& value) { - return std::move(value.get_mutable_handle()); - } -}; - -template <> -struct StructTraits<test::StructWithTraitsForUniquePtrDataView, - std::unique_ptr<int>> { - static bool IsNull(const std::unique_ptr<int>& data) { return !data; } - static void SetToNull(std::unique_ptr<int>* data) { data->reset(); } - - static int f_int32(const std::unique_ptr<int>& data) { return *data; } - - static bool Read(test::StructWithTraitsForUniquePtrDataView data, - std::unique_ptr<int>* out) { - out->reset(new int(data.f_int32())); - return true; - } -}; - -template <> -struct UnionTraits<test::UnionWithTraitsDataView, - std::unique_ptr<test::UnionWithTraitsBase>> { - static bool IsNull(const std::unique_ptr<test::UnionWithTraitsBase>& data) { - return !data; - } - static void SetToNull(std::unique_ptr<test::UnionWithTraitsBase>* data) { - data->reset(); - } - - static test::UnionWithTraitsDataView::Tag GetTag( - const std::unique_ptr<test::UnionWithTraitsBase>& data) { - if (data->type() == test::UnionWithTraitsBase::Type::INT32) - return test::UnionWithTraitsDataView::Tag::F_INT32; - - return test::UnionWithTraitsDataView::Tag::F_STRUCT; - } - - static int32_t f_int32( - const std::unique_ptr<test::UnionWithTraitsBase>& data) { - return static_cast<test::UnionWithTraitsInt32*>(data.get())->value(); - } - - static const test::NestedStructWithTraitsImpl& f_struct( - const std::unique_ptr<test::UnionWithTraitsBase>& data) { - return static_cast<test::UnionWithTraitsStruct*>(data.get())->get_struct(); - } - - static bool Read(test::UnionWithTraitsDataView data, - std::unique_ptr<test::UnionWithTraitsBase>* out) { - switch (data.tag()) { - case test::UnionWithTraitsDataView::Tag::F_INT32: { - out->reset(new test::UnionWithTraitsInt32(data.f_int32())); - return true; - } - case test::UnionWithTraitsDataView::Tag::F_STRUCT: { - auto* struct_object = new test::UnionWithTraitsStruct(); - out->reset(struct_object); - return data.ReadFStruct(&struct_object->get_mutable_struct()); - } - } - - NOTREACHED(); - return false; - } -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_STRUCT_WITH_TRAITS_IMPL_TRAITS_H_ diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc deleted file mode 100644 index 084e080..0000000 --- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc +++ /dev/null @@ -1,831 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <utility> - -#include "base/bind.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/threading/thread.h" -#include "mojo/public/cpp/bindings/associated_binding.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -template <typename... Args> -struct LambdaBinder { - using CallbackType = base::Callback<void(Args...)>; - - template <typename Func> - static void RunLambda(Func func, Args... args) { - func(std::move(args)...); - } - - template <typename Func> - static CallbackType BindLambda(Func func) { - return base::Bind(&LambdaBinder::RunLambda<Func>, func); - } -}; - -class TestSyncCommonImpl { - public: - TestSyncCommonImpl() {} - - using PingHandler = base::Callback<void(const base::Callback<void()>&)>; - using PingBinder = LambdaBinder<const base::Callback<void()>&>; - template <typename Func> - void set_ping_handler(Func handler) { - ping_handler_ = PingBinder::BindLambda(handler); - } - - using EchoHandler = - base::Callback<void(int32_t, const base::Callback<void(int32_t)>&)>; - using EchoBinder = - LambdaBinder<int32_t, const base::Callback<void(int32_t)>&>; - template <typename Func> - void set_echo_handler(Func handler) { - echo_handler_ = EchoBinder::BindLambda(handler); - } - - using AsyncEchoHandler = - base::Callback<void(int32_t, const base::Callback<void(int32_t)>&)>; - using AsyncEchoBinder = - LambdaBinder<int32_t, const base::Callback<void(int32_t)>&>; - template <typename Func> - void set_async_echo_handler(Func handler) { - async_echo_handler_ = AsyncEchoBinder::BindLambda(handler); - } - - using SendInterfaceHandler = base::Callback<void(TestSyncAssociatedPtrInfo)>; - using SendInterfaceBinder = LambdaBinder<TestSyncAssociatedPtrInfo>; - template <typename Func> - void set_send_interface_handler(Func handler) { - send_interface_handler_ = SendInterfaceBinder::BindLambda(handler); - } - - using SendRequestHandler = base::Callback<void(TestSyncAssociatedRequest)>; - using SendRequestBinder = LambdaBinder<TestSyncAssociatedRequest>; - template <typename Func> - void set_send_request_handler(Func handler) { - send_request_handler_ = SendRequestBinder::BindLambda(handler); - } - - void PingImpl(const base::Callback<void()>& callback) { - if (ping_handler_.is_null()) { - callback.Run(); - return; - } - ping_handler_.Run(callback); - } - void EchoImpl(int32_t value, const base::Callback<void(int32_t)>& callback) { - if (echo_handler_.is_null()) { - callback.Run(value); - return; - } - echo_handler_.Run(value, callback); - } - void AsyncEchoImpl(int32_t value, - const base::Callback<void(int32_t)>& callback) { - if (async_echo_handler_.is_null()) { - callback.Run(value); - return; - } - async_echo_handler_.Run(value, callback); - } - void SendInterfaceImpl(TestSyncAssociatedPtrInfo ptr) { - send_interface_handler_.Run(std::move(ptr)); - } - void SendRequestImpl(TestSyncAssociatedRequest request) { - send_request_handler_.Run(std::move(request)); - } - - private: - PingHandler ping_handler_; - EchoHandler echo_handler_; - AsyncEchoHandler async_echo_handler_; - SendInterfaceHandler send_interface_handler_; - SendRequestHandler send_request_handler_; - - DISALLOW_COPY_AND_ASSIGN(TestSyncCommonImpl); -}; - -class TestSyncImpl : public TestSync, public TestSyncCommonImpl { - public: - explicit TestSyncImpl(TestSyncRequest request) - : binding_(this, std::move(request)) {} - - // TestSync implementation: - void Ping(const PingCallback& callback) override { PingImpl(callback); } - void Echo(int32_t value, const EchoCallback& callback) override { - EchoImpl(value, callback); - } - void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override { - AsyncEchoImpl(value, callback); - } - - Binding<TestSync>* binding() { return &binding_; } - - private: - Binding<TestSync> binding_; - - DISALLOW_COPY_AND_ASSIGN(TestSyncImpl); -}; - -class TestSyncMasterImpl : public TestSyncMaster, public TestSyncCommonImpl { - public: - explicit TestSyncMasterImpl(TestSyncMasterRequest request) - : binding_(this, std::move(request)) {} - - // TestSyncMaster implementation: - void Ping(const PingCallback& callback) override { PingImpl(callback); } - void Echo(int32_t value, const EchoCallback& callback) override { - EchoImpl(value, callback); - } - void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override { - AsyncEchoImpl(value, callback); - } - void SendInterface(TestSyncAssociatedPtrInfo ptr) override { - SendInterfaceImpl(std::move(ptr)); - } - void SendRequest(TestSyncAssociatedRequest request) override { - SendRequestImpl(std::move(request)); - } - - Binding<TestSyncMaster>* binding() { return &binding_; } - - private: - Binding<TestSyncMaster> binding_; - - DISALLOW_COPY_AND_ASSIGN(TestSyncMasterImpl); -}; - -class TestSyncAssociatedImpl : public TestSync, public TestSyncCommonImpl { - public: - explicit TestSyncAssociatedImpl(TestSyncAssociatedRequest request) - : binding_(this, std::move(request)) {} - - // TestSync implementation: - void Ping(const PingCallback& callback) override { PingImpl(callback); } - void Echo(int32_t value, const EchoCallback& callback) override { - EchoImpl(value, callback); - } - void AsyncEcho(int32_t value, const AsyncEchoCallback& callback) override { - AsyncEchoImpl(value, callback); - } - - AssociatedBinding<TestSync>* binding() { return &binding_; } - - private: - AssociatedBinding<TestSync> binding_; - - DISALLOW_COPY_AND_ASSIGN(TestSyncAssociatedImpl); -}; - -template <typename Interface> -struct ImplTraits; - -template <> -struct ImplTraits<TestSync> { - using Type = TestSyncImpl; -}; - -template <> -struct ImplTraits<TestSyncMaster> { - using Type = TestSyncMasterImpl; -}; - -template <typename Interface> -using ImplTypeFor = typename ImplTraits<Interface>::Type; - -// A wrapper for either an InterfacePtr or scoped_refptr<ThreadSafeInterfacePtr> -// that exposes the InterfacePtr interface. -template <typename Interface> -class PtrWrapper { - public: - explicit PtrWrapper(InterfacePtr<Interface> ptr) : ptr_(std::move(ptr)) {} - - explicit PtrWrapper( - scoped_refptr<ThreadSafeInterfacePtr<Interface>> thread_safe_ptr) - : thread_safe_ptr_(thread_safe_ptr) {} - - PtrWrapper(PtrWrapper&& other) = default; - - Interface* operator->() { - return thread_safe_ptr_ ? thread_safe_ptr_->get() : ptr_.get(); - } - - void set_connection_error_handler(const base::Closure& error_handler) { - DCHECK(!thread_safe_ptr_); - ptr_.set_connection_error_handler(error_handler); - } - - void reset() { - ptr_ = nullptr; - thread_safe_ptr_ = nullptr; - } - - private: - InterfacePtr<Interface> ptr_; - scoped_refptr<ThreadSafeInterfacePtr<Interface>> thread_safe_ptr_; - - DISALLOW_COPY_AND_ASSIGN(PtrWrapper); -}; - -// The type parameter for SyncMethodCommonTests for varying the Interface and -// whether to use InterfacePtr or ThreadSafeInterfacePtr. -template <typename InterfaceT, bool use_thread_safe_ptr> -struct TestParams { - using Interface = InterfaceT; - static const bool kIsThreadSafeInterfacePtrTest = use_thread_safe_ptr; - - static PtrWrapper<InterfaceT> Wrap(InterfacePtr<Interface> ptr) { - if (kIsThreadSafeInterfacePtrTest) { - return PtrWrapper<Interface>( - ThreadSafeInterfacePtr<Interface>::Create(std::move(ptr))); - } else { - return PtrWrapper<Interface>(std::move(ptr)); - } - } -}; - -template <typename Interface> -class TestSyncServiceThread { - public: - TestSyncServiceThread() - : thread_("TestSyncServiceThread"), ping_called_(false) { - thread_.Start(); - } - - void SetUp(InterfaceRequest<Interface> request) { - CHECK(thread_.task_runner()->BelongsToCurrentThread()); - impl_.reset(new ImplTypeFor<Interface>(std::move(request))); - impl_->set_ping_handler( - [this](const typename Interface::PingCallback& callback) { - { - base::AutoLock locker(lock_); - ping_called_ = true; - } - callback.Run(); - }); - } - - void TearDown() { - CHECK(thread_.task_runner()->BelongsToCurrentThread()); - impl_.reset(); - } - - base::Thread* thread() { return &thread_; } - bool ping_called() const { - base::AutoLock locker(lock_); - return ping_called_; - } - - private: - base::Thread thread_; - - std::unique_ptr<ImplTypeFor<Interface>> impl_; - - mutable base::Lock lock_; - bool ping_called_; - - DISALLOW_COPY_AND_ASSIGN(TestSyncServiceThread); -}; - -class SyncMethodTest : public testing::Test { - public: - SyncMethodTest() {} - ~SyncMethodTest() override { base::RunLoop().RunUntilIdle(); } - - protected: - base::MessageLoop loop_; -}; - -template <typename T> -class SyncMethodCommonTest : public SyncMethodTest { - public: - SyncMethodCommonTest() {} - ~SyncMethodCommonTest() override {} -}; - -class SyncMethodAssociatedTest : public SyncMethodTest { - public: - SyncMethodAssociatedTest() {} - ~SyncMethodAssociatedTest() override {} - - protected: - void SetUp() override { - master_impl_.reset(new TestSyncMasterImpl(MakeRequest(&master_ptr_))); - - asso_request_ = MakeRequest(&asso_ptr_info_); - opposite_asso_request_ = MakeRequest(&opposite_asso_ptr_info_); - - master_impl_->set_send_interface_handler( - [this](TestSyncAssociatedPtrInfo ptr) { - opposite_asso_ptr_info_ = std::move(ptr); - }); - base::RunLoop run_loop; - master_impl_->set_send_request_handler( - [this, &run_loop](TestSyncAssociatedRequest request) { - asso_request_ = std::move(request); - run_loop.Quit(); - }); - - master_ptr_->SendInterface(std::move(opposite_asso_ptr_info_)); - master_ptr_->SendRequest(std::move(asso_request_)); - run_loop.Run(); - } - - void TearDown() override { - asso_ptr_info_ = TestSyncAssociatedPtrInfo(); - asso_request_ = TestSyncAssociatedRequest(); - opposite_asso_ptr_info_ = TestSyncAssociatedPtrInfo(); - opposite_asso_request_ = TestSyncAssociatedRequest(); - - master_ptr_ = nullptr; - master_impl_.reset(); - } - - InterfacePtr<TestSyncMaster> master_ptr_; - std::unique_ptr<TestSyncMasterImpl> master_impl_; - - // An associated interface whose binding lives at the |master_impl_| side. - TestSyncAssociatedPtrInfo asso_ptr_info_; - TestSyncAssociatedRequest asso_request_; - - // An associated interface whose binding lives at the |master_ptr_| side. - TestSyncAssociatedPtrInfo opposite_asso_ptr_info_; - TestSyncAssociatedRequest opposite_asso_request_; -}; - -void SetFlagAndRunClosure(bool* flag, const base::Closure& closure) { - *flag = true; - closure.Run(); -} - -void ExpectValueAndRunClosure(int32_t expected_value, - const base::Closure& closure, - int32_t value) { - EXPECT_EQ(expected_value, value); - closure.Run(); -} - -template <typename Func> -void CallAsyncEchoCallback(Func func, int32_t value) { - func(value); -} - -template <typename Func> -TestSync::AsyncEchoCallback BindAsyncEchoCallback(Func func) { - return base::Bind(&CallAsyncEchoCallback<Func>, func); -} - -// TestSync (without associated interfaces) and TestSyncMaster (with associated -// interfaces) exercise MultiplexRouter with different configurations. -// Each test is run once with an InterfacePtr and once with a -// ThreadSafeInterfacePtr to ensure that they behave the same with respect to -// sync calls. -using InterfaceTypes = testing::Types<TestParams<TestSync, true>, - TestParams<TestSync, false>, - TestParams<TestSyncMaster, true>, - TestParams<TestSyncMaster, false>>; -TYPED_TEST_CASE(SyncMethodCommonTest, InterfaceTypes); - -TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { - using Interface = typename TypeParam::Interface; - InterfacePtr<Interface> interface_ptr; - ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); - auto ptr = TypeParam::Wrap(std::move(interface_ptr)); - - base::RunLoop run_loop; - ptr->Echo(123, base::Bind(&ExpectValueAndRunClosure, 123, - run_loop.QuitClosure())); - run_loop.Run(); -} - -TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) { - using Interface = typename TypeParam::Interface; - InterfacePtr<Interface> interface_ptr; - InterfaceRequest<Interface> request = MakeRequest(&interface_ptr); - auto ptr = TypeParam::Wrap(std::move(interface_ptr)); - - TestSyncServiceThread<Interface> service_thread; - service_thread.thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&TestSyncServiceThread<Interface>::SetUp, - base::Unretained(&service_thread), base::Passed(&request))); - ASSERT_TRUE(ptr->Ping()); - ASSERT_TRUE(service_thread.ping_called()); - - int32_t output_value = -1; - ASSERT_TRUE(ptr->Echo(42, &output_value)); - ASSERT_EQ(42, output_value); - - base::RunLoop run_loop; - service_thread.thread()->task_runner()->PostTaskAndReply( - FROM_HERE, - base::Bind(&TestSyncServiceThread<Interface>::TearDown, - base::Unretained(&service_thread)), - run_loop.QuitClosure()); - run_loop.Run(); -} - -TYPED_TEST(SyncMethodCommonTest, ReenteredBySyncMethodBinding) { - // Test that an interface pointer waiting for a sync call response can be - // reentered by a binding serving sync methods on the same thread. - - using Interface = typename TypeParam::Interface; - InterfacePtr<Interface> interface_ptr; - // The binding lives on the same thread as the interface pointer. - ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); - auto ptr = TypeParam::Wrap(std::move(interface_ptr)); - int32_t output_value = -1; - ASSERT_TRUE(ptr->Echo(42, &output_value)); - EXPECT_EQ(42, output_value); -} - -TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) { - // Test that it won't result in crash or hang if an interface pointer is - // destroyed while it is waiting for a sync call response. - - using Interface = typename TypeParam::Interface; - InterfacePtr<Interface> interface_ptr; - ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); - auto ptr = TypeParam::Wrap(std::move(interface_ptr)); - impl.set_ping_handler([&ptr](const TestSync::PingCallback& callback) { - ptr.reset(); - callback.Run(); - }); - ASSERT_FALSE(ptr->Ping()); -} - -TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) { - // Test that it won't result in crash or hang if a binding is - // closed (and therefore the message pipe handle is closed) while the - // corresponding interface pointer is waiting for a sync call response. - - using Interface = typename TypeParam::Interface; - InterfacePtr<Interface> interface_ptr; - ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); - auto ptr = TypeParam::Wrap(std::move(interface_ptr)); - impl.set_ping_handler([&impl](const TestSync::PingCallback& callback) { - impl.binding()->Close(); - callback.Run(); - }); - ASSERT_FALSE(ptr->Ping()); -} - -TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) { - // Test that we can call a sync method on an interface ptr, while there is - // already a sync call ongoing. The responses arrive in order. - - using Interface = typename TypeParam::Interface; - InterfacePtr<Interface> interface_ptr; - ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); - auto ptr = TypeParam::Wrap(std::move(interface_ptr)); - - // The same variable is used to store the output of the two sync calls, in - // order to test that responses are handled in the correct order. - int32_t result_value = -1; - - bool first_call = true; - impl.set_echo_handler([&first_call, &ptr, &result_value]( - int32_t value, const TestSync::EchoCallback& callback) { - if (first_call) { - first_call = false; - ASSERT_TRUE(ptr->Echo(456, &result_value)); - EXPECT_EQ(456, result_value); - } - callback.Run(value); - }); - - ASSERT_TRUE(ptr->Echo(123, &result_value)); - EXPECT_EQ(123, result_value); -} - -TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) { - // Test that we can call a sync method on an interface ptr, while there is - // already a sync call ongoing. The responses arrive out of order. - - using Interface = typename TypeParam::Interface; - InterfacePtr<Interface> interface_ptr; - ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); - auto ptr = TypeParam::Wrap(std::move(interface_ptr)); - - // The same variable is used to store the output of the two sync calls, in - // order to test that responses are handled in the correct order. - int32_t result_value = -1; - - bool first_call = true; - impl.set_echo_handler([&first_call, &ptr, &result_value]( - int32_t value, const TestSync::EchoCallback& callback) { - callback.Run(value); - if (first_call) { - first_call = false; - ASSERT_TRUE(ptr->Echo(456, &result_value)); - EXPECT_EQ(456, result_value); - } - }); - - ASSERT_TRUE(ptr->Echo(123, &result_value)); - EXPECT_EQ(123, result_value); -} - -TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) { - // Test that while an interface pointer is waiting for the response to a sync - // call, async responses are queued until the sync call completes. - - using Interface = typename TypeParam::Interface; - InterfacePtr<Interface> interface_ptr; - ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); - auto ptr = TypeParam::Wrap(std::move(interface_ptr)); - - int32_t async_echo_request_value = -1; - TestSync::AsyncEchoCallback async_echo_request_callback; - base::RunLoop run_loop1; - impl.set_async_echo_handler( - [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( - int32_t value, const TestSync::AsyncEchoCallback& callback) { - async_echo_request_value = value; - async_echo_request_callback = callback; - run_loop1.Quit(); - }); - - bool async_echo_response_dispatched = false; - base::RunLoop run_loop2; - ptr->AsyncEcho( - 123, - BindAsyncEchoCallback( - [&async_echo_response_dispatched, &run_loop2](int32_t result) { - async_echo_response_dispatched = true; - EXPECT_EQ(123, result); - run_loop2.Quit(); - })); - // Run until the AsyncEcho request reaches the service side. - run_loop1.Run(); - - impl.set_echo_handler( - [&async_echo_request_value, &async_echo_request_callback]( - int32_t value, const TestSync::EchoCallback& callback) { - // Send back the async response first. - EXPECT_FALSE(async_echo_request_callback.is_null()); - async_echo_request_callback.Run(async_echo_request_value); - - callback.Run(value); - }); - - int32_t result_value = -1; - ASSERT_TRUE(ptr->Echo(456, &result_value)); - EXPECT_EQ(456, result_value); - - // Although the AsyncEcho response arrives before the Echo response, it should - // be queued and not yet dispatched. - EXPECT_FALSE(async_echo_response_dispatched); - - // Run until the AsyncEcho response is dispatched. - run_loop2.Run(); - - EXPECT_TRUE(async_echo_response_dispatched); -} - -TYPED_TEST(SyncMethodCommonTest, AsyncRequestQueuedDuringSyncCall) { - // Test that while an interface pointer is waiting for the response to a sync - // call, async requests for a binding running on the same thread are queued - // until the sync call completes. - - using Interface = typename TypeParam::Interface; - InterfacePtr<Interface> interface_ptr; - ImplTypeFor<Interface> impl(MakeRequest(&interface_ptr)); - auto ptr = TypeParam::Wrap(std::move(interface_ptr)); - - bool async_echo_request_dispatched = false; - impl.set_async_echo_handler([&async_echo_request_dispatched]( - int32_t value, const TestSync::AsyncEchoCallback& callback) { - async_echo_request_dispatched = true; - callback.Run(value); - }); - - bool async_echo_response_dispatched = false; - base::RunLoop run_loop; - ptr->AsyncEcho( - 123, - BindAsyncEchoCallback( - [&async_echo_response_dispatched, &run_loop](int32_t result) { - async_echo_response_dispatched = true; - EXPECT_EQ(123, result); - run_loop.Quit(); - })); - - impl.set_echo_handler([&async_echo_request_dispatched]( - int32_t value, const TestSync::EchoCallback& callback) { - // Although the AsyncEcho request is sent before the Echo request, it - // shouldn't be dispatched yet at this point, because there is an ongoing - // sync call on the same thread. - EXPECT_FALSE(async_echo_request_dispatched); - callback.Run(value); - }); - - int32_t result_value = -1; - ASSERT_TRUE(ptr->Echo(456, &result_value)); - EXPECT_EQ(456, result_value); - - // Although the AsyncEcho request is sent before the Echo request, it - // shouldn't be dispatched yet. - EXPECT_FALSE(async_echo_request_dispatched); - - // Run until the AsyncEcho response is dispatched. - run_loop.Run(); - - EXPECT_TRUE(async_echo_response_dispatched); -} - -TYPED_TEST(SyncMethodCommonTest, - QueuedMessagesProcessedBeforeErrorNotification) { - // Test that while an interface pointer is waiting for the response to a sync - // call, async responses are queued. If the message pipe is disconnected - // before the queued messages are processed, the connection error - // notification is delayed until all the queued messages are processed. - - // ThreadSafeInterfacePtr doesn't guarantee that messages are delivered before - // error notifications, so skip it for this test. - if (TypeParam::kIsThreadSafeInterfacePtrTest) - return; - - using Interface = typename TypeParam::Interface; - InterfacePtr<Interface> ptr; - ImplTypeFor<Interface> impl(MakeRequest(&ptr)); - - int32_t async_echo_request_value = -1; - TestSync::AsyncEchoCallback async_echo_request_callback; - base::RunLoop run_loop1; - impl.set_async_echo_handler( - [&async_echo_request_value, &async_echo_request_callback, &run_loop1]( - int32_t value, const TestSync::AsyncEchoCallback& callback) { - async_echo_request_value = value; - async_echo_request_callback = callback; - run_loop1.Quit(); - }); - - bool async_echo_response_dispatched = false; - bool connection_error_dispatched = false; - base::RunLoop run_loop2; - ptr->AsyncEcho( - 123, - BindAsyncEchoCallback( - [&async_echo_response_dispatched, &connection_error_dispatched, &ptr, - &run_loop2](int32_t result) { - async_echo_response_dispatched = true; - // At this point, error notification should not be dispatched - // yet. - EXPECT_FALSE(connection_error_dispatched); - EXPECT_FALSE(ptr.encountered_error()); - EXPECT_EQ(123, result); - run_loop2.Quit(); - })); - // Run until the AsyncEcho request reaches the service side. - run_loop1.Run(); - - impl.set_echo_handler( - [&impl, &async_echo_request_value, &async_echo_request_callback]( - int32_t value, const TestSync::EchoCallback& callback) { - // Send back the async response first. - EXPECT_FALSE(async_echo_request_callback.is_null()); - async_echo_request_callback.Run(async_echo_request_value); - - impl.binding()->Close(); - }); - - base::RunLoop run_loop3; - ptr.set_connection_error_handler( - base::Bind(&SetFlagAndRunClosure, &connection_error_dispatched, - run_loop3.QuitClosure())); - - int32_t result_value = -1; - ASSERT_FALSE(ptr->Echo(456, &result_value)); - EXPECT_EQ(-1, result_value); - ASSERT_FALSE(connection_error_dispatched); - EXPECT_FALSE(ptr.encountered_error()); - - // Although the AsyncEcho response arrives before the Echo response, it should - // be queued and not yet dispatched. - EXPECT_FALSE(async_echo_response_dispatched); - - // Run until the AsyncEcho response is dispatched. - run_loop2.Run(); - - EXPECT_TRUE(async_echo_response_dispatched); - - // Run until the error notification is dispatched. - run_loop3.Run(); - - ASSERT_TRUE(connection_error_dispatched); - EXPECT_TRUE(ptr.encountered_error()); -} - -TYPED_TEST(SyncMethodCommonTest, InvalidMessageDuringSyncCall) { - // Test that while an interface pointer is waiting for the response to a sync - // call, an invalid incoming message will disconnect the message pipe, cause - // the sync call to return false, and run the connection error handler - // asynchronously. - - using Interface = typename TypeParam::Interface; - MessagePipe pipe; - - InterfacePtr<Interface> interface_ptr; - interface_ptr.Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u)); - auto ptr = TypeParam::Wrap(std::move(interface_ptr)); - - MessagePipeHandle raw_binding_handle = pipe.handle1.get(); - ImplTypeFor<Interface> impl(MakeRequest<Interface>(std::move(pipe.handle1))); - - impl.set_echo_handler([&raw_binding_handle]( - int32_t value, const TestSync::EchoCallback& callback) { - // Write a 1-byte message, which is considered invalid. - char invalid_message = 0; - MojoResult result = - WriteMessageRaw(raw_binding_handle, &invalid_message, 1u, nullptr, 0u, - MOJO_WRITE_MESSAGE_FLAG_NONE); - ASSERT_EQ(MOJO_RESULT_OK, result); - callback.Run(value); - }); - - bool connection_error_dispatched = false; - base::RunLoop run_loop; - // ThreadSafeInterfacePtr doesn't support setting connection error handlers. - if (!TypeParam::kIsThreadSafeInterfacePtrTest) { - ptr.set_connection_error_handler(base::Bind(&SetFlagAndRunClosure, - &connection_error_dispatched, - run_loop.QuitClosure())); - } - - int32_t result_value = -1; - ASSERT_FALSE(ptr->Echo(456, &result_value)); - EXPECT_EQ(-1, result_value); - ASSERT_FALSE(connection_error_dispatched); - - if (!TypeParam::kIsThreadSafeInterfacePtrTest) { - run_loop.Run(); - ASSERT_TRUE(connection_error_dispatched); - } -} - -TEST_F(SyncMethodAssociatedTest, ReenteredBySyncMethodAssoBindingOfSameRouter) { - // Test that an interface pointer waiting for a sync call response can be - // reentered by an associated binding serving sync methods on the same thread. - // The associated binding belongs to the same MultiplexRouter as the waiting - // interface pointer. - - TestSyncAssociatedImpl opposite_asso_impl(std::move(opposite_asso_request_)); - TestSyncAssociatedPtr opposite_asso_ptr; - opposite_asso_ptr.Bind(std::move(opposite_asso_ptr_info_)); - - master_impl_->set_echo_handler([&opposite_asso_ptr]( - int32_t value, const TestSyncMaster::EchoCallback& callback) { - int32_t result_value = -1; - - ASSERT_TRUE(opposite_asso_ptr->Echo(123, &result_value)); - EXPECT_EQ(123, result_value); - callback.Run(value); - }); - - int32_t result_value = -1; - ASSERT_TRUE(master_ptr_->Echo(456, &result_value)); - EXPECT_EQ(456, result_value); -} - -TEST_F(SyncMethodAssociatedTest, - ReenteredBySyncMethodAssoBindingOfDifferentRouter) { - // Test that an interface pointer waiting for a sync call response can be - // reentered by an associated binding serving sync methods on the same thread. - // The associated binding belongs to a different MultiplexRouter as the - // waiting interface pointer. - - TestSyncAssociatedImpl asso_impl(std::move(asso_request_)); - TestSyncAssociatedPtr asso_ptr; - asso_ptr.Bind(std::move(asso_ptr_info_)); - - master_impl_->set_echo_handler( - [&asso_ptr](int32_t value, const TestSyncMaster::EchoCallback& callback) { - int32_t result_value = -1; - - ASSERT_TRUE(asso_ptr->Echo(123, &result_value)); - EXPECT_EQ(123, result_value); - callback.Run(value); - }); - - int32_t result_value = -1; - ASSERT_TRUE(master_ptr_->Echo(456, &result_value)); - EXPECT_EQ(456, result_value); -} - -// TODO(yzshen): Add more tests related to associated interfaces. - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/test_native_types_blink.typemap b/mojo/public/cpp/bindings/tests/test_native_types_blink.typemap deleted file mode 100644 index 1bdfbbc..0000000 --- a/mojo/public/cpp/bindings/tests/test_native_types_blink.typemap +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//mojo/public/interfaces/bindings/tests/test_native_types.mojom" -public_headers = [ "//mojo/public/cpp/bindings/tests/pickled_types_blink.h" ] -sources = [ - "//mojo/public/cpp/bindings/tests/pickled_types_blink.cc", -] -deps = [ - "//ipc", -] - -type_mappings = [ - "mojo.test.PickledEnum=mojo::test::PickledEnumBlink", - "mojo.test.PickledStruct=mojo::test::PickledStructBlink[move_only]", -] diff --git a/mojo/public/cpp/bindings/tests/test_native_types_chromium.typemap b/mojo/public/cpp/bindings/tests/test_native_types_chromium.typemap deleted file mode 100644 index 50e8076..0000000 --- a/mojo/public/cpp/bindings/tests/test_native_types_chromium.typemap +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//mojo/public/interfaces/bindings/tests/test_native_types.mojom" -public_headers = [ "//mojo/public/cpp/bindings/tests/pickled_types_chromium.h" ] -sources = [ - "//mojo/public/cpp/bindings/tests/pickled_types_chromium.cc", -] -deps = [ - "//ipc", -] - -type_mappings = [ - "mojo.test.PickledEnum=mojo::test::PickledEnumChromium", - "mojo.test.PickledStruct=mojo::test::PickledStructChromium[move_only]", -] diff --git a/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc b/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc deleted file mode 100644 index b0124aa..0000000 --- a/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> - -#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -struct RedmondRect { - int32_t left; - int32_t top; - int32_t right; - int32_t bottom; -}; - -struct RedmondNamedRegion { - std::string name; - std::vector<RedmondRect> rects; -}; - -bool AreEqualRectArrays(const std::vector<test::RectPtr>& rects1, - const std::vector<test::RectPtr>& rects2) { - if (rects1.size() != rects2.size()) - return false; - - for (size_t i = 0; i < rects1.size(); ++i) { - if (rects1[i]->x != rects2[i]->x || rects1[i]->y != rects2[i]->y || - rects1[i]->width != rects2[i]->width || - rects1[i]->height != rects2[i]->height) { - return false; - } - } - - return true; -} - -} // namespace - -template <> -struct TypeConverter<test::RectPtr, RedmondRect> { - static test::RectPtr Convert(const RedmondRect& input) { - return test::Rect::New(input.left, input.top, input.right - input.left, - input.bottom - input.top); - } -}; - -template <> -struct TypeConverter<RedmondRect, test::RectPtr> { - static RedmondRect Convert(const test::RectPtr& input) { - RedmondRect rect; - rect.left = input->x; - rect.top = input->y; - rect.right = input->x + input->width; - rect.bottom = input->y + input->height; - return rect; - } -}; - -template <> -struct TypeConverter<test::NamedRegionPtr, RedmondNamedRegion> { - static test::NamedRegionPtr Convert(const RedmondNamedRegion& input) { - return test::NamedRegion::New( - input.name, ConvertTo<std::vector<test::RectPtr>>(input.rects)); - } -}; - -template <> -struct TypeConverter<RedmondNamedRegion, test::NamedRegionPtr> { - static RedmondNamedRegion Convert(const test::NamedRegionPtr& input) { - RedmondNamedRegion region; - if (input->name) - region.name = input->name.value(); - if (input->rects) { - region.rects.reserve(input->rects->size()); - for (const auto& element : *input->rects) - region.rects.push_back(element.To<RedmondRect>()); - } - return region; - } -}; - -namespace test { -namespace { - -TEST(TypeConversionTest, CustomTypeConverter) { - RectPtr rect(Rect::New(10, 20, 50, 45)); - - RedmondRect rr = rect.To<RedmondRect>(); - EXPECT_EQ(10, rr.left); - EXPECT_EQ(20, rr.top); - EXPECT_EQ(60, rr.right); - EXPECT_EQ(65, rr.bottom); - - RectPtr rect2(Rect::From(rr)); - EXPECT_EQ(rect->x, rect2->x); - EXPECT_EQ(rect->y, rect2->y); - EXPECT_EQ(rect->width, rect2->width); - EXPECT_EQ(rect->height, rect2->height); -} - -TEST(TypeConversionTest, CustomTypeConverter_Array_Null) { - std::vector<RectPtr> rects; - - auto redmond_rects = ConvertTo<std::vector<RedmondRect>>(rects); - - EXPECT_TRUE(redmond_rects.empty()); -} - -TEST(TypeConversionTest, CustomTypeConverter_Array) { - const RedmondRect kBase = {10, 20, 30, 40}; - - std::vector<RectPtr> rects(10); - for (size_t i = 0; i < rects.size(); ++i) { - RedmondRect rr = kBase; - rr.left += static_cast<int32_t>(i); - rr.top += static_cast<int32_t>(i); - rects[i] = Rect::From(rr); - } - - auto redmond_rects = ConvertTo<std::vector<RedmondRect>>(rects); - - auto rects2 = ConvertTo<std::vector<RectPtr>>(redmond_rects); - EXPECT_TRUE(AreEqualRectArrays(rects, rects2)); -} - -TEST(TypeConversionTest, CustomTypeConverter_Nested) { - RedmondNamedRegion redmond_region; - redmond_region.name = "foopy"; - - const RedmondRect kBase = {10, 20, 30, 40}; - - for (size_t i = 0; i < 10; ++i) { - RedmondRect rect = kBase; - rect.left += static_cast<int32_t>(i); - rect.top += static_cast<int32_t>(i); - redmond_region.rects.push_back(rect); - } - - // Round-trip through generated struct and TypeConverter. - - NamedRegionPtr copy = NamedRegion::From(redmond_region); - RedmondNamedRegion redmond_region2 = copy.To<RedmondNamedRegion>(); - - EXPECT_EQ(redmond_region.name, redmond_region2.name); - EXPECT_EQ(redmond_region.rects.size(), redmond_region2.rects.size()); - for (size_t i = 0; i < redmond_region.rects.size(); ++i) { - EXPECT_EQ(redmond_region.rects[i].left, redmond_region2.rects[i].left); - EXPECT_EQ(redmond_region.rects[i].top, redmond_region2.rects[i].top); - EXPECT_EQ(redmond_region.rects[i].right, redmond_region2.rects[i].right); - EXPECT_EQ(redmond_region.rects[i].bottom, redmond_region2.rects[i].bottom); - } -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/union_unittest.cc b/mojo/public/cpp/bindings/tests/union_unittest.cc deleted file mode 100644 index bdf27df..0000000 --- a/mojo/public/cpp/bindings/tests/union_unittest.cc +++ /dev/null @@ -1,1246 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> -#include <utility> -#include <vector> - -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/lib/array_internal.h" -#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" -#include "mojo/public/cpp/bindings/lib/serialization.h" -#include "mojo/public/cpp/bindings/lib/validation_context.h" -#include "mojo/public/cpp/bindings/lib/validation_errors.h" -#include "mojo/public/cpp/test_support/test_utils.h" -#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" -#include "mojo/public/interfaces/bindings/tests/test_unions.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { - -TEST(UnionTest, PlainOldDataGetterSetter) { - PodUnionPtr pod(PodUnion::New()); - - pod->set_f_int8(10); - EXPECT_EQ(10, pod->get_f_int8()); - EXPECT_TRUE(pod->is_f_int8()); - EXPECT_FALSE(pod->is_f_int8_other()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_INT8); - - pod->set_f_uint8(11); - EXPECT_EQ(11, pod->get_f_uint8()); - EXPECT_TRUE(pod->is_f_uint8()); - EXPECT_FALSE(pod->is_f_int8()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_UINT8); - - pod->set_f_int16(12); - EXPECT_EQ(12, pod->get_f_int16()); - EXPECT_TRUE(pod->is_f_int16()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_INT16); - - pod->set_f_uint16(13); - EXPECT_EQ(13, pod->get_f_uint16()); - EXPECT_TRUE(pod->is_f_uint16()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_UINT16); - - pod->set_f_int32(14); - EXPECT_EQ(14, pod->get_f_int32()); - EXPECT_TRUE(pod->is_f_int32()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_INT32); - - pod->set_f_uint32(static_cast<uint32_t>(15)); - EXPECT_EQ(static_cast<uint32_t>(15), pod->get_f_uint32()); - EXPECT_TRUE(pod->is_f_uint32()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_UINT32); - - pod->set_f_int64(16); - EXPECT_EQ(16, pod->get_f_int64()); - EXPECT_TRUE(pod->is_f_int64()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_INT64); - - pod->set_f_uint64(static_cast<uint64_t>(17)); - EXPECT_EQ(static_cast<uint64_t>(17), pod->get_f_uint64()); - EXPECT_TRUE(pod->is_f_uint64()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_UINT64); - - pod->set_f_float(1.5); - EXPECT_EQ(1.5, pod->get_f_float()); - EXPECT_TRUE(pod->is_f_float()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_FLOAT); - - pod->set_f_double(1.9); - EXPECT_EQ(1.9, pod->get_f_double()); - EXPECT_TRUE(pod->is_f_double()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_DOUBLE); - - pod->set_f_bool(true); - EXPECT_TRUE(pod->get_f_bool()); - pod->set_f_bool(false); - EXPECT_FALSE(pod->get_f_bool()); - EXPECT_TRUE(pod->is_f_bool()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_BOOL); - - pod->set_f_enum(AnEnum::SECOND); - EXPECT_EQ(AnEnum::SECOND, pod->get_f_enum()); - EXPECT_TRUE(pod->is_f_enum()); - EXPECT_EQ(pod->which(), PodUnion::Tag::F_ENUM); -} - -TEST(UnionTest, PodEquals) { - PodUnionPtr pod1(PodUnion::New()); - PodUnionPtr pod2(PodUnion::New()); - - pod1->set_f_int8(10); - pod2->set_f_int8(10); - EXPECT_TRUE(pod1.Equals(pod2)); - - pod2->set_f_int8(11); - EXPECT_FALSE(pod1.Equals(pod2)); - - pod2->set_f_int8_other(10); - EXPECT_FALSE(pod1.Equals(pod2)); -} - -TEST(UnionTest, PodClone) { - PodUnionPtr pod(PodUnion::New()); - pod->set_f_int8(10); - - PodUnionPtr pod_clone = pod.Clone(); - EXPECT_EQ(10, pod_clone->get_f_int8()); - EXPECT_TRUE(pod_clone->is_f_int8()); - EXPECT_EQ(pod_clone->which(), PodUnion::Tag::F_INT8); -} - -TEST(UnionTest, PodSerialization) { - PodUnionPtr pod1(PodUnion::New()); - pod1->set_f_int8(10); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>( - pod1, false, &context); - EXPECT_EQ(16U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod1, &buf, &data, false, - &context); - - PodUnionPtr pod2; - mojo::internal::Deserialize<PodUnionDataView>(data, &pod2, &context); - - EXPECT_EQ(10, pod2->get_f_int8()); - EXPECT_TRUE(pod2->is_f_int8()); - EXPECT_EQ(pod2->which(), PodUnion::Tag::F_INT8); -} - -TEST(UnionTest, EnumSerialization) { - PodUnionPtr pod1(PodUnion::New()); - pod1->set_f_enum(AnEnum::SECOND); - - size_t size = mojo::internal::PrepareToSerialize<PodUnionDataView>( - pod1, false, nullptr); - EXPECT_EQ(16U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod1, &buf, &data, false, - nullptr); - - PodUnionPtr pod2; - mojo::internal::Deserialize<PodUnionDataView>(data, &pod2, nullptr); - - EXPECT_EQ(AnEnum::SECOND, pod2->get_f_enum()); - EXPECT_TRUE(pod2->is_f_enum()); - EXPECT_EQ(pod2->which(), PodUnion::Tag::F_ENUM); -} - -TEST(UnionTest, PodValidation) { - PodUnionPtr pod(PodUnion::New()); - pod->set_f_int8(10); - - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); - EXPECT_EQ(16U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_TRUE( - internal::PodUnion_Data::Validate(raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, SerializeNotNull) { - PodUnionPtr pod(PodUnion::New()); - pod->set_f_int8(0); - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); - mojo::internal::FixedBufferForTesting buf(size); - internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); - EXPECT_FALSE(data->is_null()); -} - -TEST(UnionTest, SerializeIsNullInlined) { - PodUnionPtr pod; - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); - EXPECT_EQ(16U, size); - mojo::internal::FixedBufferForTesting buf(size); - internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); - - // Check that dirty output buffers are handled correctly by serialization. - data->size = 16U; - data->tag = PodUnion::Tag::F_UINT16; - data->data.f_f_int16 = 20; - - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, true, nullptr); - EXPECT_TRUE(data->is_null()); - - PodUnionPtr pod2; - mojo::internal::Deserialize<PodUnionDataView>(data, &pod2, nullptr); - EXPECT_TRUE(pod2.is_null()); -} - -TEST(UnionTest, SerializeIsNullNotInlined) { - PodUnionPtr pod; - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); - EXPECT_EQ(16U, size); - mojo::internal::FixedBufferForTesting buf(size); - internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); - EXPECT_EQ(nullptr, data); -} - -TEST(UnionTest, NullValidation) { - void* buf = nullptr; - mojo::internal::ValidationContext validation_context(buf, 0, 0, 0); - EXPECT_TRUE(internal::PodUnion_Data::Validate( - buf, &validation_context, false)); -} - -TEST(UnionTest, OutOfAlignmentValidation) { - size_t size = sizeof(internal::PodUnion_Data); - // Get an aligned object and shift the alignment. - mojo::internal::FixedBufferForTesting aligned_buf(size + 1); - void* raw_buf = aligned_buf.Leak(); - char* buf = reinterpret_cast<char*>(raw_buf) + 1; - - internal::PodUnion_Data* data = - reinterpret_cast<internal::PodUnion_Data*>(buf); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_FALSE(internal::PodUnion_Data::Validate( - buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, OOBValidation) { - size_t size = sizeof(internal::PodUnion_Data) - 1; - mojo::internal::FixedBufferForTesting buf(size); - internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - void* raw_buf = buf.Leak(); - EXPECT_FALSE( - internal::PodUnion_Data::Validate(raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, UnknownTagValidation) { - size_t size = sizeof(internal::PodUnion_Data); - mojo::internal::FixedBufferForTesting buf(size); - internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); - data->tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(0xFFFFFF); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - void* raw_buf = buf.Leak(); - EXPECT_FALSE( - internal::PodUnion_Data::Validate(raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, UnknownEnumValueValidation) { - PodUnionPtr pod(PodUnion::New()); - pod->set_f_enum(static_cast<AnEnum>(0xFFFF)); - - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); - EXPECT_EQ(16U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_FALSE( - internal::PodUnion_Data::Validate(raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, UnknownExtensibleEnumValueValidation) { - PodUnionPtr pod(PodUnion::New()); - pod->set_f_extensible_enum(static_cast<AnExtensibleEnum>(0xFFFF)); - - size_t size = - mojo::internal::PrepareToSerialize<PodUnionDataView>(pod, false, nullptr); - EXPECT_EQ(16U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::PodUnion_Data* data = nullptr; - mojo::internal::Serialize<PodUnionDataView>(pod, &buf, &data, false, nullptr); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_TRUE( - internal::PodUnion_Data::Validate(raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, StringGetterSetter) { - ObjectUnionPtr pod(ObjectUnion::New()); - - std::string hello("hello world"); - pod->set_f_string(hello); - EXPECT_EQ(hello, pod->get_f_string()); - EXPECT_TRUE(pod->is_f_string()); - EXPECT_EQ(pod->which(), ObjectUnion::Tag::F_STRING); -} - -TEST(UnionTest, StringEquals) { - ObjectUnionPtr pod1(ObjectUnion::New()); - ObjectUnionPtr pod2(ObjectUnion::New()); - - pod1->set_f_string("hello world"); - pod2->set_f_string("hello world"); - EXPECT_TRUE(pod1.Equals(pod2)); - - pod2->set_f_string("hello universe"); - EXPECT_FALSE(pod1.Equals(pod2)); -} - -TEST(UnionTest, StringClone) { - ObjectUnionPtr pod(ObjectUnion::New()); - - std::string hello("hello world"); - pod->set_f_string(hello); - ObjectUnionPtr pod_clone = pod.Clone(); - EXPECT_EQ(hello, pod_clone->get_f_string()); - EXPECT_TRUE(pod_clone->is_f_string()); - EXPECT_EQ(pod_clone->which(), ObjectUnion::Tag::F_STRING); -} - -TEST(UnionTest, StringSerialization) { - ObjectUnionPtr pod1(ObjectUnion::New()); - - std::string hello("hello world"); - pod1->set_f_string(hello); - - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - pod1, false, nullptr); - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(pod1, &buf, &data, false, - nullptr); - - ObjectUnionPtr pod2; - mojo::internal::Deserialize<ObjectUnionDataView>(data, &pod2, nullptr); - EXPECT_EQ(hello, pod2->get_f_string()); - EXPECT_TRUE(pod2->is_f_string()); - EXPECT_EQ(pod2->which(), ObjectUnion::Tag::F_STRING); -} - -TEST(UnionTest, NullStringValidation) { - size_t size = sizeof(internal::ObjectUnion_Data); - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); - data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; - data->data.unknown = 0x0; - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - void* raw_buf = buf.Leak(); - EXPECT_FALSE(internal::ObjectUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, StringPointerOverflowValidation) { - size_t size = sizeof(internal::ObjectUnion_Data); - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); - data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; - data->data.unknown = 0xFFFFFFFFFFFFFFFF; - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - void* raw_buf = buf.Leak(); - EXPECT_FALSE(internal::ObjectUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, StringValidateOOB) { - size_t size = 32; - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); - data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; - - data->data.f_f_string.offset = 8; - char* ptr = reinterpret_cast<char*>(&data->data.f_f_string); - mojo::internal::ArrayHeader* array_header = - reinterpret_cast<mojo::internal::ArrayHeader*>(ptr + *ptr); - array_header->num_bytes = 20; // This should go out of bounds. - array_header->num_elements = 20; - mojo::internal::ValidationContext validation_context(data, 32, 0, 0); - void* raw_buf = buf.Leak(); - EXPECT_FALSE(internal::ObjectUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -// TODO(azani): Move back in array_unittest.cc when possible. -// Array tests -TEST(UnionTest, PodUnionInArray) { - SmallStructPtr small_struct(SmallStruct::New()); - small_struct->pod_union_array.emplace(2); - small_struct->pod_union_array.value()[0] = PodUnion::New(); - small_struct->pod_union_array.value()[1] = PodUnion::New(); - - small_struct->pod_union_array.value()[0]->set_f_int8(10); - small_struct->pod_union_array.value()[1]->set_f_int16(12); - - EXPECT_EQ(10, small_struct->pod_union_array.value()[0]->get_f_int8()); - EXPECT_EQ(12, small_struct->pod_union_array.value()[1]->get_f_int16()); -} - -TEST(UnionTest, PodUnionInArraySerialization) { - std::vector<PodUnionPtr> array(2); - array[0] = PodUnion::New(); - array[1] = PodUnion::New(); - - array[0]->set_f_int8(10); - array[1]->set_f_int16(12); - EXPECT_EQ(2U, array.size()); - - size_t size = - mojo::internal::PrepareToSerialize<ArrayDataView<PodUnionDataView>>( - array, nullptr); - EXPECT_EQ(40U, size); - - mojo::internal::FixedBufferForTesting buf(size); - mojo::internal::Array_Data<internal::PodUnion_Data>* data; - mojo::internal::ContainerValidateParams validate_params(0, false, nullptr); - mojo::internal::Serialize<ArrayDataView<PodUnionDataView>>( - array, &buf, &data, &validate_params, nullptr); - - std::vector<PodUnionPtr> array2; - mojo::internal::Deserialize<ArrayDataView<PodUnionDataView>>(data, &array2, - nullptr); - - EXPECT_EQ(2U, array2.size()); - - EXPECT_EQ(10, array2[0]->get_f_int8()); - EXPECT_EQ(12, array2[1]->get_f_int16()); -} - -TEST(UnionTest, PodUnionInArraySerializationWithNull) { - std::vector<PodUnionPtr> array(2); - array[0] = PodUnion::New(); - - array[0]->set_f_int8(10); - EXPECT_EQ(2U, array.size()); - - size_t size = - mojo::internal::PrepareToSerialize<ArrayDataView<PodUnionDataView>>( - array, nullptr); - EXPECT_EQ(40U, size); - - mojo::internal::FixedBufferForTesting buf(size); - mojo::internal::Array_Data<internal::PodUnion_Data>* data; - mojo::internal::ContainerValidateParams validate_params(0, true, nullptr); - mojo::internal::Serialize<ArrayDataView<PodUnionDataView>>( - array, &buf, &data, &validate_params, nullptr); - - std::vector<PodUnionPtr> array2; - mojo::internal::Deserialize<ArrayDataView<PodUnionDataView>>(data, &array2, - nullptr); - - EXPECT_EQ(2U, array2.size()); - - EXPECT_EQ(10, array2[0]->get_f_int8()); - EXPECT_TRUE(array2[1].is_null()); -} - -TEST(UnionTest, ObjectUnionInArraySerialization) { - std::vector<ObjectUnionPtr> array(2); - array[0] = ObjectUnion::New(); - array[1] = ObjectUnion::New(); - - array[0]->set_f_string("hello"); - array[1]->set_f_string("world"); - EXPECT_EQ(2U, array.size()); - - size_t size = - mojo::internal::PrepareToSerialize<ArrayDataView<ObjectUnionDataView>>( - array, nullptr); - EXPECT_EQ(72U, size); - - mojo::internal::FixedBufferForTesting buf(size); - - mojo::internal::Array_Data<internal::ObjectUnion_Data>* data; - mojo::internal::ContainerValidateParams validate_params(0, false, nullptr); - mojo::internal::Serialize<ArrayDataView<ObjectUnionDataView>>( - array, &buf, &data, &validate_params, nullptr); - - std::vector<char> new_buf; - new_buf.resize(size); - - void* raw_buf = buf.Leak(); - memcpy(new_buf.data(), raw_buf, size); - free(raw_buf); - - data = - reinterpret_cast<mojo::internal::Array_Data<internal::ObjectUnion_Data>*>( - new_buf.data()); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - ASSERT_TRUE(mojo::internal::Array_Data<internal::ObjectUnion_Data>::Validate( - data, &validation_context, &validate_params)); - - std::vector<ObjectUnionPtr> array2; - mojo::internal::Deserialize<ArrayDataView<ObjectUnionDataView>>(data, &array2, - nullptr); - - EXPECT_EQ(2U, array2.size()); - - EXPECT_EQ("hello", array2[0]->get_f_string()); - EXPECT_EQ("world", array2[1]->get_f_string()); -} - -// TODO(azani): Move back in struct_unittest.cc when possible. -// Struct tests -TEST(UnionTest, Clone_Union) { - SmallStructPtr small_struct(SmallStruct::New()); - small_struct->pod_union = PodUnion::New(); - small_struct->pod_union->set_f_int8(10); - - SmallStructPtr clone = small_struct.Clone(); - EXPECT_EQ(10, clone->pod_union->get_f_int8()); -} - -// Serialization test of a struct with a union of plain old data. -TEST(UnionTest, Serialization_UnionOfPods) { - SmallStructPtr small_struct(SmallStruct::New()); - small_struct->pod_union = PodUnion::New(); - small_struct->pod_union->set_f_int32(10); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<SmallStructDataView>( - small_struct, &context); - - mojo::internal::FixedBufferForTesting buf(size); - internal::SmallStruct_Data* data = nullptr; - mojo::internal::Serialize<SmallStructDataView>(small_struct, &buf, &data, - &context); - - SmallStructPtr deserialized; - mojo::internal::Deserialize<SmallStructDataView>(data, &deserialized, - &context); - - EXPECT_EQ(10, deserialized->pod_union->get_f_int32()); -} - -// Serialization test of a struct with a union of structs. -TEST(UnionTest, Serialization_UnionOfObjects) { - SmallObjStructPtr obj_struct(SmallObjStruct::New()); - obj_struct->obj_union = ObjectUnion::New(); - std::string hello("hello world"); - obj_struct->obj_union->set_f_string(hello); - - size_t size = mojo::internal::PrepareToSerialize<SmallObjStructDataView>( - obj_struct, nullptr); - - mojo::internal::FixedBufferForTesting buf(size); - internal::SmallObjStruct_Data* data = nullptr; - mojo::internal::Serialize<SmallObjStructDataView>(obj_struct, &buf, &data, - nullptr); - - SmallObjStructPtr deserialized; - mojo::internal::Deserialize<SmallObjStructDataView>(data, &deserialized, - nullptr); - - EXPECT_EQ(hello, deserialized->obj_union->get_f_string()); -} - -// Validation test of a struct with a union. -TEST(UnionTest, Validation_UnionsInStruct) { - SmallStructPtr small_struct(SmallStruct::New()); - small_struct->pod_union = PodUnion::New(); - small_struct->pod_union->set_f_int32(10); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<SmallStructDataView>( - small_struct, &context); - - mojo::internal::FixedBufferForTesting buf(size); - internal::SmallStruct_Data* data = nullptr; - mojo::internal::Serialize<SmallStructDataView>(small_struct, &buf, &data, - &context); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_TRUE(internal::SmallStruct_Data::Validate( - raw_buf, &validation_context)); - free(raw_buf); -} - -// Validation test of a struct union fails due to unknown union tag. -TEST(UnionTest, Validation_PodUnionInStruct_Failure) { - SmallStructPtr small_struct(SmallStruct::New()); - small_struct->pod_union = PodUnion::New(); - small_struct->pod_union->set_f_int32(10); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<SmallStructDataView>( - small_struct, &context); - - mojo::internal::FixedBufferForTesting buf(size); - internal::SmallStruct_Data* data = nullptr; - mojo::internal::Serialize<SmallStructDataView>(small_struct, &buf, &data, - &context); - data->pod_union.tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(100); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_FALSE(internal::SmallStruct_Data::Validate( - raw_buf, &validation_context)); - free(raw_buf); -} - -// Validation fails due to non-nullable null union in struct. -TEST(UnionTest, Validation_NullUnion_Failure) { - SmallStructNonNullableUnionPtr small_struct( - SmallStructNonNullableUnion::New()); - - size_t size = - mojo::internal::PrepareToSerialize<SmallStructNonNullableUnionDataView>( - small_struct, nullptr); - - mojo::internal::FixedBufferForTesting buf(size); - internal::SmallStructNonNullableUnion_Data* data = - internal::SmallStructNonNullableUnion_Data::New(&buf); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_FALSE(internal::SmallStructNonNullableUnion_Data::Validate( - raw_buf, &validation_context)); - free(raw_buf); -} - -// Validation passes with nullable null union. -TEST(UnionTest, Validation_NullableUnion) { - SmallStructPtr small_struct(SmallStruct::New()); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<SmallStructDataView>( - small_struct, &context); - - mojo::internal::FixedBufferForTesting buf(size); - internal::SmallStruct_Data* data = nullptr; - mojo::internal::Serialize<SmallStructDataView>(small_struct, &buf, &data, - &context); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_TRUE(internal::SmallStruct_Data::Validate( - raw_buf, &validation_context)); - free(raw_buf); -} - -// TODO(azani): Move back in map_unittest.cc when possible. -// Map Tests -TEST(UnionTest, PodUnionInMap) { - SmallStructPtr small_struct(SmallStruct::New()); - small_struct->pod_union_map.emplace(); - small_struct->pod_union_map.value()["one"] = PodUnion::New(); - small_struct->pod_union_map.value()["two"] = PodUnion::New(); - - small_struct->pod_union_map.value()["one"]->set_f_int8(8); - small_struct->pod_union_map.value()["two"]->set_f_int16(16); - - EXPECT_EQ(8, small_struct->pod_union_map.value()["one"]->get_f_int8()); - EXPECT_EQ(16, small_struct->pod_union_map.value()["two"]->get_f_int16()); -} - -TEST(UnionTest, PodUnionInMapSerialization) { - using MojomType = MapDataView<StringDataView, PodUnionDataView>; - - std::unordered_map<std::string, PodUnionPtr> map; - map.insert(std::make_pair("one", PodUnion::New())); - map.insert(std::make_pair("two", PodUnion::New())); - - map["one"]->set_f_int8(8); - map["two"]->set_f_int16(16); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<MojomType>(map, &context); - EXPECT_EQ(120U, size); - - mojo::internal::FixedBufferForTesting buf(size); - - typename mojo::internal::MojomTypeTraits<MojomType>::Data* data; - mojo::internal::ContainerValidateParams validate_params( - new mojo::internal::ContainerValidateParams(0, false, nullptr), - new mojo::internal::ContainerValidateParams(0, false, nullptr)); - mojo::internal::Serialize<MojomType>(map, &buf, &data, &validate_params, - &context); - - std::unordered_map<std::string, PodUnionPtr> map2; - mojo::internal::Deserialize<MojomType>(data, &map2, &context); - - EXPECT_EQ(8, map2["one"]->get_f_int8()); - EXPECT_EQ(16, map2["two"]->get_f_int16()); -} - -TEST(UnionTest, PodUnionInMapSerializationWithNull) { - using MojomType = MapDataView<StringDataView, PodUnionDataView>; - - std::unordered_map<std::string, PodUnionPtr> map; - map.insert(std::make_pair("one", PodUnion::New())); - map.insert(std::make_pair("two", nullptr)); - - map["one"]->set_f_int8(8); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<MojomType>(map, &context); - EXPECT_EQ(120U, size); - - mojo::internal::FixedBufferForTesting buf(size); - typename mojo::internal::MojomTypeTraits<MojomType>::Data* data; - mojo::internal::ContainerValidateParams validate_params( - new mojo::internal::ContainerValidateParams(0, false, nullptr), - new mojo::internal::ContainerValidateParams(0, true, nullptr)); - mojo::internal::Serialize<MojomType>(map, &buf, &data, &validate_params, - &context); - - std::unordered_map<std::string, PodUnionPtr> map2; - mojo::internal::Deserialize<MojomType>(data, &map2, &context); - - EXPECT_EQ(8, map2["one"]->get_f_int8()); - EXPECT_TRUE(map2["two"].is_null()); -} - -TEST(UnionTest, StructInUnionGetterSetterPasser) { - DummyStructPtr dummy(DummyStruct::New()); - dummy->f_int8 = 8; - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_dummy(std::move(dummy)); - - EXPECT_EQ(8, obj->get_f_dummy()->f_int8); -} - -TEST(UnionTest, StructInUnionSerialization) { - DummyStructPtr dummy(DummyStruct::New()); - dummy->f_int8 = 8; - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_dummy(std::move(dummy)); - - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); - EXPECT_EQ(32U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); - - ObjectUnionPtr obj2; - mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr); - EXPECT_EQ(8, obj2->get_f_dummy()->f_int8); -} - -TEST(UnionTest, StructInUnionValidation) { - DummyStructPtr dummy(DummyStruct::New()); - dummy->f_int8 = 8; - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_dummy(std::move(dummy)); - - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); - - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_TRUE(internal::ObjectUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, StructInUnionValidationNonNullable) { - mojo::internal::SerializationWarningObserverForTesting suppress_warning; - - DummyStructPtr dummy(nullptr); - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_dummy(std::move(dummy)); - - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); - - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_FALSE(internal::ObjectUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, StructInUnionValidationNullable) { - DummyStructPtr dummy(nullptr); - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_nullable(std::move(dummy)); - - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); - - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_TRUE(internal::ObjectUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, ArrayInUnionGetterSetter) { - std::vector<int8_t> array(2); - array[0] = 8; - array[1] = 9; - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_array_int8(std::move(array)); - - EXPECT_EQ(8, obj->get_f_array_int8()[0]); - EXPECT_EQ(9, obj->get_f_array_int8()[1]); -} - -TEST(UnionTest, ArrayInUnionSerialization) { - std::vector<int8_t> array(2); - array[0] = 8; - array[1] = 9; - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_array_int8(std::move(array)); - - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); - EXPECT_EQ(32U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); - - ObjectUnionPtr obj2; - mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr); - - EXPECT_EQ(8, obj2->get_f_array_int8()[0]); - EXPECT_EQ(9, obj2->get_f_array_int8()[1]); -} - -TEST(UnionTest, ArrayInUnionValidation) { - std::vector<int8_t> array(2); - array[0] = 8; - array[1] = 9; - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_array_int8(std::move(array)); - - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - - EXPECT_TRUE(internal::ObjectUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, MapInUnionGetterSetter) { - std::unordered_map<std::string, int8_t> map; - map.insert({"one", 1}); - map.insert({"two", 2}); - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_map_int8(std::move(map)); - - EXPECT_EQ(1, obj->get_f_map_int8()["one"]); - EXPECT_EQ(2, obj->get_f_map_int8()["two"]); -} - -TEST(UnionTest, MapInUnionSerialization) { - std::unordered_map<std::string, int8_t> map; - map.insert({"one", 1}); - map.insert({"two", 2}); - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_map_int8(std::move(map)); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, &context); - EXPECT_EQ(112U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - &context); - - ObjectUnionPtr obj2; - mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, &context); - - EXPECT_EQ(1, obj2->get_f_map_int8()["one"]); - EXPECT_EQ(2, obj2->get_f_map_int8()["two"]); -} - -TEST(UnionTest, MapInUnionValidation) { - std::unordered_map<std::string, int8_t> map; - map.insert({"one", 1}); - map.insert({"two", 2}); - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_map_int8(std::move(map)); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, &context); - EXPECT_EQ(112U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - &context); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - - EXPECT_TRUE(internal::ObjectUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, UnionInUnionGetterSetter) { - PodUnionPtr pod(PodUnion::New()); - pod->set_f_int8(10); - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_pod_union(std::move(pod)); - - EXPECT_EQ(10, obj->get_f_pod_union()->get_f_int8()); -} - -TEST(UnionTest, UnionInUnionSerialization) { - PodUnionPtr pod(PodUnion::New()); - pod->set_f_int8(10); - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_pod_union(std::move(pod)); - - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); - EXPECT_EQ(32U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); - - ObjectUnionPtr obj2; - mojo::internal::Deserialize<ObjectUnionDataView>(data, &obj2, nullptr); - EXPECT_EQ(10, obj2->get_f_pod_union()->get_f_int8()); -} - -TEST(UnionTest, UnionInUnionValidation) { - PodUnionPtr pod(PodUnion::New()); - pod->set_f_int8(10); - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_pod_union(std::move(pod)); - - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); - EXPECT_EQ(32U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_TRUE(internal::ObjectUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, UnionInUnionValidationNonNullable) { - mojo::internal::SerializationWarningObserverForTesting suppress_warning; - - PodUnionPtr pod(nullptr); - - ObjectUnionPtr obj(ObjectUnion::New()); - obj->set_f_pod_union(std::move(pod)); - - size_t size = mojo::internal::PrepareToSerialize<ObjectUnionDataView>( - obj, false, nullptr); - - mojo::internal::FixedBufferForTesting buf(size); - internal::ObjectUnion_Data* data = nullptr; - mojo::internal::Serialize<ObjectUnionDataView>(obj, &buf, &data, false, - nullptr); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 0, 0); - EXPECT_FALSE(internal::ObjectUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, HandleInUnionGetterSetter) { - ScopedMessagePipeHandle pipe0; - ScopedMessagePipeHandle pipe1; - - CreateMessagePipe(nullptr, &pipe0, &pipe1); - - HandleUnionPtr handle(HandleUnion::New()); - handle->set_f_message_pipe(std::move(pipe1)); - - std::string golden("hello world"); - WriteTextMessage(pipe0.get(), golden); - - std::string actual; - ReadTextMessage(handle->get_f_message_pipe().get(), &actual); - - EXPECT_EQ(golden, actual); -} - -TEST(UnionTest, HandleInUnionSerialization) { - ScopedMessagePipeHandle pipe0; - ScopedMessagePipeHandle pipe1; - - CreateMessagePipe(nullptr, &pipe0, &pipe1); - - HandleUnionPtr handle(HandleUnion::New()); - handle->set_f_message_pipe(std::move(pipe1)); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<HandleUnionDataView>( - handle, false, &context); - EXPECT_EQ(16U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::HandleUnion_Data* data = nullptr; - mojo::internal::Serialize<HandleUnionDataView>(handle, &buf, &data, false, - &context); - EXPECT_EQ(1U, context.handles.size()); - - HandleUnionPtr handle2(HandleUnion::New()); - mojo::internal::Deserialize<HandleUnionDataView>(data, &handle2, &context); - - std::string golden("hello world"); - WriteTextMessage(pipe0.get(), golden); - - std::string actual; - ReadTextMessage(handle2->get_f_message_pipe().get(), &actual); - - EXPECT_EQ(golden, actual); -} - -TEST(UnionTest, HandleInUnionValidation) { - ScopedMessagePipeHandle pipe0; - ScopedMessagePipeHandle pipe1; - - CreateMessagePipe(nullptr, &pipe0, &pipe1); - - HandleUnionPtr handle(HandleUnion::New()); - handle->set_f_message_pipe(std::move(pipe1)); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<HandleUnionDataView>( - handle, false, &context); - EXPECT_EQ(16U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::HandleUnion_Data* data = nullptr; - mojo::internal::Serialize<HandleUnionDataView>(handle, &buf, &data, false, - &context); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 1, 0); - EXPECT_TRUE(internal::HandleUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -TEST(UnionTest, HandleInUnionValidationNull) { - mojo::internal::SerializationWarningObserverForTesting suppress_warning; - - ScopedMessagePipeHandle pipe; - HandleUnionPtr handle(HandleUnion::New()); - handle->set_f_message_pipe(std::move(pipe)); - - mojo::internal::SerializationContext context; - size_t size = mojo::internal::PrepareToSerialize<HandleUnionDataView>( - handle, false, &context); - EXPECT_EQ(16U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::HandleUnion_Data* data = nullptr; - mojo::internal::Serialize<HandleUnionDataView>(handle, &buf, &data, false, - &context); - - void* raw_buf = buf.Leak(); - mojo::internal::ValidationContext validation_context( - data, static_cast<uint32_t>(size), 1, 0); - EXPECT_FALSE(internal::HandleUnion_Data::Validate( - raw_buf, &validation_context, false)); - free(raw_buf); -} - -class SmallCacheImpl : public SmallCache { - public: - explicit SmallCacheImpl(const base::Closure& closure) - : int_value_(0), closure_(closure) {} - ~SmallCacheImpl() override {} - int64_t int_value() const { return int_value_; } - - private: - void SetIntValue(int64_t int_value) override { - int_value_ = int_value; - closure_.Run(); - } - void GetIntValue(const GetIntValueCallback& callback) override { - callback.Run(int_value_); - } - - int64_t int_value_; - base::Closure closure_; -}; - -TEST(UnionTest, InterfaceInUnion) { - base::MessageLoop message_loop; - base::RunLoop run_loop; - SmallCacheImpl impl(run_loop.QuitClosure()); - SmallCachePtr ptr; - Binding<SmallCache> bindings(&impl, MakeRequest(&ptr)); - - HandleUnionPtr handle(HandleUnion::New()); - handle->set_f_small_cache(std::move(ptr)); - - handle->get_f_small_cache()->SetIntValue(10); - run_loop.Run(); - EXPECT_EQ(10, impl.int_value()); -} - -TEST(UnionTest, InterfaceInUnionSerialization) { - base::MessageLoop message_loop; - base::RunLoop run_loop; - SmallCacheImpl impl(run_loop.QuitClosure()); - SmallCachePtr ptr; - Binding<SmallCache> bindings(&impl, MakeRequest(&ptr)); - - mojo::internal::SerializationContext context; - HandleUnionPtr handle(HandleUnion::New()); - handle->set_f_small_cache(std::move(ptr)); - size_t size = mojo::internal::PrepareToSerialize<HandleUnionDataView>( - handle, false, &context); - EXPECT_EQ(16U, size); - - mojo::internal::FixedBufferForTesting buf(size); - internal::HandleUnion_Data* data = nullptr; - mojo::internal::Serialize<HandleUnionDataView>(handle, &buf, &data, false, - &context); - EXPECT_EQ(1U, context.handles.size()); - - HandleUnionPtr handle2(HandleUnion::New()); - mojo::internal::Deserialize<HandleUnionDataView>(data, &handle2, &context); - - handle2->get_f_small_cache()->SetIntValue(10); - run_loop.Run(); - EXPECT_EQ(10, impl.int_value()); -} - -class UnionInterfaceImpl : public UnionInterface { - public: - UnionInterfaceImpl() {} - ~UnionInterfaceImpl() override {} - - private: - void Echo(PodUnionPtr in, const EchoCallback& callback) override { - callback.Run(std::move(in)); - } -}; - -void ExpectInt16(int16_t value, PodUnionPtr out) { - EXPECT_EQ(value, out->get_f_int16()); -} - -TEST(UnionTest, UnionInInterface) { - base::MessageLoop message_loop; - UnionInterfaceImpl impl; - UnionInterfacePtr ptr; - Binding<UnionInterface> bindings(&impl, MakeRequest(&ptr)); - - PodUnionPtr pod(PodUnion::New()); - pod->set_f_int16(16); - - ptr->Echo(std::move(pod), base::Bind(&ExpectInt16, 16)); - base::RunLoop().RunUntilIdle(); -} - -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/validation_context_unittest.cc b/mojo/public/cpp/bindings/tests/validation_context_unittest.cc deleted file mode 100644 index 9ce9d60..0000000 --- a/mojo/public/cpp/bindings/tests/validation_context_unittest.cc +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> - -#include <limits> - -#include "mojo/public/cpp/bindings/lib/serialization_util.h" -#include "mojo/public/cpp/bindings/lib/validation_context.h" -#include "mojo/public/cpp/system/core.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -using Handle_Data = mojo::internal::Handle_Data; -using AssociatedEndpointHandle_Data = - mojo::internal::AssociatedEndpointHandle_Data; - -const void* ToPtr(uintptr_t ptr) { - return reinterpret_cast<const void*>(ptr); -} - -#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) -TEST(ValidationContextTest, ConstructorRangeOverflow) { - { - // Test memory range overflow. - internal::ValidationContext context( - ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 5000, 0, 0); - - EXPECT_FALSE(context.IsValidRange( - ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 1)); - EXPECT_FALSE(context.ClaimMemory( - ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 1)); - } - - if (sizeof(size_t) <= sizeof(uint32_t)) - return; - - { - // Test handle index range overflow. - size_t num_handles = - static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 5; - internal::ValidationContext context(ToPtr(0), 0, num_handles, 0); - - EXPECT_FALSE(context.ClaimHandle(Handle_Data(0))); - EXPECT_FALSE(context.ClaimHandle( - Handle_Data(std::numeric_limits<uint32_t>::max() - 1))); - - EXPECT_TRUE(context.ClaimHandle( - Handle_Data(internal::kEncodedInvalidHandleValue))); - } - - { - size_t num_associated_endpoint_handles = - static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 5; - internal::ValidationContext context(ToPtr(0), 0, 0, - num_associated_endpoint_handles); - - EXPECT_FALSE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(0))); - EXPECT_FALSE( - context.ClaimAssociatedEndpointHandle(AssociatedEndpointHandle_Data( - std::numeric_limits<uint32_t>::max() - 1))); - - EXPECT_TRUE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue))); - } -} -#endif - -TEST(ValidationContextTest, IsValidRange) { - { - internal::ValidationContext context(ToPtr(1234), 100, 0, 0); - - // Basics. - EXPECT_FALSE(context.IsValidRange(ToPtr(100), 5)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1230), 50)); - EXPECT_TRUE(context.IsValidRange(ToPtr(1234), 5)); - EXPECT_TRUE(context.IsValidRange(ToPtr(1240), 50)); - EXPECT_TRUE(context.IsValidRange(ToPtr(1234), 100)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 101)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1240), 100)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1333), 5)); - EXPECT_FALSE(context.IsValidRange(ToPtr(2234), 5)); - - // ClaimMemory() updates the valid range. - EXPECT_TRUE(context.ClaimMemory(ToPtr(1254), 10)); - - EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 1)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1254), 10)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1263), 1)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1263), 10)); - EXPECT_TRUE(context.IsValidRange(ToPtr(1264), 10)); - EXPECT_TRUE(context.IsValidRange(ToPtr(1264), 70)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1264), 71)); - } - - { - internal::ValidationContext context(ToPtr(1234), 100, 0, 0); - // Should return false for empty ranges. - EXPECT_FALSE(context.IsValidRange(ToPtr(0), 0)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1200), 0)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 0)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1240), 0)); - EXPECT_FALSE(context.IsValidRange(ToPtr(2234), 0)); - } - - { - // The valid memory range is empty. - internal::ValidationContext context(ToPtr(1234), 0, 0, 0); - - EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 1)); - EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 0)); - } - - { - internal::ValidationContext context( - ToPtr(std::numeric_limits<uintptr_t>::max() - 2000), 1000, 0, 0); - - // Test overflow. - EXPECT_FALSE(context.IsValidRange( - ToPtr(std::numeric_limits<uintptr_t>::max() - 1500), 4000)); - EXPECT_FALSE(context.IsValidRange( - ToPtr(std::numeric_limits<uintptr_t>::max() - 1500), - std::numeric_limits<uint32_t>::max())); - - // This should be fine. - EXPECT_TRUE(context.IsValidRange( - ToPtr(std::numeric_limits<uintptr_t>::max() - 1500), 200)); - } -} - -TEST(ValidationContextTest, ClaimHandle) { - { - internal::ValidationContext context(ToPtr(0), 0, 10, 0); - - // Basics. - EXPECT_TRUE(context.ClaimHandle(Handle_Data(0))); - EXPECT_FALSE(context.ClaimHandle(Handle_Data(0))); - - EXPECT_TRUE(context.ClaimHandle(Handle_Data(9))); - EXPECT_FALSE(context.ClaimHandle(Handle_Data(10))); - - // Should fail because it is smaller than the max index that has been - // claimed. - EXPECT_FALSE(context.ClaimHandle(Handle_Data(8))); - - // Should return true for invalid handle. - EXPECT_TRUE(context.ClaimHandle( - Handle_Data(internal::kEncodedInvalidHandleValue))); - EXPECT_TRUE(context.ClaimHandle( - Handle_Data(internal::kEncodedInvalidHandleValue))); - } - - { - // No handle to claim. - internal::ValidationContext context(ToPtr(0), 0, 0, 0); - - EXPECT_FALSE(context.ClaimHandle(Handle_Data(0))); - - // Should still return true for invalid handle. - EXPECT_TRUE(context.ClaimHandle( - Handle_Data(internal::kEncodedInvalidHandleValue))); - } - - { - // Test the case that |num_handles| is the same value as - // |internal::kEncodedInvalidHandleValue|. - EXPECT_EQ(internal::kEncodedInvalidHandleValue, - std::numeric_limits<uint32_t>::max()); - internal::ValidationContext context( - ToPtr(0), 0, std::numeric_limits<uint32_t>::max(), 0); - - EXPECT_TRUE(context.ClaimHandle( - Handle_Data(std::numeric_limits<uint32_t>::max() - 1))); - EXPECT_FALSE(context.ClaimHandle( - Handle_Data(std::numeric_limits<uint32_t>::max() - 1))); - EXPECT_FALSE(context.ClaimHandle(Handle_Data(0))); - - // Should still return true for invalid handle. - EXPECT_TRUE(context.ClaimHandle( - Handle_Data(internal::kEncodedInvalidHandleValue))); - } -} - -TEST(ValidationContextTest, ClaimAssociatedEndpointHandle) { - { - internal::ValidationContext context(ToPtr(0), 0, 0, 10); - - // Basics. - EXPECT_TRUE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(0))); - EXPECT_FALSE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(0))); - - EXPECT_TRUE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(9))); - EXPECT_FALSE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(10))); - - // Should fail because it is smaller than the max index that has been - // claimed. - EXPECT_FALSE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(8))); - - // Should return true for invalid handle. - EXPECT_TRUE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue))); - EXPECT_TRUE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue))); - } - - { - // No handle to claim. - internal::ValidationContext context(ToPtr(0), 0, 0, 0); - - EXPECT_FALSE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(0))); - - // Should still return true for invalid handle. - EXPECT_TRUE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue))); - } - - { - // Test the case that |num_associated_endpoint_handles| is the same value as - // |internal::kEncodedInvalidHandleValue|. - EXPECT_EQ(internal::kEncodedInvalidHandleValue, - std::numeric_limits<uint32_t>::max()); - internal::ValidationContext context(ToPtr(0), 0, 0, - std::numeric_limits<uint32_t>::max()); - - EXPECT_TRUE( - context.ClaimAssociatedEndpointHandle(AssociatedEndpointHandle_Data( - std::numeric_limits<uint32_t>::max() - 1))); - EXPECT_FALSE( - context.ClaimAssociatedEndpointHandle(AssociatedEndpointHandle_Data( - std::numeric_limits<uint32_t>::max() - 1))); - EXPECT_FALSE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(0))); - - // Should still return true for invalid handle. - EXPECT_TRUE(context.ClaimAssociatedEndpointHandle( - AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue))); - } -} - -TEST(ValidationContextTest, ClaimMemory) { - { - internal::ValidationContext context(ToPtr(1000), 2000, 0, 0); - - // Basics. - EXPECT_FALSE(context.ClaimMemory(ToPtr(500), 100)); - EXPECT_FALSE(context.ClaimMemory(ToPtr(800), 300)); - EXPECT_TRUE(context.ClaimMemory(ToPtr(1000), 100)); - EXPECT_FALSE(context.ClaimMemory(ToPtr(1099), 100)); - EXPECT_TRUE(context.ClaimMemory(ToPtr(1100), 200)); - EXPECT_FALSE(context.ClaimMemory(ToPtr(2000), 1001)); - EXPECT_TRUE(context.ClaimMemory(ToPtr(2000), 500)); - EXPECT_FALSE(context.ClaimMemory(ToPtr(2000), 500)); - EXPECT_FALSE(context.ClaimMemory(ToPtr(1400), 100)); - EXPECT_FALSE(context.ClaimMemory(ToPtr(3000), 1)); - EXPECT_TRUE(context.ClaimMemory(ToPtr(2500), 500)); - } - - { - // No memory to claim. - internal::ValidationContext context(ToPtr(10000), 0, 0, 0); - - EXPECT_FALSE(context.ClaimMemory(ToPtr(10000), 1)); - EXPECT_FALSE(context.ClaimMemory(ToPtr(10000), 0)); - } - - { - internal::ValidationContext context( - ToPtr(std::numeric_limits<uintptr_t>::max() - 1000), 500, 0, 0); - - // Test overflow. - EXPECT_FALSE(context.ClaimMemory( - ToPtr(std::numeric_limits<uintptr_t>::max() - 750), 4000)); - EXPECT_FALSE( - context.ClaimMemory(ToPtr(std::numeric_limits<uintptr_t>::max() - 750), - std::numeric_limits<uint32_t>::max())); - - // This should be fine. - EXPECT_TRUE(context.ClaimMemory( - ToPtr(std::numeric_limits<uintptr_t>::max() - 750), 200)); - } -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/validation_test_input_parser.cc b/mojo/public/cpp/bindings/tests/validation_test_input_parser.cc deleted file mode 100644 index f309737..0000000 --- a/mojo/public/cpp/bindings/tests/validation_test_input_parser.cc +++ /dev/null @@ -1,412 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/tests/validation_test_input_parser.h" - -#include <assert.h> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> - -#include <limits> -#include <map> -#include <set> -#include <utility> - -#include "mojo/public/c/system/macros.h" - -namespace mojo { -namespace test { -namespace { - -class ValidationTestInputParser { - public: - ValidationTestInputParser(const std::string& input, - std::vector<uint8_t>* data, - size_t* num_handles, - std::string* error_message); - ~ValidationTestInputParser(); - - bool Run(); - - private: - struct DataType; - - typedef std::pair<const char*, const char*> Range; - - typedef bool (ValidationTestInputParser::*ParseDataFunc)( - const DataType& type, - const std::string& value_string); - - struct DataType { - const char* name; - size_t name_size; - size_t data_size; - ParseDataFunc parse_data_func; - }; - - // A dist4/8 item that hasn't been matched with an anchr item. - struct PendingDistanceItem { - // Where this data item is located in |data_|. - size_t pos; - // Either 4 or 8 (bytes). - size_t data_size; - }; - - bool GetNextItem(Range* range); - - bool ParseItem(const Range& range); - - bool ParseUnsignedInteger(const DataType& type, - const std::string& value_string); - bool ParseSignedInteger(const DataType& type, - const std::string& value_string); - bool ParseFloat(const DataType& type, const std::string& value_string); - bool ParseDouble(const DataType& type, const std::string& value_string); - bool ParseBinarySequence(const DataType& type, - const std::string& value_string); - bool ParseDistance(const DataType& type, const std::string& value_string); - bool ParseAnchor(const DataType& type, const std::string& value_string); - bool ParseHandles(const DataType& type, const std::string& value_string); - - bool StartsWith(const Range& range, const char* prefix, size_t prefix_length); - - bool ConvertToUnsignedInteger(const std::string& value_string, - unsigned long long int* value); - - template <typename T> - void AppendData(T data) { - size_t pos = data_->size(); - data_->resize(pos + sizeof(T)); - memcpy(&(*data_)[pos], &data, sizeof(T)); - } - - template <typename TargetType, typename InputType> - bool ConvertAndAppendData(InputType value) { - if (value > std::numeric_limits<TargetType>::max() || - value < std::numeric_limits<TargetType>::min()) { - return false; - } - AppendData(static_cast<TargetType>(value)); - return true; - } - - template <typename TargetType, typename InputType> - bool ConvertAndFillData(size_t pos, InputType value) { - if (value > std::numeric_limits<TargetType>::max() || - value < std::numeric_limits<TargetType>::min()) { - return false; - } - TargetType target_value = static_cast<TargetType>(value); - assert(pos + sizeof(TargetType) <= data_->size()); - memcpy(&(*data_)[pos], &target_value, sizeof(TargetType)); - return true; - } - - static const DataType kDataTypes[]; - static const size_t kDataTypeCount; - - const std::string& input_; - size_t input_cursor_; - - std::vector<uint8_t>* data_; - size_t* num_handles_; - std::string* error_message_; - - std::map<std::string, PendingDistanceItem> pending_distance_items_; - std::set<std::string> anchors_; -}; - -#define DATA_TYPE(name, data_size, parse_data_func) \ - { name, sizeof(name) - 1, data_size, parse_data_func } - -const ValidationTestInputParser::DataType - ValidationTestInputParser::kDataTypes[] = { - DATA_TYPE("[u1]", 1, &ValidationTestInputParser::ParseUnsignedInteger), - DATA_TYPE("[u2]", 2, &ValidationTestInputParser::ParseUnsignedInteger), - DATA_TYPE("[u4]", 4, &ValidationTestInputParser::ParseUnsignedInteger), - DATA_TYPE("[u8]", 8, &ValidationTestInputParser::ParseUnsignedInteger), - DATA_TYPE("[s1]", 1, &ValidationTestInputParser::ParseSignedInteger), - DATA_TYPE("[s2]", 2, &ValidationTestInputParser::ParseSignedInteger), - DATA_TYPE("[s4]", 4, &ValidationTestInputParser::ParseSignedInteger), - DATA_TYPE("[s8]", 8, &ValidationTestInputParser::ParseSignedInteger), - DATA_TYPE("[b]", 1, &ValidationTestInputParser::ParseBinarySequence), - DATA_TYPE("[f]", 4, &ValidationTestInputParser::ParseFloat), - DATA_TYPE("[d]", 8, &ValidationTestInputParser::ParseDouble), - DATA_TYPE("[dist4]", 4, &ValidationTestInputParser::ParseDistance), - DATA_TYPE("[dist8]", 8, &ValidationTestInputParser::ParseDistance), - DATA_TYPE("[anchr]", 0, &ValidationTestInputParser::ParseAnchor), - DATA_TYPE("[handles]", 0, &ValidationTestInputParser::ParseHandles)}; - -const size_t ValidationTestInputParser::kDataTypeCount = - sizeof(ValidationTestInputParser::kDataTypes) / - sizeof(ValidationTestInputParser::kDataTypes[0]); - -ValidationTestInputParser::ValidationTestInputParser(const std::string& input, - std::vector<uint8_t>* data, - size_t* num_handles, - std::string* error_message) - : input_(input), - input_cursor_(0), - data_(data), - num_handles_(num_handles), - error_message_(error_message) { - assert(data_); - assert(num_handles_); - assert(error_message_); - data_->clear(); - *num_handles_ = 0; - error_message_->clear(); -} - -ValidationTestInputParser::~ValidationTestInputParser() { -} - -bool ValidationTestInputParser::Run() { - Range range; - bool result = true; - while (result && GetNextItem(&range)) - result = ParseItem(range); - - if (!result) { - *error_message_ = - "Error occurred when parsing " + std::string(range.first, range.second); - } else if (!pending_distance_items_.empty()) { - // We have parsed all the contents in |input_| successfully, but there are - // unmatched dist4/8 items. - *error_message_ = "Error occurred when matching [dist4/8] and [anchr]."; - result = false; - } - if (!result) { - data_->clear(); - *num_handles_ = 0; - } else { - assert(error_message_->empty()); - } - - return result; -} - -bool ValidationTestInputParser::GetNextItem(Range* range) { - const char kWhitespaceChars[] = " \t\n\r"; - const char kItemDelimiters[] = " \t\n\r/"; - const char kEndOfLineChars[] = "\n\r"; - while (true) { - // Skip leading whitespaces. - // If there are no non-whitespace characters left, |input_cursor_| will be - // set to std::npos. - input_cursor_ = input_.find_first_not_of(kWhitespaceChars, input_cursor_); - - if (input_cursor_ >= input_.size()) - return false; - - if (StartsWith( - Range(&input_[0] + input_cursor_, &input_[0] + input_.size()), - "//", - 2)) { - // Skip contents until the end of the line. - input_cursor_ = input_.find_first_of(kEndOfLineChars, input_cursor_); - } else { - range->first = &input_[0] + input_cursor_; - input_cursor_ = input_.find_first_of(kItemDelimiters, input_cursor_); - range->second = input_cursor_ >= input_.size() - ? &input_[0] + input_.size() - : &input_[0] + input_cursor_; - return true; - } - } - return false; -} - -bool ValidationTestInputParser::ParseItem(const Range& range) { - for (size_t i = 0; i < kDataTypeCount; ++i) { - if (StartsWith(range, kDataTypes[i].name, kDataTypes[i].name_size)) { - return (this->*kDataTypes[i].parse_data_func)( - kDataTypes[i], - std::string(range.first + kDataTypes[i].name_size, range.second)); - } - } - - // "[u1]" is optional. - return ParseUnsignedInteger(kDataTypes[0], - std::string(range.first, range.second)); -} - -bool ValidationTestInputParser::ParseUnsignedInteger( - const DataType& type, - const std::string& value_string) { - unsigned long long int value; - if (!ConvertToUnsignedInteger(value_string, &value)) - return false; - - switch (type.data_size) { - case 1: - return ConvertAndAppendData<uint8_t>(value); - case 2: - return ConvertAndAppendData<uint16_t>(value); - case 4: - return ConvertAndAppendData<uint32_t>(value); - case 8: - return ConvertAndAppendData<uint64_t>(value); - default: - assert(false); - return false; - } -} - -bool ValidationTestInputParser::ParseSignedInteger( - const DataType& type, - const std::string& value_string) { - long long int value; - if (sscanf(value_string.c_str(), "%lli", &value) != 1) - return false; - - switch (type.data_size) { - case 1: - return ConvertAndAppendData<int8_t>(value); - case 2: - return ConvertAndAppendData<int16_t>(value); - case 4: - return ConvertAndAppendData<int32_t>(value); - case 8: - return ConvertAndAppendData<int64_t>(value); - default: - assert(false); - return false; - } -} - -bool ValidationTestInputParser::ParseFloat(const DataType& type, - const std::string& value_string) { - static_assert(sizeof(float) == 4, "sizeof(float) is not 4"); - - float value; - if (sscanf(value_string.c_str(), "%f", &value) != 1) - return false; - - AppendData(value); - return true; -} - -bool ValidationTestInputParser::ParseDouble(const DataType& type, - const std::string& value_string) { - static_assert(sizeof(double) == 8, "sizeof(double) is not 8"); - - double value; - if (sscanf(value_string.c_str(), "%lf", &value) != 1) - return false; - - AppendData(value); - return true; -} - -bool ValidationTestInputParser::ParseBinarySequence( - const DataType& type, - const std::string& value_string) { - if (value_string.size() != 8) - return false; - - uint8_t value = 0; - for (std::string::const_iterator iter = value_string.begin(); - iter != value_string.end(); - ++iter) { - value <<= 1; - if (*iter == '1') - value++; - else if (*iter != '0') - return false; - } - AppendData(value); - return true; -} - -bool ValidationTestInputParser::ParseDistance(const DataType& type, - const std::string& value_string) { - if (pending_distance_items_.find(value_string) != - pending_distance_items_.end()) - return false; - - PendingDistanceItem item = {data_->size(), type.data_size}; - data_->resize(data_->size() + type.data_size); - pending_distance_items_[value_string] = item; - - return true; -} - -bool ValidationTestInputParser::ParseAnchor(const DataType& type, - const std::string& value_string) { - if (anchors_.find(value_string) != anchors_.end()) - return false; - anchors_.insert(value_string); - - std::map<std::string, PendingDistanceItem>::iterator iter = - pending_distance_items_.find(value_string); - if (iter == pending_distance_items_.end()) - return false; - - PendingDistanceItem dist_item = iter->second; - pending_distance_items_.erase(iter); - - size_t distance = data_->size() - dist_item.pos; - switch (dist_item.data_size) { - case 4: - return ConvertAndFillData<uint32_t>(dist_item.pos, distance); - case 8: - return ConvertAndFillData<uint64_t>(dist_item.pos, distance); - default: - assert(false); - return false; - } -} - -bool ValidationTestInputParser::ParseHandles(const DataType& type, - const std::string& value_string) { - // It should be the first item. - if (!data_->empty()) - return false; - - unsigned long long int value; - if (!ConvertToUnsignedInteger(value_string, &value)) - return false; - - if (value > std::numeric_limits<size_t>::max()) - return false; - - *num_handles_ = static_cast<size_t>(value); - return true; -} - -bool ValidationTestInputParser::StartsWith(const Range& range, - const char* prefix, - size_t prefix_length) { - if (static_cast<size_t>(range.second - range.first) < prefix_length) - return false; - - return memcmp(range.first, prefix, prefix_length) == 0; -} - -bool ValidationTestInputParser::ConvertToUnsignedInteger( - const std::string& value_string, - unsigned long long int* value) { - const char* format = nullptr; - if (value_string.find_first_of("xX") != std::string::npos) - format = "%llx"; - else - format = "%llu"; - return sscanf(value_string.c_str(), format, value) == 1; -} - -} // namespace - -bool ParseValidationTestInput(const std::string& input, - std::vector<uint8_t>* data, - size_t* num_handles, - std::string* error_message) { - ValidationTestInputParser parser(input, data, num_handles, error_message); - return parser.Run(); -} - -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/validation_test_input_parser.h b/mojo/public/cpp/bindings/tests/validation_test_input_parser.h deleted file mode 100644 index d08f359..0000000 --- a/mojo/public/cpp/bindings/tests/validation_test_input_parser.h +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_VALIDATION_TEST_INPUT_PARSER_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_VALIDATION_TEST_INPUT_PARSER_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <string> -#include <vector> - -namespace mojo { -namespace test { - -// Input Format of Mojo Message Validation Tests. -// -// Data items are separated by whitespaces: -// - ' ' (0x20) space; -// - '\t' (0x09) horizontal tab; -// - '\n' (0x0a) newline; -// - '\r' (0x0d) carriage return. -// A comment starts with //, extending to the end of the line. -// Each data item is of the format [<type>]<value>. The types defined and the -// corresponding value formats are described below. -// -// Type: u1 / u2 / u4 / u8 -// Description: Little-endian 1/2/4/8-byte unsigned integer. -// Value Format: -// - Decimal integer: 0|[1-9][0-9]* -// - Hexadecimal integer: 0[xX][0-9a-fA-F]+ -// - The type prefix (including the square brackets) of 1-byte unsigned -// integer is optional. -// -// Type: s1 / s2 / s4 / s8 -// Description: Little-endian 1/2/4/8-byte signed integer. -// Value Format: -// - Decimal integer: [-+]?(0|[1-9][0-9]*) -// - Hexadecimal integer: [-+]?0[xX][0-9a-fA-F]+ -// -// Type: b -// Description: Binary sequence of 1 byte. -// Value Format: [01]{8} -// -// Type: f / d -// Description: Little-endian IEEE-754 format of float (4 bytes) and double (8 -// bytes). -// Value Format: [-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)? -// -// Type: dist4 / dist8 -// Description: Little-endian 4/8-byte unsigned integer. The actual value is set -// to the byte distance from the location of this integer to the location of the -// anchr item with the same ID. A dist8 and anchr pair can be used to easily -// represent an encoded pointer. A dist4 and anchr pair can be used to easily -// calculate struct/array size. -// Value Format: The value is an ID: [0-9a-zA-Z_]+ -// -// Type: anchr -// Description: Mark an anchor location. It doesn’t translate into any actual -// data. -// Value Format: The value is an ID of the same format as that of dist4/8. -// -// Type: handles -// Description: The number of handles that are associated with the message. This -// special item is not part of the message data. If specified, it should be the -// first item. -// Value Format: The same format as u1/2/4/8. -// -// EXAMPLE: -// -// Suppose you have the following Mojo types defined: -// struct Bar { -// int32_t a; -// bool b; -// bool c; -// }; -// struct Foo { -// Bar x; -// uint32_t y; -// }; -// -// The following describes a valid message whose payload is a Foo struct: -// // message header -// [dist4]message_header // num_bytes -// [u4]3 // version -// [u4]0 // type -// [u4]1 // flags -// [u8]1234 // request_id -// [anchr]message_header -// -// // payload -// [dist4]foo // num_bytes -// [u4]2 // version -// [dist8]bar_ptr // x -// [u4]0xABCD // y -// [u4]0 // padding -// [anchr]foo -// -// [anchr]bar_ptr -// [dist4]bar // num_bytes -// [u4]3 // version -// [s4]-1 // a -// [b]00000010 // b and c -// 0 0 0 // padding -// [anchr]bar - -// Parses validation test input. -// On success, |data| and |num_handles| store the parsing result, -// |error_message| is cleared; on failure, |error_message| is set to a message -// describing the error, |data| is cleared and |num_handles| set to 0. -// Note: For now, this method only works on little-endian platforms. -bool ParseValidationTestInput(const std::string& input, - std::vector<uint8_t>* data, - size_t* num_handles, - std::string* error_message); - -} // namespace test -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_VALIDATION_TEST_INPUT_PARSER_H_ diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc deleted file mode 100644 index 7af7396..0000000 --- a/mojo/public/cpp/bindings/tests/validation_unittest.cc +++ /dev/null @@ -1,498 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <algorithm> -#include <string> -#include <utility> -#include <vector> - -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/threading/thread_task_runner_handle.h" -#include "mojo/public/c/system/macros.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/connector.h" -#include "mojo/public/cpp/bindings/filter_chain.h" -#include "mojo/public/cpp/bindings/interface_ptr.h" -#include "mojo/public/cpp/bindings/lib/validation_errors.h" -#include "mojo/public/cpp/bindings/message.h" -#include "mojo/public/cpp/bindings/message_header_validator.h" -#include "mojo/public/cpp/bindings/tests/validation_test_input_parser.h" -#include "mojo/public/cpp/system/core.h" -#include "mojo/public/cpp/test_support/test_support.h" -#include "mojo/public/interfaces/bindings/tests/validation_test_associated_interfaces.mojom.h" -#include "mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -template <typename T> -void Append(std::vector<uint8_t>* data_vector, T data) { - size_t pos = data_vector->size(); - data_vector->resize(pos + sizeof(T)); - memcpy(&(*data_vector)[pos], &data, sizeof(T)); -} - -bool TestInputParser(const std::string& input, - bool expected_result, - const std::vector<uint8_t>& expected_data, - size_t expected_num_handles) { - std::vector<uint8_t> data; - size_t num_handles; - std::string error_message; - - bool result = - ParseValidationTestInput(input, &data, &num_handles, &error_message); - if (expected_result) { - if (result && error_message.empty() && expected_data == data && - expected_num_handles == num_handles) { - return true; - } - - // Compare with an empty string instead of checking |error_message.empty()|, - // so that the message will be printed out if the two are not equal. - EXPECT_EQ(std::string(), error_message); - EXPECT_EQ(expected_data, data); - EXPECT_EQ(expected_num_handles, num_handles); - return false; - } - - EXPECT_FALSE(error_message.empty()); - return !result && !error_message.empty(); -} - -std::vector<std::string> GetMatchingTests(const std::vector<std::string>& names, - const std::string& prefix) { - const std::string suffix = ".data"; - std::vector<std::string> tests; - for (size_t i = 0; i < names.size(); ++i) { - if (names[i].size() >= suffix.size() && - names[i].substr(0, prefix.size()) == prefix && - names[i].substr(names[i].size() - suffix.size()) == suffix) - tests.push_back(names[i].substr(0, names[i].size() - suffix.size())); - } - return tests; -} - -bool ReadFile(const std::string& path, std::string* result) { - FILE* fp = OpenSourceRootRelativeFile(path.c_str()); - if (!fp) { - ADD_FAILURE() << "File not found: " << path; - return false; - } - fseek(fp, 0, SEEK_END); - size_t size = static_cast<size_t>(ftell(fp)); - if (size == 0) { - result->clear(); - fclose(fp); - return true; - } - fseek(fp, 0, SEEK_SET); - result->resize(size); - size_t size_read = fread(&result->at(0), 1, size, fp); - fclose(fp); - return size == size_read; -} - -bool ReadAndParseDataFile(const std::string& path, - std::vector<uint8_t>* data, - size_t* num_handles) { - std::string input; - if (!ReadFile(path, &input)) - return false; - - std::string error_message; - if (!ParseValidationTestInput(input, data, num_handles, &error_message)) { - ADD_FAILURE() << error_message; - return false; - } - - return true; -} - -bool ReadResultFile(const std::string& path, std::string* result) { - if (!ReadFile(path, result)) - return false; - - // Result files are new-line delimited text files. Remove any CRs. - result->erase(std::remove(result->begin(), result->end(), '\r'), - result->end()); - - // Remove trailing LFs. - size_t pos = result->find_last_not_of('\n'); - if (pos == std::string::npos) - result->clear(); - else - result->resize(pos + 1); - - return true; -} - -std::string GetPath(const std::string& root, const std::string& suffix) { - return "mojo/public/interfaces/bindings/tests/data/validation/" + root + - suffix; -} - -// |message| should be a newly created object. -bool ReadTestCase(const std::string& test, - Message* message, - std::string* expected) { - std::vector<uint8_t> data; - size_t num_handles; - if (!ReadAndParseDataFile(GetPath(test, ".data"), &data, &num_handles) || - !ReadResultFile(GetPath(test, ".expected"), expected)) { - return false; - } - - message->Initialize(static_cast<uint32_t>(data.size()), - false /* zero_initialized */); - if (!data.empty()) - memcpy(message->mutable_data(), &data[0], data.size()); - message->mutable_handles()->resize(num_handles); - - return true; -} - -void RunValidationTests(const std::string& prefix, - MessageReceiver* test_message_receiver) { - std::vector<std::string> names = - EnumerateSourceRootRelativeDirectory(GetPath("", "")); - std::vector<std::string> tests = GetMatchingTests(names, prefix); - ASSERT_FALSE(tests.empty()); - - for (size_t i = 0; i < tests.size(); ++i) { - Message message; - std::string expected; - ASSERT_TRUE(ReadTestCase(tests[i], &message, &expected)); - - std::string result; - base::RunLoop run_loop; - mojo::internal::ValidationErrorObserverForTesting observer( - run_loop.QuitClosure()); - ignore_result(test_message_receiver->Accept(&message)); - if (expected != "PASS") // Observer only gets called on errors. - run_loop.Run(); - if (observer.last_error() == mojo::internal::VALIDATION_ERROR_NONE) - result = "PASS"; - else - result = mojo::internal::ValidationErrorToString(observer.last_error()); - - EXPECT_EQ(expected, result) << "failed test: " << tests[i]; - } -} - -class DummyMessageReceiver : public MessageReceiver { - public: - bool Accept(Message* message) override { - return true; // Any message is OK. - } -}; - -class ValidationTest : public testing::Test { - public: - ValidationTest() {} - - protected: - base::MessageLoop loop_; -}; - -class ValidationIntegrationTest : public ValidationTest { - public: - ValidationIntegrationTest() : test_message_receiver_(nullptr) {} - - ~ValidationIntegrationTest() override {} - - void SetUp() override { - ScopedMessagePipeHandle tester_endpoint; - ASSERT_EQ(MOJO_RESULT_OK, - CreateMessagePipe(nullptr, &tester_endpoint, &testee_endpoint_)); - test_message_receiver_ = - new TestMessageReceiver(this, std::move(tester_endpoint)); - } - - void TearDown() override { - delete test_message_receiver_; - test_message_receiver_ = nullptr; - - // Make sure that the other end receives the OnConnectionError() - // notification. - PumpMessages(); - } - - MessageReceiver* test_message_receiver() { return test_message_receiver_; } - - ScopedMessagePipeHandle testee_endpoint() { - return std::move(testee_endpoint_); - } - - private: - class TestMessageReceiver : public MessageReceiver { - public: - TestMessageReceiver(ValidationIntegrationTest* owner, - ScopedMessagePipeHandle handle) - : owner_(owner), - connector_(std::move(handle), - mojo::Connector::SINGLE_THREADED_SEND, - base::ThreadTaskRunnerHandle::Get()) { - connector_.set_enforce_errors_from_incoming_receiver(false); - } - ~TestMessageReceiver() override {} - - bool Accept(Message* message) override { - return connector_.Accept(message); - } - - public: - ValidationIntegrationTest* owner_; - mojo::Connector connector_; - }; - - void PumpMessages() { base::RunLoop().RunUntilIdle(); } - - TestMessageReceiver* test_message_receiver_; - ScopedMessagePipeHandle testee_endpoint_; -}; - -class IntegrationTestInterfaceImpl : public IntegrationTestInterface { - public: - ~IntegrationTestInterfaceImpl() override {} - - void Method0(BasicStructPtr param0, - const Method0Callback& callback) override { - callback.Run(std::vector<uint8_t>()); - } -}; - -TEST_F(ValidationTest, InputParser) { - { - // The parser, as well as Append() defined above, assumes that this code is - // running on a little-endian platform. Test whether that is true. - uint16_t x = 1; - ASSERT_EQ(1, *(reinterpret_cast<char*>(&x))); - } - { - // Test empty input. - std::string input; - std::vector<uint8_t> expected; - - EXPECT_TRUE(TestInputParser(input, true, expected, 0)); - } - { - // Test input that only consists of comments and whitespaces. - std::string input = " \t // hello world \n\r \t// the answer is 42 "; - std::vector<uint8_t> expected; - - EXPECT_TRUE(TestInputParser(input, true, expected, 0)); - } - { - std::string input = - "[u1]0x10// hello world !! \n\r \t [u2]65535 \n" - "[u4]65536 [u8]0xFFFFFFFFFFFFFFFF 0 0Xff"; - std::vector<uint8_t> expected; - Append(&expected, static_cast<uint8_t>(0x10)); - Append(&expected, static_cast<uint16_t>(65535)); - Append(&expected, static_cast<uint32_t>(65536)); - Append(&expected, static_cast<uint64_t>(0xffffffffffffffff)); - Append(&expected, static_cast<uint8_t>(0)); - Append(&expected, static_cast<uint8_t>(0xff)); - - EXPECT_TRUE(TestInputParser(input, true, expected, 0)); - } - { - std::string input = "[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40"; - std::vector<uint8_t> expected; - Append(&expected, -static_cast<int64_t>(0x800)); - Append(&expected, static_cast<int8_t>(-128)); - Append(&expected, static_cast<int16_t>(0)); - Append(&expected, static_cast<int32_t>(-40)); - - EXPECT_TRUE(TestInputParser(input, true, expected, 0)); - } - { - std::string input = "[b]00001011 [b]10000000 // hello world\r [b]00000000"; - std::vector<uint8_t> expected; - Append(&expected, static_cast<uint8_t>(11)); - Append(&expected, static_cast<uint8_t>(128)); - Append(&expected, static_cast<uint8_t>(0)); - - EXPECT_TRUE(TestInputParser(input, true, expected, 0)); - } - { - std::string input = "[f]+.3e9 [d]-10.03"; - std::vector<uint8_t> expected; - Append(&expected, +.3e9f); - Append(&expected, -10.03); - - EXPECT_TRUE(TestInputParser(input, true, expected, 0)); - } - { - std::string input = "[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar"; - std::vector<uint8_t> expected; - Append(&expected, static_cast<uint32_t>(14)); - Append(&expected, static_cast<uint8_t>(0)); - Append(&expected, static_cast<uint64_t>(9)); - Append(&expected, static_cast<uint8_t>(0)); - - EXPECT_TRUE(TestInputParser(input, true, expected, 0)); - } - { - std::string input = "// This message has handles! \n[handles]50 [u8]2"; - std::vector<uint8_t> expected; - Append(&expected, static_cast<uint64_t>(2)); - - EXPECT_TRUE(TestInputParser(input, true, expected, 50)); - } - - // Test some failure cases. - { - const char* error_inputs[] = {"/ hello world", - "[u1]x", - "[u2]-1000", - "[u1]0x100", - "[s2]-0x8001", - "[b]1", - "[b]1111111k", - "[dist4]unmatched", - "[anchr]hello [dist8]hello", - "[dist4]a [dist4]a [anchr]a", - "[dist4]a [anchr]a [dist4]a [anchr]a", - "0 [handles]50", - nullptr}; - - for (size_t i = 0; error_inputs[i]; ++i) { - std::vector<uint8_t> expected; - if (!TestInputParser(error_inputs[i], false, expected, 0)) - ADD_FAILURE() << "Unexpected test result for: " << error_inputs[i]; - } - } -} - -TEST_F(ValidationTest, Conformance) { - DummyMessageReceiver dummy_receiver; - mojo::FilterChain validators(&dummy_receiver); - validators.Append<mojo::MessageHeaderValidator>(); - validators.Append<ConformanceTestInterface::RequestValidator_>(); - - RunValidationTests("conformance_", &validators); -} - -TEST_F(ValidationTest, AssociatedConformace) { - DummyMessageReceiver dummy_receiver; - mojo::FilterChain validators(&dummy_receiver); - validators.Append<mojo::MessageHeaderValidator>(); - validators.Append<AssociatedConformanceTestInterface::RequestValidator_>(); - - RunValidationTests("associated_conformance_", &validators); -} - -// This test is similar to Conformance test but its goal is specifically -// do bounds-check testing of message validation. For example we test the -// detection of off-by-one errors in method ordinals. -TEST_F(ValidationTest, BoundsCheck) { - DummyMessageReceiver dummy_receiver; - mojo::FilterChain validators(&dummy_receiver); - validators.Append<mojo::MessageHeaderValidator>(); - validators.Append<BoundsCheckTestInterface::RequestValidator_>(); - - RunValidationTests("boundscheck_", &validators); -} - -// This test is similar to the Conformance test but for responses. -TEST_F(ValidationTest, ResponseConformance) { - DummyMessageReceiver dummy_receiver; - mojo::FilterChain validators(&dummy_receiver); - validators.Append<mojo::MessageHeaderValidator>(); - validators.Append<ConformanceTestInterface::ResponseValidator_>(); - - RunValidationTests("resp_conformance_", &validators); -} - -// This test is similar to the BoundsCheck test but for responses. -TEST_F(ValidationTest, ResponseBoundsCheck) { - DummyMessageReceiver dummy_receiver; - mojo::FilterChain validators(&dummy_receiver); - validators.Append<mojo::MessageHeaderValidator>(); - validators.Append<BoundsCheckTestInterface::ResponseValidator_>(); - - RunValidationTests("resp_boundscheck_", &validators); -} - -// Test that InterfacePtr<X> applies the correct validators and they don't -// conflict with each other: -// - MessageHeaderValidator -// - X::ResponseValidator_ -TEST_F(ValidationIntegrationTest, InterfacePtr) { - IntegrationTestInterfacePtr interface_ptr = MakeProxy( - InterfacePtrInfo<IntegrationTestInterface>(testee_endpoint(), 0u)); - interface_ptr.internal_state()->EnableTestingMode(); - - RunValidationTests("integration_intf_resp", test_message_receiver()); - RunValidationTests("integration_msghdr", test_message_receiver()); -} - -// Test that Binding<X> applies the correct validators and they don't -// conflict with each other: -// - MessageHeaderValidator -// - X::RequestValidator_ -TEST_F(ValidationIntegrationTest, Binding) { - IntegrationTestInterfaceImpl interface_impl; - Binding<IntegrationTestInterface> binding( - &interface_impl, - MakeRequest<IntegrationTestInterface>(testee_endpoint())); - binding.EnableTestingMode(); - - RunValidationTests("integration_intf_rqst", test_message_receiver()); - RunValidationTests("integration_msghdr", test_message_receiver()); -} - -// Test pointer validation (specifically, that the encoded offset is 32-bit) -TEST_F(ValidationTest, ValidateEncodedPointer) { - uint64_t offset; - - offset = 0ULL; - EXPECT_TRUE(mojo::internal::ValidateEncodedPointer(&offset)); - - offset = 1ULL; - EXPECT_TRUE(mojo::internal::ValidateEncodedPointer(&offset)); - - // offset must be <= 32-bit. - offset = std::numeric_limits<uint32_t>::max() + 1ULL; - EXPECT_FALSE(mojo::internal::ValidateEncodedPointer(&offset)); -} - -// Tests the IsKnownEnumValue() function generated for BasicEnum. -TEST(EnumValueValidationTest, BasicEnum) { - // BasicEnum can have -3,0,1,10 as possible integral values. - EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(-4))); - EXPECT_TRUE(IsKnownEnumValue(static_cast<BasicEnum>(-3))); - EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(-2))); - EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(-1))); - EXPECT_TRUE(IsKnownEnumValue(static_cast<BasicEnum>(0))); - EXPECT_TRUE(IsKnownEnumValue(static_cast<BasicEnum>(1))); - EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(2))); - EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(9))); - // In the mojom, we represent this value as hex (0xa). - EXPECT_TRUE(IsKnownEnumValue(static_cast<BasicEnum>(10))); - EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(11))); -} - -// Tests the IsKnownEnumValue() method generated for StructWithEnum. -TEST(EnumValueValidationTest, EnumWithin) { - // StructWithEnum::EnumWithin can have [0,4] as possible integral values. - EXPECT_FALSE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(-1))); - EXPECT_TRUE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(0))); - EXPECT_TRUE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(1))); - EXPECT_TRUE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(2))); - EXPECT_TRUE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(3))); - EXPECT_FALSE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(4))); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/variant_test_util.h b/mojo/public/cpp/bindings/tests/variant_test_util.h deleted file mode 100644 index 3f6b1f1..0000000 --- a/mojo/public/cpp/bindings/tests/variant_test_util.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_BINDINGS_TESTS_VARIANT_TEST_UTIL_H_ -#define MOJO_PUBLIC_CPP_BINDINGS_TESTS_VARIANT_TEST_UTIL_H_ - -#include <string.h> - -#include "base/logging.h" -#include "mojo/public/cpp/bindings/interface_request.h" - -namespace mojo { -namespace test { - -// Converts a request of Interface1 to a request of Interface0. Interface0 and -// Interface1 are expected to be two variants of the same mojom interface. -// In real-world use cases, users shouldn't need to worry about this. Because it -// is rare to deal with two variants of the same interface in the same app. -template <typename Interface0, typename Interface1> -InterfaceRequest<Interface0> ConvertInterfaceRequest( - InterfaceRequest<Interface1> request) { - DCHECK_EQ(0, strcmp(Interface0::Name_, Interface1::Name_)); - InterfaceRequest<Interface0> result; - result.Bind(request.PassMessagePipe()); - return result; -} - -} // namespace test -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_BINDINGS_TESTS_VARIANT_TEST_UTIL_H_ diff --git a/mojo/public/cpp/bindings/tests/versioning_apptest.cc b/mojo/public/cpp/bindings/tests/versioning_apptest.cc deleted file mode 100644 index 95a89c0..0000000 --- a/mojo/public/cpp/bindings/tests/versioning_apptest.cc +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> - -#include "base/macros.h" -#include "mojo/public/interfaces/bindings/tests/versioning_test_client.mojom.h" -#include "services/service_manager/public/cpp/application_test_base.h" -#include "services/service_manager/public/cpp/connector.h" - -namespace mojo { -namespace test { -namespace versioning { - -class VersioningApplicationTest : public ApplicationTestBase { - public: - VersioningApplicationTest() : ApplicationTestBase() {} - ~VersioningApplicationTest() override {} - - protected: - // ApplicationTestBase overrides. - void SetUp() override { - ApplicationTestBase::SetUp(); - - connector()->BindInterface("versioning_test_service", &database_); - } - - HumanResourceDatabasePtr database_; - - private: - DISALLOW_COPY_AND_ASSIGN(VersioningApplicationTest); -}; - -TEST_F(VersioningApplicationTest, Struct) { - // The service side uses a newer version of Employee defintion. - // The returned struct should be truncated. - EmployeePtr employee(Employee::New()); - employee->employee_id = 1; - employee->name = "Homer Simpson"; - employee->department = DEPARTMENT_DEV; - - database_->QueryEmployee(1, true, - [&employee](EmployeePtr returned_employee, - Array<uint8_t> returned_finger_print) { - EXPECT_TRUE(employee->Equals(*returned_employee)); - EXPECT_FALSE(returned_finger_print.is_null()); - }); - database_.WaitForIncomingResponse(); - - // Passing a struct of older version to the service side works. - EmployeePtr new_employee(Employee::New()); - new_employee->employee_id = 2; - new_employee->name = "Marge Simpson"; - new_employee->department = DEPARTMENT_SALES; - - database_->AddEmployee(new_employee.Clone(), - [](bool success) { EXPECT_TRUE(success); }); - database_.WaitForIncomingResponse(); - - database_->QueryEmployee( - 2, false, [&new_employee](EmployeePtr returned_employee, - Array<uint8_t> returned_finger_print) { - EXPECT_TRUE(new_employee->Equals(*returned_employee)); - EXPECT_TRUE(returned_finger_print.is_null()); - }); - database_.WaitForIncomingResponse(); -} - -TEST_F(VersioningApplicationTest, QueryVersion) { - EXPECT_EQ(0u, database_.version()); - database_.QueryVersion([](uint32_t version) { EXPECT_EQ(1u, version); }); - database_.WaitForIncomingResponse(); - EXPECT_EQ(1u, database_.version()); -} - -TEST_F(VersioningApplicationTest, RequireVersion) { - EXPECT_EQ(0u, database_.version()); - - database_.RequireVersion(1); - EXPECT_EQ(1u, database_.version()); - database_->QueryEmployee(3, false, - [](EmployeePtr returned_employee, - Array<uint8_t> returned_finger_print) {}); - database_.WaitForIncomingResponse(); - EXPECT_FALSE(database_.encountered_error()); - - // Requiring a version higher than what the service side implements will close - // the pipe. - database_.RequireVersion(3); - EXPECT_EQ(3u, database_.version()); - database_->QueryEmployee(1, false, - [](EmployeePtr returned_employee, - Array<uint8_t> returned_finger_print) {}); - database_.WaitForIncomingResponse(); - EXPECT_TRUE(database_.encountered_error()); -} - -TEST_F(VersioningApplicationTest, CallNonexistentMethod) { - EXPECT_EQ(0u, database_.version()); - - Array<uint8_t> new_finger_print(128); - for (size_t i = 0; i < 128; ++i) - new_finger_print[i] = i + 13; - - // Although the client side doesn't know whether the service side supports - // version 1, calling a version 1 method succeeds as long as the service side - // supports version 1. - database_->AttachFingerPrint(1, new_finger_print.Clone(), - [](bool success) { EXPECT_TRUE(success); }); - database_.WaitForIncomingResponse(); - - // Calling a version 2 method (which the service side doesn't support) closes - // the pipe. - database_->ListEmployeeIds([](Array<uint64_t> ids) { EXPECT_TRUE(false); }); - database_.WaitForIncomingResponse(); - EXPECT_TRUE(database_.encountered_error()); -} - -} // namespace versioning -} // namespace examples -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/versioning_test_service.cc b/mojo/public/cpp/bindings/tests/versioning_test_service.cc deleted file mode 100644 index 313a624..0000000 --- a/mojo/public/cpp/bindings/tests/versioning_test_service.cc +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stdint.h> - -#include <map> -#include <utility> - -#include "base/macros.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/public/interfaces/bindings/tests/versioning_test_service.mojom.h" -#include "services/service_manager/public/c/main.h" -#include "services/service_manager/public/cpp/interface_factory.h" -#include "services/service_manager/public/cpp/service.h" -#include "services/service_manager/public/cpp/service_runner.h" - -namespace mojo { -namespace test { -namespace versioning { - -struct EmployeeInfo { - public: - EmployeeInfo() {} - - EmployeePtr employee; - Array<uint8_t> finger_print; - - private: - DISALLOW_COPY_AND_ASSIGN(EmployeeInfo); -}; - -class HumanResourceDatabaseImpl : public HumanResourceDatabase { - public: - explicit HumanResourceDatabaseImpl( - InterfaceRequest<HumanResourceDatabase> request) - : strong_binding_(this, std::move(request)) { - // Pretend that there is already some data in the system. - EmployeeInfo* info = new EmployeeInfo(); - employees_[1] = info; - info->employee = Employee::New(); - info->employee->employee_id = 1; - info->employee->name = "Homer Simpson"; - info->employee->department = DEPARTMENT_DEV; - info->employee->birthday = Date::New(); - info->employee->birthday->year = 1955; - info->employee->birthday->month = 5; - info->employee->birthday->day = 12; - info->finger_print.resize(1024); - for (uint32_t i = 0; i < 1024; ++i) - info->finger_print[i] = i; - } - - ~HumanResourceDatabaseImpl() override { - for (auto iter = employees_.begin(); iter != employees_.end(); ++iter) - delete iter->second; - } - - void AddEmployee(EmployeePtr employee, - const AddEmployeeCallback& callback) override { - uint64_t id = employee->employee_id; - if (employees_.find(id) == employees_.end()) - employees_[id] = new EmployeeInfo(); - employees_[id]->employee = std::move(employee); - callback.Run(true); - } - - void QueryEmployee(uint64_t id, - bool retrieve_finger_print, - const QueryEmployeeCallback& callback) override { - if (employees_.find(id) == employees_.end()) { - callback.Run(nullptr, Array<uint8_t>()); - return; - } - callback.Run(employees_[id]->employee.Clone(), - retrieve_finger_print ? employees_[id]->finger_print.Clone() - : Array<uint8_t>()); - } - - void AttachFingerPrint(uint64_t id, - Array<uint8_t> finger_print, - const AttachFingerPrintCallback& callback) override { - if (employees_.find(id) == employees_.end()) { - callback.Run(false); - return; - } - employees_[id]->finger_print = std::move(finger_print); - callback.Run(true); - } - - private: - std::map<uint64_t, EmployeeInfo*> employees_; - - StrongBinding<HumanResourceDatabase> strong_binding_; -}; - -class HumanResourceSystemServer - : public service_manager::Service, - public InterfaceFactory<HumanResourceDatabase> { - public: - HumanResourceSystemServer() {} - - // service_manager::Service implementation. - bool OnConnect(Connection* connection) override { - connection->AddInterface<HumanResourceDatabase>(this); - return true; - } - - // InterfaceFactory<HumanResourceDatabase> implementation. - void Create(Connection* connection, - InterfaceRequest<HumanResourceDatabase> request) override { - // It will be deleted automatically when the underlying pipe encounters a - // connection error. - new HumanResourceDatabaseImpl(std::move(request)); - } -}; - -} // namespace versioning -} // namespace test -} // namespace mojo - -MojoResult ServiceMain(MojoHandle request) { - mojo::ServiceRunner runner( - new mojo::test::versioning::HumanResourceSystemServer()); - - return runner.Run(request); -} diff --git a/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc deleted file mode 100644 index 959d25b..0000000 --- a/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/lib/wtf_hash_util.h" - -#include "mojo/public/interfaces/bindings/tests/test_structs.mojom-blink.h" -#include "mojo/public/interfaces/bindings/tests/test_wtf_types.mojom-blink.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/Source/wtf/HashFunctions.h" - -namespace mojo { -namespace test { -namespace { - -using WTFHashTest = testing::Test; - -TEST_F(WTFHashTest, NestedStruct) { - // Just check that this template instantiation compiles. - ASSERT_EQ(::mojo::internal::Hash( - ::mojo::internal::kHashSeed, - blink::SimpleNestedStruct::New(blink::ContainsOther::New(1))), - ::mojo::internal::Hash( - ::mojo::internal::kHashSeed, - blink::SimpleNestedStruct::New(blink::ContainsOther::New(1)))); -} - -TEST_F(WTFHashTest, UnmappedNativeStruct) { - // Just check that this template instantiation compiles. - ASSERT_EQ(::mojo::internal::Hash(::mojo::internal::kHashSeed, - blink::UnmappedNativeStruct::New()), - ::mojo::internal::Hash(::mojo::internal::kHashSeed, - blink::UnmappedNativeStruct::New())); -} - -TEST_F(WTFHashTest, Enum) { - // Just check that this template instantiation compiles. - - // Top-level. - ASSERT_EQ(WTF::DefaultHash<blink::TopLevelEnum>::Hash().hash( - blink::TopLevelEnum::E0), - WTF::DefaultHash<blink::TopLevelEnum>::Hash().hash( - blink::TopLevelEnum::E0)); - - // Nested in struct. - ASSERT_EQ(WTF::DefaultHash<blink::TestWTFStruct::NestedEnum>::Hash().hash( - blink::TestWTFStruct::NestedEnum::E0), - WTF::DefaultHash<blink::TestWTFStruct::NestedEnum>::Hash().hash( - blink::TestWTFStruct::NestedEnum::E0)); - - // Nested in interface. - ASSERT_EQ(WTF::DefaultHash<blink::TestWTF::NestedEnum>::Hash().hash( - blink::TestWTF::NestedEnum::E0), - WTF::DefaultHash<blink::TestWTF::NestedEnum>::Hash().hash( - blink::TestWTF::NestedEnum::E0)); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/wtf_map_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_map_unittest.cc deleted file mode 100644 index dc40143..0000000 --- a/mojo/public/cpp/bindings/tests/wtf_map_unittest.cc +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/bindings/tests/rect_blink.h" -#include "mojo/public/interfaces/bindings/tests/rect.mojom-blink.h" -#include "mojo/public/interfaces/bindings/tests/test_structs.mojom-blink.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -TEST(WTFMapTest, StructKey) { - WTF::HashMap<blink::RectPtr, int32_t> map; - map.insert(blink::Rect::New(1, 2, 3, 4), 123); - - blink::RectPtr key = blink::Rect::New(1, 2, 3, 4); - ASSERT_NE(map.end(), map.find(key)); - ASSERT_EQ(123, map.find(key)->value); - - map.erase(key); - ASSERT_EQ(0u, map.size()); -} - -TEST(WTFMapTest, TypemappedStructKey) { - WTF::HashMap<blink::ContainsHashablePtr, int32_t> map; - map.insert(blink::ContainsHashable::New(RectBlink(1, 2, 3, 4)), 123); - - blink::ContainsHashablePtr key = - blink::ContainsHashable::New(RectBlink(1, 2, 3, 4)); - ASSERT_NE(map.end(), map.find(key)); - ASSERT_EQ(123, map.find(key)->value); - - map.erase(key); - ASSERT_EQ(0u, map.size()); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc deleted file mode 100644 index 363ef7c..0000000 --- a/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/bind.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" -#include "mojo/public/cpp/bindings/lib/serialization.h" -#include "mojo/public/cpp/bindings/lib/wtf_serialization.h" -#include "mojo/public/cpp/bindings/tests/variant_test_util.h" -#include "mojo/public/interfaces/bindings/tests/test_wtf_types.mojom-blink.h" -#include "mojo/public/interfaces/bindings/tests/test_wtf_types.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/Source/wtf/text/StringHash.h" - -namespace mojo { -namespace test { -namespace { - -const char kHelloWorld[] = "hello world"; - -// Replace the "o"s in "hello world" with "o"s with acute. -const char kUTF8HelloWorld[] = "hell\xC3\xB3 w\xC3\xB3rld"; - -class TestWTFImpl : public TestWTF { - public: - explicit TestWTFImpl(TestWTFRequest request) - : binding_(this, std::move(request)) {} - - // mojo::test::TestWTF implementation: - void EchoString(const base::Optional<std::string>& str, - const EchoStringCallback& callback) override { - callback.Run(str); - } - - void EchoStringArray( - const base::Optional<std::vector<base::Optional<std::string>>>& arr, - const EchoStringArrayCallback& callback) override { - callback.Run(std::move(arr)); - } - - void EchoStringMap( - const base::Optional< - std::unordered_map<std::string, base::Optional<std::string>>>& - str_map, - const EchoStringMapCallback& callback) override { - callback.Run(std::move(str_map)); - } - - private: - Binding<TestWTF> binding_; -}; - -class WTFTypesTest : public testing::Test { - public: - WTFTypesTest() {} - - private: - base::MessageLoop loop_; -}; - -WTF::Vector<WTF::String> ConstructStringArray() { - WTF::Vector<WTF::String> strs(4); - // strs[0] is null. - // strs[1] is empty. - strs[1] = ""; - strs[2] = kHelloWorld; - strs[3] = WTF::String::fromUTF8(kUTF8HelloWorld); - - return strs; -} - -WTF::HashMap<WTF::String, WTF::String> ConstructStringMap() { - WTF::HashMap<WTF::String, WTF::String> str_map; - // A null string as value. - str_map.insert("0", WTF::String()); - str_map.insert("1", kHelloWorld); - str_map.insert("2", WTF::String::fromUTF8(kUTF8HelloWorld)); - - return str_map; -} - -void ExpectString(const WTF::String& expected_string, - const base::Closure& closure, - const WTF::String& string) { - EXPECT_EQ(expected_string, string); - closure.Run(); -} - -void ExpectStringArray(WTF::Optional<WTF::Vector<WTF::String>>* expected_arr, - const base::Closure& closure, - const WTF::Optional<WTF::Vector<WTF::String>>& arr) { - EXPECT_EQ(*expected_arr, arr); - closure.Run(); -} - -void ExpectStringMap( - WTF::Optional<WTF::HashMap<WTF::String, WTF::String>>* expected_map, - const base::Closure& closure, - const WTF::Optional<WTF::HashMap<WTF::String, WTF::String>>& map) { - EXPECT_EQ(*expected_map, map); - closure.Run(); -} - -} // namespace - -TEST_F(WTFTypesTest, Serialization_WTFVectorToWTFVector) { - using MojomType = ArrayDataView<StringDataView>; - - WTF::Vector<WTF::String> strs = ConstructStringArray(); - auto cloned_strs = strs; - - mojo::internal::SerializationContext context; - size_t size = - mojo::internal::PrepareToSerialize<MojomType>(cloned_strs, &context); - - mojo::internal::FixedBufferForTesting buf(size); - typename mojo::internal::MojomTypeTraits<MojomType>::Data* data; - mojo::internal::ContainerValidateParams validate_params( - 0, true, new mojo::internal::ContainerValidateParams(0, false, nullptr)); - mojo::internal::Serialize<MojomType>(cloned_strs, &buf, &data, - &validate_params, &context); - - WTF::Vector<WTF::String> strs2; - mojo::internal::Deserialize<MojomType>(data, &strs2, &context); - - EXPECT_EQ(strs, strs2); -} - -TEST_F(WTFTypesTest, Serialization_WTFVectorToStlVector) { - using MojomType = ArrayDataView<StringDataView>; - - WTF::Vector<WTF::String> strs = ConstructStringArray(); - auto cloned_strs = strs; - - mojo::internal::SerializationContext context; - size_t size = - mojo::internal::PrepareToSerialize<MojomType>(cloned_strs, &context); - - mojo::internal::FixedBufferForTesting buf(size); - typename mojo::internal::MojomTypeTraits<MojomType>::Data* data; - mojo::internal::ContainerValidateParams validate_params( - 0, true, new mojo::internal::ContainerValidateParams(0, false, nullptr)); - mojo::internal::Serialize<MojomType>(cloned_strs, &buf, &data, - &validate_params, &context); - - std::vector<base::Optional<std::string>> strs2; - mojo::internal::Deserialize<MojomType>(data, &strs2, &context); - - ASSERT_EQ(4u, strs2.size()); - EXPECT_FALSE(strs2[0]); - EXPECT_EQ("", *strs2[1]); - EXPECT_EQ(kHelloWorld, *strs2[2]); - EXPECT_EQ(kUTF8HelloWorld, *strs2[3]); -} - -TEST_F(WTFTypesTest, Serialization_PublicAPI) { - blink::TestWTFStructPtr input(blink::TestWTFStruct::New(kHelloWorld, 42)); - - blink::TestWTFStructPtr cloned_input = input.Clone(); - - auto data = blink::TestWTFStruct::Serialize(&input); - - blink::TestWTFStructPtr output; - ASSERT_TRUE(blink::TestWTFStruct::Deserialize(std::move(data), &output)); - EXPECT_TRUE(cloned_input.Equals(output)); -} - -TEST_F(WTFTypesTest, SendString) { - blink::TestWTFPtr ptr; - TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(MakeRequest(&ptr))); - - WTF::Vector<WTF::String> strs = ConstructStringArray(); - - for (size_t i = 0; i < strs.size(); ++i) { - base::RunLoop loop; - // Test that a WTF::String is unchanged after the following conversion: - // - serialized; - // - deserialized as base::Optional<std::string>; - // - serialized; - // - deserialized as WTF::String. - ptr->EchoString(strs[i], - base::Bind(&ExpectString, strs[i], loop.QuitClosure())); - loop.Run(); - } -} - -TEST_F(WTFTypesTest, SendStringArray) { - blink::TestWTFPtr ptr; - TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(MakeRequest(&ptr))); - - WTF::Optional<WTF::Vector<WTF::String>> arrs[3]; - // arrs[0] is empty. - arrs[0].emplace(); - // arrs[1] is null. - arrs[2] = ConstructStringArray(); - - for (size_t i = 0; i < arraysize(arrs); ++i) { - base::RunLoop loop; - // Test that a WTF::Optional<WTF::Vector<WTF::String>> is unchanged after - // the following conversion: - // - serialized; - // - deserialized as - // base::Optional<std::vector<base::Optional<std::string>>>; - // - serialized; - // - deserialized as WTF::Optional<WTF::Vector<WTF::String>>. - ptr->EchoStringArray( - arrs[i], base::Bind(&ExpectStringArray, base::Unretained(&arrs[i]), - loop.QuitClosure())); - loop.Run(); - } -} - -TEST_F(WTFTypesTest, SendStringMap) { - blink::TestWTFPtr ptr; - TestWTFImpl impl(ConvertInterfaceRequest<TestWTF>(MakeRequest(&ptr))); - - WTF::Optional<WTF::HashMap<WTF::String, WTF::String>> maps[3]; - // maps[0] is empty. - maps[0].emplace(); - // maps[1] is null. - maps[2] = ConstructStringMap(); - - for (size_t i = 0; i < arraysize(maps); ++i) { - base::RunLoop loop; - // Test that a WTF::Optional<WTF::HashMap<WTF::String, WTF::String>> is - // unchanged after the following conversion: - // - serialized; - // - deserialized as base::Optional< - // std::unordered_map<std::string, base::Optional<std::string>>>; - // - serialized; - // - deserialized as WTF::Optional<WTF::HashMap<WTF::String, - // WTF::String>>. - ptr->EchoStringMap(maps[i], - base::Bind(&ExpectStringMap, base::Unretained(&maps[i]), - loop.QuitClosure())); - loop.Run(); - } -} - -} // namespace test -} // namespace mojo |