| //===-- Unittests for the internal Semaphore class ------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "hdr/errno_macros.h" | |
| #include "hdr/fcntl_macros.h" | |
| #include "src/semaphore/linux/semaphore.h" | |
| #include "test/UnitTest/Test.h" | |
| using LIBC_NAMESPACE::Semaphore; | |
| TEST(LlvmLibcSemaphoreTest, InitAndGetValue) { | |
| Semaphore sem(3); | |
| ASSERT_TRUE(sem.is_valid()); | |
| ASSERT_EQ(sem.getvalue(), 3); | |
| } | |
| TEST(LlvmLibcSemaphoreTest, Destroy) { | |
| Semaphore sem(5); | |
| ASSERT_TRUE(sem.is_valid()); | |
| sem.destroy(); | |
| ASSERT_FALSE(sem.is_valid()); | |
| } | |
| // Named semaphore tests. | |
| TEST(LlvmLibcSemaphoreTest, NamedOpenCloseUnlink) { | |
| const char *name = "/llvmlibc_test_sem"; | |
| // clean up any leftover from previous test runs. | |
| Semaphore::unlink(name); | |
| // create a new named semaphore. | |
| auto result = Semaphore::open(name, O_CREAT | O_EXCL, 0644, 7); | |
| ASSERT_TRUE(result.has_value()); | |
| Semaphore *sem = result.value(); | |
| ASSERT_TRUE(sem->is_valid()); | |
| ASSERT_EQ(sem->getvalue(), 7); | |
| // close and unlink. | |
| ASSERT_EQ(Semaphore::close(sem), 0); | |
| ASSERT_EQ(Semaphore::unlink(name), 0); | |
| } | |
| TEST(LlvmLibcSemaphoreTest, NamedOpenExisting) { | |
| const char *name = "/llvmlibc_test_sem_exist"; | |
| Semaphore::unlink(name); | |
| // create a named semaphore. | |
| auto r1 = Semaphore::open(name, O_CREAT | O_EXCL, 0644, 10); | |
| ASSERT_TRUE(r1.has_value()); | |
| Semaphore *sem1 = r1.value(); | |
| ASSERT_EQ(sem1->getvalue(), 10); | |
| // open the same semaphore again without O_EXCL. | |
| auto r2 = Semaphore::open(name, O_CREAT, 0644, 99); | |
| ASSERT_TRUE(r2.has_value()); | |
| Semaphore *sem2 = r2.value(); | |
| ASSERT_EQ(sem2->getvalue(), 10); | |
| ASSERT_EQ(Semaphore::close(sem2), 0); | |
| ASSERT_EQ(Semaphore::close(sem1), 0); | |
| ASSERT_EQ(Semaphore::unlink(name), 0); | |
| } | |
| TEST(LlvmLibcSemaphoreTest, NamedOpenExclFails) { | |
| const char *name = "/llvmlibc_test_sem_excl"; | |
| Semaphore::unlink(name); | |
| // create a named semaphore. | |
| auto r1 = Semaphore::open(name, O_CREAT | O_EXCL, 0644, 1); | |
| ASSERT_TRUE(r1.has_value()); | |
| // trying O_CREAT | O_EXCL again should fail with EEXIST. | |
| auto r2 = Semaphore::open(name, O_CREAT | O_EXCL, 0644, 1); | |
| ASSERT_FALSE(r2.has_value()); | |
| ASSERT_EQ(r2.error(), EEXIST); | |
| ASSERT_EQ(Semaphore::close(r1.value()), 0); | |
| ASSERT_EQ(Semaphore::unlink(name), 0); | |
| } | |
| TEST(LlvmLibcSemaphoreTest, NamedOpenNonExistent) { | |
| // opening a non-existent semaphore without O_CREAT should fail. | |
| auto result = Semaphore::open("/llvmlibc_nonexistent", 0, 0, 0); | |
| ASSERT_FALSE(result.has_value()); | |
| ASSERT_EQ(result.error(), ENOENT); | |
| } | |
| TEST(LlvmLibcSemaphoreTest, NamedOpenInvalidName) { | |
| // empty name. | |
| auto r1 = Semaphore::open("", O_CREAT, 0644, 0); | |
| ASSERT_FALSE(r1.has_value()); | |
| ASSERT_EQ(r1.error(), EINVAL); | |
| // name with embedded slash. | |
| auto r2 = Semaphore::open("/has/slash", O_CREAT, 0644, 0); | |
| ASSERT_FALSE(r2.has_value()); | |
| ASSERT_EQ(r2.error(), EINVAL); | |
| // just a slash. | |
| auto r3 = Semaphore::open("/", O_CREAT, 0644, 0); | |
| ASSERT_FALSE(r3.has_value()); | |
| ASSERT_EQ(r3.error(), EINVAL); | |
| } |