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