Asterisk - The Open Source Telephony Project  18.5.0
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 
48 AST_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  res = AST_TEST_FAIL;
95  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]);
96  }
97  }
98 
99  if (i + 1 != ARRAY_LEN(zones)) {
100  /* stat(2) only has resolution to 1 second - must wait, or the mtime is the same */
101  usleep(1100000);
102  }
103  }
104  }
105 
106  snprintf(syscmd, sizeof(syscmd), "rm -rf %s", tmpdir);
107  if (ast_safe_system(syscmd)) {
108  ast_log(LOG_WARNING, "system(%s) returned non-zero.\n", syscmd);
109  }
110 
111  return res;
112 }
113 
114 AST_TEST_DEFINE(test_time_str_to_unit)
115 {
116  switch (cmd) {
117  case TEST_INIT:
118  info->name = "time_str_to_unit";
119  info->category = "/main/stdtime/";
120  info->summary = "Verify string to time unit conversions";
121  info->description = info->summary;
122  return AST_TEST_NOT_RUN;
123  case TEST_EXECUTE:
124  break;
125  }
126 
127  /* Nominal */
128  ast_test_validate(test, ast_time_str_to_unit("ns") == TIME_UNIT_NANOSECOND);
129  ast_test_validate(test, ast_time_str_to_unit("us") == TIME_UNIT_MICROSECOND);
130  ast_test_validate(test, ast_time_str_to_unit("ms") == TIME_UNIT_MILLISECOND);
131  ast_test_validate(test, ast_time_str_to_unit("s") == TIME_UNIT_SECOND);
132  ast_test_validate(test, ast_time_str_to_unit("m") == TIME_UNIT_MINUTE);
133  ast_test_validate(test, ast_time_str_to_unit("h") == TIME_UNIT_HOUR);
134  ast_test_validate(test, ast_time_str_to_unit("d") == TIME_UNIT_DAY);
135  ast_test_validate(test, ast_time_str_to_unit("w") == TIME_UNIT_WEEK);
136  ast_test_validate(test, ast_time_str_to_unit("mo") == TIME_UNIT_MONTH);
137  ast_test_validate(test, ast_time_str_to_unit("y") == TIME_UNIT_YEAR);
138 
139  /* Plural */
140  ast_test_validate(test, ast_time_str_to_unit("nanoseconds") == TIME_UNIT_NANOSECOND);
141  ast_test_validate(test, ast_time_str_to_unit("microseconds") == TIME_UNIT_MICROSECOND);
142  ast_test_validate(test, ast_time_str_to_unit("milliseconds") == TIME_UNIT_MILLISECOND);
143  ast_test_validate(test, ast_time_str_to_unit("seconds") == TIME_UNIT_SECOND);
144  ast_test_validate(test, ast_time_str_to_unit("minutes") == TIME_UNIT_MINUTE);
145  ast_test_validate(test, ast_time_str_to_unit("hours") == TIME_UNIT_HOUR);
146  ast_test_validate(test, ast_time_str_to_unit("days") == TIME_UNIT_DAY);
147  ast_test_validate(test, ast_time_str_to_unit("weeks") == TIME_UNIT_WEEK);
148  ast_test_validate(test, ast_time_str_to_unit("months") == TIME_UNIT_MONTH);
149  ast_test_validate(test, ast_time_str_to_unit("years") == TIME_UNIT_YEAR);
150 
151  /* Case */
152  ast_test_validate(test, ast_time_str_to_unit("Nsec") == TIME_UNIT_NANOSECOND);
153  ast_test_validate(test, ast_time_str_to_unit("Usec") == TIME_UNIT_MICROSECOND);
154  ast_test_validate(test, ast_time_str_to_unit("Msec") == TIME_UNIT_MILLISECOND);
155  ast_test_validate(test, ast_time_str_to_unit("Sec") == TIME_UNIT_SECOND);
156  ast_test_validate(test, ast_time_str_to_unit("Min") == TIME_UNIT_MINUTE);
157  ast_test_validate(test, ast_time_str_to_unit("Hr") == TIME_UNIT_HOUR);
158  ast_test_validate(test, ast_time_str_to_unit("Day") == TIME_UNIT_DAY);
159  ast_test_validate(test, ast_time_str_to_unit("Wk") == TIME_UNIT_WEEK);
160  ast_test_validate(test, ast_time_str_to_unit("Mth") == TIME_UNIT_MONTH);
161  ast_test_validate(test, ast_time_str_to_unit("Yr") == TIME_UNIT_YEAR);
162 
163  return AST_TEST_PASS;
164 }
165 
166 AST_TEST_DEFINE(test_time_create_by_unit)
167 {
168  struct timeval tv;
169 
170  switch (cmd) {
171  case TEST_INIT:
172  info->name = "time_create_by_unit";
173  info->category = "/main/stdtime/";
174  info->summary = "Verify unit value to timeval conversions";
175  info->description = info->summary;
176  return AST_TEST_NOT_RUN;
177  case TEST_EXECUTE:
178  break;
179  }
180 
181  /* Nominal */
182  ast_test_validate(test, ast_time_create_by_unit(1000, TIME_UNIT_NANOSECOND).tv_usec == 1);
183  ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_MICROSECOND).tv_usec == 1);
184  ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_MILLISECOND).tv_usec == 1000);
185  ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_SECOND).tv_sec == 1);
186  ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_MINUTE).tv_sec == 60);
187  ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_HOUR).tv_sec == 3600);
188  ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_DAY).tv_sec == 86400);
189  ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_WEEK).tv_sec == 604800);
190  ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_MONTH).tv_sec == 2629746);
191  ast_test_validate(test, ast_time_create_by_unit(1, TIME_UNIT_YEAR).tv_sec == 31556952);
192 
193  /* timeval normalization */
195  ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
196 
198  ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
199 
201  ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
202 
203  return AST_TEST_PASS;
204 }
205 
206 AST_TEST_DEFINE(test_time_create_by_unit_str)
207 {
208  struct timeval tv;
209 
210  switch (cmd) {
211  case TEST_INIT:
212  info->name = "time_create_by_unit_str";
213  info->category = "/main/stdtime/";
214  info->summary = "Verify value with unit as a string to timeval conversions";
215  info->description = info->summary;
216  return AST_TEST_NOT_RUN;
217  case TEST_EXECUTE:
218  break;
219  }
220 
221  /* Nominal */
222  ast_test_validate(test, ast_time_create_by_unit_str(1000, "ns").tv_usec == 1);
223  ast_test_validate(test, ast_time_create_by_unit_str(1, "us").tv_usec == 1);
224  ast_test_validate(test, ast_time_create_by_unit_str(1, "ms").tv_usec == 1000);
225  ast_test_validate(test, ast_time_create_by_unit_str(1, "s").tv_sec == 1);
226  ast_test_validate(test, ast_time_create_by_unit_str(1, "m").tv_sec == 60);
227  ast_test_validate(test, ast_time_create_by_unit_str(1, "h").tv_sec == 3600);
228  ast_test_validate(test, ast_time_create_by_unit_str(1, "d").tv_sec == 86400);
229  ast_test_validate(test, ast_time_create_by_unit_str(1, "w").tv_sec == 604800);
230  ast_test_validate(test, ast_time_create_by_unit_str(1, "mo").tv_sec == 2629746);
231  ast_test_validate(test, ast_time_create_by_unit_str(1, "yr").tv_sec == 31556952);
232 
233  /* timeval normalization */
234  tv = ast_time_create_by_unit_str(1500000000, "ns");
235  ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
236 
237  tv = ast_time_create_by_unit_str(1500000, "us");
238  ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
239 
240  tv = ast_time_create_by_unit_str(1500, "ms");
241  ast_test_validate(test, tv.tv_sec == 1 && tv.tv_usec == 500000);
242 
243  return AST_TEST_PASS;
244 }
245 
246 AST_TEST_DEFINE(test_time_tv_to_usec)
247 {
248  struct timeval tv;
249 
250  switch (cmd) {
251  case TEST_INIT:
252  info->name = "time_tv_to_usec";
253  info->category = "/main/stdtime/";
254  info->summary = "Verify conversion of a timeval structure to microseconds";
255  info->description = info->summary;
256  return AST_TEST_NOT_RUN;
257  case TEST_EXECUTE:
258  break;
259  }
260 
261  tv = ast_time_create(0, 0);
262  ast_test_validate(test, ast_time_tv_to_usec(&tv) == 0);
263 
264  tv = ast_time_create(0, 1);
265  ast_test_validate(test, ast_time_tv_to_usec(&tv) == 1);
266 
267  tv = ast_time_create(1, 0);
268  ast_test_validate(test, ast_time_tv_to_usec(&tv) == 1000000);
269 
270  tv = ast_time_create(1, 1);
271  ast_test_validate(test, ast_time_tv_to_usec(&tv) == 1000001);
272 
273  return AST_TEST_PASS;
274 }
275 
276 static int unload_module(void)
277 {
278  AST_TEST_UNREGISTER(test_time_create_by_unit_str);
279  AST_TEST_UNREGISTER(test_time_create_by_unit);
280  AST_TEST_UNREGISTER(test_time_str_to_unit);
281  AST_TEST_UNREGISTER(test_time_tv_to_usec);
282  AST_TEST_UNREGISTER(test_timezone_watch);
283  return 0;
284 }
285 
286 static int load_module(void)
287 {
288  AST_TEST_REGISTER(test_timezone_watch);
289  AST_TEST_REGISTER(test_time_tv_to_usec);
290  AST_TEST_REGISTER(test_time_str_to_unit);
291  AST_TEST_REGISTER(test_time_create_by_unit);
292  AST_TEST_REGISTER(test_time_create_by_unit_str);
294 }
295 
static const char type[]
Definition: chan_ooh323.c:109
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
ast_suseconds_t ast_time_tv_to_usec(const struct timeval *tv)
Convert a timeval structure to microseconds.
Definition: time.c:89
#define LOG_WARNING
Definition: logger.h:274
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
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:142
Test Framework API.
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
Utility functions.
static int unload_module(void)
Definition: test_time.c:276
#define ast_log
Definition: astobj2.c:42
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
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 AST_TEST_UNREGISTER(cb)
Definition: test.h:128
def info(msg)
int errno
static int load_module(void)
Definition: test_time.c:286
AST_TEST_DEFINE(test_timezone_watch)
Definition: test_time.c:48
struct timeval ast_time_create(ast_time_t sec, ast_suseconds_t usec)
Create a timeval object initialized to given values.
Definition: time.c:94
int tm_hour
Definition: localtime.h:38
enum TIME_UNIT ast_time_str_to_unit(const char *unit)
Convert a string to a time unit enumeration value.
Definition: time.c:65
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:112
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
void ast_localtime_wakeup_monitor(struct ast_test *info)
Definition: localtime.c:795
#define TZDIR
Definition: test_time.c:44