2
* Copyright 2013 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 3, as published
6
* by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranties of
10
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11
* PURPOSE. See the GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License along
14
* with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Charles Kerr <charles.kerr@canonical.com>
20
#include <datetime/clock.h>
21
#include <datetime/timezones.h>
23
#include "glib-fixture.h"
29
using unity::indicator::datetime::Clock;
30
using unity::indicator::datetime::LiveClock;
31
using unity::indicator::datetime::Timezones;
33
class ClockFixture: public GlibFixture
37
typedef GlibFixture super;
40
on_bus_opened (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself)
42
auto self = static_cast<ClockFixture*>(gself);
45
self->system_bus = g_bus_get_finish (res, &err);
46
g_assert_no_error (err);
48
g_main_loop_quit (self->loop);
52
on_bus_closed (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself)
54
auto self = static_cast<ClockFixture*>(gself);
57
g_dbus_connection_close_finish (self->system_bus, res, &err);
58
g_assert_no_error (err);
60
g_main_loop_quit (self->loop);
65
GTestDBus * test_dbus;
66
GDBusConnection * system_bus;
72
// pull up a test dbus
73
test_dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
74
g_test_dbus_up (test_dbus);
75
const char * address = g_test_dbus_get_bus_address (test_dbus);
76
g_setenv ("DBUS_SYSTEM_BUS_ADDRESS", address, TRUE);
77
g_debug ("test_dbus's address is %s", address);
79
// wait for the GDBusConnection before returning
80
g_bus_get (G_BUS_TYPE_SYSTEM, nullptr, on_bus_opened, this);
81
g_main_loop_run (loop);
84
virtual void TearDown ()
86
// close the system bus
87
g_dbus_connection_close (system_bus, nullptr, on_bus_closed, this);
88
g_main_loop_run (loop);
89
g_clear_object (&system_bus);
91
// tear down the test dbus
92
g_test_dbus_down (test_dbus);
93
g_clear_object (&test_dbus);
100
void emitPrepareForSleep ()
102
g_dbus_connection_emit_signal (g_bus_get_sync (G_BUS_TYPE_SYSTEM, nullptr, nullptr),
104
"/org/freedesktop/login1", // object path
105
"org.freedesktop.login1.Manager", // interface
106
"PrepareForSleep", // signal name
107
g_variant_new("(b)", FALSE),
116
#define TIMEZONE_FILE (SANDBOX"/timezone")
118
TEST_F (ClockFixture, HelloFixture)
120
std::shared_ptr<Timezones> zones (new Timezones);
121
zones->timezone.set("America/New_York");
122
LiveClock clock (zones);
125
GTimeZone * tz_nyc = g_time_zone_new (file_timezone.c_str());
126
GDateTime * now_nyc = g_date_time_new_now (tz_nyc);
127
GDateTime * now = clock.localtime();
128
EXPECT_EQ (g_date_time_get_utc_offset(now_nyc), g_date_time_get_utc_offset(now));
129
EXPECT_LE (abs(g_date_time_difference(now_nyc,now)), G_USEC_PER_SEC);
130
g_date_time_unref (now);
131
g_date_time_unref (now_nyc);
132
g_time_zone_unref (tz_nyc);
134
/// change the timezones!
135
clock.skewDetected.connect([this](){
136
g_main_loop_quit(loop);
138
file_timezone = "America/Los_Angeles";
139
g_idle_add ([](gpointer str){
140
set_file(static_cast<const char*>(str));
141
return G_SOURCE_REMOVE;
142
}, const_cast<char*>(file_timezone.c_str()));
143
g_main_loop_run (loop);
145
GTimeZone * tz_la = g_time_zone_new (file_timezone.c_str());
146
GDateTime * now_la = g_date_time_new_now (tz_la);
147
now = clock.localtime();
148
EXPECT_EQ (g_date_time_get_utc_offset(now_la), g_date_time_get_utc_offset(now));
149
EXPECT_LE (abs(g_date_time_difference(now_la,now)), G_USEC_PER_SEC);
150
g_date_time_unref (now);
151
g_date_time_unref (now_la);
152
g_time_zone_unref (tz_la);
157
TEST_F (ClockFixture, TimezoneChangeTriggersSkew)
159
std::shared_ptr<Timezones> zones (new Timezones);
160
zones->timezone.set("America/New_York");
161
LiveClock clock (zones);
162
//std::string file_timezone = "America/New_York";
163
//set_file (file_timezone);
164
//std::shared_ptr<TimezoneDetector> detector (new TimezoneDetector(TIMEZONE_FILE));
165
//LiveClock clock (detector);
167
GTimeZone * tz_nyc = g_time_zone_new ("America/New_York");
168
GDateTime * now_nyc = g_date_time_new_now (tz_nyc);
169
GDateTime * now = clock.localtime();
170
EXPECT_EQ (g_date_time_get_utc_offset(now_nyc), g_date_time_get_utc_offset(now));
171
EXPECT_LE (abs(g_date_time_difference(now_nyc,now)), G_USEC_PER_SEC);
172
g_date_time_unref (now);
173
g_date_time_unref (now_nyc);
174
g_time_zone_unref (tz_nyc);
176
/// change the timezones!
177
clock.skewDetected.connect([this](){
178
g_main_loop_quit(loop);
180
g_idle_add ([](gpointer gs){
181
static_cast<Timezones*>(gs)->timezone.set("America/Los_Angeles");
182
return G_SOURCE_REMOVE;
184
g_main_loop_run (loop);
186
GTimeZone * tz_la = g_time_zone_new ("America/Los_Angeles");
187
GDateTime * now_la = g_date_time_new_now (tz_la);
188
now = clock.localtime();
189
EXPECT_EQ (g_date_time_get_utc_offset(now_la), g_date_time_get_utc_offset(now));
190
EXPECT_LE (abs(g_date_time_difference(now_la,now)), G_USEC_PER_SEC);
191
g_date_time_unref (now);
192
g_date_time_unref (now_la);
193
g_time_zone_unref (tz_la);
197
* Confirm that a "PrepareForSleep" event wil trigger a skew event
199
TEST_F (ClockFixture, SleepTriggersSkew)
201
std::shared_ptr<Timezones> zones (new Timezones);
202
zones->timezone.set("America/New_York");
203
LiveClock clock (zones);
204
wait_msec (500); // wait for the bus to set up
207
clock.skewDetected.connect([&skewed, this](){
209
g_main_loop_quit(loop);
210
return G_SOURCE_REMOVE;
213
g_idle_add ([](gpointer gself){
214
static_cast<ClockFixture*>(gself)->emitPrepareForSleep();
215
return G_SOURCE_REMOVE;
223
* Confirm that normal time passing doesn't trigger a skew event.
224
* that idling changing the clock's time triggers a skew event
226
TEST_F (ClockFixture, IdleDoesNotTriggerSkew)
228
std::shared_ptr<Timezones> zones (new Timezones);
229
zones->timezone.set("America/New_York");
230
LiveClock clock (zones);
231
wait_msec (500); // wait for the bus to set up
234
clock.skewDetected.connect([&skewed](){
237
return G_SOURCE_REMOVE;
240
const unsigned int intervalSec = 4;
241
clock.skewTestIntervalSec.set(intervalSec);
242
wait_msec (intervalSec * 2.5 * 1000);
243
EXPECT_FALSE (skewed);