From d4f80ae7ca433e74a1f841e04c66a29ef1830979 Mon Sep 17 00:00:00 2001 From: Myles Watson Date: Fri, 19 Aug 2016 15:22:42 +0000 Subject: [PATCH] Add a socket unit test for the async_manager This reverts commit 10986700c302f79376894ebef9f2ec92a65b8b08. Which reverted commit 1387d4330da52034af67d1dbc61b870e8f89c820. Some minor style changes as well. Change-Id: I83ea40b4cf96adfa58c24d0cd9109ed9974519f1 --- vendor_libs/test_vendor_lib/Android.mk | 1 + .../test_vendor_lib/test/async_manager_unittest.cc | 148 +++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 vendor_libs/test_vendor_lib/test/async_manager_unittest.cc diff --git a/vendor_libs/test_vendor_lib/Android.mk b/vendor_libs/test_vendor_lib/Android.mk index 6b112e5b2..6ad3e37e6 100644 --- a/vendor_libs/test_vendor_lib/Android.mk +++ b/vendor_libs/test_vendor_lib/Android.mk @@ -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 index 000000000..90972d00e --- /dev/null +++ b/vendor_libs/test_vendor_lib/test/async_manager_unittest.cc @@ -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 +#include +#include +#include + +#include +#include +#include +#include +#include + +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(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 -- 2.11.0