summaryrefslogtreecommitdiff
path: root/unittests/Host/MainLoopTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Host/MainLoopTest.cpp')
-rw-r--r--unittests/Host/MainLoopTest.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/unittests/Host/MainLoopTest.cpp b/unittests/Host/MainLoopTest.cpp
new file mode 100644
index 0000000000000..a2a673d38ca54
--- /dev/null
+++ b/unittests/Host/MainLoopTest.cpp
@@ -0,0 +1,120 @@
+//===-- MainLoopTest.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/MainLoop.h"
+#include "lldb/Host/common/TCPSocket.h"
+#include "gtest/gtest.h"
+#include <future>
+
+using namespace lldb_private;
+
+namespace {
+class MainLoopTest : public testing::Test {
+public:
+ static void SetUpTestCase() {
+#ifdef _MSC_VER
+ WSADATA data;
+ ASSERT_EQ(0, WSAStartup(MAKEWORD(2, 2), &data));
+#endif
+ }
+
+ static void TearDownTestCase() {
+#ifdef _MSC_VER
+ ASSERT_EQ(0, WSACleanup());
+#endif
+ }
+
+ void SetUp() override {
+ bool child_processes_inherit = false;
+ Error error;
+ std::unique_ptr<TCPSocket> listen_socket_up(
+ new TCPSocket(true, child_processes_inherit));
+ ASSERT_TRUE(error.Success());
+ error = listen_socket_up->Listen("localhost:0", 5);
+ ASSERT_TRUE(error.Success());
+
+ Socket *accept_socket;
+ std::future<Error> accept_error = std::async(std::launch::async, [&] {
+ return listen_socket_up->Accept(accept_socket);
+ });
+
+ std::unique_ptr<TCPSocket> connect_socket_up(
+ new TCPSocket(true, child_processes_inherit));
+ error = connect_socket_up->Connect(
+ llvm::formatv("localhost:{0}", listen_socket_up->GetLocalPortNumber())
+ .str());
+ ASSERT_TRUE(error.Success());
+ ASSERT_TRUE(accept_error.get().Success());
+
+ callback_count = 0;
+ socketpair[0] = std::move(connect_socket_up);
+ socketpair[1].reset(accept_socket);
+ }
+
+ void TearDown() override {
+ socketpair[0].reset();
+ socketpair[1].reset();
+ }
+
+protected:
+ MainLoop::Callback make_callback() {
+ return [&](MainLoopBase &loop) {
+ ++callback_count;
+ loop.RequestTermination();
+ };
+ }
+ std::shared_ptr<Socket> socketpair[2];
+ unsigned callback_count;
+};
+} // namespace
+
+TEST_F(MainLoopTest, ReadObject) {
+ char X = 'X';
+ size_t len = sizeof(X);
+ ASSERT_TRUE(socketpair[0]->Write(&X, len).Success());
+
+ MainLoop loop;
+
+ Error error;
+ auto handle = loop.RegisterReadObject(socketpair[1], make_callback(), error);
+ ASSERT_TRUE(error.Success());
+ ASSERT_TRUE(handle);
+ ASSERT_TRUE(loop.Run().Success());
+ ASSERT_EQ(1u, callback_count);
+}
+
+TEST_F(MainLoopTest, TerminatesImmediately) {
+ char X = 'X';
+ size_t len = sizeof(X);
+ ASSERT_TRUE(socketpair[0]->Write(&X, len).Success());
+ ASSERT_TRUE(socketpair[1]->Write(&X, len).Success());
+
+ MainLoop loop;
+ Error error;
+ auto handle0 = loop.RegisterReadObject(socketpair[0], make_callback(), error);
+ ASSERT_TRUE(error.Success());
+ auto handle1 = loop.RegisterReadObject(socketpair[1], make_callback(), error);
+ ASSERT_TRUE(error.Success());
+
+ ASSERT_TRUE(loop.Run().Success());
+ ASSERT_EQ(1u, callback_count);
+}
+
+#ifdef LLVM_ON_UNIX
+TEST_F(MainLoopTest, Signal) {
+ MainLoop loop;
+ Error error;
+
+ auto handle = loop.RegisterSignal(SIGUSR1, make_callback(), error);
+ ASSERT_TRUE(error.Success());
+ kill(getpid(), SIGUSR1);
+ ASSERT_TRUE(loop.Run().Success());
+ ASSERT_EQ(1u, callback_count);
+}
+#endif