mirror of
https://github.com/linux-msm/qdl.git
synced 2026-10-07 06:29:17 -07:00
Include <stdint.h> to provide the definition of uintptr_t and fix the GCC build failure Signed-off-by: Ali Erdinc Koroglu <ali.koroglu@oss.qualcomm.com>
182 lines
4.0 KiB
C
182 lines
4.0 KiB
C
// SPDX-License-Identifier: BSD-3-Clause
|
|
#define _FILE_OFFSET_BITS 64
|
|
|
|
#include <dirent.h>
|
|
#include <errno.h>
|
|
#include <setjmp.h>
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#include <cmocka.h>
|
|
|
|
#include "oscompat.h"
|
|
|
|
#define WORKDIR "test_oscompat_workdir"
|
|
|
|
static bool is_dir(const char *path)
|
|
{
|
|
struct stat st;
|
|
|
|
return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
|
|
}
|
|
|
|
static void rmtree(const char *path)
|
|
{
|
|
struct dirent *ent;
|
|
DIR *dir;
|
|
|
|
dir = opendir(path);
|
|
if (dir) {
|
|
while ((ent = readdir(dir)) != NULL) {
|
|
char child[PATH_MAX];
|
|
struct stat st;
|
|
|
|
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
|
continue;
|
|
|
|
if (snprintf(child, sizeof(child), "%s/%s", path,
|
|
ent->d_name) >= (int)sizeof(child)) {
|
|
fprintf(stderr,
|
|
"skipping overly-long path %s/%s\n",
|
|
path, ent->d_name);
|
|
continue;
|
|
}
|
|
if (stat(child, &st) == 0 && S_ISDIR(st.st_mode))
|
|
rmtree(child);
|
|
else
|
|
unlink(child);
|
|
}
|
|
closedir(dir);
|
|
}
|
|
|
|
rmdir(path);
|
|
}
|
|
|
|
/* ----------------------------- path_is_absolute -------------------------- */
|
|
|
|
static void test_path_is_absolute(void **state)
|
|
{
|
|
(void)state;
|
|
|
|
#ifndef _WIN32
|
|
assert_true(path_is_absolute("/"));
|
|
assert_true(path_is_absolute("/foo/bar"));
|
|
assert_false(path_is_absolute("foo"));
|
|
assert_false(path_is_absolute("./foo"));
|
|
assert_false(path_is_absolute(""));
|
|
#else
|
|
assert_true(path_is_absolute("C:\\foo"));
|
|
assert_true(path_is_absolute("C:/foo"));
|
|
assert_true(path_is_absolute("c:foo")); /* drive-relative */
|
|
assert_true(path_is_absolute("\\\\server\\share"));
|
|
assert_false(path_is_absolute("foo"));
|
|
assert_false(path_is_absolute("\\foo")); /* single backslash */
|
|
assert_false(path_is_absolute(""));
|
|
#endif
|
|
}
|
|
|
|
/* ------------------------------- qdl_mkdir_p ----------------------------- */
|
|
|
|
static void test_mkdir_p_creates_nested(void **state)
|
|
{
|
|
(void)state;
|
|
|
|
assert_int_equal(qdl_mkdir_p(WORKDIR "/a/b/c"), 0);
|
|
assert_true(is_dir(WORKDIR));
|
|
assert_true(is_dir(WORKDIR "/a"));
|
|
assert_true(is_dir(WORKDIR "/a/b"));
|
|
assert_true(is_dir(WORKDIR "/a/b/c"));
|
|
}
|
|
|
|
static void test_mkdir_p_is_idempotent(void **state)
|
|
{
|
|
(void)state;
|
|
|
|
assert_int_equal(qdl_mkdir_p(WORKDIR "/idem"), 0);
|
|
/* An already existing directory is not an error. */
|
|
assert_int_equal(qdl_mkdir_p(WORKDIR "/idem"), 0);
|
|
assert_true(is_dir(WORKDIR "/idem"));
|
|
}
|
|
|
|
static void test_mkdir_p_trailing_slash(void **state)
|
|
{
|
|
(void)state;
|
|
|
|
assert_int_equal(qdl_mkdir_p(WORKDIR "/x/y/"), 0);
|
|
assert_true(is_dir(WORKDIR "/x/y"));
|
|
}
|
|
|
|
static void test_mkdir_p_existing_and_dot(void **state)
|
|
{
|
|
(void)state;
|
|
|
|
/* The current directory always exists; this must succeed. */
|
|
assert_int_equal(qdl_mkdir_p("."), 0);
|
|
/* An empty path is a no-op. */
|
|
assert_int_equal(qdl_mkdir_p(""), 0);
|
|
}
|
|
|
|
static void test_mkdir_p_too_long(void **state)
|
|
{
|
|
char path[PATH_MAX + 16];
|
|
|
|
(void)state;
|
|
|
|
memset(path, 'a', sizeof(path) - 1);
|
|
path[sizeof(path) - 1] = '\0';
|
|
|
|
assert_int_equal(qdl_mkdir_p(path), -1);
|
|
assert_int_equal(errno, ENAMETOOLONG);
|
|
}
|
|
|
|
static void test_mkdir_p_component_not_a_dir(void **state)
|
|
{
|
|
const char *file = WORKDIR "/afile";
|
|
FILE *fp;
|
|
|
|
(void)state;
|
|
|
|
assert_int_equal(qdl_mkdir_p(WORKDIR), 0);
|
|
fp = fopen(file, "wb");
|
|
assert_non_null(fp);
|
|
fclose(fp);
|
|
|
|
/* A path component that is a regular file cannot be descended into. */
|
|
assert_int_equal(qdl_mkdir_p(WORKDIR "/afile/sub"), -1);
|
|
}
|
|
|
|
static int group_setup(void **state)
|
|
{
|
|
(void)state;
|
|
rmtree(WORKDIR);
|
|
return 0;
|
|
}
|
|
|
|
static int group_teardown(void **state)
|
|
{
|
|
(void)state;
|
|
rmtree(WORKDIR);
|
|
return 0;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
const struct CMUnitTest tests[] = {
|
|
cmocka_unit_test(test_path_is_absolute),
|
|
cmocka_unit_test(test_mkdir_p_creates_nested),
|
|
cmocka_unit_test(test_mkdir_p_is_idempotent),
|
|
cmocka_unit_test(test_mkdir_p_trailing_slash),
|
|
cmocka_unit_test(test_mkdir_p_existing_and_dot),
|
|
cmocka_unit_test(test_mkdir_p_too_long),
|
|
cmocka_unit_test(test_mkdir_p_component_not_a_dir),
|
|
};
|
|
|
|
return cmocka_run_group_tests(tests, group_setup, group_teardown);
|
|
}
|