/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "perfetto/base/utils.h" #include <fcntl.h> #include <signal.h> #include <stdint.h> #include <unistd.h> #include "gtest/gtest.h" #include "perfetto/base/file_utils.h" #include "perfetto/base/pipe.h" namespace perfetto { namespace base { namespace { TEST(UtilsTest, ArraySize) { char char_arr_1[1]; char char_arr_4[4]; EXPECT_EQ(1u, ArraySize(char_arr_1)); EXPECT_EQ(4u, ArraySize(char_arr_4)); int32_t int32_arr_1[1]; int32_t int32_arr_4[4]; EXPECT_EQ(1u, ArraySize(int32_arr_1)); EXPECT_EQ(4u, ArraySize(int32_arr_4)); uint64_t int64_arr_1[1]; uint64_t int64_arr_4[4]; EXPECT_EQ(1u, ArraySize(int64_arr_1)); EXPECT_EQ(4u, ArraySize(int64_arr_4)); char kString[] = "foo"; EXPECT_EQ(4u, ArraySize(kString)); struct Bar { int32_t a; int32_t b; }; Bar bar_1[1]; Bar bar_4[4]; EXPECT_EQ(1u, ArraySize(bar_1)); EXPECT_EQ(4u, ArraySize(bar_4)); } // Fuchsia doesn't currently support sigaction(), see // fuchsia.atlassian.net/browse/ZX-560. #if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) TEST(UtilsTest, EintrWrapper) { Pipe pipe = Pipe::Create(); struct sigaction sa = {}; struct sigaction old_sa = {}; // Glibc headers for sa_sigaction trigger this. #pragma GCC diagnostic push #if defined(__clang__) #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion" #endif sa.sa_sigaction = [](int, siginfo_t*, void*) {}; #pragma GCC diagnostic pop ASSERT_EQ(0, sigaction(SIGUSR2, &sa, &old_sa)); int parent_pid = getpid(); pid_t pid = fork(); ASSERT_NE(-1, pid); if (pid == 0 /* child */) { usleep(5000); kill(parent_pid, SIGUSR2); ignore_result(WriteAll(*pipe.wr, "foo\0", 4)); _exit(0); } char buf[6] = {}; EXPECT_EQ(4, PERFETTO_EINTR(read(*pipe.rd, buf, sizeof(buf)))); EXPECT_EQ(0, PERFETTO_EINTR(close(*pipe.rd))); pipe.wr.reset(); // A 2nd close should fail with the proper errno. int res = close(*pipe.rd); auto err = errno; EXPECT_EQ(-1, res); EXPECT_EQ(EBADF, err); pipe.rd.release(); // Restore the old handler. sigaction(SIGUSR2, &old_sa, nullptr); } #endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) TEST(UtilsTest, Align) { EXPECT_EQ(0u, AlignUp<4>(0)); EXPECT_EQ(4u, AlignUp<4>(1)); EXPECT_EQ(4u, AlignUp<4>(3)); EXPECT_EQ(4u, AlignUp<4>(4)); EXPECT_EQ(8u, AlignUp<4>(5)); EXPECT_EQ(0u, AlignUp<16>(0)); EXPECT_EQ(16u, AlignUp<16>(1)); EXPECT_EQ(16u, AlignUp<16>(15)); EXPECT_EQ(16u, AlignUp<16>(16)); EXPECT_EQ(32u, AlignUp<16>(17)); EXPECT_EQ(0xffffff00u, AlignUp<16>(0xffffff00 - 1)); } } // namespace } // namespace base } // namespace perfetto