Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
test_file.c File Reference
#include "asterisk.h"
#include <sys/stat.h>
#include <stdio.h>
#include "asterisk/file.h"
#include "asterisk/paths.h"
#include "asterisk/test.h"
#include "asterisk/module.h"
#include "asterisk/strings.h"
#include "asterisk/vector.h"
Include dependency graph for test_file.c:

Go to the source code of this file.

Macros

#define FOUND   -7
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (read_dirs_test)
 
 AST_VECTOR (_filenames, struct ast_str *)
 
static int handle_find_file (const char *dir_name, const char *filename, void *obj)
 
static int load_module (void)
 
static void rm_file (struct ast_str *filename)
 
static int test_files_create (struct ast_test *test, char *dir_name, struct _filenames *filenames, int num)
 
static int test_files_destroy (struct ast_test *test, char *dir_name, struct _filenames *filenames)
 
static char * test_files_get_one (struct _filenames *filenames, int num)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "File test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 

Macro Definition Documentation

◆ FOUND

#define FOUND   -7

Definition at line 36 of file test_file.c.

Referenced by AST_TEST_DEFINE(), and handle_find_file().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 195 of file test_file.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 195 of file test_file.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 195 of file test_file.c.

◆ AST_TEST_DEFINE()

AST_TEST_DEFINE ( read_dirs_test  )

Definition at line 136 of file test_file.c.

References ast_file_read_dirs(), ast_random(), ast_str_alloca, ast_str_buffer(), ast_str_set(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, FOUND, handle_find_file(), sip_to_pjsip::info(), mkdtemp(), NULL, TEST_EXECUTE, test_files_create(), test_files_destroy(), test_files_get_one(), and TEST_INIT.

137 {
138  char tmp_dir[] = "/tmp/tmpdir.XXXXXX";
139  struct ast_str *tmp_sub_dir;
140  struct _filenames filenames;
141  enum ast_test_result_state res;
142  const int num_files = 10 + (ast_random() % 10); /* 10-19 random files */
143 
144  switch (cmd) {
145  case TEST_INIT:
146  info->name = "read_dir_test";
147  info->category = "/main/file/";
148  info->summary = "Read a directory's content";
149  info->description = "Iterate over directories looking for a file.";
150  return AST_TEST_NOT_RUN;
151  case TEST_EXECUTE:
152  break;
153  }
154 
155  /*
156  * We want to test recursively searching into a subdirectory, so
157  * create a top level tmp directory where we will start the search.
158  */
159  if (!(mkdtemp(tmp_dir))) {
160  ast_test_status_update(test, "Failed to create directory: %s\n", tmp_dir);
161  return AST_TEST_FAIL;
162  }
163 
164  tmp_sub_dir = ast_str_alloca(32);
165  ast_str_set(&tmp_sub_dir, 0, "%s/XXXXXX", tmp_dir);
166 
167  if (test_files_create(test, ast_str_buffer(tmp_sub_dir), &filenames, num_files)) {
168  test_files_destroy(test, tmp_dir, NULL);
169  return AST_TEST_FAIL;
170  }
171 
173  &filenames, num_files), 2) == FOUND ? AST_TEST_PASS : AST_TEST_FAIL;
174 
175  if (test_files_destroy(test, ast_str_buffer(tmp_sub_dir), &filenames) ||
176  test_files_destroy(test, tmp_dir, NULL)) {
177  res = AST_TEST_FAIL;
178  }
179 
180  return res;
181 }
#define FOUND
Definition: test_file.c:36
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int test_files_destroy(struct ast_test *test, char *dir_name, struct _filenames *filenames)
Definition: test_file.c:49
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define NULL
Definition: resample.c:96
int ast_file_read_dirs(const char *dir_name, ast_file_on_file on_file, void *obj, int max_depth)
Recursively iterate through files and directories up to max_depth.
Definition: file.c:1231
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
long int ast_random(void)
Definition: main/utils.c:2064
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
char * mkdtemp(char *template_s)
def info(msg)
static char * test_files_get_one(struct _filenames *filenames, int num)
Definition: test_file.c:112
static int test_files_create(struct ast_test *test, char *dir_name, struct _filenames *filenames, int num)
Definition: test_file.c:66
static int handle_find_file(const char *dir_name, const char *filename, void *obj)
Definition: test_file.c:119
ast_test_result_state
Definition: test.h:200

◆ AST_VECTOR()

AST_VECTOR ( _filenames  ,
struct ast_str  
)

◆ handle_find_file()

static int handle_find_file ( const char *  dir_name,
const char *  filename,
void *  obj 
)
static

Definition at line 119 of file test_file.c.

References ast_alloca, ast_log, errno, FOUND, and LOG_ERROR.

Referenced by AST_TEST_DEFINE().

120 {
121  struct stat statbuf;
122  char *full_path = ast_alloca(strlen(dir_name) + strlen(filename) + 2);
123 
124  sprintf(full_path, "%s/%s", dir_name, filename);
125 
126  errno = 0;
127  if (stat(full_path, &statbuf)) {
128  ast_log(LOG_ERROR, "Error reading path stats - %s: %s\n",
129  full_path, strerror(errno));
130  return 0;
131  }
132  /* obj contains the name of the file we are looking for */
133  return strcmp(obj, filename) ? 0 : FOUND;
134 }
#define FOUND
Definition: test_file.c:36
#define ast_log
Definition: astobj2.c:42
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
int errno

◆ load_module()

static int load_module ( void  )
static

Definition at line 189 of file test_file.c.

References AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

190 {
191  AST_TEST_REGISTER(read_dirs_test);
193 }
#define AST_TEST_REGISTER(cb)
Definition: test.h:127

◆ rm_file()

static void rm_file ( struct ast_str filename)
static

Definition at line 40 of file test_file.c.

References ast_free, ast_log, ast_str_buffer(), and LOG_ERROR.

Referenced by test_files_destroy().

41 {
42  if (unlink(ast_str_buffer(filename))) {
43  ast_log(LOG_ERROR, "Unable to remove file: %s\n", ast_str_buffer(filename));
44  }
45 
46  ast_free(filename);
47 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
#define ast_free(a)
Definition: astmm.h:182

◆ test_files_create()

static int test_files_create ( struct ast_test test,
char *  dir_name,
struct _filenames *  filenames,
int  num 
)
static

Definition at line 66 of file test_file.c.

References ast_free, ast_str_buffer(), ast_str_create, ast_str_set(), ast_test_status_update, AST_VECTOR_APPEND, AST_VECTOR_INIT, mkdtemp(), and test_files_destroy().

Referenced by AST_TEST_DEFINE().

68 {
69  int i;
70 
71  if (!(mkdtemp(dir_name))) {
72  ast_test_status_update(test, "Failed to create directory: %s\n", dir_name);
73  return -1;
74  }
75 
76 
77  AST_VECTOR_INIT(filenames, num);
78 
79  /*
80  * Create "num" files under the specified directory
81  */
82  for (i = 0; i < num; ++i) {
83  int fd;
84  struct ast_str *filename = ast_str_create(32);
85 
86  if (!filename) {
87  break;
88  }
89 
90  ast_str_set(&filename, 0, "%s/XXXXXX", dir_name);
91 
92  fd = mkstemp(ast_str_buffer(filename));
93  if (fd < 0) {
94  ast_test_status_update(test, "Failed to create file: %s\n",
95  ast_str_buffer(filename));
96  ast_free(filename);
97  break;
98  }
99  close(fd);
100 
101  AST_VECTOR_APPEND(filenames, filename);
102  }
103 
104  if (i != num) {
105  test_files_destroy(test, dir_name, filenames);
106  return -1;
107  }
108 
109  return 0;
110 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
static int test_files_destroy(struct ast_test *test, char *dir_name, struct _filenames *filenames)
Definition: test_file.c:49
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
char * mkdtemp(char *template_s)
#define ast_free(a)
Definition: astmm.h:182
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ test_files_destroy()

static int test_files_destroy ( struct ast_test test,
char *  dir_name,
struct _filenames *  filenames 
)
static

Definition at line 49 of file test_file.c.

References ast_test_status_update, AST_VECTOR_CALLBACK_VOID, AST_VECTOR_FREE, and rm_file().

Referenced by AST_TEST_DEFINE(), and test_files_create().

51 {
52  int res;
53 
54  if (filenames) {
56  AST_VECTOR_FREE(filenames);
57  }
58 
59  if ((res = rmdir(dir_name)) < 0) {
60  ast_test_status_update(test, "Failed to remove directory: %s\n", dir_name);
61  }
62 
63  return res;
64 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
static void rm_file(struct ast_str *filename)
Definition: test_file.c:40
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865

◆ test_files_get_one()

static char* test_files_get_one ( struct _filenames *  filenames,
int  num 
)
static

Definition at line 112 of file test_file.c.

References ast_random(), ast_str_buffer(), and AST_VECTOR_GET.

Referenced by AST_TEST_DEFINE().

113 {
114  /* Every file is in a directory and contains a '/' so okay to do this */
115  return strrchr(ast_str_buffer(
116  AST_VECTOR_GET(filenames, ast_random() % (num - 1))), '/') + 1;
117 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
long int ast_random(void)
Definition: main/utils.c:2064
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 183 of file test_file.c.

References AST_TEST_UNREGISTER.

184 {
185  AST_TEST_UNREGISTER(read_dirs_test);
186  return 0;
187 }
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "File test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 195 of file test_file.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 195 of file test_file.c.