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
test_timer_basic(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, &micros);
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
test_timer_stop(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 (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
test_timer_continue(void)66 test_timer_continue (void)
67 {
68   GTimer *timer;
69   gdouble elapsed, elapsed2;
70 
71   timer = g_timer_new ();
72   g_usleep (100);
73   g_timer_stop (timer);
74 
75   elapsed = g_timer_elapsed (timer, NULL);
76   g_timer_continue (timer);
77   g_usleep (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
test_timer_reset(void)86 test_timer_reset (void)
87 {
88   GTimer *timer;
89   gdouble elapsed, elapsed2;
90 
91   timer = g_timer_new ();
92   g_usleep (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
test_timer_is_active(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
test_timeval_add(void)121 test_timeval_add (void)
122 {
123   GTimeVal time = { 1, 0 };
124 
125   g_time_val_add (&time, 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, -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, 1000);
135   g_assert_cmpint (time.tv_sec, ==, 1);
136   g_assert_cmpint (time.tv_usec, ==, 510);
137 
138   g_time_val_add (&time, 0);
139   g_assert_cmpint (time.tv_sec, ==, 1);
140   g_assert_cmpint (time.tv_usec, ==, 510);
141 
142   g_time_val_add (&time, -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
test_timeval_from_iso8601(void)154 test_timeval_from_iso8601 (void)
155 {
156   gchar *old_tz = g_strdup (g_getenv ("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 ("TZ", "UTC", TRUE))
215     {
216       g_test_skip ("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 (tests[i].in, &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 ("TZ");
237 
238   g_free (old_tz);
239 }
240 
241 typedef struct {
242   GTimeVal val;
243   const gchar *expected;
244 } TimeValFormatTest;
245 
246 static void
test_timeval_to_iso8601(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 ("TZ");
259 
260   for (i = 0; i < G_N_ELEMENTS (tests); i++)
261     {
262       out = g_time_val_to_iso8601 (&(tests[i].val));
263       g_assert_cmpstr (out, ==, tests[i].expected);
264 
265       ret = g_time_val_from_iso8601 (out, &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 (out);
270     }
271 }
272 
273 /* Test error handling for g_time_val_to_iso8601() on dates which are too large. */
274 static void
test_timeval_to_iso8601_overflow(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 ("G_MAXINT == G_MAXLONG - we can't make g_time_val_to_iso8601() overflow.");
283       return;
284     }
285 
286   g_unsetenv ("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 (&val);
292   g_assert_null (out);
293 }
294 
295 int
main(int argc,char * argv[])296 main (int argc, char *argv[])
297 {
298   g_test_init (&argc, &argv, NULL);
299 
300   g_test_add_func ("/timer/basic", test_timer_basic);
301   g_test_add_func ("/timer/stop", test_timer_stop);
302   g_test_add_func ("/timer/continue", test_timer_continue);
303   g_test_add_func ("/timer/reset", test_timer_reset);
304   g_test_add_func ("/timer/is_active", test_timer_is_active);
305   g_test_add_func ("/timeval/add", test_timeval_add);
306   g_test_add_func ("/timeval/from-iso8601", test_timeval_from_iso8601);
307   g_test_add_func ("/timeval/to-iso8601", test_timeval_to_iso8601);
308   g_test_add_func ("/timeval/to-iso8601/overflow", test_timeval_to_iso8601_overflow);
309 
310   return g_test_run ();
311 }
312