~unity8-desktop-session-team/indicator-session/indicator-session-using-upstart

« back to all changes in this revision

Viewing changes to tests/backend-dbus/test-users.cc

  • Committer: Charles Kerr
  • Date: 2012-07-06 20:11:40 UTC
  • Revision ID: charles.kerr@canonical.com-20120706201140-q0n8a8jo68dpsmwu
if tests aren't explicitly requested, don't fail the build if dbus-test-runner isn't installed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2013 Canonical Ltd.
3
 
 *
4
 
 * Authors:
5
 
 *   Charles Kerr <charles.kerr@canonical.com>
6
 
 *
7
 
 * This program is free software: you can redistribute it and/or modify it
8
 
 * under the terms of the GNU General Public License version 3, as published
9
 
 * by the Free Software Foundation.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful, but
12
 
 * WITHOUT ANY WARRANTY; without even the implied warranties of
13
 
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14
 
 * PURPOSE.  See the GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License along
17
 
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
 */
19
 
 
20
 
#include "gtest-mock-dbus-fixture.h"
21
 
 
22
 
#include "backend.h"
23
 
#include "backend-dbus/backend-dbus.h"
24
 
 
25
 
/***
26
 
****
27
 
***/
28
 
 
29
 
class Users: public GTestMockDBusFixture
30
 
{
31
 
  private:
32
 
 
33
 
    typedef GTestMockDBusFixture super;
34
 
 
35
 
  protected:
36
 
 
37
 
    GCancellable * cancellable;
38
 
    IndicatorSessionUsers * users;
39
 
 
40
 
    virtual void SetUp ()
41
 
    {
42
 
      super :: SetUp ();
43
 
 
44
 
      init_event_keys (0);
45
 
 
46
 
      // init 'users'
47
 
      cancellable = g_cancellable_new ();
48
 
      users = 0;
49
 
      backend_get (cancellable, NULL, &users, NULL);
50
 
      g_assert (users != 0);
51
 
 
52
 
      // wait for the users added by GTestMockDBusFixture::SetUp() to show up
53
 
      wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED, 12);
54
 
      init_event_keys (0);
55
 
    }
56
 
 
57
 
    virtual void TearDown ()
58
 
    {
59
 
      g_cancellable_cancel (cancellable);
60
 
      g_clear_object (&cancellable);
61
 
      g_clear_object (&users);
62
 
 
63
 
      super :: TearDown ();
64
 
    }
65
 
 
66
 
  protected:
67
 
 
68
 
    void compare_user (const MockUser * mu, const IndicatorSessionUser * isu, const std::string& user_state)
69
 
    {
70
 
      ASSERT_EQ (user_state, login1_seat->user_state (mu->uid()));
71
 
      ASSERT_EQ (mu->uid(), isu->uid);
72
 
      ASSERT_EQ (mu->login_frequency(), isu->login_frequency);
73
 
      ASSERT_STREQ (mu->username(), isu->user_name);
74
 
      ASSERT_STREQ (mu->realname(), isu->real_name);
75
 
      ASSERT_EQ (mu->uid(), isu->uid);
76
 
      ASSERT_EQ (user_state!="offline", isu->is_logged_in);
77
 
      ASSERT_EQ (user_state=="active", isu->is_current_user);
78
 
    }
79
 
 
80
 
    void compare_user (const MockUser * mu, guint uid, const std::string& user_state)
81
 
    {
82
 
      IndicatorSessionUser * isu;
83
 
      isu = indicator_session_users_get_user (users, uid);
84
 
      compare_user (mu, isu, user_state);
85
 
      indicator_session_user_free (isu);
86
 
    }
87
 
 
88
 
    void compare_user (guint uid, const std::string& user_state)
89
 
    {
90
 
      IndicatorSessionUser * isu = indicator_session_users_get_user (users, uid);
91
 
      MockUser * mu = accounts->find_by_uid (uid);
92
 
      compare_user (mu, isu, user_state);
93
 
      indicator_session_user_free (isu);
94
 
    }
95
 
 
96
 
  private:
97
 
 
98
 
    void init_event_keys (size_t n)
99
 
    {
100
 
      expected_event_count = n;
101
 
      event_keys.clear();
102
 
    }
103
 
 
104
 
    static gboolean
105
 
    wait_for_signals__timeout (gpointer name)
106
 
    {
107
 
      g_error ("%s: timed out waiting for signal '%s'", G_STRLOC, (char*)name);
108
 
      return G_SOURCE_REMOVE;
109
 
    }
110
 
 
111
 
    static void
112
 
    wait_for_signals__event (IndicatorSessionUser * u G_GNUC_UNUSED,
113
 
                             guint                  uid,
114
 
                             gpointer               gself)
115
 
    {
116
 
      Users * self = static_cast<Users*>(gself);
117
 
 
118
 
      self->event_keys.push_back (uid);
119
 
 
120
 
      if (self->event_keys.size() == self->expected_event_count)
121
 
        g_main_loop_quit (self->loop);
122
 
    }
123
 
 
124
 
  protected:
125
 
 
126
 
    std::vector<guint> event_keys;
127
 
    size_t expected_event_count;
128
 
 
129
 
    void wait_for_signals (gpointer o, const gchar * name, size_t n)
130
 
    {
131
 
      const int timeout_seconds = 5; // arbitrary
132
 
 
133
 
      init_event_keys (n);
134
 
 
135
 
      guint handler_id = g_signal_connect (o, name,
136
 
                                           G_CALLBACK(wait_for_signals__event),
137
 
                                           this);
138
 
      gulong timeout_id = g_timeout_add_seconds (timeout_seconds,
139
 
                                                 wait_for_signals__timeout,
140
 
                                                 (gpointer)name);
141
 
      g_main_loop_run (loop);
142
 
      g_source_remove (timeout_id);
143
 
      g_signal_handler_disconnect (o, handler_id);
144
 
    }
145
 
};
146
 
 
147
 
/***
148
 
****
149
 
***/
150
 
 
151
 
/**
152
 
 * Confirm that the fixture's SetUp() and TearDown() work
153
 
 */
154
 
TEST_F (Users, HelloWorld)
155
 
{
156
 
  ASSERT_TRUE (true);
157
 
}
158
 
 
159
 
/**
160
 
 * Confirm that 'users' can get the cached users from our Mock Accounts
161
 
 */
162
 
TEST_F (Users, InitialUsers)
163
 
{
164
 
  GList * l;
165
 
  GList * uids = indicator_session_users_get_uids (users);
166
 
 
167
 
  ASSERT_EQ (12, g_list_length (uids));
168
 
 
169
 
  for (l=uids; l!=NULL; l=l->next)
170
 
    {
171
 
      const guint uid = GPOINTER_TO_UINT (l->data);
172
 
      compare_user (uid, login1_seat->user_state (uid));
173
 
    }
174
 
 
175
 
  g_list_free (uids);
176
 
}
177
 
 
178
 
/**
179
 
 * Confirm that 'users' can tell when a new user is added
180
 
 */
181
 
TEST_F (Users, UserAdded)
182
 
{
183
 
  MockUser * mu;
184
 
 
185
 
  mu = new MockUser (loop, conn, "pcushing", "Peter Cushing", 2);
186
 
  accounts->add_user (mu);
187
 
  ASSERT_EQ (0, event_keys.size());
188
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED, 1);
189
 
  ASSERT_EQ (1, event_keys.size());
190
 
  compare_user (mu, event_keys[0], "offline");
191
 
}
192
 
 
193
 
/**
194
 
 * Confirm that 'users' can tell when a user is removed
195
 
 */
196
 
TEST_F (Users, UserRemoved)
197
 
{
198
 
  MockUser * mu = accounts->find_by_username ("pdavison");
199
 
 
200
 
  /* confirm that users knows about pdavison */
201
 
  IndicatorSessionUser * isu = indicator_session_users_get_user (users, mu->uid());
202
 
  ASSERT_TRUE (isu != NULL);
203
 
  compare_user (mu, isu, "offline");
204
 
  g_clear_pointer (&isu, indicator_session_user_free);
205
 
 
206
 
  /* on the bus, remove pdavison. */
207
 
  accounts->remove_user (mu);
208
 
 
209
 
  /* now, users should emit a 'user removed' signal... */
210
 
  ASSERT_EQ (0, event_keys.size());
211
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED, 1);
212
 
  ASSERT_EQ (1, event_keys.size());
213
 
 
214
 
  /* confirm that users won't give us pdavison's info */
215
 
  isu = indicator_session_users_get_user (users, mu->uid());
216
 
  ASSERT_TRUE (isu == NULL);
217
 
 
218
 
  /* confirm that users won't give us pdavison's uid */
219
 
  GList * uids = indicator_session_users_get_uids (users);
220
 
  ASSERT_TRUE (g_list_find (uids, GUINT_TO_POINTER(mu->uid())) == NULL);
221
 
  g_list_free (uids);
222
 
 
223
 
  delete mu;
224
 
}
225
 
 
226
 
/**
227
 
 * Confirm that 'users' notices when a user's real name changes
228
 
 */
229
 
TEST_F (Users, RealnameChanged)
230
 
{
231
 
  MockUser * mu;
232
 
 
233
 
  mu = accounts->find_by_username ("pdavison");
234
 
  const char * const realname = "Peter M. G. Moffett";
235
 
  mu->set_realname (realname);
236
 
  ASSERT_NE (mu->realname(), realname);
237
 
  ASSERT_STREQ (mu->realname(), realname);
238
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1);
239
 
  ASSERT_EQ (1, event_keys.size());
240
 
  compare_user (mu, event_keys[0], "offline");
241
 
}
242
 
 
243
 
/**
244
 
 * Confirm that 'users' notices when users log in and out
245
 
 */
246
 
TEST_F (Users, LogInLogOut)
247
 
{
248
 
  // The fist doctor logs in.
249
 
  // Confirm that 'users' notices.
250
 
  MockUser * mu = accounts->find_by_username ("whartnell");
251
 
  ASSERT_EQ (login1_seat->user_state (mu->uid()), "offline");
252
 
  const int session_tag = login1_manager->add_session (login1_seat, mu);
253
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1);
254
 
  ASSERT_EQ (1, event_keys.size());
255
 
  compare_user (mu, event_keys[0], "online");
256
 
 
257
 
  // The first doctor logs out.
258
 
  // Confirm that 'users' notices.
259
 
  login1_manager->remove_session (login1_seat, session_tag);
260
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1);
261
 
  ASSERT_EQ (1, event_keys.size());
262
 
  compare_user (mu, event_keys[0], "offline");
263
 
}
264
 
 
265
 
/**
266
 
 * Confirm that 'users' notices when the active session changes
267
 
 */
268
 
TEST_F (Users, ActivateSession)
269
 
{
270
 
  // confirm preconditions: msmith is active, msmith is offline
271
 
  MockUser * const whartnell = accounts->find_by_username ("whartnell");
272
 
  ASSERT_EQ (login1_seat->user_state (whartnell->uid()), "offline");
273
 
  MockUser * const msmith = accounts->find_by_username ("msmith");
274
 
  ASSERT_EQ (login1_seat->user_state (msmith->uid()), "active");
275
 
 
276
 
  // whartnell logs in... confirm that 'users' notices
277
 
  login1_manager->add_session (login1_seat, whartnell);
278
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1);
279
 
  ASSERT_EQ (1, event_keys.size());
280
 
  compare_user (whartnell, event_keys[0], "online");
281
 
 
282
 
  // activate whartnell's session... confirm that 'users' sees:
283
 
  //  1. msmith changes from 'active' to 'online'
284
 
  //  2. whartnell changes from 'online' to 'active'
285
 
  login1_seat->switch_to_user (whartnell->username());
286
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2);
287
 
  ASSERT_EQ (2, event_keys.size());
288
 
  compare_user (msmith, event_keys[0], "online");
289
 
  compare_user (whartnell, event_keys[1], "active");
290
 
 
291
 
  // reverse the test
292
 
  login1_seat->switch_to_user (msmith->username());
293
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2);
294
 
  ASSERT_EQ (2, event_keys.size());
295
 
  compare_user (whartnell, event_keys[0], "online");
296
 
  compare_user (msmith, event_keys[1], "active");
297
 
}
298
 
 
299
 
/**
300
 
 * Confirm that we can change the active session via users' API.
301
 
 * This is nearly the same as ActivateSession but uses users' API
302
 
 */
303
 
TEST_F (Users, ActivateUser)
304
 
{
305
 
  // confirm preconditions: msmith is active, msmith is offline
306
 
  MockUser * const whartnell = accounts->find_by_username ("whartnell");
307
 
  ASSERT_EQ (login1_seat->user_state (whartnell->uid()), "offline");
308
 
  MockUser * const msmith = accounts->find_by_username ("msmith");
309
 
  ASSERT_EQ (login1_seat->user_state (msmith->uid()), "active");
310
 
 
311
 
  // whartnell logs in... confirm that 'users' notices
312
 
  login1_manager->add_session (login1_seat, whartnell);
313
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1);
314
 
  ASSERT_EQ (1, event_keys.size());
315
 
  compare_user (whartnell, event_keys[0], "online");
316
 
 
317
 
  // activate whartnell's session... confirm that 'users' sees:
318
 
  //  1. msmith changes from 'active' to 'online'
319
 
  //  2. whartnell changes from 'online' to 'active'
320
 
  indicator_session_users_activate_user (users, whartnell->uid());
321
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2);
322
 
  ASSERT_EQ (2, event_keys.size());
323
 
  compare_user (msmith, event_keys[0], "online");
324
 
  compare_user (whartnell, event_keys[1], "active");
325
 
 
326
 
  // reverse the test
327
 
  indicator_session_users_activate_user (users, msmith->uid());
328
 
  wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2);
329
 
  ASSERT_EQ (2, event_keys.size());
330
 
  compare_user (whartnell, event_keys[0], "online");
331
 
  compare_user (msmith, event_keys[1], "active");
332
 
}
333
 
 
334
 
/**
335
 
 * Confirm that adding a Guest doesn't show up in the users list
336
 
 */
337
 
TEST_F (Users, UnwantedGuest)
338
 
{
339
 
  GList * uids;
340
 
 
341
 
  uids = indicator_session_users_get_uids (users);
342
 
  const size_t n = g_list_length (uids);
343
 
  g_list_free (uids);
344
 
 
345
 
  MockUser * mu = new MockUser (loop, conn, "guest-jjbEVV", "Guest", 1);
346
 
  mu->set_system_account (true);
347
 
  accounts->add_user (mu);
348
 
  wait_msec (50);
349
 
 
350
 
  uids = indicator_session_users_get_uids (users);
351
 
  ASSERT_EQ (n, g_list_length (uids));
352
 
  g_list_free (uids);
353
 
}
354
 
 
355
 
 
356
 
/**
357
 
 * Confirm that we can detect live sessions
358
 
 */
359
 
TEST_F (Users, LiveSession)
360
 
{
361
 
  gboolean b;
362
 
 
363
 
  // not initially a live session
364
 
  ASSERT_FALSE (indicator_session_users_is_live_session (users));
365
 
  g_object_get (users, INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION, &b, NULL);
366
 
  ASSERT_FALSE (b);
367
 
 
368
 
  // now add the criteria for a live session
369
 
  MockUser * live_user = new MockUser (loop, conn, "ubuntu", "Ubuntu", 1, 999);
370
 
  live_user->set_system_account (true);
371
 
  accounts->add_user (live_user);
372
 
  const int session_tag = login1_manager->add_session (login1_seat, live_user);
373
 
  wait_msec (100);
374
 
  login1_seat->activate_session (session_tag);
375
 
  wait_for_signal (users, "notify::" INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION);
376
 
 
377
 
  // confirm the backend thinks it's a live session
378
 
  ASSERT_TRUE (indicator_session_users_is_live_session (users));
379
 
  g_object_get (users, INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION, &b, NULL);
380
 
  ASSERT_TRUE (b);
381
 
}