1 | /* Unit tests for GTimer |
2 | * Copyright (C) 2013 Red Hat, Inc. |
3 | * |
4 | * This work is provided "as is"; redistribution and modification |
5 | * in whole or in part, in any medium, physical or electronic is |
6 | * permitted without restriction. |
7 | * |
8 | * This work is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
11 | * |
12 | * In no event shall the authors or contributors be liable for any |
13 | * direct, indirect, incidental, special, exemplary, or consequential |
14 | * damages (including, but not limited to, procurement of substitute |
15 | * goods or services; loss of use, data, or profits; or business |
16 | * interruption) however caused and on any theory of liability, whether |
17 | * in contract, strict liability, or tort (including negligence or |
18 | * otherwise) arising in any way out of the use of this software, even |
19 | * if advised of the possibility of such damage. |
20 | * |
21 | * Author: Matthias Clasen |
22 | */ |
23 | |
24 | /* We test a few deprecated APIs here. */ |
25 | #define GLIB_DISABLE_DEPRECATION_WARNINGS 1 |
26 | |
27 | #include "glib.h" |
28 | |
29 | static void |
30 | test_timer_basic (void) |
31 | { |
32 | GTimer *timer; |
33 | gdouble elapsed; |
34 | gulong micros; |
35 | |
36 | timer = g_timer_new (); |
37 | |
38 | elapsed = g_timer_elapsed (timer, microseconds: µs); |
39 | |
40 | g_assert_cmpfloat (elapsed, <, 1.0); |
41 | g_assert_cmpuint (micros, ==, ((guint64)(elapsed * 1e6)) % 1000000); |
42 | |
43 | g_timer_destroy (timer); |
44 | } |
45 | |
46 | static void |
47 | test_timer_stop (void) |
48 | { |
49 | GTimer *timer; |
50 | gdouble elapsed, elapsed2; |
51 | |
52 | timer = g_timer_new (); |
53 | |
54 | g_timer_stop (timer); |
55 | |
56 | elapsed = g_timer_elapsed (timer, NULL); |
57 | g_usleep (microseconds: 100); |
58 | elapsed2 = g_timer_elapsed (timer, NULL); |
59 | |
60 | g_assert_cmpfloat (elapsed, ==, elapsed2); |
61 | |
62 | g_timer_destroy (timer); |
63 | } |
64 | |
65 | static void |
66 | test_timer_continue (void) |
67 | { |
68 | GTimer *timer; |
69 | gdouble elapsed, elapsed2; |
70 | |
71 | timer = g_timer_new (); |
72 | g_usleep (microseconds: 100); |
73 | g_timer_stop (timer); |
74 | |
75 | elapsed = g_timer_elapsed (timer, NULL); |
76 | g_timer_continue (timer); |
77 | g_usleep (microseconds: 100); |
78 | elapsed2 = g_timer_elapsed (timer, NULL); |
79 | |
80 | g_assert_cmpfloat (elapsed, <, elapsed2); |
81 | |
82 | g_timer_destroy (timer); |
83 | } |
84 | |
85 | static void |
86 | test_timer_reset (void) |
87 | { |
88 | GTimer *timer; |
89 | gdouble elapsed, elapsed2; |
90 | |
91 | timer = g_timer_new (); |
92 | g_usleep (microseconds: 100); |
93 | g_timer_stop (timer); |
94 | |
95 | elapsed = g_timer_elapsed (timer, NULL); |
96 | g_timer_reset (timer); |
97 | elapsed2 = g_timer_elapsed (timer, NULL); |
98 | |
99 | g_assert_cmpfloat (elapsed, >, elapsed2); |
100 | |
101 | g_timer_destroy (timer); |
102 | } |
103 | |
104 | static void |
105 | test_timer_is_active (void) |
106 | { |
107 | GTimer *timer; |
108 | gboolean is_active; |
109 | |
110 | timer = g_timer_new (); |
111 | is_active = g_timer_is_active (timer); |
112 | g_assert_true (is_active); |
113 | g_timer_stop (timer); |
114 | is_active = g_timer_is_active (timer); |
115 | g_assert_false (is_active); |
116 | |
117 | g_timer_destroy (timer); |
118 | } |
119 | |
120 | static void |
121 | test_timeval_add (void) |
122 | { |
123 | GTimeVal time = { 1, 0 }; |
124 | |
125 | g_time_val_add (time_: &time, microseconds: 10); |
126 | |
127 | g_assert_cmpint (time.tv_sec, ==, 1); |
128 | g_assert_cmpint (time.tv_usec, ==, 10); |
129 | |
130 | g_time_val_add (time_: &time, microseconds: -500); |
131 | g_assert_cmpint (time.tv_sec, ==, 0); |
132 | g_assert_cmpint (time.tv_usec, ==, G_USEC_PER_SEC - 490); |
133 | |
134 | g_time_val_add (time_: &time, microseconds: 1000); |
135 | g_assert_cmpint (time.tv_sec, ==, 1); |
136 | g_assert_cmpint (time.tv_usec, ==, 510); |
137 | |
138 | g_time_val_add (time_: &time, microseconds: 0); |
139 | g_assert_cmpint (time.tv_sec, ==, 1); |
140 | g_assert_cmpint (time.tv_usec, ==, 510); |
141 | |
142 | g_time_val_add (time_: &time, microseconds: -210); |
143 | g_assert_cmpint (time.tv_sec, ==, 1); |
144 | g_assert_cmpint (time.tv_usec, ==, 300); |
145 | } |
146 | |
147 | typedef struct { |
148 | gboolean success; |
149 | const gchar *in; |
150 | GTimeVal val; |
151 | } TimeValParseTest; |
152 | |
153 | static void |
154 | test_timeval_from_iso8601 (void) |
155 | { |
156 | gchar *old_tz = g_strdup (str: g_getenv (variable: "TZ" )); |
157 | TimeValParseTest tests[] = { |
158 | { TRUE, "1990-11-01T10:21:17Z" , { 657454877, 0 } }, |
159 | { TRUE, "19901101T102117Z" , { 657454877, 0 } }, |
160 | { TRUE, "19901101T102117+5" , { 657454577, 0 } }, |
161 | { TRUE, "19901101T102117+3:15" , { 657443177, 0 } }, |
162 | { TRUE, " 1990-11-01T10:21:17Z " , { 657454877, 0 } }, |
163 | { TRUE, "1970-01-01T00:00:17.12Z" , { 17, 120000 } }, |
164 | { TRUE, "1970-01-01T00:00:17.1234Z" , { 17, 123400 } }, |
165 | { TRUE, "1970-01-01T00:00:17.123456Z" , { 17, 123456 } }, |
166 | { TRUE, "1980-02-22T12:36:00+02:00" , { 320063760, 0 } }, |
167 | { FALSE, " " , { 0, 0 } }, |
168 | { FALSE, "x" , { 0, 0 } }, |
169 | { FALSE, "123x" , { 0, 0 } }, |
170 | { FALSE, "2001-10+x" , { 0, 0 } }, |
171 | { FALSE, "1980-02-22T" , { 0, 0 } }, |
172 | { FALSE, "2001-10-08Tx" , { 0, 0 } }, |
173 | { FALSE, "2001-10-08T10:11x" , { 0, 0 } }, |
174 | { FALSE, "Wed Dec 19 17:20:20 GMT 2007" , { 0, 0 } }, |
175 | { FALSE, "1980-02-22T10:36:00Zulu" , { 0, 0 } }, |
176 | { FALSE, "2T0+819855292164632335" , { 0, 0 } }, |
177 | { TRUE, "2018-08-03T14:08:05.446178377+01:00" , { 1533301685, 446178 } }, |
178 | { FALSE, "2147483648-08-03T14:08:05.446178377+01:00" , { 0, 0 } }, |
179 | { FALSE, "2018-13-03T14:08:05.446178377+01:00" , { 0, 0 } }, |
180 | { FALSE, "2018-00-03T14:08:05.446178377+01:00" , { 0, 0 } }, |
181 | { FALSE, "2018-08-00T14:08:05.446178377+01:00" , { 0, 0 } }, |
182 | { FALSE, "2018-08-32T14:08:05.446178377+01:00" , { 0, 0 } }, |
183 | { FALSE, "2018-08-03T24:08:05.446178377+01:00" , { 0, 0 } }, |
184 | { FALSE, "2018-08-03T14:60:05.446178377+01:00" , { 0, 0 } }, |
185 | { FALSE, "2018-08-03T14:08:63.446178377+01:00" , { 0, 0 } }, |
186 | { FALSE, "2018-08-03T14:08:05.446178377+100:00" , { 0, 0 } }, |
187 | { FALSE, "2018-08-03T14:08:05.446178377+01:60" , { 0, 0 } }, |
188 | { TRUE, "20180803T140805.446178377+0100" , { 1533301685, 446178 } }, |
189 | { FALSE, "21474836480803T140805.446178377+0100" , { 0, 0 } }, |
190 | { FALSE, "20181303T140805.446178377+0100" , { 0, 0 } }, |
191 | { FALSE, "20180003T140805.446178377+0100" , { 0, 0 } }, |
192 | { FALSE, "20180800T140805.446178377+0100" , { 0, 0 } }, |
193 | { FALSE, "20180832T140805.446178377+0100" , { 0, 0 } }, |
194 | { FALSE, "20180803T240805.446178377+0100" , { 0, 0 } }, |
195 | { FALSE, "20180803T146005.446178377+0100" , { 0, 0 } }, |
196 | { FALSE, "20180803T140863.446178377+0100" , { 0, 0 } }, |
197 | { FALSE, "20180803T140805.446178377+10000" , { 0, 0 } }, |
198 | { FALSE, "20180803T140805.446178377+0160" , { 0, 0 } }, |
199 | { TRUE, "+1980-02-22T12:36:00+02:00" , { 320063760, 0 } }, |
200 | { FALSE, "-0005-01-01T00:00:00Z" , { 0, 0 } }, |
201 | { FALSE, "2018-08-06" , { 0, 0 } }, |
202 | { FALSE, "2018-08-06 13:51:00Z" , { 0, 0 } }, |
203 | { TRUE, "20180803T140805,446178377+0100" , { 1533301685, 446178 } }, |
204 | { TRUE, "2018-08-03T14:08:05.446178377-01:00" , { 1533308885, 446178 } }, |
205 | { FALSE, "2018-08-03T14:08:05.446178377 01:00" , { 0, 0 } }, |
206 | { TRUE, "1990-11-01T10:21:17" , { 657454877, 0 } }, |
207 | { TRUE, "1990-11-01T10:21:17 " , { 657454877, 0 } }, |
208 | }; |
209 | GTimeVal out; |
210 | gboolean success; |
211 | gsize i; |
212 | |
213 | /* Always run in UTC so the comparisons of parsed values are valid. */ |
214 | if (!g_setenv (variable: "TZ" , value: "UTC" , TRUE)) |
215 | { |
216 | g_test_skip (msg: "Failed to set TZ=UTC" ); |
217 | return; |
218 | } |
219 | |
220 | for (i = 0; i < G_N_ELEMENTS (tests); i++) |
221 | { |
222 | out.tv_sec = 0; |
223 | out.tv_usec = 0; |
224 | success = g_time_val_from_iso8601 (iso_date: tests[i].in, time_: &out); |
225 | g_assert (success == tests[i].success); |
226 | if (tests[i].success) |
227 | { |
228 | g_assert_cmpint (out.tv_sec, ==, tests[i].val.tv_sec); |
229 | g_assert_cmpint (out.tv_usec, ==, tests[i].val.tv_usec); |
230 | } |
231 | } |
232 | |
233 | if (old_tz != NULL) |
234 | g_assert_true (g_setenv ("TZ" , old_tz, TRUE)); |
235 | else |
236 | g_unsetenv (variable: "TZ" ); |
237 | |
238 | g_free (mem: old_tz); |
239 | } |
240 | |
241 | typedef struct { |
242 | GTimeVal val; |
243 | const gchar *expected; |
244 | } TimeValFormatTest; |
245 | |
246 | static void |
247 | test_timeval_to_iso8601 (void) |
248 | { |
249 | TimeValFormatTest tests[] = { |
250 | { { 657454877, 0 }, "1990-11-01T10:21:17Z" }, |
251 | { { 17, 123400 }, "1970-01-01T00:00:17.123400Z" } |
252 | }; |
253 | gsize i; |
254 | gchar *out; |
255 | GTimeVal val; |
256 | gboolean ret; |
257 | |
258 | g_unsetenv (variable: "TZ" ); |
259 | |
260 | for (i = 0; i < G_N_ELEMENTS (tests); i++) |
261 | { |
262 | out = g_time_val_to_iso8601 (time_: &(tests[i].val)); |
263 | g_assert_cmpstr (out, ==, tests[i].expected); |
264 | |
265 | ret = g_time_val_from_iso8601 (iso_date: out, time_: &val); |
266 | g_assert (ret); |
267 | g_assert_cmpint (val.tv_sec, ==, tests[i].val.tv_sec); |
268 | g_assert_cmpint (val.tv_usec, ==, tests[i].val.tv_usec); |
269 | g_free (mem: out); |
270 | } |
271 | } |
272 | |
273 | /* Test error handling for g_time_val_to_iso8601() on dates which are too large. */ |
274 | static void |
275 | test_timeval_to_iso8601_overflow (void) |
276 | { |
277 | GTimeVal val; |
278 | gchar *out = NULL; |
279 | |
280 | if ((glong) G_MAXINT == G_MAXLONG) |
281 | { |
282 | g_test_skip (msg: "G_MAXINT == G_MAXLONG - we can't make g_time_val_to_iso8601() overflow." ); |
283 | return; |
284 | } |
285 | |
286 | g_unsetenv (variable: "TZ" ); |
287 | |
288 | val.tv_sec = G_MAXLONG; |
289 | val.tv_usec = G_USEC_PER_SEC - 1; |
290 | |
291 | out = g_time_val_to_iso8601 (time_: &val); |
292 | g_assert_null (out); |
293 | } |
294 | |
295 | int |
296 | main (int argc, char *argv[]) |
297 | { |
298 | g_test_init (argc: &argc, argv: &argv, NULL); |
299 | |
300 | g_test_add_func (testpath: "/timer/basic" , test_func: test_timer_basic); |
301 | g_test_add_func (testpath: "/timer/stop" , test_func: test_timer_stop); |
302 | g_test_add_func (testpath: "/timer/continue" , test_func: test_timer_continue); |
303 | g_test_add_func (testpath: "/timer/reset" , test_func: test_timer_reset); |
304 | g_test_add_func (testpath: "/timer/is_active" , test_func: test_timer_is_active); |
305 | g_test_add_func (testpath: "/timeval/add" , test_func: test_timeval_add); |
306 | g_test_add_func (testpath: "/timeval/from-iso8601" , test_func: test_timeval_from_iso8601); |
307 | g_test_add_func (testpath: "/timeval/to-iso8601" , test_func: test_timeval_to_iso8601); |
308 | g_test_add_func (testpath: "/timeval/to-iso8601/overflow" , test_func: test_timeval_to_iso8601_overflow); |
309 | |
310 | return g_test_run (); |
311 | } |
312 | |