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