OSDN Git Service

Added unit test for async_manager with sockets
authorJorge E. Moreira <jemoreira@google.com>
Wed, 17 Aug 2016 20:53:00 +0000 (13:53 -0700)
committerMyles Watson <mylesgw@google.com>
Thu, 18 Aug 2016 15:31:34 +0000 (15:31 +0000)
Change-Id: I8d31f766722e4b4a6c6fe00e30a957ac43176cf1

vendor_libs/test_vendor_lib/Android.mk
vendor_libs/test_vendor_lib/test/async_manager_unittest.cc [new file with mode: 0644]

index 6b112e5..6ad3e37 100644 (file)
@@ -63,6 +63,7 @@ LOCAL_SRC_FILES := \
     src/hci_transport.cc \
     src/packet.cc \
     src/packet_stream.cc \
+    test/async_manager_unittest.cc \
     test/hci_transport_unittest.cc \
     test/packet_stream_unittest.cc
 
diff --git a/vendor_libs/test_vendor_lib/test/async_manager_unittest.cc b/vendor_libs/test_vendor_lib/test/async_manager_unittest.cc
new file mode 100644 (file)
index 0000000..a526915
--- /dev/null
@@ -0,0 +1,146 @@
+//
+// Copyright 2015 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 "async_manager.h"
+#include <gtest/gtest.h>
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+extern "C" {
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+class AsyncManagerSocketTest : public ::testing::Test {
+ public:
+  static const uint16_t kPort = 6111;
+  static const size_t kBufferSize = 16;
+
+  bool CheckBufferEquals() { return strcmp(server_buffer, client_buffer) == 0; }
+
+ protected:
+  void StartServer() {
+    struct sockaddr_in serv_addr;
+    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
+    EXPECT_FALSE(socket_fd < 0);
+
+    memset(&serv_addr, 0, sizeof(serv_addr));
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_addr.s_addr = INADDR_ANY;
+    serv_addr.sin_port = htons(kPort);
+    EXPECT_FALSE(bind(socket_fd, (sockaddr*)&serv_addr, sizeof(serv_addr)) < 0);
+
+    listen(socket_fd, 1);
+  }
+
+  int AcceptConnection(int socket_fd) {
+    struct sockaddr_in cli_addr;
+    memset(&cli_addr, 0, sizeof(cli_addr));
+    socklen_t clilen = sizeof(cli_addr);
+
+    int connection_fd = accept(socket_fd, (struct sockaddr*)&cli_addr, &clilen);
+    EXPECT_FALSE(connection_fd < 0);
+
+    return connection_fd;
+  }
+
+  void ReadIncomingMessage(int fd) {
+    int n = TEMP_FAILURE_RETRY(read(fd, server_buffer, kBufferSize - 1));
+    EXPECT_FALSE(n < 0);
+
+    if (n == 0) {  // got EOF
+      async_manager.StopWatchingFileDescriptor(fd);
+      close(fd);
+    } else {
+      n = write(fd, "1", 1);
+    }
+  }
+
+  void SetUp() override {
+    memset(server_buffer, 0, kBufferSize);
+
+    StartServer();
+
+    async_manager.WatchFdForNonBlockingReads(socket_fd, [this](int fd) {
+      int connection_fd = AcceptConnection(fd);
+
+      async_manager.WatchFdForNonBlockingReads(
+          connection_fd, [this](int fd) { ReadIncomingMessage(fd); });
+    });
+  }
+
+  void TearDown() override {
+    async_manager.StopWatchingFileDescriptor(socket_fd);
+    close(socket_fd);
+    EXPECT_TRUE(CheckBufferEquals());
+  }
+
+  int ConnectClient() {
+    int socket_cli_fd = socket(AF_INET, SOCK_STREAM, 0);
+    EXPECT_FALSE(socket_cli_fd < 0);
+
+    struct hostent* server;
+    server = gethostbyname("localhost");
+    EXPECT_FALSE(server == NULL);
+
+    struct sockaddr_in serv_addr;
+    memset((void*)&serv_addr, 0, sizeof(serv_addr));
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_addr.s_addr = *(reinterpret_cast<in_addr_t*>(server->h_addr));
+    serv_addr.sin_port = htons(kPort);
+
+    int result =
+        connect(socket_cli_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
+    EXPECT_FALSE(result < 0);
+
+    return socket_cli_fd;
+  }
+
+  void WriteFromClient(int socket_cli_fd) {
+    strcpy(client_buffer, "1");
+    int n = write(socket_cli_fd, client_buffer, strlen(client_buffer));
+    EXPECT_TRUE(n > 0);
+  }
+
+  void AwaitServerResponse(int socket_cli_fd) {
+    int n = read(socket_cli_fd, client_buffer, 1);
+    EXPECT_TRUE(n > 0);
+  }
+
+ private:
+  AsyncManager async_manager;
+  int socket_fd;
+  char server_buffer[kBufferSize];
+  char client_buffer[kBufferSize];
+};
+
+TEST_F(AsyncManagerSocketTest, TestOneConnection) {
+  int socket_cli_fd = ConnectClient();
+
+  WriteFromClient(socket_cli_fd);
+
+  AwaitServerResponse(socket_cli_fd);
+
+  close(socket_cli_fd);
+}
+
+}  // namespace test_vendor_lib