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 TEST(io, ReadFdExactly_whole) { 41 const char expected[] = "Foobar"; 42 TemporaryFile tf; 43 ASSERT_NE(-1, tf.fd); 44 45 ASSERT_TRUE(android::base::WriteStringToFd(expected, tf.fd)) << strerror(errno); 46 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 47 48 // Test reading the whole file. 49 char buf[sizeof(expected)] = {}; 50 ASSERT_TRUE(ReadFdExactly(tf.fd, buf, sizeof(buf) - 1)) << strerror(errno); 51 EXPECT_STREQ(expected, buf); 52 } 53 54 TEST(io, ReadFdExactly_eof) { 55 const char expected[] = "Foobar"; 56 TemporaryFile tf; 57 ASSERT_NE(-1, tf.fd); 58 59 ASSERT_TRUE(android::base::WriteStringToFd(expected, tf.fd)) << strerror(errno); 60 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 61 62 // Test that not having enough data will fail. 63 char buf[sizeof(expected) + 1] = {}; 64 ASSERT_FALSE(ReadFdExactly(tf.fd, buf, sizeof(buf))); 65 EXPECT_EQ(0, errno) << strerror(errno); 66 } 67 68 TEST(io, ReadFdExactly_partial) { 69 const char input[] = "Foobar"; 70 TemporaryFile tf; 71 ASSERT_NE(-1, tf.fd); 72 73 ASSERT_TRUE(android::base::WriteStringToFd(input, tf.fd)) << strerror(errno); 74 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 75 76 // Test reading a partial file. 77 char buf[sizeof(input) - 1] = {}; 78 ASSERT_TRUE(ReadFdExactly(tf.fd, buf, sizeof(buf) - 1)); 79 80 std::string expected(input); 81 expected.pop_back(); 82 EXPECT_STREQ(expected.c_str(), buf); 83 } 84 85 TEST(io, WriteFdExactly_whole) { 86 const char expected[] = "Foobar"; 87 TemporaryFile tf; 88 ASSERT_NE(-1, tf.fd); 89 90 // Test writing the whole string to the file. 91 ASSERT_TRUE(WriteFdExactly(tf.fd, expected, sizeof(expected))) 92 << strerror(errno); 93 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 94 95 std::string s; 96 ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)); 97 EXPECT_STREQ(expected, s.c_str()); 98 } 99 100 TEST(io, WriteFdExactly_partial) { 101 const char buf[] = "Foobar"; 102 TemporaryFile tf; 103 ASSERT_NE(-1, tf.fd); 104 105 // Test writing a partial string to the file. 106 ASSERT_TRUE(WriteFdExactly(tf.fd, buf, sizeof(buf) - 2)) << strerror(errno); 107 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 108 109 std::string expected(buf); 110 expected.pop_back(); 111 112 std::string s; 113 ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)); 114 EXPECT_EQ(expected, s); 115 } 116 117 TEST(io, WriteFdExactly_ENOSPC) { 118 int fd = open("/dev/full", O_WRONLY); 119 ASSERT_NE(-1, fd); 120 121 char buf[] = "foo"; 122 ASSERT_FALSE(WriteFdExactly(fd, buf, sizeof(buf))); 123 ASSERT_EQ(ENOSPC, errno); 124 } 125 126 TEST(io, WriteFdExactly_string) { 127 const char str[] = "Foobar"; 128 TemporaryFile tf; 129 ASSERT_NE(-1, tf.fd); 130 131 // Test writing a partial string to the file. 132 ASSERT_TRUE(WriteFdExactly(tf.fd, str)) << strerror(errno); 133 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 134 135 std::string s; 136 ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)); 137 EXPECT_STREQ(str, s.c_str()); 138 } 139 140 TEST(io, WriteFdFmt) { 141 TemporaryFile tf; 142 ASSERT_NE(-1, tf.fd); 143 144 // Test writing a partial string to the file. 145 ASSERT_TRUE(WriteFdFmt(tf.fd, "Foo%s%d", "bar", 123)) << strerror(errno); 146 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)); 147 148 std::string s; 149 ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)); 150 EXPECT_STREQ("Foobar123", s.c_str()); 151 } 152