From 65e16b8d9e508284ce5bda981a6d01adedbc37f0 Mon Sep 17 00:00:00 2001 From: Anderson Toshiyuki Sasaki Date: Wed, 24 Oct 2018 20:01:04 +0200 Subject: [PATCH] tests: Introduce torture_make_temp_dir() Introduces a function to create temporary dir for testing purposes. Also adds a minimal test for the temporary directory creation. Signed-off-by: Anderson Toshiyuki Sasaki Reviewed-by: Andreas Schneider --- tests/torture.c | 204 +++++++++++++++++++++++++++++ tests/torture.h | 2 + tests/unittests/CMakeLists.txt | 1 + tests/unittests/torture_temp_dir.c | 51 ++++++++ 4 files changed, 258 insertions(+) create mode 100644 tests/unittests/torture_temp_dir.c diff --git a/tests/torture.c b/tests/torture.c index f12fc23b..41e7cb8f 100644 --- a/tests/torture.c +++ b/tests/torture.c @@ -788,6 +788,210 @@ void torture_teardown_sshd_server(void **state) torture_teardown_socket_dir(state); } +char *torture_make_temp_dir(const char *template) +{ + char *new_dir = NULL; + char *template_copy = NULL; + + if (template == NULL) { + goto end; + } + + template_copy = strdup(template); + if (template_copy == NULL) { + goto end; + } + + new_dir = mkdtemp(template_copy); + if (new_dir == NULL) { + free(template_copy); + } + +end: + return new_dir; +} + +#else /* _WIN32 */ + +char *torture_make_temp_dir(const char *template) +{ + DWORD rc = 0; + char tmp_dir_path[MAX_PATH]; + char tmp_file_name[MAX_PATH]; + char *prefix = NULL; + char *path = NULL; + char *prefix_end = NULL; + char *slash = NULL; + + BOOL created; + + if (template == NULL) { + goto end; + } + + prefix = strdup(template); + if (prefix == NULL) { + goto end; + } + + /* Replace slashes with backslashes */ + slash = strchr(prefix, '/'); + for (; slash != NULL; slash = strchr(prefix, '/')) { + *slash = '\\'; + } + + prefix_end = strstr(prefix, "XXXXXX"); + if (prefix_end != NULL) { + *prefix_end = '\0'; + } + + rc = GetTempPathA(MAX_PATH, tmp_dir_path); + if ((rc > MAX_PATH) || (rc == 0)) { + goto free_prefix; + } + + rc = GetTempFileNameA(tmp_dir_path, TEXT(prefix), 0, tmp_file_name); + if (rc == 0) { + goto free_prefix; + } + + path = strdup(tmp_file_name); + if (path == NULL) { + goto free_prefix; + } + + /* GetTempFileNameA() creates a temporary file; we need to remove it */ + rc = DeleteFileA(path); + if (rc == 0) { + rc = -1; + SAFE_FREE(path); + goto free_prefix; + } + + created = CreateDirectoryA(path, NULL); + if (!created) { + SAFE_FREE(path); + } + +free_prefix: + SAFE_FREE(prefix); +end: + return path; +} + +static int recursive_rm_dir_content(const char *path) +{ + WIN32_FIND_DATA file_data; + HANDLE file_handle; + DWORD attributes; + + DWORD last_error = 0; + + char file_path[MAX_PATH]; + + int rc = 0; + BOOL removed; + + strcpy(file_path, path); + strcat(file_path, "\\*"); + + file_handle = FindFirstFile(file_path, &file_data); + + if (file_handle == INVALID_HANDLE_VALUE) { + last_error = GetLastError(); + + /* Empty directory */ + if (last_error == ERROR_FILE_NOT_FOUND) { + rc = 0; + } + else { + /*TODO print error message?*/ + rc = last_error; + } + goto end; + } + else { + do { + rc = strcmp(file_data.cFileName, "."); + if (rc == 0) { + continue; + } + + rc = strcmp(file_data.cFileName, ".."); + if (rc == 0) { + continue; + } + + /* Create full file path */ + strcpy(file_path, path); + strcat(file_path, "\\"); + strcat(file_path, file_data.cFileName); + + attributes = GetFileAttributes(file_path); + if (attributes & FILE_ATTRIBUTE_DIRECTORY) { + rc = recursive_rm_dir_content((const char *)file_path); + if (rc != 0) { + goto end; + } + + removed = RemoveDirectoryA(file_path); + + if (!removed) { + last_error = GetLastError(); + + /*TODO print error message?*/ + + rc = last_error; + goto end; + } + } + else { + rc = remove(file_path); + if (rc) { + goto end; + } + } + + } while(FindNextFile(file_handle, &file_data)); + + FindClose(file_handle); + } + +end: + return rc; +} + +int torture_rmdirs(const char *path) +{ + int rc = 0; + BOOL removed; + + rc = recursive_rm_dir_content(path); + if (rc) { + return rc; + } + + removed = RemoveDirectoryA(path); + if (!removed) { + rc = -1; + } + + return rc; +} + +int torture_isdir(const char *path) +{ + + DWORD attributes = 0; + + attributes = GetFileAttributes(path); + if (attributes & FILE_ATTRIBUTE_DIRECTORY) { + return 1; + } + + return 0; +} + #endif /* _WIN32 */ int torture_libssh_verbosity(void){ diff --git a/tests/torture.h b/tests/torture.h index 8f3991d6..661f92f0 100644 --- a/tests/torture.h +++ b/tests/torture.h @@ -125,4 +125,6 @@ void torture_teardown_sshd_server(void **state); */ int torture_run_tests(void); +char *torture_make_temp_dir(const char *template); + #endif /* _TORTURE_H */ diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt index 5c3b723f..04e905ca 100644 --- a/tests/unittests/CMakeLists.txt +++ b/tests/unittests/CMakeLists.txt @@ -16,6 +16,7 @@ set(LIBSSH_UNIT_TESTS torture_knownhosts_parsing torture_hashes torture_packet_filter + torture_temp_dir ) set(LIBSSH_THREAD_UNIT_TESTS diff --git a/tests/unittests/torture_temp_dir.c b/tests/unittests/torture_temp_dir.c new file mode 100644 index 00000000..feff23c7 --- /dev/null +++ b/tests/unittests/torture_temp_dir.c @@ -0,0 +1,51 @@ +#include "config.h" + +#include "torture.h" +#define LIBSSH_STATIC + +const char template[] = "temp_dir_XXXXXX"; + +static int setup(void **state) +{ + char *temp_dir = NULL; + + temp_dir = torture_make_temp_dir(template); + assert_non_null(temp_dir); + + *state = (void *)temp_dir; + + return 0; +} + +static int teardown(void **state) +{ + char *temp_dir = *((char **)state); + + torture_rmdirs((const char *)temp_dir); + + free(temp_dir); + + return 0; +} + + +static void torture_create_temp_dir(void **state) +{ + char *temp_dir = *((char **)state); + + printf("Created temp dir: %s\n", temp_dir); +} + +int torture_run_tests(void) +{ + int rc; + struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(torture_create_temp_dir, setup, teardown), + }; + + torture_filter_tests(tests); + rc = cmocka_run_group_tests(tests, NULL, NULL); + + return rc; +} +