shell_service_protocol_test.cpp revision 73096f2e1d87da571187515af6aa7c2171a70693
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "shell_service.h" 18 19#include <gtest/gtest.h> 20 21#include <signal.h> 22#include <string.h> 23 24#include "sysdeps.h" 25 26class ShellProtocolTest : public ::testing::Test { 27 public: 28 static void SetUpTestCase() { 29#if !defined(_WIN32) 30 // This is normally done in main.cpp. 31 saved_sigpipe_handler_ = signal(SIGPIPE, SIG_IGN); 32#endif 33 } 34 35 static void TearDownTestCase() { 36#if !defined(_WIN32) 37 signal(SIGPIPE, saved_sigpipe_handler_); 38#endif 39 } 40 41 // Initializes the socketpair and ShellProtocols needed for testing. 42 void SetUp() { 43 int fds[2]; 44 ASSERT_EQ(0, adb_socketpair(fds)); 45 read_fd_ = fds[0]; 46 write_fd_ = fds[1]; 47 48 write_protocol_ = new ShellProtocol(write_fd_); 49 ASSERT_TRUE(write_protocol_ != nullptr); 50 51 read_protocol_ = new ShellProtocol(read_fd_); 52 ASSERT_TRUE(read_protocol_ != nullptr); 53 } 54 55 // Cleans up FDs and ShellProtocols. If an FD is closed manually during a 56 // test, set it to -1 to prevent TearDown() trying to close it again. 57 void TearDown() { 58 for (int fd : {read_fd_, write_fd_}) { 59 if (fd >= 0) { 60 adb_close(fd); 61 } 62 } 63 for (ShellProtocol* protocol : {read_protocol_, write_protocol_}) { 64 if (protocol) { 65 delete protocol; 66 } 67 } 68 } 69 70 // Fakes the buffer size so we can test filling buffers. 71 void SetReadDataCapacity(size_t size) { 72 read_protocol_->buffer_end_ = read_protocol_->data() + size; 73 } 74 75 static sighandler_t saved_sigpipe_handler_; 76 77 int read_fd_ = -1, write_fd_ = -1; 78 ShellProtocol *read_protocol_ = nullptr, *write_protocol_ = nullptr; 79}; 80 81sighandler_t ShellProtocolTest::saved_sigpipe_handler_ = nullptr; 82 83namespace { 84 85// Returns true if the packet contains the given values. 86bool PacketEquals(const ShellProtocol* protocol, ShellProtocol::Id id, 87 const void* data, size_t data_length) { 88 return (protocol->id() == id && 89 protocol->data_length() == data_length && 90 !memcmp(data, protocol->data(), data_length)); 91} 92 93} // namespace 94 95// Tests data that can fit in a single packet. 96TEST_F(ShellProtocolTest, FullPacket) { 97 ShellProtocol::Id id = ShellProtocol::kIdStdout; 98 char data[] = "abc 123 \0\r\n"; 99 100 memcpy(write_protocol_->data(), data, sizeof(data)); 101 ASSERT_TRUE(write_protocol_->Write(id, sizeof(data))); 102 103 ASSERT_TRUE(read_protocol_->Read()); 104 ASSERT_TRUE(PacketEquals(read_protocol_, id, data, sizeof(data))); 105} 106 107// Tests data that has to be read multiple times due to smaller read buffer. 108TEST_F(ShellProtocolTest, ReadBufferOverflow) { 109 ShellProtocol::Id id = ShellProtocol::kIdStdin; 110 111 memcpy(write_protocol_->data(), "1234567890", 10); 112 ASSERT_TRUE(write_protocol_->Write(id, 10)); 113 114 SetReadDataCapacity(4); 115 ASSERT_TRUE(read_protocol_->Read()); 116 ASSERT_TRUE(PacketEquals(read_protocol_, id, "1234", 4)); 117 ASSERT_TRUE(read_protocol_->Read()); 118 ASSERT_TRUE(PacketEquals(read_protocol_, id, "5678", 4)); 119 ASSERT_TRUE(read_protocol_->Read()); 120 ASSERT_TRUE(PacketEquals(read_protocol_, id, "90", 2)); 121} 122 123// Tests a zero length packet. 124TEST_F(ShellProtocolTest, ZeroLengthPacket) { 125 ShellProtocol::Id id = ShellProtocol::kIdStderr; 126 127 ASSERT_TRUE(write_protocol_->Write(id, 0)); 128 ASSERT_TRUE(read_protocol_->Read()); 129 ASSERT_TRUE(PacketEquals(read_protocol_, id, nullptr, 0)); 130} 131 132// Tests exit code packets. 133TEST_F(ShellProtocolTest, ExitCodePacket) { 134 write_protocol_->data()[0] = 20; 135 ASSERT_TRUE(write_protocol_->Write(ShellProtocol::kIdExit, 1)); 136 137 ASSERT_TRUE(read_protocol_->Read()); 138 ASSERT_EQ(ShellProtocol::kIdExit, read_protocol_->id()); 139 ASSERT_EQ(20, read_protocol_->data()[0]); 140} 141 142// Tests writing to a closed pipe. 143TEST_F(ShellProtocolTest, WriteToClosedPipeFail) { 144 adb_close(read_fd_); 145 read_fd_ = -1; 146 147 ASSERT_FALSE(write_protocol_->Write(ShellProtocol::kIdStdout, 0)); 148} 149 150// Tests writing to a closed FD. 151TEST_F(ShellProtocolTest, WriteToClosedFdFail) { 152 adb_close(write_fd_); 153 write_fd_ = -1; 154 155 ASSERT_FALSE(write_protocol_->Write(ShellProtocol::kIdStdout, 0)); 156} 157 158// Tests reading from a closed pipe. 159TEST_F(ShellProtocolTest, ReadFromClosedPipeFail) { 160 adb_close(write_fd_); 161 write_fd_ = -1; 162 163 ASSERT_FALSE(read_protocol_->Read()); 164} 165 166// Tests reading from a closed FD. 167TEST_F(ShellProtocolTest, ReadFromClosedFdFail) { 168 adb_close(read_fd_); 169 read_fd_ = -1; 170 171 ASSERT_FALSE(read_protocol_->Read()); 172} 173 174// Tests reading from a closed pipe that has a packet waiting. This checks that 175// even if the pipe closes before we can fully read its contents we will still 176// be able to access the last packets. 177TEST_F(ShellProtocolTest, ReadPacketFromClosedPipe) { 178 ShellProtocol::Id id = ShellProtocol::kIdStdout; 179 char data[] = "foo bar"; 180 181 memcpy(write_protocol_->data(), data, sizeof(data)); 182 ASSERT_TRUE(write_protocol_->Write(id, sizeof(data))); 183 adb_close(write_fd_); 184 write_fd_ = -1; 185 186 // First read should grab the packet. 187 ASSERT_TRUE(read_protocol_->Read()); 188 ASSERT_TRUE(PacketEquals(read_protocol_, id, data, sizeof(data))); 189 190 // Second read should fail. 191 ASSERT_FALSE(read_protocol_->Read()); 192} 193