1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// This file tests the C++ Mojo system core wrappers.
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// TODO(vtl): Maybe rename "CoreCppTest" -> "CoreTest" if/when this gets
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// compiled into a different binary from the C API tests.
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/system/core.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <map>
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/system/macros.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace mojo {
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(CoreCppTest, GetTimeTicksNow) {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const MojoTimeTicks start = GetTimeTicksNow();
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(static_cast<MojoTimeTicks>(0), start)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      << "GetTimeTicksNow should return nonzero value";
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(CoreCppTest, Basic) {
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Basic |Handle| implementation:
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_HANDLE_INVALID, kInvalidHandleValue);
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Handle h0;
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(kInvalidHandleValue, h0.value());
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(kInvalidHandleValue, *h0.mutable_value());
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(h0.is_valid());
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Handle h1(static_cast<MojoHandle>(123));
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<MojoHandle>(123), h1.value());
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<MojoHandle>(123), *h1.mutable_value());
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(h1.is_valid());
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *h1.mutable_value() = static_cast<MojoHandle>(456);
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<MojoHandle>(456), h1.value());
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(h1.is_valid());
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    h1.swap(h0);
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<MojoHandle>(456), h0.value());
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(h0.is_valid());
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(h1.is_valid());
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    h1.set_value(static_cast<MojoHandle>(789));
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    h0.swap(h1);
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<MojoHandle>(789), h0.value());
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(h0.is_valid());
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<MojoHandle>(456), h1.value());
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(h1.is_valid());
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Make sure copy constructor works.
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Handle h2(h0);
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<MojoHandle>(789), h2.value());
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // And assignment.
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    h2 = h1;
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(static_cast<MojoHandle>(456), h2.value());
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Make sure that we can put |Handle|s into |std::map|s.
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    h0 = Handle(static_cast<MojoHandle>(987));
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    h1 = Handle(static_cast<MojoHandle>(654));
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    h2 = Handle(static_cast<MojoHandle>(321));
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Handle h3;
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::map<Handle, int> handle_to_int;
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    handle_to_int[h0] = 0;
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    handle_to_int[h1] = 1;
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    handle_to_int[h2] = 2;
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    handle_to_int[h3] = 3;
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(4u, handle_to_int.size());
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(handle_to_int.find(h0) == handle_to_int.end());
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(0, handle_to_int[h0]);
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(handle_to_int.find(h1) == handle_to_int.end());
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(1, handle_to_int[h1]);
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(handle_to_int.find(h2) == handle_to_int.end());
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(2, handle_to_int[h2]);
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(handle_to_int.find(h3) == handle_to_int.end());
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(3, handle_to_int[h3]);
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(handle_to_int.find(Handle(static_cast<MojoHandle>(13579))) ==
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    handle_to_int.end());
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(vtl): With C++11, support |std::unordered_map|s, etc. (Or figure out
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // how to support the variations of |hash_map|.)
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // |Handle|/|ScopedHandle| functions:
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ScopedHandle h;
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(kInvalidHandleValue, h.get().value());
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // This should be a no-op.
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Close(h.Pass());
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // It should still be invalid.
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(kInvalidHandleValue, h.get().value());
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              Wait(h.get(), ~MOJO_HANDLE_SIGNAL_NONE, 1000000));
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::vector<Handle> wh;
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wh.push_back(h.get());
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    std::vector<MojoHandleSignals> sigs;
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    sigs.push_back(~MOJO_HANDLE_SIGNAL_NONE);
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              WaitMany(wh, sigs, MOJO_DEADLINE_INDEFINITE));
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |MakeScopedHandle| (just compilation tests):
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  {
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_FALSE(MakeScopedHandle(Handle()).is_valid());
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_FALSE(MakeScopedHandle(MessagePipeHandle()).is_valid());
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_FALSE(MakeScopedHandle(DataPipeProducerHandle()).is_valid());
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_FALSE(MakeScopedHandle(DataPipeConsumerHandle()).is_valid());
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    EXPECT_FALSE(MakeScopedHandle(SharedBufferHandle()).is_valid());
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // |MessagePipeHandle|/|ScopedMessagePipeHandle| functions:
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MessagePipeHandle h_invalid;
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_FALSE(h_invalid.is_valid());
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              WriteMessageRaw(h_invalid,
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              NULL, 0,
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              NULL, 0,
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              MOJO_WRITE_MESSAGE_FLAG_NONE));
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    char buffer[10] = { 0 };
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              WriteMessageRaw(h_invalid,
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              buffer, sizeof(buffer),
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              NULL, 0,
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              MOJO_WRITE_MESSAGE_FLAG_NONE));
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              ReadMessageRaw(h_invalid,
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             NULL, NULL,
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             NULL, NULL,
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             MOJO_READ_MESSAGE_FLAG_NONE));
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              ReadMessageRaw(h_invalid,
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             buffer, &buffer_size,
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             NULL, NULL,
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             MOJO_READ_MESSAGE_FLAG_NONE));
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Basic tests of waiting and closing.
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MojoHandle hv0 = kInvalidHandleValue;
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScopedMessagePipeHandle h0;
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScopedMessagePipeHandle h1;
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_FALSE(h0.get().is_valid());
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_FALSE(h1.get().is_valid());
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      CreateMessagePipe(NULL, &h0, &h1);
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_TRUE(h0.get().is_valid());
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_TRUE(h1.get().is_valid());
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_NE(h0.get().value(), h1.get().value());
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Save the handle values, so we can check that things got closed
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // correctly.
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      hv0 = h0.get().value();
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      MojoHandle hv1 = h1.get().value();
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                Wait(h0.get(), MOJO_HANDLE_SIGNAL_READABLE, 0));
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      std::vector<Handle> wh;
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      wh.push_back(h0.get());
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      wh.push_back(h1.get());
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      std::vector<MojoHandleSignals> sigs;
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      sigs.push_back(MOJO_HANDLE_SIGNAL_READABLE);
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      sigs.push_back(MOJO_HANDLE_SIGNAL_WRITABLE);
173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EXPECT_EQ(1, WaitMany(wh, sigs, 1000));
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Test closing |h1| explicitly.
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Close(h1.Pass());
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_FALSE(h1.get().is_valid());
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Make sure |h1| is closed.
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                MojoWait(hv1, ~MOJO_HANDLE_SIGNAL_NONE,
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         MOJO_DEADLINE_INDEFINITE));
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                Wait(h0.get(), MOJO_HANDLE_SIGNAL_READABLE,
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     MOJO_DEADLINE_INDEFINITE));
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // |hv0| should have been closed when |h0| went out of scope, so this close
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // should fail.
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv0));
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Actually test writing/reading messages.
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScopedMessagePipeHandle h0;
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScopedMessagePipeHandle h1;
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      CreateMessagePipe(NULL, &h0, &h1);
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const char kHello[] = "hello";
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello));
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_OK,
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                WriteMessageRaw(h0.get(),
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                kHello, kHelloSize,
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                NULL, 0,
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                MOJO_WRITE_MESSAGE_FLAG_NONE));
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_OK,
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                Wait(h1.get(), MOJO_HANDLE_SIGNAL_READABLE,
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     MOJO_DEADLINE_INDEFINITE));
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      char buffer[10] = { 0 };
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_OK,
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                ReadMessageRaw(h1.get(),
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               buffer, &buffer_size,
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               NULL, NULL,
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               MOJO_READ_MESSAGE_FLAG_NONE));
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(kHelloSize, buffer_size);
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_STREQ(kHello, buffer);
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Send a handle over the previously-establish message pipe. Use the
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // |MessagePipe| wrapper (to test it), which automatically creates a
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // message pipe.
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      MessagePipe mp;
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Write a message to |mp.handle0|, before we send |mp.handle1|.
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const char kWorld[] = "world!";
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld));
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_OK,
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                WriteMessageRaw(mp.handle0.get(),
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                kWorld, kWorldSize,
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                NULL, 0,
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                MOJO_WRITE_MESSAGE_FLAG_NONE));
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Send |mp.handle1| over |h1| to |h0|.
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      MojoHandle handles[5];
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      handles[0] = mp.handle1.release().value();
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_NE(kInvalidHandleValue, handles[0]);
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_FALSE(mp.handle1.get().is_valid());
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      uint32_t handles_count = 1;
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_OK,
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                WriteMessageRaw(h1.get(),
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                kHello, kHelloSize,
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                handles, handles_count,
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                MOJO_WRITE_MESSAGE_FLAG_NONE));
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // |handles[0]| should actually be invalid now.
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handles[0]));
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Read "hello" and the sent handle.
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_OK,
248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                Wait(h0.get(), MOJO_HANDLE_SIGNAL_READABLE,
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     MOJO_DEADLINE_INDEFINITE));
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      memset(buffer, 0, sizeof(buffer));
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      buffer_size = static_cast<uint32_t>(sizeof(buffer));
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      for (size_t i = 0; i < MOJO_ARRAYSIZE(handles); i++)
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        handles[i] = kInvalidHandleValue;
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      handles_count = static_cast<uint32_t>(MOJO_ARRAYSIZE(handles));
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_OK,
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                ReadMessageRaw(h0.get(),
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               buffer, &buffer_size,
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               handles, &handles_count,
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               MOJO_READ_MESSAGE_FLAG_NONE));
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(kHelloSize, buffer_size);
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_STREQ(kHello, buffer);
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(1u, handles_count);
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_NE(kInvalidHandleValue, handles[0]);
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Read from the sent/received handle.
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      mp.handle1.reset(MessagePipeHandle(handles[0]));
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Save |handles[0]| to check that it gets properly closed.
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      hv0 = handles[0];
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_OK,
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                Wait(mp.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE,
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     MOJO_DEADLINE_INDEFINITE));
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      memset(buffer, 0, sizeof(buffer));
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      buffer_size = static_cast<uint32_t>(sizeof(buffer));
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      for (size_t i = 0; i < MOJO_ARRAYSIZE(handles); i++)
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        handles[i] = kInvalidHandleValue;
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      handles_count = static_cast<uint32_t>(MOJO_ARRAYSIZE(handles));
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(MOJO_RESULT_OK,
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                ReadMessageRaw(mp.handle1.get(),
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               buffer, &buffer_size,
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               handles, &handles_count,
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               MOJO_READ_MESSAGE_FLAG_NONE));
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(kWorldSize, buffer_size);
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_STREQ(kWorld, buffer);
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(0u, handles_count);
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv0));
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(vtl): Test |CloseRaw()|.
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(vtl): Test |reset()| more thoroughly?
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(CoreCppTest, TearDownWithMessagesEnqueued) {
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Tear down a message pipe which still has a message enqueued, with the
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // message also having a valid message pipe handle.
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScopedMessagePipeHandle h0;
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScopedMessagePipeHandle h1;
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    CreateMessagePipe(NULL, &h0, &h1);
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Send a handle over the previously-establish message pipe.
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScopedMessagePipeHandle h2;
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScopedMessagePipeHandle h3;
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    CreateMessagePipe(NULL, &h2, &h3);
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Write a message to |h2|, before we send |h3|.
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const char kWorld[] = "world!";
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld));
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              WriteMessageRaw(h2.get(),
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              kWorld, kWorldSize,
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              NULL, 0,
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              MOJO_WRITE_MESSAGE_FLAG_NONE));
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // And also a message to |h3|.
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              WriteMessageRaw(h3.get(),
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              kWorld, kWorldSize,
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              NULL, 0,
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              MOJO_WRITE_MESSAGE_FLAG_NONE));
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Send |h3| over |h1| to |h0|.
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const char kHello[] = "hello";
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello));
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MojoHandle h3_value;
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    h3_value = h3.release().value();
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(kInvalidHandleValue, h3_value);
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(h3.get().is_valid());
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              WriteMessageRaw(h1.get(),
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              kHello, kHelloSize,
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              &h3_value, 1,
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              MOJO_WRITE_MESSAGE_FLAG_NONE));
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // |h3_value| should actually be invalid now.
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value));
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0.release().value()));
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1.release().value()));
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2.release().value()));
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Do this in a different order: make the enqueued message pipe handle only
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // half-alive.
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScopedMessagePipeHandle h0;
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScopedMessagePipeHandle h1;
346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    CreateMessagePipe(NULL, &h0, &h1);
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Send a handle over the previously-establish message pipe.
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScopedMessagePipeHandle h2;
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScopedMessagePipeHandle h3;
351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    CreateMessagePipe(NULL, &h2, &h3);
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Write a message to |h2|, before we send |h3|.
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const char kWorld[] = "world!";
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld));
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              WriteMessageRaw(h2.get(),
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              kWorld, kWorldSize,
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              NULL, 0,
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              MOJO_WRITE_MESSAGE_FLAG_NONE));
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // And also a message to |h3|.
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              WriteMessageRaw(h3.get(),
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              kWorld, kWorldSize,
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              NULL, 0,
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              MOJO_WRITE_MESSAGE_FLAG_NONE));
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Send |h3| over |h1| to |h0|.
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const char kHello[] = "hello";
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello));
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MojoHandle h3_value;
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    h3_value = h3.release().value();
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_NE(kInvalidHandleValue, h3_value);
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(h3.get().is_valid());
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              WriteMessageRaw(h1.get(),
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              kHello, kHelloSize,
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              &h3_value, 1,
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              MOJO_WRITE_MESSAGE_FLAG_NONE));
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // |h3_value| should actually be invalid now.
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value));
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2.release().value()));
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0.release().value()));
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1.release().value()));
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
389f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST(CoreCppTest, ScopedHandleMoveCtor) {
390f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ScopedSharedBufferHandle buffer1;
391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(NULL, 1024, &buffer1));
392f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(buffer1.is_valid());
393f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
394f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ScopedSharedBufferHandle buffer2;
395f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(NULL, 1024, &buffer2));
396f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(buffer2.is_valid());
397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If this fails to close buffer1, ScopedHandleBase::CloseIfNecessary() will
399f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // assert.
400f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  buffer1 = buffer2.Pass();
401f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
402f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(buffer1.is_valid());
403f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(buffer2.is_valid());
404f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
406f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST(CoreCppTest, ScopedHandleMoveCtorSelf) {
407f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ScopedSharedBufferHandle buffer1;
408f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(NULL, 1024, &buffer1));
409f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(buffer1.is_valid());
410f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
411f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  buffer1 = buffer1.Pass();
412f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
413f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(buffer1.is_valid());
414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
415f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(vtl): Write data pipe tests.
417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace mojo
420