gdatetime: Add g_date_time_source_new()
[platform/upstream/glib.git] / glib / tests / timeout.c
1 #include <glib.h>
2 #include <unistd.h>
3
4 static GMainLoop *loop;
5
6 static gboolean
7 stop_waiting (gpointer data)
8 {
9   g_main_loop_quit (loop);
10
11   return FALSE;
12 }
13
14 static gboolean
15 function (gpointer data)
16 {
17   g_assert_not_reached ();
18 }
19
20 static void
21 test_seconds (void)
22 {
23   /* Bug 642052 mentions that g_timeout_add_seconds(21475) schedules a
24    * job that runs once per second.
25    *
26    * Test that that isn't true anymore by scheduling two jobs:
27    *   - one, as above
28    *   - another that runs in 2100ms
29    *
30    * If everything is working properly, the 2100ms one should run first
31    * (and exit the mainloop).  If we ever see the 21475 second job run
32    * then we have trouble (since it ran in less than 2 seconds).
33    *
34    * We need a timeout of at least 2 seconds because
35    * g_timeout_add_second can add as much as an additional second of
36    * latency.
37    */
38   loop = g_main_loop_new (NULL, FALSE);
39
40   g_timeout_add (2100, stop_waiting, NULL);
41   g_timeout_add_seconds (21475, function, NULL);
42
43   g_main_loop_run (loop);
44 }
45
46 static gint64 last_time;
47 static gint count;
48
49 static gboolean
50 test_func (gpointer data)
51 {
52   gint64 current_time;
53
54   current_time = g_get_monotonic_time ();
55
56   /* We accept 2 on the first iteration because _add_seconds() can
57    * have an initial latency of 1 second, see its documentation.
58    */
59   if (count == 0)
60     g_assert (current_time / 1000000 - last_time / 1000000 <= 2);
61   else
62     g_assert (current_time / 1000000 - last_time / 1000000 == 1);
63
64   last_time = current_time;
65   count++;
66
67   /* Make the timeout take up to 0.1 seconds.
68    * We should still get scheduled for the next second.
69    */
70   g_usleep (count * 10000);
71
72   if (count < 10)
73     return TRUE;
74
75   g_main_loop_quit (loop);
76
77   return FALSE;
78 }
79
80 static void
81 test_rounding (void)
82 {
83   loop = g_main_loop_new (NULL, FALSE);
84
85   last_time = g_get_monotonic_time ();
86   g_timeout_add_seconds (1, test_func, NULL);
87
88   g_main_loop_run (loop);
89 }
90
91 static gboolean
92 on_test_date_time_watch_timeout (gpointer user_data)
93 {
94   *((gboolean*)user_data) = TRUE;
95
96   g_main_loop_quit (loop);
97
98   return TRUE;
99 }
100
101 /* This test isn't very useful; it's hard to actually test much of the
102  * functionality of g_date_time_source_new() without a means to set
103  * the system clock (which typically requires system-specific
104  * interfaces as well as elevated privileges).
105  *
106  * But at least we're running the code and ensuring the timer fires.
107  */
108 static void
109 test_date_time_create_watch (gboolean cancel_on_set)
110 {
111   GSource *source;
112   GDateTime *now, *expiry;
113   gboolean fired = FALSE;
114   gint64 orig_time_monotonic, end_time_monotonic;
115   gint64 elapsed_monotonic_seconds;
116   
117   loop = g_main_loop_new (NULL, FALSE);
118
119   orig_time_monotonic = g_get_monotonic_time ();
120
121   now = g_date_time_new_now_local ();
122   expiry = g_date_time_add_seconds (now, 7);
123   g_date_time_unref (now);
124
125   source = g_date_time_source_new (expiry, cancel_on_set);
126   g_source_set_callback (source, on_test_date_time_watch_timeout, &fired, NULL);
127   g_source_attach (source, NULL);
128   g_source_unref (source);
129
130   g_main_loop_run (loop);
131
132   g_assert (fired);
133   if (!cancel_on_set)
134     {
135       end_time_monotonic = g_get_monotonic_time ();
136       
137       elapsed_monotonic_seconds = 1 + (end_time_monotonic - orig_time_monotonic) / G_TIME_SPAN_SECOND;
138       
139       g_assert_cmpint (elapsed_monotonic_seconds, >=, 7);
140     }
141   else
142     {
143       /* We can't really assert much about the cancel_on_set case */
144     }
145 }
146
147 static void
148 test_date_time_create_watch_nocancel_on_set (void)
149 {
150   test_date_time_create_watch (FALSE);
151 }
152
153 static void
154 test_date_time_create_watch_cancel_on_set (void)
155 {
156   test_date_time_create_watch (TRUE);
157 }
158
159 int
160 main (int argc, char *argv[])
161 {
162   g_test_init (&argc, &argv, NULL);
163
164   g_test_add_func ("/timeout/seconds", test_seconds);
165   g_test_add_func ("/timeout/rounding", test_rounding);
166   g_test_add_func ("/timeout/datetime_watch_nocancel_on_set", test_date_time_create_watch_nocancel_on_set);
167   g_test_add_func ("/timeout/datetime_watch_cancel_on_set", test_date_time_create_watch_cancel_on_set);
168
169   return g_test_run ();
170 }