summaryrefslogtreecommitdiff
path: root/Tests
diff options
context:
space:
mode:
authorMax Wipfli <mail@maxwipfli.ch>2021-07-11 20:42:46 +0200
committerIdan Horowitz <idan.horowitz@gmail.com>2022-02-13 21:58:26 +0200
commitf3cf1b33d7a1c7f774c4c48ebc7f098c829cb99b (patch)
tree58dada7747bd4e1aa2a719d9c89c45bff164a518 /Tests
parente8f491b01de29408aab7933e32a3885b708f5409 (diff)
downloadserenity-f3cf1b33d7a1c7f774c4c48ebc7f098c829cb99b.zip
Tests: Add test for LibC mkdir()
Diffstat (limited to 'Tests')
-rw-r--r--Tests/LibC/CMakeLists.txt1
-rw-r--r--Tests/LibC/TestMkDir.cpp105
2 files changed, 106 insertions, 0 deletions
diff --git a/Tests/LibC/CMakeLists.txt b/Tests/LibC/CMakeLists.txt
index 2391c05ae0..4d60aea78a 100644
--- a/Tests/LibC/CMakeLists.txt
+++ b/Tests/LibC/CMakeLists.txt
@@ -11,6 +11,7 @@ set(TEST_SOURCES
TestLibCTime.cpp
TestMalloc.cpp
TestMemmem.cpp
+ TestMkDir.cpp
TestQsort.cpp
TestRaise.cpp
TestRealpath.cpp
diff --git a/Tests/LibC/TestMkDir.cpp b/Tests/LibC/TestMkDir.cpp
new file mode 100644
index 0000000000..2d419d3e4f
--- /dev/null
+++ b/Tests/LibC/TestMkDir.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2021, Max Wipfli <max.wipfli@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibTest/TestCase.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+
+static String random_dirname()
+{
+ return String::formatted("/tmp/test_mkdir_{:04x}", (u16)rand());
+}
+
+TEST_SETUP
+{
+ srand(time(NULL));
+}
+
+TEST_CASE(basic)
+{
+ auto dirname = random_dirname();
+ int res = mkdir(dirname.characters(), 0755);
+ EXPECT(res == 0);
+
+ res = mkdir(dirname.characters(), 0755);
+ int cached_errno = errno;
+ EXPECT(res < 0);
+ EXPECT_EQ(cached_errno, EEXIST);
+}
+
+TEST_CASE(insufficient_permissions)
+{
+ VERIFY(getuid() != 0);
+ int res = mkdir("/root/foo", 0755);
+ int cached_errno = errno;
+ EXPECT(res < 0);
+ EXPECT_EQ(cached_errno, EACCES);
+}
+
+TEST_CASE(nonexistent_parent)
+{
+ auto parent = random_dirname();
+ auto child = String::formatted("{}/foo", parent);
+ int res = mkdir(child.characters(), 0755);
+ int cached_errno = errno;
+ EXPECT(res < 0);
+ EXPECT_EQ(cached_errno, ENOENT);
+}
+
+TEST_CASE(parent_is_file)
+{
+ int res = mkdir("/etc/passwd/foo", 0755);
+ int cached_errno = errno;
+ EXPECT(res < 0);
+ EXPECT_EQ(cached_errno, ENOTDIR);
+}
+
+TEST_CASE(pledge)
+{
+ int res = pledge("stdio cpath", nullptr);
+ EXPECT(res == 0);
+
+ auto dirname = random_dirname();
+ res = mkdir(dirname.characters(), 0755);
+ EXPECT(res == 0);
+ // FIXME: Somehow also check that mkdir() stops working when removing the cpath promise. This is currently
+ // not possible because this would prevent the unveil test case from properly working.
+}
+
+TEST_CASE(unveil)
+{
+ int res = unveil("/tmp", "rwc");
+ EXPECT(res == 0);
+
+ auto dirname = random_dirname();
+ res = mkdir(dirname.characters(), 0755);
+ EXPECT(res == 0);
+
+ res = unveil("/tmp", "rw");
+ EXPECT(res == 0);
+
+ dirname = random_dirname();
+ res = mkdir(dirname.characters(), 0755);
+ int cached_errno = errno;
+ EXPECT(res < 0);
+ EXPECT_EQ(cached_errno, EACCES);
+
+ res = unveil("/tmp", "");
+ EXPECT(res == 0);
+
+ dirname = random_dirname();
+ res = mkdir(dirname.characters(), 0755);
+ cached_errno = errno;
+ EXPECT(res < 0);
+ EXPECT_EQ(cached_errno, ENOENT);
+
+ res = unveil(nullptr, nullptr);
+ EXPECT(res == 0);
+}