1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <fbl/unique_fd.h>
6
7 #include <fbl/algorithm.h>
8 #include <unittest/unittest.h>
9
10 #include <utility>
11
12 namespace {
13
invalid_fd_test()14 bool invalid_fd_test() {
15 BEGIN_TEST;
16
17 {
18 fbl::unique_fd fd;
19
20 EXPECT_EQ(fd.get(), fbl::unique_fd::InvalidValue());
21 EXPECT_EQ(fbl::unique_fd::InvalidValue(), fd.get());
22
23 EXPECT_EQ(static_cast<int>(fd), fbl::unique_fd::InvalidValue());
24 EXPECT_EQ(fbl::unique_fd::InvalidValue(), static_cast<int>(fd));
25
26 EXPECT_EQ(false, fd.is_valid());
27 EXPECT_EQ(static_cast<bool>(fd), false);
28 EXPECT_EQ(false, static_cast<bool>(fd));
29
30 EXPECT_FALSE(fd);
31 }
32
33 END_TEST;
34 }
35
valid_comparison_test()36 bool valid_comparison_test() {
37 BEGIN_TEST;
38
39 int pipes[2];
40 EXPECT_EQ(pipe(pipes), 0);
41 {
42 fbl::unique_fd in(pipes[1]);
43 fbl::unique_fd out(pipes[0]);
44
45 EXPECT_NE(in.get(), fbl::unique_fd::InvalidValue());
46 EXPECT_NE(out.get(), fbl::unique_fd::InvalidValue());
47 EXPECT_NE(fbl::unique_fd::InvalidValue(), in.get());
48 EXPECT_NE(fbl::unique_fd::InvalidValue(), out.get());
49
50 EXPECT_EQ(in.get(), in.get());
51 EXPECT_NE(in.get(), out.get());
52 EXPECT_FALSE(in == out);
53 EXPECT_TRUE(in == in);
54 EXPECT_TRUE(out == out);
55 EXPECT_EQ(pipes[1], in.get());
56
57 EXPECT_TRUE(in);
58 EXPECT_TRUE(out);
59 }
60
61 END_TEST;
62 }
63
verify_pipes_open(int in,int out)64 bool verify_pipes_open(int in, int out) {
65 BEGIN_HELPER;
66 char w = 'a';
67 EXPECT_EQ(write(in, &w, 1), 1);
68 char r;
69 EXPECT_EQ(read(out, &r, 1), 1);
70 EXPECT_EQ(r, w);
71 END_HELPER;
72 }
73
verify_pipes_closed(int in,int out)74 bool verify_pipes_closed(int in, int out) {
75 BEGIN_HELPER;
76 char c = 'a';
77 EXPECT_EQ(write(in, &c, 1), -1);
78 EXPECT_EQ(read(out, &c, 1), -1);
79 END_HELPER;
80 }
81
scoping_test()82 bool scoping_test() {
83 BEGIN_TEST;
84 int pipes[2];
85 EXPECT_EQ(pipe(pipes), 0);
86 EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0]));
87 {
88 fbl::unique_fd in(pipes[1]);
89 fbl::unique_fd out(pipes[0]);
90
91 EXPECT_EQ(pipes[0], out.get());
92 EXPECT_EQ(pipes[1], in.get());
93 EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
94 }
95 EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0]));
96 END_TEST;
97 }
98
swap_test()99 bool swap_test() {
100 BEGIN_TEST;
101 int pipes[2];
102 EXPECT_EQ(pipe(pipes), 0);
103 EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0]));
104 {
105 fbl::unique_fd in(pipes[1]);
106 fbl::unique_fd out(pipes[0]);
107
108 in.swap(out);
109 EXPECT_EQ(pipes[0], in.get());
110 EXPECT_EQ(pipes[1], out.get());
111 EXPECT_TRUE(verify_pipes_open(out.get(), in.get()));
112 }
113 EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0]));
114 EXPECT_TRUE(verify_pipes_closed(pipes[0], pipes[1]));
115 END_TEST;
116 }
117
move_test()118 bool move_test() {
119 BEGIN_TEST;
120 // Move assignment
121 int pipes[2];
122 EXPECT_EQ(pipe(pipes), 0);
123 EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0]));
124 {
125 fbl::unique_fd in(pipes[1]);
126 fbl::unique_fd out(pipes[0]);
127
128 fbl::unique_fd in2, out2;
129 EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
130 EXPECT_TRUE(verify_pipes_closed(in2.get(), out2.get()));
131
132 in2 = std::move(in);
133 out2 = std::move(out);
134
135 EXPECT_TRUE(verify_pipes_closed(in.get(), out.get()));
136 EXPECT_TRUE(verify_pipes_open(in2.get(), out2.get()));
137 }
138 EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0]));
139
140 // Move constructor
141 EXPECT_EQ(pipe(pipes), 0);
142 EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0]));
143 {
144 fbl::unique_fd in(pipes[1]);
145 fbl::unique_fd out(pipes[0]);
146
147 EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
148
149 fbl::unique_fd in2 = std::move(in);
150 fbl::unique_fd out2 = std::move(out);
151
152 EXPECT_TRUE(verify_pipes_closed(in.get(), out.get()));
153 EXPECT_TRUE(verify_pipes_open(in2.get(), out2.get()));
154 }
155 EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0]));
156 END_TEST;
157 }
158
reset_test()159 bool reset_test() {
160 BEGIN_TEST;
161 int pipes[2];
162 EXPECT_EQ(pipe(pipes), 0);
163 int other_pipes[2];
164 EXPECT_EQ(pipe(other_pipes), 0);
165 EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0]));
166 EXPECT_TRUE(verify_pipes_open(other_pipes[1], other_pipes[0]));
167 {
168 fbl::unique_fd in(pipes[1]);
169 fbl::unique_fd out(pipes[0]);
170
171 EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
172 EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0]));
173 EXPECT_TRUE(verify_pipes_open(other_pipes[1], other_pipes[0]));
174
175 in.reset(other_pipes[1]);
176 out.reset(other_pipes[0]);
177
178 EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
179 EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0]));
180 EXPECT_TRUE(verify_pipes_open(other_pipes[1], other_pipes[0]));
181
182 in.reset();
183 out.reset();
184
185 EXPECT_TRUE(verify_pipes_closed(in.get(), out.get()));
186 EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0]));
187 EXPECT_TRUE(verify_pipes_closed(other_pipes[1], other_pipes[0]));
188 }
189 EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0]));
190 EXPECT_TRUE(verify_pipes_closed(other_pipes[1], other_pipes[0]));
191 END_TEST;
192 }
193
duplicate_test()194 bool duplicate_test() {
195 BEGIN_TEST;
196 int pipes[2];
197 EXPECT_EQ(pipe(pipes), 0);
198
199 fbl::unique_fd in(pipes[1]);
200 fbl::unique_fd out(pipes[0]);
201 EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
202 {
203 fbl::unique_fd in2 = in.duplicate();
204 fbl::unique_fd out2 = out.duplicate();
205 EXPECT_TRUE(verify_pipes_open(in2.get(), out2.get()));
206
207 EXPECT_TRUE(verify_pipes_open(in2.get(), out.get()));
208 EXPECT_TRUE(verify_pipes_open(in.get(), out2.get()));
209 EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
210 }
211 EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
212
213 END_TEST;
214 }
215
216 } // namespace
217
218 BEGIN_TEST_CASE(unique_fd_tests)
219 RUN_TEST(invalid_fd_test)
220 RUN_TEST(valid_comparison_test)
221 RUN_TEST(scoping_test)
222 RUN_TEST(swap_test)
223 RUN_TEST(move_test)
224 RUN_TEST(reset_test)
225 RUN_TEST(duplicate_test)
226 END_TEST_CASE(unique_fd_tests)
227