summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorKevin Harwell <kharwell@digium.com>2016-10-28 15:11:35 -0500
committerKevin Harwell <kharwell@digium.com>2016-11-04 13:58:21 -0500
commitbd4d7d8ad05bbe8d86b89429dfa55fbc3a0c108d (patch)
tree5da8f30e8611577b74ed2f1237d1e1407b73fc27 /tests
parent57a9797e0ac51eae3b8f3254627646b9698a60d2 (diff)
stasis_recording/stored: remove calls to deprecated readdir_r function.
The readdir_r function has been deprecated and should no longer be used. This patch removes the readdir_r dependency (replaced it with readdir) and also moves the directory search code to a more centralized spot (file.c) Also removed a strict dependency on the dirent structure's d_type field as it is not portable. The code now checks to see if the value is available. If so, it tries to use it, but defaults back to using the stats function if necessary. Lastly, for most implementations of readdir it *should* be thread-safe to make concurrent calls to it as long as different directory streams are specified. glibc falls into this category. However, since it is possible that there exist some implementations that are not safe, locking has been added for those other than glibc. ASTERISK-26412 ASTERISK-26509 #close Change-Id: Id8f54689b1e2873e82a09d0d0d2faf41964e80ba
Diffstat (limited to 'tests')
-rw-r--r--tests/test_file.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/tests/test_file.c b/tests/test_file.c
new file mode 100644
index 000000000..4b3d8b6e4
--- /dev/null
+++ b/tests/test_file.c
@@ -0,0 +1,183 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2016, Digium, Inc.
+ *
+ * Kevin Harwell <kharwell@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+ <depend>TEST_FRAMEWORK</depend>
+ <support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/file.h"
+#include "asterisk/paths.h"
+#include "asterisk/test.h"
+#include "asterisk/module.h"
+#include "asterisk/strings.h"
+#include "asterisk/vector.h"
+
+#define FOUND -7
+
+AST_VECTOR(_filenames, struct ast_str *);
+
+static void rm_file(struct ast_str *filename)
+{
+ if (unlink(ast_str_buffer(filename))) {
+ ast_log(LOG_ERROR, "Unable to remove file: %s\n", ast_str_buffer(filename));
+ }
+
+ ast_free(filename);
+}
+
+static int test_files_destroy(struct ast_test *test, char *dir_name,
+ struct _filenames *filenames)
+{
+ int res;
+
+ if (filenames) {
+ AST_VECTOR_CALLBACK_VOID(filenames, rm_file);
+ AST_VECTOR_FREE(filenames);
+ }
+
+ if ((res = rmdir(dir_name)) < 0) {
+ ast_test_status_update(test, "Failed to remove directory: %s\n", dir_name);
+ }
+
+ return res;
+}
+
+static int test_files_create(struct ast_test *test, char *dir_name,
+ struct _filenames *filenames, int num)
+{
+ int i;
+
+ if (!(mkdtemp(dir_name))) {
+ ast_test_status_update(test, "Failed to create directory: %s\n", dir_name);
+ return -1;
+ }
+
+
+ AST_VECTOR_INIT(filenames, num);
+
+ /*
+ * Create "num" files under the specified directory
+ */
+ for (i = 0; i < num; ++i) {
+ int fd;
+ struct ast_str *filename = ast_str_create(32);
+
+ if (!filename) {
+ break;
+ }
+
+ ast_str_set(&filename, 0, "%s/XXXXXX", dir_name);
+
+ fd = mkstemp(ast_str_buffer(filename));
+ if (fd < 0) {
+ ast_test_status_update(test, "Failed to create file: %s\n",
+ ast_str_buffer(filename));
+ ast_free(filename);
+ break;
+ }
+ close(fd);
+
+ AST_VECTOR_APPEND(filenames, filename);
+ }
+
+ if (i != num) {
+ test_files_destroy(test, dir_name, filenames);
+ return -1;
+ }
+
+ return 0;
+}
+
+static char *test_files_get_one(struct _filenames *filenames, int num)
+{
+ /* Every file is in a directory and contains a '/' so okay to do this */
+ return strrchr(ast_str_buffer(
+ AST_VECTOR_GET(filenames, ast_random() % (num - 1))), '/') + 1;
+}
+
+static int handle_find_file(const char *dir_name, const char *filename, void *obj)
+{
+ /* obj contains the name of the file we are looking for */
+ return strcmp(obj, filename) ? 0 : FOUND;
+}
+
+AST_TEST_DEFINE(read_dirs_test)
+{
+ char tmp_dir[] = "/tmp/tmpdir.XXXXXX";
+ struct ast_str *tmp_sub_dir;
+ struct _filenames filenames;
+ enum ast_test_result_state res;
+ const int num_files = 10 + (ast_random() % 10); /* 10-19 random files */
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "read_dir_test";
+ info->category = "/main/file/";
+ info->summary = "Read a directory's content";
+ info->description = "Iterate over directories looking for a file.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ /*
+ * We want to test recursively searching into a subdirectory, so
+ * create a top level tmp directory where we will start the search.
+ */
+ if (!(mkdtemp(tmp_dir))) {
+ ast_test_status_update(test, "Failed to create directory: %s\n", tmp_dir);
+ return AST_TEST_FAIL;
+ }
+
+ tmp_sub_dir = ast_str_alloca(32);
+ ast_str_set(&tmp_sub_dir, 0, "%s/XXXXXX", tmp_dir);
+
+ if (test_files_create(test, ast_str_buffer(tmp_sub_dir), &filenames, num_files)) {
+ test_files_destroy(test, tmp_dir, NULL);
+ return AST_TEST_FAIL;
+ }
+
+ res = ast_file_read_dirs(tmp_dir, handle_find_file, test_files_get_one(
+ &filenames, num_files), 2) == FOUND ? AST_TEST_PASS : AST_TEST_FAIL;
+
+ if (test_files_destroy(test, ast_str_buffer(tmp_sub_dir), &filenames) ||
+ test_files_destroy(test, tmp_dir, NULL)) {
+ res = AST_TEST_FAIL;
+ }
+
+ return res;
+}
+
+static int unload_module(void)
+{
+ AST_TEST_UNREGISTER(read_dirs_test);
+ return 0;
+}
+
+static int load_module(void)
+{
+ AST_TEST_REGISTER(read_dirs_test);
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "File test module");