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
POSIX_TEST(io,ReadFdExactly_whole)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
POSIX_TEST(io,ReadFdExactly_eof)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
POSIX_TEST(io,ReadFdExactly_partial)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
POSIX_TEST(io,WriteFdExactly_whole)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
POSIX_TEST(io,WriteFdExactly_partial)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
POSIX_TEST(io,WriteFdExactly_ENOSPC)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
POSIX_TEST(io,WriteFdExactly_string)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
POSIX_TEST(io,WriteFdFmt)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