blob: 27d81a91b27dc27ffc0ff36ac4f147952fea834a [file] [log] [blame]
// 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)