summaryrefslogtreecommitdiffstats
path: root/mojo/system/embedder/embedder_unittest.cc
blob: 797097d056a29f6c17edcd33b991f76ea9b0d501 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// 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/system/embedder/embedder.h"

#include <string.h>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
// TODO(vtl): Remove build_config.h include when fully implemented on Windows.
#include "build/build_config.h"
#include "mojo/public/system/core.h"
#include "mojo/system/embedder/platform_channel_pair.h"
#include "mojo/system/embedder/test_embedder.h"
#include "mojo/system/test_utils.h"

namespace mojo {
namespace embedder {
namespace {

typedef system::test::TestWithIOThreadBase EmbedderTest;

void StoreChannelInfo(ChannelInfo** store_channel_info_here,
                      ChannelInfo* channel_info) {
  CHECK(store_channel_info_here);
  CHECK(channel_info);
  *store_channel_info_here = channel_info;
}

TEST_F(EmbedderTest, ChannelsBasic) {
  Init();

// TODO(vtl): |PlatformChannelPair| not implemented on Windows yet.
#if !defined(OS_WIN)
  PlatformChannelPair channel_pair;
  ScopedPlatformHandle server_handle = channel_pair.PassServerHandle();
  ScopedPlatformHandle client_handle = channel_pair.PassClientHandle();

  ChannelInfo* server_channel_info = NULL;
  MojoHandle server_mp = CreateChannel(server_handle.Pass(),
                                       io_thread_task_runner(),
                                       base::Bind(&StoreChannelInfo,
                                                  &server_channel_info));
  EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);

  ChannelInfo* client_channel_info = NULL;
  MojoHandle client_mp = CreateChannel(client_handle.Pass(),
                                       io_thread_task_runner(),
                                       base::Bind(&StoreChannelInfo,
                                                  &client_channel_info));
  EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);

  // We can write to a message pipe handle immediately.
  const char kHello[] = "hello";
  EXPECT_EQ(MOJO_RESULT_OK,
            MojoWriteMessage(server_mp, kHello,
                             static_cast<uint32_t>(sizeof(kHello)), NULL, 0u,
                             MOJO_WRITE_MESSAGE_FLAG_NONE));

  // Now wait for the other side to become readable.
  EXPECT_EQ(MOJO_RESULT_OK,
            MojoWait(client_mp, MOJO_WAIT_FLAG_READABLE,
                     MOJO_DEADLINE_INDEFINITE));

  char buffer[1000] = {};
  uint32_t num_bytes = static_cast<uint32_t>(sizeof(kHello));
  EXPECT_EQ(MOJO_RESULT_OK,
            MojoReadMessage(client_mp, buffer, &num_bytes, NULL, NULL,
                            MOJO_READ_MESSAGE_FLAG_NONE));
  EXPECT_EQ(sizeof(kHello), num_bytes);
  EXPECT_EQ(0, memcmp(buffer, kHello, num_bytes));

  // TODO(vtl): FIXME -- This rapid-fire closing leads to a warning: "Received a
  // message for nonexistent local destination ID 1". This is due to a race
  // condition (in channel.cc/message_pipe.cc).
  EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
  EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));

  EXPECT_TRUE(server_channel_info != NULL);
  system::test::PostTaskAndWait(io_thread_task_runner(),
                                FROM_HERE,
                                base::Bind(&DestroyChannelOnIOThread,
                                           server_channel_info));

  EXPECT_TRUE(client_channel_info != NULL);
  system::test::PostTaskAndWait(io_thread_task_runner(),
                                FROM_HERE,
                                base::Bind(&DestroyChannelOnIOThread,
                                           client_channel_info));
#endif  // !defined(OS_WIN)

  EXPECT_TRUE(test::Shutdown());
}

// TODO(vtl): Test immediate write & close.
// TODO(vtl): Test broken-connection cases.

}  // namespace
}  // namespace embedder
}  // namespace mojo