diff options
Diffstat (limited to 'mojo/public/cpp/utility/tests')
-rw-r--r-- | mojo/public/cpp/utility/tests/BUILD.gn | 31 | ||||
-rw-r--r-- | mojo/public/cpp/utility/tests/mutex_unittest.cc | 259 | ||||
-rw-r--r-- | mojo/public/cpp/utility/tests/run_loop_unittest.cc | 425 | ||||
-rw-r--r-- | mojo/public/cpp/utility/tests/thread_unittest.cc | 106 |
4 files changed, 0 insertions, 821 deletions
diff --git a/mojo/public/cpp/utility/tests/BUILD.gn b/mojo/public/cpp/utility/tests/BUILD.gn deleted file mode 100644 index a8a96c1..0000000 --- a/mojo/public/cpp/utility/tests/BUILD.gn +++ /dev/null @@ -1,31 +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. - -import("../../../mojo_sdk.gni") - -mojo_sdk_source_set("tests") { - testonly = true - - sources = [ - "run_loop_unittest.cc", - ] - - deps = [ - "//testing/gtest", - ] - - mojo_sdk_deps = [ - "mojo/public/cpp/system", - "mojo/public/cpp/test_support:test_utils", - "mojo/public/cpp/utility", - ] - - # crbug.com/342893 - if (!is_win) { - sources += [ - "mutex_unittest.cc", - "thread_unittest.cc", - ] - } -} diff --git a/mojo/public/cpp/utility/tests/mutex_unittest.cc b/mojo/public/cpp/utility/tests/mutex_unittest.cc deleted file mode 100644 index 78e95c5..0000000 --- a/mojo/public/cpp/utility/tests/mutex_unittest.cc +++ /dev/null @@ -1,259 +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/utility/mutex.h" - -#include <stdlib.h> // For |rand()|. -#include <time.h> // For |nanosleep()| (defined by POSIX). - -#include <vector> - -#include "mojo/public/cpp/system/macros.h" -#include "mojo/public/cpp/utility/thread.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -TEST(MutexTest, TrivialSingleThreaded) { - Mutex mutex; - - mutex.Lock(); - mutex.AssertHeld(); - mutex.Unlock(); - - EXPECT_TRUE(mutex.TryLock()); - mutex.AssertHeld(); - mutex.Unlock(); - - { - MutexLock lock(&mutex); - mutex.AssertHeld(); - } - - EXPECT_TRUE(mutex.TryLock()); - mutex.Unlock(); -} - -class Fiddler { - public: - enum Type { kTypeLock, kTypeTry }; - Fiddler(size_t times_to_lock, - Type type, - bool should_sleep, - Mutex* mutex, - int* shared_value) - : times_to_lock_(times_to_lock), - type_(type), - should_sleep_(should_sleep), - mutex_(mutex), - shared_value_(shared_value) { - } - - ~Fiddler() { - } - - void Fiddle() { - for (size_t i = 0; i < times_to_lock_;) { - switch (type_) { - case kTypeLock: { - mutex_->Lock(); - int old_shared_value = *shared_value_; - if (should_sleep_) - SleepALittle(); - *shared_value_ = old_shared_value + 1; - mutex_->Unlock(); - i++; - break; - } - case kTypeTry: - if (mutex_->TryLock()) { - int old_shared_value = *shared_value_; - if (should_sleep_) - SleepALittle(); - *shared_value_ = old_shared_value + 1; - mutex_->Unlock(); - i++; - } else { - SleepALittle(); // Don't spin. - } - break; - } - } - } - - private: - static void SleepALittle() { - static const long kNanosPerMilli = 1000000; - struct timespec req = { - 0, // Seconds. - (rand() % 10) * kNanosPerMilli // Nanoseconds. - }; - int rv = nanosleep(&req, nullptr); - MOJO_ALLOW_UNUSED_LOCAL(rv); - assert(rv == 0); - } - - const size_t times_to_lock_; - const Type type_; - const bool should_sleep_; - Mutex* const mutex_; - int* const shared_value_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(Fiddler); -}; - -class FiddlerThread : public Thread { - public: - // Takes ownership of |fiddler|. - FiddlerThread(Fiddler* fiddler) - : fiddler_(fiddler) { - } - - ~FiddlerThread() override { delete fiddler_; } - - void Run() override { fiddler_->Fiddle(); } - - private: - Fiddler* const fiddler_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(FiddlerThread); -}; - -// This does a stress test (that also checks exclusion). -TEST(MutexTest, ThreadedStress) { - static const size_t kNumThreads = 20; - static const int kTimesToLockEach = 20; - assert(kNumThreads % 4 == 0); - - Mutex mutex; - int shared_value = 0; - - std::vector<FiddlerThread*> fiddler_threads; - - for (size_t i = 0; i < kNumThreads; i += 4) { - fiddler_threads.push_back(new FiddlerThread(new Fiddler( - kTimesToLockEach, Fiddler::kTypeLock, false, &mutex, &shared_value))); - fiddler_threads.push_back(new FiddlerThread(new Fiddler( - kTimesToLockEach, Fiddler::kTypeTry, false, &mutex, &shared_value))); - fiddler_threads.push_back(new FiddlerThread(new Fiddler( - kTimesToLockEach, Fiddler::kTypeLock, true, &mutex, &shared_value))); - fiddler_threads.push_back(new FiddlerThread(new Fiddler( - kTimesToLockEach, Fiddler::kTypeTry, true, &mutex, &shared_value))); - } - - for (size_t i = 0; i < kNumThreads; i++) - fiddler_threads[i]->Start(); - - // Do some fiddling ourselves. - Fiddler(kTimesToLockEach, Fiddler::kTypeLock, true, &mutex, &shared_value) - .Fiddle(); - - // Join. - for (size_t i = 0; i < kNumThreads; i++) - fiddler_threads[i]->Join(); - - EXPECT_EQ(static_cast<int>(kNumThreads + 1) * kTimesToLockEach, shared_value); - - // Delete. - for (size_t i = 0; i < kNumThreads; i++) - delete fiddler_threads[i]; - fiddler_threads.clear(); -} - -class TryThread : public Thread { - public: - explicit TryThread(Mutex* mutex) : mutex_(mutex), try_lock_succeeded_() {} - ~TryThread() override {} - - void Run() override { - try_lock_succeeded_ = mutex_->TryLock(); - if (try_lock_succeeded_) - mutex_->Unlock(); - } - - bool try_lock_succeeded() const { return try_lock_succeeded_; } - - private: - Mutex* const mutex_; - bool try_lock_succeeded_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(TryThread); -}; - -TEST(MutexTest, TryLock) { - Mutex mutex; - - // |TryLock()| should succeed -- we don't have the lock. - { - TryThread thread(&mutex); - thread.Start(); - thread.Join(); - EXPECT_TRUE(thread.try_lock_succeeded()); - } - - // Take the lock. - ASSERT_TRUE(mutex.TryLock()); - - // Now it should fail. - { - TryThread thread(&mutex); - thread.Start(); - thread.Join(); - EXPECT_FALSE(thread.try_lock_succeeded()); - } - - // Release the lock. - mutex.Unlock(); - - // It should succeed again. - { - TryThread thread(&mutex); - thread.Start(); - thread.Join(); - EXPECT_TRUE(thread.try_lock_succeeded()); - } -} - - -// Tests of assertions for Debug builds. -#if !defined(NDEBUG) -// Test |AssertHeld()| (which is an actual user API). -TEST(MutexTest, DebugAssertHeldFailure) { - Mutex mutex; - EXPECT_DEATH_IF_SUPPORTED(mutex.AssertHeld(), ""); -} - -// Test other consistency checks. -TEST(MutexTest, DebugAssertionFailures) { - // Unlock without lock held. - EXPECT_DEATH_IF_SUPPORTED({ - Mutex mutex; - mutex.Unlock(); - }, ""); - - // Lock with lock held (on same thread). - EXPECT_DEATH_IF_SUPPORTED({ - Mutex mutex; - mutex.Lock(); - mutex.Lock(); - }, ""); - - // Try lock with lock held. - EXPECT_DEATH_IF_SUPPORTED({ - Mutex mutex; - mutex.Lock(); - mutex.TryLock(); - }, ""); - - // Destroy lock with lock held. - EXPECT_DEATH_IF_SUPPORTED({ - Mutex mutex; - mutex.Lock(); - }, ""); -} -#endif // !defined(NDEBUG) - -} // namespace -} // namespace mojo diff --git a/mojo/public/cpp/utility/tests/run_loop_unittest.cc b/mojo/public/cpp/utility/tests/run_loop_unittest.cc deleted file mode 100644 index 4ab4876..0000000 --- a/mojo/public/cpp/utility/tests/run_loop_unittest.cc +++ /dev/null @@ -1,425 +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/utility/run_loop.h" - -#include <string> - -#include "mojo/public/cpp/system/core.h" -#include "mojo/public/cpp/test_support/test_utils.h" -#include "mojo/public/cpp/utility/run_loop_handler.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -class TestRunLoopHandler : public RunLoopHandler { - public: - TestRunLoopHandler() - : ready_count_(0), - error_count_(0), - last_error_result_(MOJO_RESULT_OK) { - } - ~TestRunLoopHandler() override {} - - void clear_ready_count() { ready_count_ = 0; } - int ready_count() const { return ready_count_; } - - void clear_error_count() { error_count_ = 0; } - int error_count() const { return error_count_; } - - MojoResult last_error_result() const { return last_error_result_; } - - // RunLoopHandler: - void OnHandleReady(const Handle& handle) override { ready_count_++; } - void OnHandleError(const Handle& handle, MojoResult result) override { - error_count_++; - last_error_result_ = result; - } - - private: - int ready_count_; - int error_count_; - MojoResult last_error_result_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(TestRunLoopHandler); -}; - -class RunLoopTest : public testing::Test { - public: - RunLoopTest() {} - - void SetUp() override { - Test::SetUp(); - RunLoop::SetUp(); - } - void TearDown() override { - RunLoop::TearDown(); - Test::TearDown(); - } - - private: - MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopTest); -}; - -// Trivial test to verify Run() with no added handles returns. -TEST_F(RunLoopTest, ExitsWithNoHandles) { - RunLoop run_loop; - run_loop.Run(); -} - -class RemoveOnReadyRunLoopHandler : public TestRunLoopHandler { - public: - RemoveOnReadyRunLoopHandler() : run_loop_(nullptr) {} - ~RemoveOnReadyRunLoopHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - - // RunLoopHandler: - void OnHandleReady(const Handle& handle) override { - run_loop_->RemoveHandler(handle); - TestRunLoopHandler::OnHandleReady(handle); - } - - private: - RunLoop* run_loop_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(RemoveOnReadyRunLoopHandler); -}; - -// Verifies RunLoop quits when no more handles (handle is removed when ready). -TEST_F(RunLoopTest, HandleReady) { - RemoveOnReadyRunLoopHandler handler; - MessagePipe test_pipe; - EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string())); - - RunLoop run_loop; - handler.set_run_loop(&run_loop); - run_loop.AddHandler(&handler, test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE); - run_loop.Run(); - EXPECT_EQ(1, handler.ready_count()); - EXPECT_EQ(0, handler.error_count()); - EXPECT_FALSE(run_loop.HasHandler(test_pipe.handle0.get())); -} - -class QuitOnReadyRunLoopHandler : public TestRunLoopHandler { - public: - QuitOnReadyRunLoopHandler() : run_loop_(nullptr) {} - ~QuitOnReadyRunLoopHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - - // RunLoopHandler: - void OnHandleReady(const Handle& handle) override { - run_loop_->Quit(); - TestRunLoopHandler::OnHandleReady(handle); - } - - private: - RunLoop* run_loop_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(QuitOnReadyRunLoopHandler); -}; - -// Verifies Quit() from OnHandleReady() quits the loop. -TEST_F(RunLoopTest, QuitFromReady) { - QuitOnReadyRunLoopHandler handler; - MessagePipe test_pipe; - EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string())); - - RunLoop run_loop; - handler.set_run_loop(&run_loop); - run_loop.AddHandler(&handler, test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE); - run_loop.Run(); - EXPECT_EQ(1, handler.ready_count()); - EXPECT_EQ(0, handler.error_count()); - EXPECT_TRUE(run_loop.HasHandler(test_pipe.handle0.get())); -} - -class QuitOnErrorRunLoopHandler : public TestRunLoopHandler { - public: - QuitOnErrorRunLoopHandler() : run_loop_(nullptr) {} - ~QuitOnErrorRunLoopHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - - // RunLoopHandler: - void OnHandleError(const Handle& handle, MojoResult result) override { - run_loop_->Quit(); - TestRunLoopHandler::OnHandleError(handle, result); - } - - private: - RunLoop* run_loop_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(QuitOnErrorRunLoopHandler); -}; - -// Verifies Quit() when the deadline is reached works. -TEST_F(RunLoopTest, QuitWhenDeadlineExpired) { - QuitOnErrorRunLoopHandler handler; - MessagePipe test_pipe; - RunLoop run_loop; - handler.set_run_loop(&run_loop); - run_loop.AddHandler(&handler, test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - static_cast<MojoDeadline>(10000)); - run_loop.Run(); - EXPECT_EQ(0, handler.ready_count()); - EXPECT_EQ(1, handler.error_count()); - EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, handler.last_error_result()); - EXPECT_FALSE(run_loop.HasHandler(test_pipe.handle0.get())); -} - -// Test that handlers are notified of loop destruction. -TEST_F(RunLoopTest, Destruction) { - TestRunLoopHandler handler; - MessagePipe test_pipe; - { - RunLoop run_loop; - run_loop.AddHandler(&handler, - test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - } - EXPECT_EQ(1, handler.error_count()); - EXPECT_EQ(MOJO_RESULT_ABORTED, handler.last_error_result()); -} - -class RemoveManyRunLoopHandler : public TestRunLoopHandler { - public: - RemoveManyRunLoopHandler() : run_loop_(nullptr) {} - ~RemoveManyRunLoopHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - void add_handle(const Handle& handle) { handles_.push_back(handle); } - - // RunLoopHandler: - void OnHandleError(const Handle& handle, MojoResult result) override { - for (size_t i = 0; i < handles_.size(); i++) - run_loop_->RemoveHandler(handles_[i]); - TestRunLoopHandler::OnHandleError(handle, result); - } - - private: - std::vector<Handle> handles_; - RunLoop* run_loop_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(RemoveManyRunLoopHandler); -}; - -// Test that handlers are notified of loop destruction. -TEST_F(RunLoopTest, MultipleHandleDestruction) { - RemoveManyRunLoopHandler odd_handler; - TestRunLoopHandler even_handler; - MessagePipe test_pipe1, test_pipe2, test_pipe3; - { - RunLoop run_loop; - odd_handler.set_run_loop(&run_loop); - odd_handler.add_handle(test_pipe1.handle0.get()); - odd_handler.add_handle(test_pipe3.handle0.get()); - run_loop.AddHandler(&odd_handler, - test_pipe1.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - run_loop.AddHandler(&even_handler, - test_pipe2.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - run_loop.AddHandler(&odd_handler, - test_pipe3.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - } - EXPECT_EQ(1, odd_handler.error_count()); - EXPECT_EQ(1, even_handler.error_count()); - EXPECT_EQ(MOJO_RESULT_ABORTED, odd_handler.last_error_result()); - EXPECT_EQ(MOJO_RESULT_ABORTED, even_handler.last_error_result()); -} - -class AddHandlerOnErrorHandler : public TestRunLoopHandler { - public: - AddHandlerOnErrorHandler() : run_loop_(nullptr) {} - ~AddHandlerOnErrorHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - - // RunLoopHandler: - void OnHandleError(const Handle& handle, MojoResult result) override { - run_loop_->AddHandler(this, handle, - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - TestRunLoopHandler::OnHandleError(handle, result); - } - - private: - RunLoop* run_loop_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(AddHandlerOnErrorHandler); -}; - -TEST_F(RunLoopTest, AddHandlerOnError) { - AddHandlerOnErrorHandler handler; - MessagePipe test_pipe; - { - RunLoop run_loop; - handler.set_run_loop(&run_loop); - run_loop.AddHandler(&handler, - test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - } - EXPECT_EQ(1, handler.error_count()); - EXPECT_EQ(MOJO_RESULT_ABORTED, handler.last_error_result()); -} - -TEST_F(RunLoopTest, Current) { - EXPECT_TRUE(RunLoop::current() == nullptr); - { - RunLoop run_loop; - EXPECT_EQ(&run_loop, RunLoop::current()); - } - EXPECT_TRUE(RunLoop::current() == nullptr); -} - -class NestingRunLoopHandler : public TestRunLoopHandler { - public: - static const size_t kDepthLimit; - static const char kSignalMagic; - - NestingRunLoopHandler() - : run_loop_(nullptr), - pipe_(nullptr), - depth_(0), - reached_depth_limit_(false) {} - - ~NestingRunLoopHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - void set_pipe(MessagePipe* pipe) { pipe_ = pipe; } - bool reached_depth_limit() const { return reached_depth_limit_; } - - // RunLoopHandler: - void OnHandleReady(const Handle& handle) override { - TestRunLoopHandler::OnHandleReady(handle); - EXPECT_EQ(handle.value(), pipe_->handle0.get().value()); - - ReadSignal(); - size_t current_depth = ++depth_; - if (current_depth < kDepthLimit) { - WriteSignal(); - run_loop_->Run(); - if (current_depth == kDepthLimit - 1) { - // The topmost loop Quit()-ed, so its parent takes back the - // control without exeeding deadline. - EXPECT_EQ(error_count(), 0); - } else { - EXPECT_EQ(error_count(), 1); - } - - } else { - EXPECT_EQ(current_depth, kDepthLimit); - reached_depth_limit_ = true; - run_loop_->Quit(); - } - --depth_; - } - - void WriteSignal() { - char write_byte = kSignalMagic; - MojoResult write_result = - WriteMessageRaw(pipe_->handle1.get(), &write_byte, 1, nullptr, 0, - MOJO_WRITE_MESSAGE_FLAG_NONE); - EXPECT_EQ(write_result, MOJO_RESULT_OK); - } - - void ReadSignal() { - char read_byte = 0; - uint32_t bytes_read = 1; - uint32_t handles_read = 0; - MojoResult read_result = - ReadMessageRaw(pipe_->handle0.get(), &read_byte, &bytes_read, nullptr, - &handles_read, MOJO_READ_MESSAGE_FLAG_NONE); - EXPECT_EQ(read_result, MOJO_RESULT_OK); - EXPECT_EQ(read_byte, kSignalMagic); - } - - private: - RunLoop* run_loop_; - MessagePipe* pipe_; - size_t depth_; - bool reached_depth_limit_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(NestingRunLoopHandler); -}; - -const size_t NestingRunLoopHandler::kDepthLimit = 10; -const char NestingRunLoopHandler::kSignalMagic = 'X'; - -TEST_F(RunLoopTest, NestedRun) { - NestingRunLoopHandler handler; - MessagePipe test_pipe; - RunLoop run_loop; - handler.set_run_loop(&run_loop); - handler.set_pipe(&test_pipe); - run_loop.AddHandler(&handler, test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - static_cast<MojoDeadline>(10000)); - handler.WriteSignal(); - run_loop.Run(); - - EXPECT_TRUE(handler.reached_depth_limit()); - // Got MOJO_RESULT_DEADLINE_EXCEEDED once then removed from the - // RunLoop's handler list. - EXPECT_EQ(handler.error_count(), 1); - EXPECT_EQ(handler.last_error_result(), MOJO_RESULT_DEADLINE_EXCEEDED); -} - -struct Task { - Task(int num, std::vector<int>* sequence) : num(num), sequence(sequence) {} - - void Run() const { sequence->push_back(num); } - - int num; - std::vector<int>* sequence; -}; - -TEST_F(RunLoopTest, DelayedTaskOrder) { - std::vector<int> sequence; - RunLoop run_loop; - run_loop.PostDelayedTask(Closure(Task(1, &sequence)), 0); - run_loop.PostDelayedTask(Closure(Task(2, &sequence)), 0); - run_loop.PostDelayedTask(Closure(Task(3, &sequence)), 0); - run_loop.RunUntilIdle(); - - ASSERT_EQ(3u, sequence.size()); - EXPECT_EQ(1, sequence[0]); - EXPECT_EQ(2, sequence[1]); - EXPECT_EQ(3, sequence[2]); -} - -struct QuittingTask { - explicit QuittingTask(RunLoop* run_loop) : run_loop(run_loop) {} - - void Run() const { run_loop->Quit(); } - - RunLoop* run_loop; -}; - -TEST_F(RunLoopTest, QuitFromDelayedTask) { - TestRunLoopHandler handler; - MessagePipe test_pipe; - RunLoop run_loop; - run_loop.AddHandler(&handler, - test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - run_loop.PostDelayedTask(Closure(QuittingTask(&run_loop)), 0); - run_loop.Run(); -} - -} // namespace -} // namespace mojo diff --git a/mojo/public/cpp/utility/tests/thread_unittest.cc b/mojo/public/cpp/utility/tests/thread_unittest.cc deleted file mode 100644 index 57c4ad9..0000000 --- a/mojo/public/cpp/utility/tests/thread_unittest.cc +++ /dev/null @@ -1,106 +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/utility/thread.h" - -#include "mojo/public/cpp/system/macros.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -class SetIntThread : public Thread { - public: - SetIntThread(int* int_to_set, int value) - : int_to_set_(int_to_set), - value_(value) { - } - SetIntThread(const Options& options, int* int_to_set, int value) - : Thread(options), - int_to_set_(int_to_set), - value_(value) { - } - - ~SetIntThread() override {} - - void Run() override { *int_to_set_ = value_; } - - private: - int* const int_to_set_; - const int value_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(SetIntThread); -}; - -TEST(ThreadTest, CreateAndJoin) { - int value = 0; - - // Not starting the thread should result in a no-op. - { - SetIntThread thread(&value, 1234567); - } - EXPECT_EQ(0, value); - - // Start and join. - { - SetIntThread thread(&value, 12345678); - thread.Start(); - thread.Join(); - EXPECT_EQ(12345678, value); - } - - // Ditto, with non-default (but reasonable) stack size. - { - Thread::Options options; - options.set_stack_size(1024 * 1024); // 1 MB. - SetIntThread thread(options, &value, 12345678); - thread.Start(); - thread.Join(); - EXPECT_EQ(12345678, value); - } -} - -// Tests of assertions for Debug builds. -// Note: It's okay to create threads, despite gtest having to fork. (The threads -// are in the child process.) -#if !defined(NDEBUG) -TEST(ThreadTest, DebugAssertionFailures) { - // Can only start once. - EXPECT_DEATH_IF_SUPPORTED({ - int value = 0; - SetIntThread thread(&value, 1); - thread.Start(); - thread.Start(); - }, ""); - - // Must join (if you start). - EXPECT_DEATH_IF_SUPPORTED({ - int value = 0; - SetIntThread thread(&value, 2); - thread.Start(); - }, ""); - - // Can only join once. - EXPECT_DEATH_IF_SUPPORTED({ - int value = 0; - SetIntThread thread(&value, 3); - thread.Start(); - thread.Join(); - thread.Join(); - }, ""); - - // Stack too big (we're making certain assumptions here). - EXPECT_DEATH_IF_SUPPORTED({ - int value = 0; - Thread::Options options; - options.set_stack_size(static_cast<size_t>(-1)); - SetIntThread thread(options, &value, 4); - thread.Start(); - thread.Join(); - }, ""); -} -#endif // !defined(NDEBUG) - -} // namespace -} // namespace mojo |