text/plain
•
4.75 KB
•
247 lines
#include "test_helpers.h"
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "storage.h"
#define TEST_ROOT_FS "./sdcard/.tests"
#define COPY_BUF_SIZE 1024
static bool remove_tree_fs(const char* path) {
struct stat st;
if (lstat(path, &st) != 0) {
return errno == ENOENT;
}
if (!S_ISDIR(st.st_mode)) {
return unlink(path) == 0;
}
DIR* dir = opendir(path);
if (!dir) {
return false;
}
struct dirent* entry;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0) {
continue;
}
char child[512];
int written =
snprintf(child, sizeof(child), "%s/%s", path, entry->d_name);
if (written < 0 || written >= (int)sizeof(child)) {
closedir(dir);
return false;
}
if (!remove_tree_fs(child)) {
closedir(dir);
return false;
}
}
closedir(dir);
return rmdir(path) == 0;
}
bool test_storage_mkdir_p(const char* dir_rel) {
if (!dir_rel || !dir_rel[0]) {
return false;
}
char tmp[STORAGE_MAX_PATH];
size_t offset = 0;
if (dir_rel[0] == '/') {
offset = 1;
}
snprintf(tmp, sizeof(tmp), "%s", dir_rel + offset);
for (char* p = tmp; *p; p++) {
if (*p == '/') {
*p = '\0';
if (tmp[0] && !storage_mkdir(tmp)) {
return false;
}
*p = '/';
}
}
return tmp[0] ? storage_mkdir(tmp) : false;
}
static bool ensure_parent_dir(const char* storage_rel) {
char path[STORAGE_MAX_PATH];
snprintf(path, sizeof(path), "%s", storage_rel);
char* slash = strrchr(path, '/');
if (!slash) {
return true;
}
*slash = '\0';
if (!path[0]) {
return true;
}
return test_storage_mkdir_p(path);
}
static bool copy_file_to_storage_path(const char* fs_src, const char* storage_dst) {
if (!ensure_parent_dir(storage_dst)) {
return false;
}
FILE* src = fopen(fs_src, "rb");
if (!src) {
return false;
}
storage_file_t dst = storage_open(storage_dst, "w");
if (!dst) {
fclose(src);
return false;
}
char buf[COPY_BUF_SIZE];
size_t n;
while ((n = fread(buf, 1, sizeof(buf), src)) > 0) {
if (storage_write(dst, buf, n) != n) {
storage_close(dst);
fclose(src);
return false;
}
}
storage_close(dst);
fclose(src);
return true;
}
bool test_prepare_storage(void) {
if (!storage_init()) {
return false;
}
if (!remove_tree_fs(TEST_ROOT_FS)) {
return false;
}
return storage_mkdir(".tests");
}
bool test_copy_fixture_to_storage(const char* fixture_rel,
const char* storage_rel) {
if (!fixture_rel || !storage_rel) {
return false;
}
char fixture_path[512];
int written = snprintf(fixture_path, sizeof(fixture_path),
"tests/fixtures/%s", fixture_rel);
if (written < 0 || written >= (int)sizeof(fixture_path)) {
return false;
}
return copy_file_to_storage_path(fixture_path, storage_rel);
}
bool test_copy_storage_file(const char* src_rel, const char* dst_rel) {
if (!src_rel || !dst_rel) {
return false;
}
if (!ensure_parent_dir(dst_rel)) {
return false;
}
storage_file_t src = storage_open(src_rel, "r");
if (!src) {
return false;
}
storage_file_t dst = storage_open(dst_rel, "w");
if (!dst) {
storage_close(src);
return false;
}
char buf[COPY_BUF_SIZE];
size_t n;
while ((n = storage_read(src, buf, sizeof(buf))) > 0) {
if (storage_write(dst, buf, n) != n) {
storage_close(dst);
storage_close(src);
return false;
}
}
storage_close(dst);
storage_close(src);
return true;
}
bool test_write_storage_text(const char* storage_rel, const char* text) {
if (!storage_rel || !text) {
return false;
}
if (!ensure_parent_dir(storage_rel)) {
return false;
}
storage_file_t f = storage_open(storage_rel, "w");
if (!f) {
return false;
}
size_t len = strlen(text);
bool ok = storage_write(f, text, len) == len;
storage_close(f);
return ok;
}
bool test_storage_file_exists(const char* storage_rel) {
storage_file_t f = storage_open(storage_rel, "r");
if (!f) {
return false;
}
storage_close(f);
return true;
}
bool test_preserve_storage_file(const char* path,
const char* backup_path,
bool* had_original) {
if (!path || !backup_path || !had_original) {
return false;
}
*had_original = false;
if (!test_storage_file_exists(path)) {
return true;
}
if (!test_copy_storage_file(path, backup_path)) {
return false;
}
*had_original = true;
return true;
}
bool test_restore_storage_file(const char* path,
const char* backup_path,
bool had_original) {
if (!path || !backup_path) {
return false;
}
if (had_original) {
return test_copy_storage_file(backup_path, path);
}
return storage_remove(path);
}