Split mojo/public/cpp/system/tests/core_unittest.cc, part 1.
R=azani@chromium.org
Review URL: https://codereview.chromium.org/2102263003 .
diff --git a/mojo/public/cpp/system/tests/BUILD.gn b/mojo/public/cpp/system/tests/BUILD.gn
index fdfe73b..b278180 100644
--- a/mojo/public/cpp/system/tests/BUILD.gn
+++ b/mojo/public/cpp/system/tests/BUILD.gn
@@ -9,7 +9,10 @@
sources = [
"core_unittest.cc",
+ "data_pipe_unittest.cc",
+ "handle_unittest.cc",
"macros_unittest.cc",
+ "time_unittest.cc",
]
deps = [
diff --git a/mojo/public/cpp/system/tests/core_unittest.cc b/mojo/public/cpp/system/tests/core_unittest.cc
index 05769ca..d0da86b 100644
--- a/mojo/public/cpp/system/tests/core_unittest.cc
+++ b/mojo/public/cpp/system/tests/core_unittest.cc
@@ -8,6 +8,7 @@
#include <stddef.h>
#include <map>
+#include <vector>
#include "mojo/public/cpp/system/buffer.h"
#include "mojo/public/cpp/system/data_pipe.h"
@@ -22,88 +23,11 @@
namespace mojo {
namespace {
-TEST(CoreTest, GetTimeTicksNow) {
- const MojoTimeTicks start = GetTimeTicksNow();
- EXPECT_NE(static_cast<MojoTimeTicks>(0), start)
- << "GetTimeTicksNow should return nonzero value";
-}
-
TEST(CoreTest, Basic) {
- // Basic |Handle| implementation:
- {
- EXPECT_EQ(MOJO_HANDLE_INVALID, kInvalidHandleValue);
-
- Handle h0;
- EXPECT_EQ(kInvalidHandleValue, h0.value());
- EXPECT_EQ(kInvalidHandleValue, *h0.mutable_value());
- EXPECT_FALSE(h0.is_valid());
-
- Handle h1(static_cast<MojoHandle>(123));
- EXPECT_EQ(static_cast<MojoHandle>(123), h1.value());
- EXPECT_EQ(static_cast<MojoHandle>(123), *h1.mutable_value());
- EXPECT_TRUE(h1.is_valid());
- *h1.mutable_value() = static_cast<MojoHandle>(456);
- EXPECT_EQ(static_cast<MojoHandle>(456), h1.value());
- EXPECT_TRUE(h1.is_valid());
-
- h1.swap(h0);
- EXPECT_EQ(static_cast<MojoHandle>(456), h0.value());
- EXPECT_TRUE(h0.is_valid());
- EXPECT_FALSE(h1.is_valid());
-
- h1.set_value(static_cast<MojoHandle>(789));
- h0.swap(h1);
- EXPECT_EQ(static_cast<MojoHandle>(789), h0.value());
- EXPECT_TRUE(h0.is_valid());
- EXPECT_EQ(static_cast<MojoHandle>(456), h1.value());
- EXPECT_TRUE(h1.is_valid());
-
- // Make sure copy constructor works.
- Handle h2(h0);
- EXPECT_EQ(static_cast<MojoHandle>(789), h2.value());
- // And assignment.
- h2 = h1;
- EXPECT_EQ(static_cast<MojoHandle>(456), h2.value());
-
- // Make sure that we can put |Handle|s into |std::map|s.
- h0 = Handle(static_cast<MojoHandle>(987));
- h1 = Handle(static_cast<MojoHandle>(654));
- h2 = Handle(static_cast<MojoHandle>(321));
- Handle h3;
- std::map<Handle, int> handle_to_int;
- handle_to_int[h0] = 0;
- handle_to_int[h1] = 1;
- handle_to_int[h2] = 2;
- handle_to_int[h3] = 3;
-
- EXPECT_EQ(4u, handle_to_int.size());
- EXPECT_FALSE(handle_to_int.find(h0) == handle_to_int.end());
- EXPECT_EQ(0, handle_to_int[h0]);
- EXPECT_FALSE(handle_to_int.find(h1) == handle_to_int.end());
- EXPECT_EQ(1, handle_to_int[h1]);
- EXPECT_FALSE(handle_to_int.find(h2) == handle_to_int.end());
- EXPECT_EQ(2, handle_to_int[h2]);
- EXPECT_FALSE(handle_to_int.find(h3) == handle_to_int.end());
- EXPECT_EQ(3, handle_to_int[h3]);
- EXPECT_TRUE(handle_to_int.find(Handle(static_cast<MojoHandle>(13579))) ==
- handle_to_int.end());
-
- // TODO(vtl): With C++11, support |std::unordered_map|s, etc. (Or figure out
- // how to support the variations of |hash_map|.)
- }
-
- // |Handle|/|ScopedHandle| functions:
+ // |Wait|/|WaitMany|:
{
ScopedHandle h;
- EXPECT_EQ(kInvalidHandleValue, h.get().value());
-
- // This should be a no-op.
- Close(h.Pass());
-
- // It should still be invalid.
- EXPECT_EQ(kInvalidHandleValue, h.get().value());
-
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
Wait(h.get(), ~MOJO_HANDLE_SIGNAL_NONE, 1000000, nullptr));
@@ -128,10 +52,7 @@
// |MakeScopedHandle| (just compilation tests):
{
- EXPECT_FALSE(MakeScopedHandle(Handle()).is_valid());
EXPECT_FALSE(MakeScopedHandle(MessagePipeHandle()).is_valid());
- EXPECT_FALSE(MakeScopedHandle(DataPipeProducerHandle()).is_valid());
- EXPECT_FALSE(MakeScopedHandle(DataPipeConsumerHandle()).is_valid());
EXPECT_FALSE(MakeScopedHandle(SharedBufferHandle()).is_valid());
}
@@ -472,33 +393,6 @@
}
}
-TEST(CoreTest, ScopedHandleMoveCtor) {
- ScopedSharedBufferHandle buffer1;
- EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1));
- EXPECT_TRUE(buffer1.is_valid());
-
- ScopedSharedBufferHandle buffer2;
- EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer2));
- EXPECT_TRUE(buffer2.is_valid());
-
- // If this fails to close buffer1, ScopedHandleBase::CloseIfNecessary() will
- // assert.
- buffer1 = buffer2.Pass();
-
- EXPECT_TRUE(buffer1.is_valid());
- EXPECT_FALSE(buffer2.is_valid());
-}
-
-TEST(CoreTest, ScopedHandleMoveCtorSelf) {
- ScopedSharedBufferHandle buffer1;
- EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1));
- EXPECT_TRUE(buffer1.is_valid());
-
- buffer1 = buffer1.Pass();
-
- EXPECT_TRUE(buffer1.is_valid());
-}
-
TEST(CoreTest, WaitManyResult) {
{
WaitManyResult wmr(MOJO_RESULT_OK);
@@ -543,104 +437,5 @@
}
}
-TEST(CoreTest, DataPipe) {
- ScopedDataPipeProducerHandle ph;
- ScopedDataPipeConsumerHandle ch;
-
- ASSERT_EQ(MOJO_RESULT_OK, CreateDataPipe(nullptr, &ph, &ch));
- ASSERT_TRUE(ph.get().is_valid());
- ASSERT_TRUE(ch.get().is_valid());
-
- uint32_t read_threshold = 123u;
- EXPECT_EQ(MOJO_RESULT_OK,
- GetDataPipeConsumerOptions(ch.get(), &read_threshold));
- EXPECT_EQ(0u, read_threshold);
-
- EXPECT_EQ(MOJO_RESULT_OK, SetDataPipeConsumerOptions(ch.get(), 2u));
-
- EXPECT_EQ(MOJO_RESULT_OK,
- GetDataPipeConsumerOptions(ch.get(), &read_threshold));
- EXPECT_EQ(2u, read_threshold);
-
- // Write a byte.
- static const char kA = 'A';
- uint32_t num_bytes = 1u;
- EXPECT_EQ(MOJO_RESULT_OK,
- WriteDataRaw(ph.get(), &kA, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
-
- // Waiting for "read threshold" should fail. (Wait a nonzero amount, in case
- // there's some latency.)
- MojoHandleSignalsState state;
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, &state));
- // ... but it should be readable.
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, state.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
- MOJO_HANDLE_SIGNAL_READ_THRESHOLD,
- state.satisfiable_signals);
-
- // Do a two-phase write of another byte.
- void* write_buffer = nullptr;
- num_bytes = 0u;
- ASSERT_EQ(MOJO_RESULT_OK,
- BeginWriteDataRaw(ph.get(), &write_buffer, &num_bytes,
- MOJO_WRITE_DATA_FLAG_NONE));
- ASSERT_TRUE(write_buffer);
- ASSERT_GT(num_bytes, 0u);
- static_cast<char*>(write_buffer)[0] = 'B';
- EXPECT_EQ(MOJO_RESULT_OK, EndWriteDataRaw(ph.get(), 1u));
-
- // Now waiting for "read threshold" should succeed. (Wait a nonzero amount, in
- // case there's some latency.)
- state = MojoHandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_OK,
- Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, &state));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_READ_THRESHOLD,
- state.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
- MOJO_HANDLE_SIGNAL_READ_THRESHOLD,
- state.satisfiable_signals);
-
- // Read a byte.
- char read_byte = 'x';
- num_bytes = 1u;
- EXPECT_EQ(MOJO_RESULT_OK, ReadDataRaw(ch.get(), &read_byte, &num_bytes,
- MOJO_READ_DATA_FLAG_NONE));
- EXPECT_EQ(1u, num_bytes);
- EXPECT_EQ('A', read_byte);
-
- // Waiting for "read threshold" should now fail.
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 0, nullptr));
-
- // Reset the read threshold/options.
- EXPECT_EQ(MOJO_RESULT_OK, SetDataPipeConsumerOptionsToDefault(ch.get()));
-
- // Waiting for "read threshold" should now succeed.
- EXPECT_EQ(MOJO_RESULT_OK,
- Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 0, nullptr));
-
- // Do a two-phase read.
- const void* read_buffer = nullptr;
- num_bytes = 0u;
- ASSERT_EQ(MOJO_RESULT_OK, BeginReadDataRaw(ch.get(), &read_buffer, &num_bytes,
- MOJO_READ_DATA_FLAG_NONE));
- ASSERT_TRUE(read_buffer);
- ASSERT_EQ(1u, num_bytes);
- EXPECT_EQ('B', static_cast<const char*>(read_buffer)[0]);
- EXPECT_EQ(MOJO_RESULT_OK, EndReadDataRaw(ch.get(), 1u));
-
- // Waiting for "read" should now fail (time out).
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, nullptr));
-
- // Close the producer.
- ph.reset();
-
- // Waiting for "read" should now fail.
- EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, nullptr));
-}
-
} // namespace
} // namespace mojo
diff --git a/mojo/public/cpp/system/tests/data_pipe_unittest.cc b/mojo/public/cpp/system/tests/data_pipe_unittest.cc
new file mode 100644
index 0000000..b75eca0
--- /dev/null
+++ b/mojo/public/cpp/system/tests/data_pipe_unittest.cc
@@ -0,0 +1,121 @@
+// 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.
+
+// This file tests the C++ wrappers in mojo/public/cpp/system/data_pipe.h.
+
+#include "mojo/public/cpp/system/data_pipe.h"
+
+#include "mojo/public/cpp/system/handle.h"
+#include "mojo/public/cpp/system/macros.h"
+#include "mojo/public/cpp/system/wait.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace {
+
+TEST(DataPipe, Basic) {
+ // Cursory compilation tests of |MakeScopedHandle()| with data pipe handles.
+ EXPECT_FALSE(MakeScopedHandle(DataPipeProducerHandle()).is_valid());
+ EXPECT_FALSE(MakeScopedHandle(DataPipeConsumerHandle()).is_valid());
+
+ ScopedDataPipeProducerHandle ph;
+ ScopedDataPipeConsumerHandle ch;
+
+ ASSERT_EQ(MOJO_RESULT_OK, CreateDataPipe(nullptr, &ph, &ch));
+ ASSERT_TRUE(ph.get().is_valid());
+ ASSERT_TRUE(ch.get().is_valid());
+
+ uint32_t read_threshold = 123u;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ GetDataPipeConsumerOptions(ch.get(), &read_threshold));
+ EXPECT_EQ(0u, read_threshold);
+
+ EXPECT_EQ(MOJO_RESULT_OK, SetDataPipeConsumerOptions(ch.get(), 2u));
+
+ EXPECT_EQ(MOJO_RESULT_OK,
+ GetDataPipeConsumerOptions(ch.get(), &read_threshold));
+ EXPECT_EQ(2u, read_threshold);
+
+ // Write a byte.
+ static const char kA = 'A';
+ uint32_t num_bytes = 1u;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ WriteDataRaw(ph.get(), &kA, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
+
+ // Waiting for "read threshold" should fail. (Wait a nonzero amount, in case
+ // there's some latency.)
+ MojoHandleSignalsState state;
+ EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
+ Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, &state));
+ // ... but it should be readable.
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, state.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
+ MOJO_HANDLE_SIGNAL_READ_THRESHOLD,
+ state.satisfiable_signals);
+
+ // Do a two-phase write of another byte.
+ void* write_buffer = nullptr;
+ num_bytes = 0u;
+ ASSERT_EQ(MOJO_RESULT_OK,
+ BeginWriteDataRaw(ph.get(), &write_buffer, &num_bytes,
+ MOJO_WRITE_DATA_FLAG_NONE));
+ ASSERT_TRUE(write_buffer);
+ ASSERT_GT(num_bytes, 0u);
+ static_cast<char*>(write_buffer)[0] = 'B';
+ EXPECT_EQ(MOJO_RESULT_OK, EndWriteDataRaw(ph.get(), 1u));
+
+ // Now waiting for "read threshold" should succeed. (Wait a nonzero amount, in
+ // case there's some latency.)
+ state = MojoHandleSignalsState();
+ EXPECT_EQ(MOJO_RESULT_OK,
+ Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, &state));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_READ_THRESHOLD,
+ state.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
+ MOJO_HANDLE_SIGNAL_READ_THRESHOLD,
+ state.satisfiable_signals);
+
+ // Read a byte.
+ char read_byte = 'x';
+ num_bytes = 1u;
+ EXPECT_EQ(MOJO_RESULT_OK, ReadDataRaw(ch.get(), &read_byte, &num_bytes,
+ MOJO_READ_DATA_FLAG_NONE));
+ EXPECT_EQ(1u, num_bytes);
+ EXPECT_EQ('A', read_byte);
+
+ // Waiting for "read threshold" should now fail.
+ EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
+ Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 0, nullptr));
+
+ // Reset the read threshold/options.
+ EXPECT_EQ(MOJO_RESULT_OK, SetDataPipeConsumerOptionsToDefault(ch.get()));
+
+ // Waiting for "read threshold" should now succeed.
+ EXPECT_EQ(MOJO_RESULT_OK,
+ Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 0, nullptr));
+
+ // Do a two-phase read.
+ const void* read_buffer = nullptr;
+ num_bytes = 0u;
+ ASSERT_EQ(MOJO_RESULT_OK, BeginReadDataRaw(ch.get(), &read_buffer, &num_bytes,
+ MOJO_READ_DATA_FLAG_NONE));
+ ASSERT_TRUE(read_buffer);
+ ASSERT_EQ(1u, num_bytes);
+ EXPECT_EQ('B', static_cast<const char*>(read_buffer)[0]);
+ EXPECT_EQ(MOJO_RESULT_OK, EndReadDataRaw(ch.get(), 1u));
+
+ // Waiting for "read" should now fail (time out).
+ EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
+ Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, nullptr));
+
+ // Close the producer.
+ ph.reset();
+
+ // Waiting for "read" should now fail.
+ EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
+ Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, nullptr));
+}
+
+} // namespace mojo
+} // namespace
diff --git a/mojo/public/cpp/system/tests/handle_unittest.cc b/mojo/public/cpp/system/tests/handle_unittest.cc
new file mode 100644
index 0000000..6c40da1
--- /dev/null
+++ b/mojo/public/cpp/system/tests/handle_unittest.cc
@@ -0,0 +1,175 @@
+// 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.
+
+// This file tests the C++ wrappers in mojo/public/cpp/system/handle.h.
+
+#include "mojo/public/cpp/system/handle.h"
+
+#include <map>
+#include <utility>
+
+#include "mojo/public/cpp/system/buffer.h"
+#include "mojo/public/cpp/system/macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace {
+
+// Basic |Handle| tests.
+TEST(HandleTest, Handle) {
+ EXPECT_EQ(MOJO_HANDLE_INVALID, kInvalidHandleValue);
+
+ Handle h0;
+ EXPECT_EQ(kInvalidHandleValue, h0.value());
+ EXPECT_EQ(kInvalidHandleValue, *h0.mutable_value());
+ EXPECT_FALSE(h0.is_valid());
+
+ Handle h1(static_cast<MojoHandle>(123));
+ EXPECT_EQ(static_cast<MojoHandle>(123), h1.value());
+ EXPECT_EQ(static_cast<MojoHandle>(123), *h1.mutable_value());
+ EXPECT_TRUE(h1.is_valid());
+ *h1.mutable_value() = static_cast<MojoHandle>(456);
+ EXPECT_EQ(static_cast<MojoHandle>(456), h1.value());
+ EXPECT_TRUE(h1.is_valid());
+
+ h1.swap(h0);
+ EXPECT_EQ(static_cast<MojoHandle>(456), h0.value());
+ EXPECT_TRUE(h0.is_valid());
+ EXPECT_FALSE(h1.is_valid());
+
+ h1.set_value(static_cast<MojoHandle>(789));
+ h0.swap(h1);
+ EXPECT_EQ(static_cast<MojoHandle>(789), h0.value());
+ EXPECT_TRUE(h0.is_valid());
+ EXPECT_EQ(static_cast<MojoHandle>(456), h1.value());
+ EXPECT_TRUE(h1.is_valid());
+
+ // Make sure copy constructor works.
+ Handle h2(h0);
+ EXPECT_EQ(static_cast<MojoHandle>(789), h2.value());
+ // And assignment.
+ h2 = h1;
+ EXPECT_EQ(static_cast<MojoHandle>(456), h2.value());
+
+ // Make sure that we can put |Handle|s into |std::map|s.
+ h0 = Handle(static_cast<MojoHandle>(987));
+ h1 = Handle(static_cast<MojoHandle>(654));
+ h2 = Handle(static_cast<MojoHandle>(321));
+ Handle h3;
+ std::map<Handle, int> handle_to_int;
+ handle_to_int[h0] = 0;
+ handle_to_int[h1] = 1;
+ handle_to_int[h2] = 2;
+ handle_to_int[h3] = 3;
+
+ EXPECT_EQ(4u, handle_to_int.size());
+ EXPECT_FALSE(handle_to_int.find(h0) == handle_to_int.end());
+ EXPECT_EQ(0, handle_to_int[h0]);
+ EXPECT_FALSE(handle_to_int.find(h1) == handle_to_int.end());
+ EXPECT_EQ(1, handle_to_int[h1]);
+ EXPECT_FALSE(handle_to_int.find(h2) == handle_to_int.end());
+ EXPECT_EQ(2, handle_to_int[h2]);
+ EXPECT_FALSE(handle_to_int.find(h3) == handle_to_int.end());
+ EXPECT_EQ(3, handle_to_int[h3]);
+ EXPECT_TRUE(handle_to_int.find(Handle(static_cast<MojoHandle>(13579))) ==
+ handle_to_int.end());
+
+ // TODO(vtl): With C++11, support |std::unordered_map|s, etc.
+}
+
+// Basic |ScopedHandle| tests.
+TEST(HandleTest, ScopedHandle) {
+ // Invalid |ScopedHandle|:
+ {
+ ScopedHandle sh0;
+
+ EXPECT_EQ(kInvalidHandleValue, sh0.get().value());
+ EXPECT_FALSE(sh0.is_valid());
+
+ // This should be a no-op.
+ Close(sh0.Pass());
+
+ // It should still be invalid.
+ EXPECT_FALSE(sh0.is_valid());
+
+ // Move constructible:
+ ScopedHandle sh1(std::move(sh0));
+ EXPECT_FALSE(sh0.is_valid());
+ EXPECT_FALSE(sh1.is_valid());
+
+ // Move assignable:
+ sh0 = std::move(sh1);
+ EXPECT_FALSE(sh0.is_valid());
+ EXPECT_FALSE(sh1.is_valid());
+ }
+
+ // "Valid" |ScopedHandle| (but note that we can't test that it closes the
+ // handle on leaving scope without having a valid handle!):
+ {
+ Handle h0(static_cast<MojoHandle>(123));
+ ScopedHandle sh0(h0);
+
+ EXPECT_EQ(h0.value(), sh0.get().value());
+ EXPECT_TRUE(sh0.is_valid());
+
+ // Move constructible:
+ ScopedHandle sh1(std::move(sh0));
+ EXPECT_FALSE(sh0.is_valid());
+ EXPECT_TRUE(sh1.is_valid());
+
+ // Move assignable:
+ sh0 = std::move(sh1);
+ EXPECT_TRUE(sh0.is_valid());
+ EXPECT_FALSE(sh1.is_valid());
+
+ // We have to release |sh0|, since it's not really valid.
+ Handle h1 = sh0.release();
+ EXPECT_EQ(h0.value(), h1.value());
+ }
+}
+
+TEST(HandleTest, MakeScopedHandle) {
+ EXPECT_FALSE(MakeScopedHandle(Handle()).is_valid());
+
+ Handle h(static_cast<MojoHandle>(123));
+ auto sh = MakeScopedHandle(h);
+ EXPECT_TRUE(sh.is_valid());
+ EXPECT_EQ(h.value(), sh.get().value());
+ // Have to release |sh0|, since it's not really valid.
+ ignore_result(sh.release());
+}
+
+TEST(HandleTest, ScopedHandleMoveCtor) {
+ // We'll use a shared buffer handle (since we need a valid handle) in a
+ // |ScopedSharedBufferHandle|.
+ ScopedSharedBufferHandle buffer1;
+ EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1));
+ EXPECT_TRUE(buffer1.is_valid());
+
+ ScopedSharedBufferHandle buffer2;
+ EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer2));
+ EXPECT_TRUE(buffer2.is_valid());
+
+ // If this fails to close buffer1, ScopedHandleBase::CloseIfNecessary() will
+ // assert.
+ buffer1 = buffer2.Pass();
+
+ EXPECT_TRUE(buffer1.is_valid());
+ EXPECT_FALSE(buffer2.is_valid());
+}
+
+TEST(HandleTest, ScopedHandleMoveCtorSelf) {
+ // We'll use a shared buffer handle (since we need a valid handle) in a
+ // |ScopedSharedBufferHandle|.
+ ScopedSharedBufferHandle buffer1;
+ EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1));
+ EXPECT_TRUE(buffer1.is_valid());
+
+ buffer1 = buffer1.Pass();
+
+ EXPECT_TRUE(buffer1.is_valid());
+}
+
+} // namespace mojo
+} // namespace
diff --git a/mojo/public/cpp/system/tests/time_unittest.cc b/mojo/public/cpp/system/tests/time_unittest.cc
new file mode 100644
index 0000000..45c07a7
--- /dev/null
+++ b/mojo/public/cpp/system/tests/time_unittest.cc
@@ -0,0 +1,20 @@
+// 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.
+
+// This file tests the C++ wrappers in mojo/public/cpp/system/time.h.
+
+#include "mojo/public/cpp/system/time.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace {
+
+TEST(TimeTest, GetTimeTicksNow) {
+ const MojoTimeTicks start = GetTimeTicksNow();
+ EXPECT_NE(static_cast<MojoTimeTicks>(0), start);
+}
+
+} // namespace
+} // namespace mojo