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 "adb_io.h" 18 19 #include <gtest/gtest.h> 20 21 #include <fcntl.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <sys/stat.h> 25 #include <sys/types.h> 26 #include <unistd.h> 27 28 #include <string> 29 30 #include <android-base/file.h> 31 #include <android-base/test_utils.h> 32 33 // All of these tests fail on Windows because they use the C Runtime open(), 34 // but the adb_io APIs expect file descriptors from adb_open(). This could 35 // theoretically be fixed by making adb_read()/adb_write() fallback to using 36 // read()/write() if an unrecognized fd is used, and by making adb_open() return 37 // fds far from the range that open() returns. But all of that might defeat the 38 // purpose of the tests. 39 40 #if defined(_WIN32) 41 #define POSIX_TEST(x,y) TEST(DISABLED_ ## x,y) 42 #else 43 #define POSIX_TEST TEST 44 #endif 45 46 POSIX_TEST(io, ReadFdExactly_whole) { 47 const char expected[] = "Foobar"; 48 TemporaryFile tf; 49 ASSERT_NE(-1, tf.fd); 50 51 ASSERT_TRUE(android::base::WriteStringToFd(expected, tf.fd)) << strerror(errno); 52 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 53 54 // Test reading the whole file. 55 char buf[sizeof(expected)] = {}; 56 ASSERT_TRUE(ReadFdExactly(tf.fd, buf, sizeof(buf) - 1)) << strerror(errno); 57 EXPECT_STREQ(expected, buf); 58 } 59 60 POSIX_TEST(io, ReadFdExactly_eof) { 61 const char expected[] = "Foobar"; 62 TemporaryFile tf; 63 ASSERT_NE(-1, tf.fd); 64 65 ASSERT_TRUE(android::base::WriteStringToFd(expected, tf.fd)) << strerror(errno); 66 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 67 68 // Test that not having enough data will fail. 69 char buf[sizeof(expected) + 1] = {}; 70 ASSERT_FALSE(ReadFdExactly(tf.fd, buf, sizeof(buf))); 71 EXPECT_EQ(0, errno) << strerror(errno); 72 } 73 74 POSIX_TEST(io, ReadFdExactly_partial) { 75 const char input[] = "Foobar"; 76 TemporaryFile tf; 77 ASSERT_NE(-1, tf.fd); 78 79 ASSERT_TRUE(android::base::WriteStringToFd(input, tf.fd)) << strerror(errno); 80 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 81 82 // Test reading a partial file. 83 char buf[sizeof(input) - 1] = {}; 84 ASSERT_TRUE(ReadFdExactly(tf.fd, buf, sizeof(buf) - 1)); 85 86 std::string expected(input); 87 expected.pop_back(); 88 EXPECT_STREQ(expected.c_str(), buf); 89 } 90 91 POSIX_TEST(io, WriteFdExactly_whole) { 92 const char expected[] = "Foobar"; 93 TemporaryFile tf; 94 ASSERT_NE(-1, tf.fd); 95 96 // Test writing the whole string to the file. 97 ASSERT_TRUE(WriteFdExactly(tf.fd, expected, sizeof(expected))) 98 << strerror(errno); 99 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 100 101 std::string s; 102 ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)); 103 EXPECT_STREQ(expected, s.c_str()); 104 } 105 106 POSIX_TEST(io, WriteFdExactly_partial) { 107 const char buf[] = "Foobar"; 108 TemporaryFile tf; 109 ASSERT_NE(-1, tf.fd); 110 111 // Test writing a partial string to the file. 112 ASSERT_TRUE(WriteFdExactly(tf.fd, buf, sizeof(buf) - 2)) << strerror(errno); 113 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 114 115 std::string expected(buf); 116 expected.pop_back(); 117 118 std::string s; 119 ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)); 120 EXPECT_EQ(expected, s); 121 } 122 123 POSIX_TEST(io, WriteFdExactly_ENOSPC) { 124 int fd = open("/dev/full", O_WRONLY); 125 ASSERT_NE(-1, fd); 126 127 char buf[] = "foo"; 128 ASSERT_FALSE(WriteFdExactly(fd, buf, sizeof(buf))); 129 ASSERT_EQ(ENOSPC, errno); 130 } 131 132 POSIX_TEST(io, WriteFdExactly_string) { 133 const char str[] = "Foobar"; 134 TemporaryFile tf; 135 ASSERT_NE(-1, tf.fd); 136 137 // Test writing a partial string to the file. 138 ASSERT_TRUE(WriteFdExactly(tf.fd, str)) << strerror(errno); 139 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 140 141 std::string s; 142 ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)); 143 EXPECT_STREQ(str, s.c_str()); 144 } 145 146 POSIX_TEST(io, WriteFdFmt) { 147 TemporaryFile tf; 148 ASSERT_NE(-1, tf.fd); 149 150 // Test writing a partial string to the file. 151 ASSERT_TRUE(WriteFdFmt(tf.fd, "Foo%s%d", "bar", 123)) << strerror(errno); 152 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 153 154 std::string s; 155 ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)); 156 EXPECT_STREQ("Foobar123", s.c_str()); 157 } 158