| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <fbl/unique_fd.h> |
| |
| #include <fbl/algorithm.h> |
| #include <unittest/unittest.h> |
| |
| #include <utility> |
| |
| namespace { |
| |
| bool invalid_fd_test() { |
| BEGIN_TEST; |
| |
| { |
| fbl::unique_fd fd; |
| |
| EXPECT_EQ(fd.get(), fbl::unique_fd::InvalidValue()); |
| EXPECT_EQ(fbl::unique_fd::InvalidValue(), fd.get()); |
| |
| EXPECT_EQ(static_cast<int>(fd), fbl::unique_fd::InvalidValue()); |
| EXPECT_EQ(fbl::unique_fd::InvalidValue(), static_cast<int>(fd)); |
| |
| EXPECT_EQ(false, fd.is_valid()); |
| EXPECT_EQ(static_cast<bool>(fd), false); |
| EXPECT_EQ(false, static_cast<bool>(fd)); |
| |
| EXPECT_FALSE(fd); |
| } |
| |
| END_TEST; |
| } |
| |
| bool valid_comparison_test() { |
| BEGIN_TEST; |
| |
| int pipes[2]; |
| EXPECT_EQ(pipe(pipes), 0); |
| { |
| fbl::unique_fd in(pipes[1]); |
| fbl::unique_fd out(pipes[0]); |
| |
| EXPECT_NE(in.get(), fbl::unique_fd::InvalidValue()); |
| EXPECT_NE(out.get(), fbl::unique_fd::InvalidValue()); |
| EXPECT_NE(fbl::unique_fd::InvalidValue(), in.get()); |
| EXPECT_NE(fbl::unique_fd::InvalidValue(), out.get()); |
| |
| EXPECT_EQ(in.get(), in.get()); |
| EXPECT_NE(in.get(), out.get()); |
| EXPECT_FALSE(in == out); |
| EXPECT_TRUE(in == in); |
| EXPECT_TRUE(out == out); |
| EXPECT_EQ(pipes[1], in.get()); |
| |
| EXPECT_TRUE(in); |
| EXPECT_TRUE(out); |
| } |
| |
| END_TEST; |
| } |
| |
| bool verify_pipes_open(int in, int out) { |
| BEGIN_HELPER; |
| char w = 'a'; |
| EXPECT_EQ(write(in, &w, 1), 1); |
| char r; |
| EXPECT_EQ(read(out, &r, 1), 1); |
| EXPECT_EQ(r, w); |
| END_HELPER; |
| } |
| |
| bool verify_pipes_closed(int in, int out) { |
| BEGIN_HELPER; |
| char c = 'a'; |
| EXPECT_EQ(write(in, &c, 1), -1); |
| EXPECT_EQ(read(out, &c, 1), -1); |
| END_HELPER; |
| } |
| |
| bool scoping_test() { |
| BEGIN_TEST; |
| int pipes[2]; |
| EXPECT_EQ(pipe(pipes), 0); |
| EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0])); |
| { |
| fbl::unique_fd in(pipes[1]); |
| fbl::unique_fd out(pipes[0]); |
| |
| EXPECT_EQ(pipes[0], out.get()); |
| EXPECT_EQ(pipes[1], in.get()); |
| EXPECT_TRUE(verify_pipes_open(in.get(), out.get())); |
| } |
| EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0])); |
| END_TEST; |
| } |
| |
| bool swap_test() { |
| BEGIN_TEST; |
| int pipes[2]; |
| EXPECT_EQ(pipe(pipes), 0); |
| EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0])); |
| { |
| fbl::unique_fd in(pipes[1]); |
| fbl::unique_fd out(pipes[0]); |
| |
| in.swap(out); |
| EXPECT_EQ(pipes[0], in.get()); |
| EXPECT_EQ(pipes[1], out.get()); |
| EXPECT_TRUE(verify_pipes_open(out.get(), in.get())); |
| } |
| EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0])); |
| EXPECT_TRUE(verify_pipes_closed(pipes[0], pipes[1])); |
| END_TEST; |
| } |
| |
| bool move_test() { |
| BEGIN_TEST; |
| // Move assignment |
| int pipes[2]; |
| EXPECT_EQ(pipe(pipes), 0); |
| EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0])); |
| { |
| fbl::unique_fd in(pipes[1]); |
| fbl::unique_fd out(pipes[0]); |
| |
| fbl::unique_fd in2, out2; |
| EXPECT_TRUE(verify_pipes_open(in.get(), out.get())); |
| EXPECT_TRUE(verify_pipes_closed(in2.get(), out2.get())); |
| |
| in2 = std::move(in); |
| out2 = std::move(out); |
| |
| EXPECT_TRUE(verify_pipes_closed(in.get(), out.get())); |
| EXPECT_TRUE(verify_pipes_open(in2.get(), out2.get())); |
| } |
| EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0])); |
| |
| // Move constructor |
| EXPECT_EQ(pipe(pipes), 0); |
| EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0])); |
| { |
| fbl::unique_fd in(pipes[1]); |
| fbl::unique_fd out(pipes[0]); |
| |
| EXPECT_TRUE(verify_pipes_open(in.get(), out.get())); |
| |
| fbl::unique_fd in2 = std::move(in); |
| fbl::unique_fd out2 = std::move(out); |
| |
| EXPECT_TRUE(verify_pipes_closed(in.get(), out.get())); |
| EXPECT_TRUE(verify_pipes_open(in2.get(), out2.get())); |
| } |
| EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0])); |
| END_TEST; |
| } |
| |
| bool reset_test() { |
| BEGIN_TEST; |
| int pipes[2]; |
| EXPECT_EQ(pipe(pipes), 0); |
| int other_pipes[2]; |
| EXPECT_EQ(pipe(other_pipes), 0); |
| EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0])); |
| EXPECT_TRUE(verify_pipes_open(other_pipes[1], other_pipes[0])); |
| { |
| fbl::unique_fd in(pipes[1]); |
| fbl::unique_fd out(pipes[0]); |
| |
| EXPECT_TRUE(verify_pipes_open(in.get(), out.get())); |
| EXPECT_TRUE(verify_pipes_open(pipes[1], pipes[0])); |
| EXPECT_TRUE(verify_pipes_open(other_pipes[1], other_pipes[0])); |
| |
| in.reset(other_pipes[1]); |
| out.reset(other_pipes[0]); |
| |
| EXPECT_TRUE(verify_pipes_open(in.get(), out.get())); |
| EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0])); |
| EXPECT_TRUE(verify_pipes_open(other_pipes[1], other_pipes[0])); |
| |
| in.reset(); |
| out.reset(); |
| |
| EXPECT_TRUE(verify_pipes_closed(in.get(), out.get())); |
| EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0])); |
| EXPECT_TRUE(verify_pipes_closed(other_pipes[1], other_pipes[0])); |
| } |
| EXPECT_TRUE(verify_pipes_closed(pipes[1], pipes[0])); |
| EXPECT_TRUE(verify_pipes_closed(other_pipes[1], other_pipes[0])); |
| END_TEST; |
| } |
| |
| bool duplicate_test() { |
| BEGIN_TEST; |
| int pipes[2]; |
| EXPECT_EQ(pipe(pipes), 0); |
| |
| fbl::unique_fd in(pipes[1]); |
| fbl::unique_fd out(pipes[0]); |
| EXPECT_TRUE(verify_pipes_open(in.get(), out.get())); |
| { |
| fbl::unique_fd in2 = in.duplicate(); |
| fbl::unique_fd out2 = out.duplicate(); |
| EXPECT_TRUE(verify_pipes_open(in2.get(), out2.get())); |
| |
| EXPECT_TRUE(verify_pipes_open(in2.get(), out.get())); |
| EXPECT_TRUE(verify_pipes_open(in.get(), out2.get())); |
| EXPECT_TRUE(verify_pipes_open(in.get(), out.get())); |
| } |
| EXPECT_TRUE(verify_pipes_open(in.get(), out.get())); |
| |
| END_TEST; |
| } |
| |
| } // namespace |
| |
| BEGIN_TEST_CASE(unique_fd_tests) |
| RUN_TEST(invalid_fd_test) |
| RUN_TEST(valid_comparison_test) |
| RUN_TEST(scoping_test) |
| RUN_TEST(swap_test) |
| RUN_TEST(move_test) |
| RUN_TEST(reset_test) |
| RUN_TEST(duplicate_test) |
| END_TEST_CASE(unique_fd_tests) |