node_channel_unittest.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "mojo/core/node_channel.h"
  5. #include "base/callback_helpers.h"
  6. #include "base/logging.h"
  7. #include "base/memory/scoped_refptr.h"
  8. #include "base/message_loop/message_pump_type.h"
  9. #include "base/test/task_environment.h"
  10. #include "base/threading/thread.h"
  11. #include "mojo/core/embedder/embedder.h"
  12. #include "mojo/core/test/mock_node_channel_delegate.h"
  13. #include "mojo/public/cpp/platform/platform_channel.h"
  14. #include "mojo/public/cpp/platform/platform_channel_endpoint.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. namespace mojo {
  17. namespace core {
  18. namespace {
  19. using NodeChannelTest = testing::Test;
  20. using ports::NodeName;
  21. using testing::_;
  22. scoped_refptr<NodeChannel> CreateNodeChannel(NodeChannel::Delegate* delegate,
  23. PlatformChannelEndpoint endpoint) {
  24. return NodeChannel::Create(delegate, ConnectionParams(std::move(endpoint)),
  25. Channel::HandlePolicy::kAcceptHandles,
  26. GetIOTaskRunner(), base::NullCallback());
  27. }
  28. TEST_F(NodeChannelTest, DestructionIsSafe) {
  29. // Regression test for https://crbug.com/1081874.
  30. base::test::TaskEnvironment task_environment;
  31. PlatformChannel channel;
  32. MockNodeChannelDelegate local_delegate;
  33. auto local_channel =
  34. CreateNodeChannel(&local_delegate, channel.TakeLocalEndpoint());
  35. local_channel->Start();
  36. MockNodeChannelDelegate remote_delegate;
  37. auto remote_channel =
  38. CreateNodeChannel(&remote_delegate, channel.TakeRemoteEndpoint());
  39. remote_channel->Start();
  40. // Verify end-to-end operation
  41. const NodeName kRemoteNodeName{123, 456};
  42. const NodeName kToken{987, 654};
  43. base::RunLoop loop;
  44. EXPECT_CALL(local_delegate,
  45. OnAcceptInvitee(ports::kInvalidNodeName, kRemoteNodeName, kToken))
  46. .WillRepeatedly([&] { loop.Quit(); });
  47. remote_channel->AcceptInvitee(kRemoteNodeName, kToken);
  48. loop.Run();
  49. // Now send another message to the local endpoint but tear it down
  50. // immediately. This will race with the message being received on the IO
  51. // thread, and although the corresponding delegate call may or may not
  52. // dispatch as a result, the race should still be memory-safe.
  53. remote_channel->AcceptInvitee(kRemoteNodeName, kToken);
  54. base::RunLoop error_loop;
  55. EXPECT_CALL(remote_delegate, OnChannelError).WillOnce([&] {
  56. error_loop.Quit();
  57. });
  58. local_channel.reset();
  59. error_loop.Run();
  60. }
  61. TEST_F(NodeChannelTest, MessagesCannotBeSmallerThanOldestVersion) {
  62. base::test::TaskEnvironment task_environment;
  63. PlatformChannel channel;
  64. MockNodeChannelDelegate local_delegate;
  65. auto local_channel =
  66. CreateNodeChannel(&local_delegate, channel.TakeLocalEndpoint());
  67. local_channel->Start();
  68. MockNodeChannelDelegate remote_delegate;
  69. auto remote_channel =
  70. CreateNodeChannel(&remote_delegate, channel.TakeRemoteEndpoint());
  71. remote_channel->Start();
  72. base::RunLoop loop;
  73. // It's a bad message and shouldn't be passed to the delegate.
  74. EXPECT_CALL(local_delegate, OnRequestPortMerge(_, _, _)).Times(0);
  75. // This good message should go through after.
  76. const NodeName kRemoteNodeName{123, 456};
  77. const NodeName kToken{987, 654};
  78. EXPECT_CALL(local_delegate,
  79. OnAcceptInvitee(ports::kInvalidNodeName, kRemoteNodeName, kToken))
  80. .WillRepeatedly([&] {
  81. loop.Quit(); });
  82. // 1 byte is not enough to contain the oldest version of the request port
  83. // merge payload, it should be discarded.
  84. int payload_size = 1;
  85. int capacity = /*sizeof(header)=*/8 + payload_size;
  86. auto message =
  87. Channel::Message::CreateMessage(capacity, capacity, /*num_handles=*/0);
  88. memset(message->mutable_payload(), 0, capacity);
  89. // Set the type of this message as REQUEST_PORT_MERGE (6)
  90. *reinterpret_cast<uint32_t*>(message->mutable_payload()) = 6;
  91. // This short message should be ignored.
  92. remote_channel->SendChannelMessage(std::move(message));
  93. remote_channel->AcceptInvitee(kRemoteNodeName, kToken);
  94. loop.Run();
  95. remote_channel->ShutDown();
  96. local_channel->ShutDown();
  97. }
  98. } // namespace
  99. } // namespace core
  100. } // namespace mojo