Asterisk - The Open Source Telephony Project GIT-master-a358458
test_time.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2010, Digium, Inc.
5 *
6 * Tilghman Lesher <tlesher AT digium DOT 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/*!
20 * \file
21 * \brief Timezone tests
22 *
23 * \author\verbatim Tilghman Lesher <tlesher AT digium DOT 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/utils.h"
36#include "asterisk/app.h"
37#include "asterisk/module.h"
38#include "asterisk/test.h"
39
40#ifndef TZDIR
41#ifdef SOLARIS
42#define TZDIR "/usr/share/lib/zoneinfo"
43#else
44#define TZDIR "/usr/share/zoneinfo"
45#endif /* defined SOLARIS */
46#endif /* !defined TZDIR */
47
48AST_TEST_DEFINE(test_timezone_watch)
49{
50 const char *zones[] = { "America/Chicago", "America/New_York" };
51 int type, i, res = AST_TEST_PASS;
52 struct timeval tv = ast_tvnow();
53 struct ast_tm atm[ARRAY_LEN(zones)];
54 char tmpdir[] = "/tmp/timezone.XXXXXX";
55 char tzfile[50], syscmd[256];
56
57 switch (cmd) {
58 case TEST_INIT:
59 info->name = "timezone_watch";
60 info->category = "/main/stdtime/";
61 info->summary = "Verify deleting timezone file purges cache";
62 info->description =
63 "Verifies that the caching engine properly destroys a timezone entry when its file is deleted.";
64 return AST_TEST_NOT_RUN;
65 case TEST_EXECUTE:
66 break;
67 }
68
69 if (!mkdtemp(tmpdir)) {
70 ast_test_status_update(test, "Unable to create working directory: %s\n", strerror(errno));
71 return AST_TEST_NOT_RUN;
72 }
73 snprintf(tzfile, sizeof(tzfile), "%s/test", tmpdir);
74
75 for (type = 0; type <
76#ifdef SOLARIS
77 1 /* Solaris doesn't use symlinks for timezones */
78#else
79 2
80#endif
81 ; type++) {
82 ast_test_status_update(test, "Executing %s test...\n", type == 0 ? "deletion" : "symlink");
83 for (i = 0; i < ARRAY_LEN(zones); i++) {
84 int system_res;
85 snprintf(syscmd, sizeof(syscmd), "%s " TZDIR "/%s %s", type == 0 ? "cp" : "ln -sf", zones[i], tzfile);
86 if ((system_res = ast_safe_system(syscmd))) {
87 ast_log(LOG_WARNING, "system(%s) returned non-zero: %d\n", syscmd, system_res);
88 }
90 ast_test_status_update(test, "Querying timezone %s\n", tzfile);
91 ast_localtime(&tv, &atm[i], tzfile);
92 if (i != 0) {
93 if (atm[i].tm_hour == atm[i - 1].tm_hour) {
94 if (atm[i].tm_isdst == atm[i - 1].tm_isdst) {
95 res = AST_TEST_FAIL;
96 ast_test_status_update(test, "Failed %s test: %d(%s) = %d(%s)\n", type == 0 ? "deletion" : "symlink", atm[i].tm_hour, zones[i], atm[i-1].tm_hour, zones[i-1]);
97 } else {
98 ast_log(LOG_WARNING, "DST transition during %s test: %d(%s/%d) != %d(%s/%d)\n", type == 0 ? "deletion" : "symlink", atm[i].tm_hour, zones[i], atm[i].tm_isdst, atm[i-1].tm_hour, zones[i-1], atm[i-1].tm_isdst);
99 }
100 }
101 }
102
103 if (i + 1 != ARRAY_LEN(zones)) {
104 /* stat(2) only has resolution to 1 second - must wait, or the mtime is the same */
105 usleep(1100000);
106 }
107 }
108 }
109
110 snprintf(syscmd, sizeof(syscmd), "rm -rf %s", tmpdir);
111 if (ast_safe_system(syscmd)) {
112 ast_log(LOG_WARNING, "system(%s) returned non-zero.\n", syscmd);
113 }
114
115 return res;
116}
117
118AST_TEST_DEFINE(test_time_str_to_unit)
119{
120 switch (cmd) {
121 case TEST_INIT:
122 info->name = "time_str_to_unit";
123 info->category = "/main/stdtime/";
124 info->summary = "Verify string to time unit conversions";
125 info->description = info->summary;
126 return AST_TEST_NOT_RUN;
127 case TEST_EXECUTE:
128 break;
129 }
130
131 /* Nominal */
132 ast_test_validate(test, ast_time_str_to_unit("ns") == TIME_UNIT_NANOSECOND);
133 ast_test_validate(test, ast_time_str_to_unit("us") == TIME_UNIT_MICROSECOND);
134 ast_test_validate(test, ast_time_str_to_unit("ms") == TIME_UNIT_MILLISECOND);
135 ast_test_validate(test, ast_time_str_to_unit("s") == TIME_UNIT_SECOND);
136 ast_test_validate(test, ast_time_str_to_unit("m") == TIME_UNIT_MINUTE);
137 ast_test_validate(test, ast_time_str_to_unit("h") == TIME_UNIT_HOUR);
138 ast_test_validate(test, ast_time_str_to_unit("d") == TIME_UNIT_DAY);
139 ast_test_validate(test, ast_time_str_to_unit("w") == TIME_UNIT_WEEK);
140 ast_test_validate(test, ast_time_str_to_unit("mo") == TIME_UNIT_MONTH);
141 ast_test_validate(test, ast_time_str_to_unit("y") == TIME_UNIT_YEAR);
142
143 /* Plural */
144 ast_test_validate(test, ast_time_str_to_unit("nanoseconds") == TIME_UNIT_NANOSECOND);
145 ast_test_validate(test, ast_time_str_to_unit("microseconds") == TIME_UNIT_MICROSECOND);
146 ast_test_validate(test, ast_time_str_to_unit("milliseconds") == TIME_UNIT_MILLISECOND);
147 ast_test_validate(test, ast_time_str_to_unit("seconds") == TIME_UNIT_SECOND);
148 ast_test_validate(test, ast_time_str_to_unit("minutes") == TIME_UNIT_MINUTE);
149 ast_test_validate(test, ast_time_str_to_unit("hours") == TIME_UNIT_HOUR);
150 ast_test_validate(test, ast_time_str_to_unit("days") == TIME_UNIT_DAY);
151 ast_test_validate(test, ast_time_str_to_unit("weeks") == TIME_UNIT_WEEK);
152 ast_test_validate(test, ast_time_str_to_unit("months") == TIME_UNIT_MONTH);
153 ast_test_validate(test, ast_time_str_to_unit("years") == TIME_UNIT_YEAR);
154
155 /* Case */
156 ast_test_validate(test, ast_time_str_to_unit("Nsec") == TIME_UNIT_NANOSECOND);
157 ast_test_validate(test, ast_time_str_to_unit("Usec") == TIME_UNIT_MICROSECOND);
158 ast_test_validate(test, ast_time_str_to_unit("Msec") == TIME_UNIT_MILLISECOND);
159 ast_test_validate(test, ast_time_str_to_unit("Sec") == TIME_UNIT_SECOND);
160 ast_test_validate(test, ast_time_str_to_unit("Min") == TIME_UNIT_MINUTE);
161 ast_test_validate(test, ast_time_str_to_unit("Hr") == TIME_UNIT_HOUR);
162 ast_test_validate(test, ast_time_str_to_unit("Day") == TIME_UNIT_DAY);
163 ast_test_validate(test, ast_time_str_to_unit("Wk") == TIME_UNIT_WEEK);
164 ast_test_validate(test, ast_time_str_to_unit("Mth") == TIME_UNIT_MONTH);
165 ast_test_validate(test, ast_time_str_to_unit("Yr") == TIME_UNIT_YEAR);
166
167 return AST_TEST_PASS;
168}
169
170AST_TEST_DEFINE(test_time_create_by_unit)
171{
172 struct timeval tv;
173
174 switch (cmd) {
175 case TEST_INIT:
176 info->name = "time_create_by_unit";
177 info->category = "/main/stdtime/";
178 info->summary = "Verify unit value to timeval conversions";
179 info->description = info->summary;
180 return AST_TEST_NOT_RUN;
181 case TEST_EXECUTE:
182 break;
183 }
184
185 /* Nominal */
186 ast_test_validate(test, ast_time_create_by_unit(1000, TIME_UNIT_NANOSECOND).tv_usec == 1);
187 ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_MICROSECOND).tv_usec == 1);
188 ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_MILLISECOND).tv_usec == 1000);
189 ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_SECOND).tv_sec == 1);
190 ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_MINUTE).tv_sec == 60);
191 ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_HOUR).tv_sec == 3600);
192 ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_DAY).tv_sec == 86400);
193 ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_WEEK).tv_sec == 604800);
194 ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_MONTH).tv_sec == 2629746);
195 ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_YEAR).tv_sec == 31556952);
196
197 /* timeval normalization */
199 ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
200
202 ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
203
205 ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
206
207 return AST_TEST_PASS;
208}
209
210AST_TEST_DEFINE(test_time_create_by_unit_str)
211{
212 struct timeval tv;
213
214 switch (cmd) {
215 case TEST_INIT:
216 info->name = "time_create_by_unit_str";
217 info->category = "/main/stdtime/";
218 info->summary = "Verify value with unit as a string to timeval conversions";
219 info->description = info->summary;
220 return AST_TEST_NOT_RUN;
221 case TEST_EXECUTE:
222 break;
223 }
224
225 /* Nominal */
226 ast_test_validate(test, ast_time_create_by_unit_str(1000, "ns").tv_usec == 1);
227 ast_test_validate(test, ast_time_create_by_unit_str(1, "us").tv_usec == 1);
228 ast_test_validate(test, ast_time_create_by_unit_str(1, "ms").tv_usec == 1000);
229 ast_test_validate(test, ast_time_create_by_unit_str(1, "s").tv_sec == 1);
230 ast_test_validate(test, ast_time_create_by_unit_str(1, "m").tv_sec == 60);
231 ast_test_validate(test, ast_time_create_by_unit_str(1, "h").tv_sec == 3600);
232 ast_test_validate(test, ast_time_create_by_unit_str(1, "d").tv_sec == 86400);
233 ast_test_validate(test, ast_time_create_by_unit_str(1, "w").tv_sec == 604800);
234 ast_test_validate(test, ast_time_create_by_unit_str(1, "mo").tv_sec == 2629746);
235 ast_test_validate(test, ast_time_create_by_unit_str(1, "yr").tv_sec == 31556952);
236
237 /* timeval normalization */
238 tv = ast_time_create_by_unit_str(1500000000, "ns");
239 ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
240
241 tv = ast_time_create_by_unit_str(1500000, "us");
242 ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
243
244 tv = ast_time_create_by_unit_str(1500, "ms");
245 ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
246
247 return AST_TEST_PASS;
248}
249
250AST_TEST_DEFINE(test_time_tv_to_usec)
251{
252 struct timeval tv;
253
254 switch (cmd) {
255 case TEST_INIT:
256 info->name = "time_tv_to_usec";
257 info->category = "/main/stdtime/";
258 info->summary = "Verify conversion of a timeval structure to microseconds";
259 info->description = info->summary;
260 return AST_TEST_NOT_RUN;
261 case TEST_EXECUTE:
262 break;
263 }
264
265 tv = ast_time_create(0, 0);
266 ast_test_validate(test, ast_time_tv_to_usec(&tv) == 0);
267
268 tv = ast_time_create(0, 1);
269 ast_test_validate(test, ast_time_tv_to_usec(&tv) == 1);
270
271 tv = ast_time_create(1, 0);
272 ast_test_validate(test, ast_time_tv_to_usec(&tv) == 1000000);
273
274 tv = ast_time_create(1, 1);
275 ast_test_validate(test, ast_time_tv_to_usec(&tv) == 1000001);
276
277 return AST_TEST_PASS;
278}
279
280static int unload_module(void)
281{
282 AST_TEST_UNREGISTER(test_time_create_by_unit_str);
283 AST_TEST_UNREGISTER(test_time_create_by_unit);
284 AST_TEST_UNREGISTER(test_time_str_to_unit);
285 AST_TEST_UNREGISTER(test_time_tv_to_usec);
286 AST_TEST_UNREGISTER(test_timezone_watch);
287 return 0;
288}
289
290static int load_module(void)
291{
292 AST_TEST_REGISTER(test_timezone_watch);
293 AST_TEST_REGISTER(test_time_tv_to_usec);
294 AST_TEST_REGISTER(test_time_str_to_unit);
295 AST_TEST_REGISTER(test_time_create_by_unit);
296 AST_TEST_REGISTER(test_time_create_by_unit_str);
298}
299
Asterisk main include file. File version handling, generic pbx functions.
#define ast_log
Definition: astobj2.c:42
static const char type[]
Definition: chan_ooh323.c:109
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: extconf.c:829
char * mkdtemp(char *template_s)
#define LOG_WARNING
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
void ast_localtime_wakeup_monitor(struct ast_test *info)
Definition: localtime.c:795
int errno
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
def info(msg)
int tm_hour
Definition: localtime.h:38
int tm_isdst
Definition: localtime.h:44
Test Framework API.
@ TEST_INIT
Definition: test.h:200
@ TEST_EXECUTE
Definition: test.h:201
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
@ AST_TEST_PASS
Definition: test.h:195
@ AST_TEST_FAIL
Definition: test.h:196
@ AST_TEST_NOT_RUN
Definition: test.h:194
AST_TEST_DEFINE(test_timezone_watch)
Definition: test_time.c:48
#define TZDIR
Definition: test_time.c:44
static int load_module(void)
Definition: test_time.c:290
static int unload_module(void)
Definition: test_time.c:280
enum TIME_UNIT ast_time_str_to_unit(const char *unit)
Convert a string to a time unit enumeration value.
Definition: time.c:66
@ TIME_UNIT_MONTH
Definition: time.h:348
@ TIME_UNIT_MICROSECOND
Definition: time.h:341
@ TIME_UNIT_WEEK
Definition: time.h:347
@ TIME_UNIT_MINUTE
Definition: time.h:344
@ TIME_UNIT_SECOND
Definition: time.h:343
@ TIME_UNIT_YEAR
Definition: time.h:349
@ TIME_UNIT_MILLISECOND
Definition: time.h:342
@ TIME_UNIT_HOUR
Definition: time.h:345
@ TIME_UNIT_DAY
Definition: time.h:346
@ TIME_UNIT_NANOSECOND
Definition: time.h:340
struct timeval ast_time_create(ast_time_t sec, ast_suseconds_t usec)
Create a timeval object initialized to given values.
Definition: time.c:95
struct timeval ast_time_create_by_unit(unsigned long val, enum TIME_UNIT unit)
Convert the given unit value, and create a timeval object from it.
Definition: time.c:113
struct timeval ast_time_create_by_unit_str(unsigned long val, const char *unit)
Convert the given unit value, and create a timeval object from it.
Definition: time.c:143
ast_suseconds_t ast_time_tv_to_usec(const struct timeval *tv)
Convert a timeval structure to microseconds.
Definition: time.c:90
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
Utility functions.
#define ARRAY_LEN(a)
Definition: utils.h:666