OSDN Git Service

Add a socket unit test for the async_manager
authorMyles Watson <mylesgw@google.com>
Fri, 19 Aug 2016 15:22:42 +0000 (15:22 +0000)
committerMyles Watson <mylesgw@google.com>
Fri, 19 Aug 2016 20:42:55 +0000 (13:42 -0700)
This reverts commit 10986700c302f79376894ebef9f2ec92a65b8b08.
Which reverted commit 1387d4330da52034af67d1dbc61b870e8f89c820.

Some minor style changes as well.

Change-Id: I83ea40b4cf96adfa58c24d0cd9109ed9974519f1

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..90972d0
--- /dev/null
@@ -0,0 +1,148 @@
+//
+// Copyright 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 "async_manager.h"
+#include <gtest/gtest.h>
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+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