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