[PATCH 3/4] test: self: add ramfs test

Ahmad Fatoum a.fatoum at pengutronix.de
Sun Oct 9 23:14:36 PDT 2022


Add some simple testing for ramfs: creating a directory, filling it with
files, writing some data into them, unlinking some files again, reading
data out of them, iterating over the files and cleaning up the directory
again.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 test/self/Kconfig  |   5 ++
 test/self/Makefile |   1 +
 test/self/ramfs.c  | 189 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+)
 create mode 100644 test/self/ramfs.c

diff --git a/test/self/Kconfig b/test/self/Kconfig
index 4bf4b874d5e4..052b49972329 100644
--- a/test/self/Kconfig
+++ b/test/self/Kconfig
@@ -33,6 +33,7 @@ config SELFTEST_ENABLE_ALL
 	select SELFTEST_PROGRESS_NOTIFIER
 	select SELFTEST_OF_MANIPULATION
 	select SELFTEST_ENVIRONMENT_VARIABLES
+	select SELFTEST_FS_RAMFS
 	help
 	  Selects all self-tests compatible with current configuration
 
@@ -58,4 +59,8 @@ config SELFTEST_PROGRESS_NOTIFIER
 config SELFTEST_ENVIRONMENT_VARIABLES
 	bool "environment variable selftest"
 
+config SELFTEST_FS_RAMFS
+	bool "ramfs selftest"
+	depends on FS_RAMFS
+
 endif
diff --git a/test/self/Makefile b/test/self/Makefile
index ca9f9c34d1e5..6f2c0d394034 100644
--- a/test/self/Makefile
+++ b/test/self/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_SELFTEST_PRINTF) += printf.o
 obj-$(CONFIG_SELFTEST_PROGRESS_NOTIFIER) += progress-notifier.o
 obj-$(CONFIG_SELFTEST_OF_MANIPULATION) += of_manipulation.o of_manipulation.dtb.o
 obj-$(CONFIG_SELFTEST_ENVIRONMENT_VARIABLES) += envvar.o
+obj-$(CONFIG_FS_RAMFS) += ramfs.o
diff --git a/test/self/ramfs.c b/test/self/ramfs.c
new file mode 100644
index 000000000000..927b035e1e8c
--- /dev/null
+++ b/test/self/ramfs.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <common.h>
+#include <fcntl.h>
+#include <fs.h>
+#include <dirent.h>
+#include <libfile.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <bselftest.h>
+#include <linux/sizes.h>
+
+BSELFTEST_GLOBALS();
+
+#define __expect(_ret, _cond, fmt, ...) ({ \
+	bool cond = (_cond); \
+	int ret = (_ret); \
+	total_tests++; \
+	\
+	if (!cond) { \
+		failed_tests++; \
+		printf("%s:%d error %pe: " fmt "\n", \
+		       __func__, __LINE__, ERR_PTR(ret), ##__VA_ARGS__); \
+	} \
+	cond; \
+})
+
+#define expect_success(ret, ...) __expect((ret), (ret) >= 0, __VA_ARGS__)
+#define expect_fail(ret, ...) __expect((ret), (ret) < 0, __VA_ARGS__)
+
+static inline int get_file_count(int i)
+{
+	if (40 <= i && i < 50)
+		return 40;
+
+	if (i >= 50)
+		i -= 10;
+
+	/* we create a file for i == 0 as well */
+	return i + 1;
+}
+
+static void test_ramfs(void)
+{
+	char fname[128];
+	char *content = NULL;
+	char *oldpwd = NULL;
+	DIR *dir = NULL;
+	const char *dname;
+	struct stat st;
+	int i, j, ret, fd;
+	struct dirent *d;
+
+	dname = make_temp("ramfs-test");
+	ret = mkdir(dname, 0777);
+
+	if (!expect_success(ret, "creating directory"))
+		return;
+
+	ret = stat(dname, &st);
+	if (!expect_success(ret, "stating directory"))
+		goto out;
+
+	expect_success(S_ISDIR(st.st_mode) ? 0 : -ENOTDIR,
+		       "directory check");
+
+	content = malloc(99);
+	if (WARN_ON(!content))
+		goto out;
+
+	for (i = 0; i < 99; i++) {
+		scnprintf(fname, sizeof(fname), "%s/file-%02d", dname, i);
+
+		fd = open(fname, O_RDWR | O_CREAT);
+		if (!expect_success(fd, "creating file"))
+			continue;
+
+		for (j = 0; j < i; j++)
+			content[j] = i;
+
+		ret = write(fd, content, i);
+		expect_success(ret, "writing file");
+		close(fd);
+
+		if (40 <= i && i < 50) {
+			ret = unlink(fname);
+			expect_success(ret, "unlinking file");
+		}
+
+		ret = stat(fname, &st);
+		if (40 <= i && i < 50) {
+			expect_fail(ret, "stating file");
+		} else {
+			expect_success(ret, "stating file");
+
+			expect_success(S_ISREG(st.st_mode) ? 0 : -EINVAL,
+				       "stating file");
+		}
+
+		dir = opendir(dname);
+		if (!expect_success(PTR_ERR_OR_ZERO(dir), "opening parent directory"))
+			continue;
+
+		j = 0;
+
+		while ((d = readdir(dir))) {
+			if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
+				continue;
+
+			j++;
+		}
+
+		expect_success(j == get_file_count(i) ? 0 : -EINVAL,
+			       "unexpected file count iterating directory");
+
+		closedir(dir);
+	}
+
+	oldpwd = pushd(dname);
+	if (!expect_success(oldpwd != NULL ? 0 : -EINVAL, "pushd()"))
+		goto out;;
+
+	dir = opendir(".");
+	if (!expect_success(PTR_ERR_OR_ZERO(dir), "opening parent directory"))
+		goto out;
+
+	i = 1;
+
+	while ((d = readdir(dir))) {
+		size_t size = 0;
+		char *buf;
+
+		if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
+			continue;
+
+		buf = read_file(d->d_name, &size);
+		if (size) {
+			for (j = 0; j < size; j++) {
+				expect_success(buf[j] == size ? 0 : -EINVAL,
+					       "unexpected file content");
+			}
+		}
+
+		scnprintf(fname, sizeof(fname), "file-%02zu", size);
+
+		expect_success(strcmp(d->d_name, fname) == 0 ? 0 : -EINVAL,
+			       "unexpected file content");
+
+		free(buf);
+
+		i++;
+	}
+
+	expect_success(i == 90 ? 0 : -EINVAL,
+		       "unexpected file count iterating directory: %u", i);
+
+	ret = make_directory("test/a/b/c/d/e/f/g/h/i/j/k/l");
+	expect_success(ret, "make_directory()");
+
+	if (!ret) {
+		const char hello[] = "hello";
+		char *buf;
+
+		ret = write_file("test/a/b/c/d/e/f/g/h/i/j/k/l/FILE",
+				 ARRAY_AND_SIZE(hello));
+		expect_success(ret, "write_file()");
+
+		buf = read_file("test/a/b/c/d/e/f/g/h/i/j/k/l/FILE", NULL);
+		if (expect_success(PTR_ERR_OR_ZERO(buf), "read_file()")) {
+			expect_success(memcmp(buf, ARRAY_AND_SIZE(hello)),
+				       "read_file() content");
+		}
+	}
+
+out:
+	popd(oldpwd);
+	free(content);
+
+	closedir(dir);
+
+	ret = unlink_recursive(dname, NULL);
+	expect_success(ret, "unlinking directory");
+
+	dir = opendir(dname);
+	expect_fail(dir ? 0 : -EISDIR, "opening removed directory");
+}
+bselftest(core, test_ramfs);
-- 
2.30.2




More information about the barebox mailing list