Asterisk - The Open Source Telephony Project GIT-master-3dae2cf
test_logger.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2009, Digium, Inc.
5 *
6 * Kevin P. Fleming <kpfleming@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Test module for the logging subsystem
22 *
23 * \author\verbatim Kevin P. Fleming <kpfleming@digium.com> \endverbatim
24 *
25 * \ingroup tests
26 */
27
28/*** MODULEINFO
29 <depend>TEST_FRAMEWORK</depend>
30 <support_level>core</support_level>
31 ***/
32
33#include "asterisk.h"
34
35#include "asterisk/file.h"
36#include "asterisk/channel.h"
37#include "asterisk/pbx.h"
38#include "asterisk/module.h"
39#include "asterisk/lock.h"
40#include "asterisk/app.h"
41#include "asterisk/cli.h"
42
43struct test {
44 const char *name;
45 unsigned int x_success;
46 unsigned int x_failure;
47 unsigned int u_success;
48 unsigned int u_failure;
49};
50
51static void output_tests(struct test *tests, size_t num_tests, int fd)
52{
53 unsigned int x;
54
55 for (x = 0; x < num_tests; x++) {
56 ast_cli(fd, "Test %u: %s\n", x + 1, tests[x].name);
57 ast_cli(fd, "\tExpected Successes: %u\n", tests[x].x_success);
58 ast_cli(fd, "\tExpected Failures: %u\n", tests[x].x_failure);
59 ast_cli(fd, "\tUnexpected Successes: %u\n", tests[x].u_success);
60 ast_cli(fd, "\tUnexpected Failures: %u\n", tests[x].u_failure);
61 ast_cli(fd, "Test %u Result: %s\n", x + 1, (tests[x].u_success + tests[x].u_failure) ? "FAIL" : "PASS");
62 }
63}
64
65static char *handle_cli_dynamic_level_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
66{
67 unsigned int level;
68 unsigned int x;
69 unsigned int test;
70 struct test tests[] = {
71 { .name = "Simple register/message/unregister",
72 },
73 { .name = "Register multiple levels",
74 },
75 };
76
77 switch (cmd) {
78 case CLI_INIT:
79 e->command = "logger test dynamic";
80 e->usage = ""
81 "Usage: logger test dynamic\n"
82 "";
83 return NULL;
84 case CLI_GENERATE:
85 return NULL;
86 }
87
88 for (test = 0; test < ARRAY_LEN(tests); test++) {
89 ast_cli(a->fd, "Test %u: %s.\n", test + 1, tests[test].name);
90 switch (test) {
91 case 0:
92 if ((level = ast_logger_register_level("test")) != -1) {
93 ast_cli(a->fd, "Test: got level %u\n", level);
94 ast_log_dynamic_level(level, "Logger Dynamic Test: Test 1\n");
96 tests[test].x_success++;
97 } else {
98 ast_cli(a->fd, "Test: Failed, could not register level 'test'.\n");
99 tests[test].u_failure++;
100 }
101 break;
102 case 1:
103 {
104 char level_name[18][8];
105
106 for (x = 0; x < ARRAY_LEN(level_name); x++) {
107 sprintf(level_name[x], "level%02u", x);
108 if ((level = ast_logger_register_level(level_name[x])) == -1) {
109 if (x < 16) {
110 tests[test].u_failure++;
111 } else {
112 tests[test].x_failure++;
113 }
114 level_name[x][0] = '\0';
115 } else {
116 ast_cli(a->fd, "Test: registered '%s', got level %u\n", level_name[x], level);
117 if (x < 16) {
118 tests[test].x_success++;
119 } else {
120 tests[test].u_success++;
121 }
122 }
123 }
124
125 for (x = 0; x < ARRAY_LEN(level_name); x++) {
126 if (!ast_strlen_zero(level_name[x])) {
127 ast_logger_unregister_level(level_name[x]);
128 }
129 }
130 }
131 }
132 }
133
134 output_tests(tests, ARRAY_LEN(tests), a->fd);
135
136 return CLI_SUCCESS;
137}
138
139static char *handle_cli_performance_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
140{
141 unsigned int level;
142 unsigned int test;
143 struct test tests[] = {
144 { .name = "Log 10,000 messages",
145 },
146 };
147
148 switch (cmd) {
149 case CLI_INIT:
150 e->command = "logger test performance";
151 e->usage = ""
152 "Usage: logger test performance\n"
153 "";
154 return NULL;
155 case CLI_GENERATE:
156 return NULL;
157 }
158
159 for (test = 0; test < ARRAY_LEN(tests); test++) {
160 ast_cli(a->fd, "Test %u: %s.\n", test + 1, tests[test].name);
161 switch (test) {
162 case 0:
163 if ((level = ast_logger_register_level("perftest")) != -1) {
164 unsigned int x;
165 struct timeval start, end;
166 int elapsed;
167
168 ast_cli(a->fd, "Test: got level %u\n", level);
169 start = ast_tvnow();
170 for (x = 0; x < 10000; x++) {
171 ast_log_dynamic_level(level, "Performance test log message\n");
172 }
173 end = ast_tvnow();
174 elapsed = ast_tvdiff_ms(end, start);
175 ast_cli(a->fd, "Test: 10,000 messages in %f seconds.\n", (float) elapsed / 1000);
176 ast_logger_unregister_level("perftest");
177 tests[test].x_success++;
178 } else {
179 ast_cli(a->fd, "Test: Failed, could not register level 'perftest'.\n");
180 tests[test].u_failure++;
181 }
182 break;
183 }
184 }
185
186 output_tests(tests, ARRAY_LEN(tests), a->fd);
187
188 return CLI_SUCCESS;
189}
190
191static char *handle_cli_queue_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
192{
193 int level;
194 int current_queue_limit;
195 unsigned int x;
196 struct timeval start, end;
197 int elapsed;
198 char tmppath[] = "/tmp/asterisk_logger_queue.XXXXXX";
199 int fd;
200
201 switch (cmd) {
202 case CLI_INIT:
203 e->command = "logger test queue";
204 e->usage = ""
205 "Usage: logger test queue\n"
206 "";
207 return NULL;
208 case CLI_GENERATE:
209 return NULL;
210 }
211
212 fd = mkstemp(tmppath);
213 if (fd < 0) {
214 ast_cli(a->fd, "Test: Failed, could not create temporary log file '%s'.\n", tmppath);
215 return CLI_SUCCESS;
216 }
217
218 level = ast_logger_register_level("queuetest");
219 if (level < 0) {
220 ast_cli(a->fd, "Test: Failed, could not register level 'queuetest'.\n");
221 return CLI_SUCCESS;
222 }
223 ast_cli(a->fd, "Test: got level %d for 'queuetest'.\n", level);
224
225 if (ast_logger_create_channel(tmppath, "queuetest") != AST_LOGGER_SUCCESS) {
226 ast_cli(a->fd, "Test: Unable to create logger channel '%s'\n", tmppath);
227 goto error;
228 }
229
230 current_queue_limit = ast_logger_get_queue_limit();
231 ast_cli(a->fd, "Test: Current queue limit: %d. Setting to 100 for test.\n", current_queue_limit);
233
234 ast_cli(a->fd, "Test: You should see SOME 'exceeded' and 'resumed' messages after the test "
235 "is completed. How many is dependent on system resources.\n");
236
237 start = ast_tvnow();
238 for (x = 0; x < 10000; x++) {
239 ast_log_dynamic_level(level, "Performance test log message %2d\n", x);
240 }
241 end = ast_tvnow();
242 elapsed = ast_tvdiff_ms(end, start);
243 ast_cli(a->fd, "Test: 10,000 messages in %f seconds.\n", (float) elapsed / 1000);
244 ast_cli(a->fd, "Test: Completed. Resetting queue limit to %d.\n", current_queue_limit);
245 ast_logger_set_queue_limit(current_queue_limit);
246
247error:
248
250 ast_logger_unregister_level("queuetest");
251 close(fd);
252 unlink(tmppath);
253
254 return CLI_SUCCESS;
255}
256
257static struct ast_cli_entry cli_logger[] = {
258 AST_CLI_DEFINE(handle_cli_dynamic_level_test, "Test the dynamic logger level implementation"),
259 AST_CLI_DEFINE(handle_cli_performance_test, "Test the logger performance"),
260 AST_CLI_DEFINE(handle_cli_queue_test, "Test the logger queue"),
261};
262
263static int unload_module(void)
264{
266 return 0;
267}
268
269static int load_module(void)
270{
273}
274
Asterisk main include file. File version handling, generic pbx functions.
General Asterisk PBX channel definitions.
Standard Command Line Interface.
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
char * end
Definition: eagi_proxy.c:73
Generic File Format Support. Should be included by clients of the file handling routines....
static const char name[]
Definition: format_mp3.c:68
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
int ast_logger_get_queue_limit(void)
Get the maximum number of messages allowed in the processing queue.
Definition: logger.c:2937
int ast_logger_create_channel(const char *log_channel, const char *components)
Create a log channel.
Definition: logger.c:1521
int ast_logger_remove_channel(const char *log_channel)
Delete the specified log channel.
Definition: logger.c:1587
@ AST_LOGGER_SUCCESS
#define ast_log_dynamic_level(level,...)
Send a log message to a dynamically registered log level.
int ast_logger_register_level(const char *name)
Register a new logger level.
Definition: logger.c:2851
void ast_logger_set_queue_limit(int queue_limit)
Set the maximum number of messages allowed in the processing queue.
Definition: logger.c:2932
void ast_logger_unregister_level(const char *name)
Unregister a previously registered logger level.
Definition: logger.c:2909
Asterisk locking-related definitions:
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:581
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
Core PBX routines and definitions.
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
descriptor for a cli entry.
Definition: cli.h:171
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
unsigned int x_failure
Definition: test_logger.c:46
unsigned int u_failure
Definition: test_logger.c:48
const char * name
Definition: test_logger.c:44
unsigned int x_success
Definition: test_logger.c:45
unsigned int u_success
Definition: test_logger.c:47
static struct test_val a
static char * handle_cli_performance_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: test_logger.c:139
static char * handle_cli_dynamic_level_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: test_logger.c:65
static void output_tests(struct test *tests, size_t num_tests, int fd)
Definition: test_logger.c:51
static int load_module(void)
Definition: test_logger.c:269
static int unload_module(void)
Definition: test_logger.c:263
static char * handle_cli_queue_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: test_logger.c:191
static struct ast_cli_entry cli_logger[]
Definition: test_logger.c:257
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
int error(const char *format,...)
Definition: utils/frame.c:999
#define ARRAY_LEN(a)
Definition: utils.h:666