Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 022d447e authored by Josh Gao's avatar Josh Gao
Browse files

adb: make fdevent_test, socket_test compile on Windows.

Switch pthread_* to use the adb_thread_* abstractions to allow the fdevent
and socket tests to compile on Win32.

Bug: http://b/27105824
Change-Id: I6541bb1398780b999837e701837d7f86a5eee8ca
parent 6487e74a
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ LIBADB_SRC_FILES := \
LIBADB_TEST_SRCS := \
    adb_io_test.cpp \
    adb_utils_test.cpp \
    fdevent_test.cpp \
    socket_test.cpp \
    sysdeps_test.cpp \
    transport_test.cpp \

@@ -87,14 +89,6 @@ LIBADB_windows_SRC_FILES := \
    sysdeps_win32.cpp \
    usb_windows.cpp \

LIBADB_TEST_linux_SRCS := \
    fdevent_test.cpp \
    socket_test.cpp \

LIBADB_TEST_darwin_SRCS := \
    fdevent_test.cpp \
    socket_test.cpp \

LIBADB_TEST_windows_SRCS := \
    sysdeps_win32_test.cpp \

+11 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <string.h>
#include <unistd.h>

#include <atomic>
#include <list>
#include <unordered_map>
#include <vector>
@@ -70,6 +71,7 @@ struct PollNode {
// That's why we don't need a lock for fdevent.
static auto& g_poll_node_map = *new std::unordered_map<int, PollNode>();
static auto& g_pending_list = *new std::list<fdevent*>();
static std::atomic<bool> terminate_loop(false);
static bool main_thread_valid;
static unsigned long main_thread_id;

@@ -364,6 +366,10 @@ void fdevent_loop()
#endif // !ADB_HOST

    while (true) {
        if (terminate_loop) {
            return;
        }

        D("--- --- waiting for events");

        fdevent_process();
@@ -376,6 +382,10 @@ void fdevent_loop()
    }
}

void fdevent_terminate_loop() {
    terminate_loop = true;
}

size_t fdevent_installed_count() {
    return g_poll_node_map.size();
}
@@ -384,4 +394,5 @@ void fdevent_reset() {
    g_poll_node_map.clear();
    g_pending_list.clear();
    main_thread_valid = false;
    terminate_loop = false;
}
+2 −2
Original line number Diff line number Diff line
@@ -76,9 +76,9 @@ void fdevent_set_timeout(fdevent *fde, int64_t timeout_ms);
*/
void fdevent_loop();

// For debugging only.
// The following functions are used only for tests.
void fdevent_terminate_loop();
size_t fdevent_installed_count();
// For debugging only.
void fdevent_reset();

#endif
+24 −39
Original line number Diff line number Diff line
@@ -18,15 +18,13 @@

#include <gtest/gtest.h>

#include <pthread.h>
#include <signal.h>

#include <limits>
#include <queue>
#include <string>
#include <vector>

#include "adb_io.h"
#include "fdevent_test.h"

class FdHandler {
  public:
@@ -48,7 +46,7 @@ class FdHandler {
        if (events & FDE_READ) {
            ASSERT_EQ(fd, handler->read_fd_);
            char c;
            ASSERT_EQ(1, read(fd, &c, 1));
            ASSERT_EQ(1, adb_read(fd, &c, 1));
            handler->queue_.push(c);
            fdevent_add(&handler->write_fde_, FDE_WRITE);
        }
@@ -57,7 +55,7 @@ class FdHandler {
            ASSERT_FALSE(handler->queue_.empty());
            char c = handler->queue_.front();
            handler->queue_.pop();
            ASSERT_EQ(1, write(fd, &c, 1));
            ASSERT_EQ(1, adb_write(fd, &c, 1));
            if (handler->queue_.empty()) {
              fdevent_del(&handler->write_fde_, FDE_WRITE);
            }
@@ -72,29 +70,19 @@ class FdHandler {
    std::queue<char> queue_;
};

static void signal_handler(int) {
    pthread_exit(nullptr);
}

class FdeventTest : public ::testing::Test {
  protected:
    static void SetUpTestCase() {
        ASSERT_NE(SIG_ERR, signal(SIGUSR1, signal_handler));
        ASSERT_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
    }

    virtual void SetUp() {
        fdevent_reset();
        ASSERT_EQ(0u, fdevent_installed_count());
    }
};

struct ThreadArg {
    int first_read_fd;
    int last_write_fd;
    size_t middle_pipe_count;
};

TEST_F(FdeventTest, fdevent_terminate) {
    adb_thread_t thread;
    PrepareThread();
    ASSERT_TRUE(adb_thread_create([](void*) { fdevent_loop(); }, nullptr, &thread));
    TerminateThread(thread);
}

static void FdEventThreadFunc(ThreadArg* arg) {
    std::vector<int> read_fds;
    std::vector<int> write_fds;
@@ -102,7 +90,7 @@ static void FdEventThreadFunc(ThreadArg* arg) {
    read_fds.push_back(arg->first_read_fd);
    for (size_t i = 0; i < arg->middle_pipe_count; ++i) {
        int fds[2];
        ASSERT_EQ(0, pipe(fds));
        ASSERT_EQ(0, adb_socketpair(fds));
        read_fds.push_back(fds[0]);
        write_fds.push_back(fds[1]);
    }
@@ -122,9 +110,9 @@ TEST_F(FdeventTest, smoke) {
    const std::string MESSAGE = "fdevent_test";
    int fd_pair1[2];
    int fd_pair2[2];
    ASSERT_EQ(0, pipe(fd_pair1));
    ASSERT_EQ(0, pipe(fd_pair2));
    pthread_t thread;
    ASSERT_EQ(0, adb_socketpair(fd_pair1));
    ASSERT_EQ(0, adb_socketpair(fd_pair2));
    adb_thread_t thread;
    ThreadArg thread_arg;
    thread_arg.first_read_fd = fd_pair1[0];
    thread_arg.last_write_fd = fd_pair2[1];
@@ -132,9 +120,9 @@ TEST_F(FdeventTest, smoke) {
    int writer = fd_pair1[1];
    int reader = fd_pair2[0];

    ASSERT_EQ(0, pthread_create(&thread, nullptr,
                                reinterpret_cast<void* (*)(void*)>(FdEventThreadFunc),
                                &thread_arg));
    PrepareThread();
    ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(FdEventThreadFunc), &thread_arg,
                                  &thread));

    for (size_t i = 0; i < MESSAGE_LOOP_COUNT; ++i) {
        std::string read_buffer = MESSAGE;
@@ -144,10 +132,9 @@ TEST_F(FdeventTest, smoke) {
        ASSERT_EQ(read_buffer, write_buffer);
    }

    ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
    ASSERT_EQ(0, pthread_join(thread, nullptr));
    ASSERT_EQ(0, close(writer));
    ASSERT_EQ(0, close(reader));
    TerminateThread(thread);
    ASSERT_EQ(0, adb_close(writer));
    ASSERT_EQ(0, adb_close(reader));
}

struct InvalidFdArg {
@@ -161,7 +148,7 @@ static void InvalidFdEventCallback(int fd, unsigned events, void* userdata) {
    ASSERT_EQ(arg->expected_events, events);
    fdevent_remove(&arg->fde);
    if (++*(arg->happened_event_count) == 2) {
        pthread_exit(nullptr);
        fdevent_terminate_loop();
    }
}

@@ -184,9 +171,7 @@ static void InvalidFdThreadFunc(void*) {
}

TEST_F(FdeventTest, invalid_fd) {
    pthread_t thread;
    ASSERT_EQ(0, pthread_create(&thread, nullptr,
                                reinterpret_cast<void* (*)(void*)>(InvalidFdThreadFunc),
                                nullptr));
    ASSERT_EQ(0, pthread_join(thread, nullptr));
    adb_thread_t thread;
    ASSERT_TRUE(adb_thread_create(InvalidFdThreadFunc, nullptr, &thread));
    ASSERT_TRUE(adb_thread_join(thread));
}

adb/fdevent_test.h

0 → 100644
+58 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include "socket.h"
#include "sysdeps.h"

class FdeventTest : public ::testing::Test {
  protected:
    int dummy = -1;

    static void SetUpTestCase() {
#if !defined(_WIN32)
        ASSERT_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
#endif
    }

    void SetUp() override {
        fdevent_reset();
        ASSERT_EQ(0u, fdevent_installed_count());
    }

    // Register a dummy socket used to wake up the fdevent loop to tell it to die.
    void PrepareThread() {
        int dummy_fds[2];
        if (adb_socketpair(dummy_fds) != 0) {
            FAIL() << "failed to create socketpair: " << strerror(errno);
        }

        asocket* dummy_socket = create_local_socket(dummy_fds[1]);
        if (!dummy_socket) {
            FAIL() << "failed to create local socket: " << strerror(errno);
        }
        dummy_socket->ready(dummy_socket);
        dummy = dummy_fds[0];
    }

    void TerminateThread(adb_thread_t thread) {
        fdevent_terminate_loop();
        ASSERT_TRUE(WriteFdExactly(dummy, "", 1));
        ASSERT_TRUE(adb_thread_join(thread));
        ASSERT_EQ(0, adb_close(dummy));
    }
};
Loading