~xavi-garcia-mena/keeper/restore

« back to all changes in this revision

Viewing changes to tests/helper/helpers-test.cc

  • Committer: Xavi Garcia Mena
  • Date: 2016-06-08 13:02:53 UTC
  • mto: This revision was merged to the branch mainline in revision 27.
  • Revision ID: xavi.garcia.mena@canonical.com-20160608130253-u1p41zp1u4vgdis3
Preliminar version with fixed backup helper and unit tests for the backup helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2013-2016 Canonical Ltd.
 
3
 *
 
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.
 
7
 *
 
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.
 
12
 *
 
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/>.
 
15
 *
 
16
 * Authors:
 
17
 *     Ted Gould <ted.gould@canonical.com>
 
18
 *     Xavi Garcia <xavi.garcia.mena@gmail.com>
 
19
 */
 
20
 
 
21
#include <future>
 
22
#include <thread>
 
23
 
 
24
#include <QCoreApplication>
 
25
#include <QSignalSpy>
 
26
 
 
27
#include <gtest/gtest.h>
 
28
#include <gio/gio.h>
 
29
#include <ubuntu-app-launch/registry.h>
 
30
#include <libdbustest/dbus-test.h>
 
31
 
 
32
#include "mir-mock.h"
 
33
#include <helper/backup-helper.h>
 
34
 
 
35
 
 
36
 
 
37
extern "C" {
 
38
    #include <ubuntu-app-launch.h>
 
39
    #include <fcntl.h>
 
40
}
 
41
 
 
42
class LibUAL : public ::testing::Test
 
43
{
 
44
protected:
 
45
    DbusTestService* service = NULL;
 
46
    DbusTestDbusMock* mock = NULL;
 
47
    DbusTestDbusMock* cgmock = NULL;
 
48
    GDBusConnection* bus = NULL;
 
49
    std::string last_focus_appid;
 
50
    std::string last_resume_appid;
 
51
    guint resume_timeout = 0;
 
52
    std::shared_ptr<ubuntu::app_launch::Registry> registry;
 
53
 
 
54
private:
 
55
    static void focus_cb(const gchar* appid, gpointer user_data)
 
56
    {
 
57
        g_debug("Focus Callback: %s", appid);
 
58
        LibUAL* _this = static_cast<LibUAL*>(user_data);
 
59
        _this->last_focus_appid = appid;
 
60
    }
 
61
 
 
62
    static void resume_cb(const gchar* appid, gpointer user_data)
 
63
    {
 
64
        g_debug("Resume Callback: %s", appid);
 
65
        LibUAL* _this = static_cast<LibUAL*>(user_data);
 
66
        _this->last_resume_appid = appid;
 
67
 
 
68
        if (_this->resume_timeout > 0)
 
69
        {
 
70
            _this->pause(_this->resume_timeout);
 
71
        }
 
72
    }
 
73
 
 
74
protected:
 
75
    /* Useful debugging stuff, but not on by default.  You really want to
 
76
       not get all this noise typically */
 
77
    void debugConnection()
 
78
    {
 
79
        if (true)
 
80
        {
 
81
            return;
 
82
        }
 
83
 
 
84
        DbusTestBustle* bustle = dbus_test_bustle_new("test.bustle");
 
85
        dbus_test_service_add_task(service, DBUS_TEST_TASK(bustle));
 
86
        g_object_unref(bustle);
 
87
 
 
88
        DbusTestProcess* monitor = dbus_test_process_new("dbus-monitor");
 
89
        dbus_test_service_add_task(service, DBUS_TEST_TASK(monitor));
 
90
        g_object_unref(monitor);
 
91
    }
 
92
 
 
93
    virtual void SetUp()
 
94
    {
 
95
        /* Click DB test mode */
 
96
        g_setenv("TEST_CLICK_DB", "click-db-dir", TRUE);
 
97
        g_setenv("TEST_CLICK_USER", "test-user", TRUE);
 
98
 
 
99
        gchar* linkfarmpath = g_build_filename(CMAKE_SOURCE_DIR, "link-farm", NULL);
 
100
        g_setenv("UBUNTU_APP_LAUNCH_LINK_FARM", linkfarmpath, TRUE);
 
101
        g_free(linkfarmpath);
 
102
 
 
103
        g_setenv("XDG_DATA_DIRS", CMAKE_SOURCE_DIR, TRUE);
 
104
        g_setenv("XDG_CACHE_HOME", CMAKE_SOURCE_DIR "/libertine-data", TRUE);
 
105
        g_setenv("XDG_DATA_HOME", CMAKE_SOURCE_DIR "/libertine-home", TRUE);
 
106
 
 
107
        service = dbus_test_service_new(NULL);
 
108
 
 
109
        debugConnection();
 
110
 
 
111
        mock = dbus_test_dbus_mock_new("com.ubuntu.Upstart");
 
112
 
 
113
        DbusTestDbusMockObject* obj =
 
114
            dbus_test_dbus_mock_get_object(mock, "/com/ubuntu/Upstart", "com.ubuntu.Upstart0_6", NULL);
 
115
 
 
116
        dbus_test_dbus_mock_object_add_method(mock, obj, "EmitEvent", G_VARIANT_TYPE("(sasb)"), NULL, "", NULL);
 
117
 
 
118
        dbus_test_dbus_mock_object_add_method(mock, obj, "GetJobByName", G_VARIANT_TYPE("s"), G_VARIANT_TYPE("o"),
 
119
                                              "if args[0] == 'application-click':\n"
 
120
                                              " ret = dbus.ObjectPath('/com/test/application_click')\n"
 
121
                                              "elif args[0] == 'application-legacy':\n"
 
122
                                              " ret = dbus.ObjectPath('/com/test/application_legacy')\n"
 
123
                                              "elif args[0] == 'untrusted-helper':\n"
 
124
                                              " ret = dbus.ObjectPath('/com/test/untrusted/helper')\n",
 
125
                                              NULL);
 
126
 
 
127
        dbus_test_dbus_mock_object_add_method(mock, obj, "SetEnv", G_VARIANT_TYPE("(assb)"), NULL, "", NULL);
 
128
 
 
129
        /* Click App */
 
130
        DbusTestDbusMockObject* jobobj =
 
131
            dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL);
 
132
 
 
133
        dbus_test_dbus_mock_object_add_method(
 
134
            mock, jobobj, "Start", G_VARIANT_TYPE("(asb)"), NULL,
 
135
            "if args[0][0] == 'APP_ID=com.test.good_application_1.2.3':"
 
136
            "    raise dbus.exceptions.DBusException('Foo running', name='com.ubuntu.Upstart0_6.Error.AlreadyStarted')",
 
137
            NULL);
 
138
 
 
139
        dbus_test_dbus_mock_object_add_method(mock, jobobj, "Stop", G_VARIANT_TYPE("(asb)"), NULL, "", NULL);
 
140
 
 
141
        dbus_test_dbus_mock_object_add_method(mock, jobobj, "GetAllInstances", NULL, G_VARIANT_TYPE("ao"),
 
142
                                              "ret = [ dbus.ObjectPath('/com/test/app_instance') ]", NULL);
 
143
 
 
144
        DbusTestDbusMockObject* instobj =
 
145
            dbus_test_dbus_mock_get_object(mock, "/com/test/app_instance", "com.ubuntu.Upstart0_6.Instance", NULL);
 
146
        dbus_test_dbus_mock_object_add_property(mock, instobj, "name", G_VARIANT_TYPE_STRING,
 
147
                                                g_variant_new_string("com.test.good_application_1.2.3"), NULL);
 
148
        gchar* process_var = g_strdup_printf("[('main', %d)]", getpid());
 
149
        dbus_test_dbus_mock_object_add_property(mock, instobj, "processes", G_VARIANT_TYPE("a(si)"),
 
150
                                                g_variant_new_parsed(process_var), NULL);
 
151
        g_free(process_var);
 
152
 
 
153
        /*  Legacy App */
 
154
        DbusTestDbusMockObject* ljobobj =
 
155
            dbus_test_dbus_mock_get_object(mock, "/com/test/application_legacy", "com.ubuntu.Upstart0_6.Job", NULL);
 
156
 
 
157
        dbus_test_dbus_mock_object_add_method(mock, ljobobj, "Start", G_VARIANT_TYPE("(asb)"), NULL, "", NULL);
 
158
 
 
159
        dbus_test_dbus_mock_object_add_method(mock, ljobobj, "Stop", G_VARIANT_TYPE("(asb)"), NULL, "", NULL);
 
160
 
 
161
        dbus_test_dbus_mock_object_add_method(mock, ljobobj, "GetAllInstances", NULL, G_VARIANT_TYPE("ao"),
 
162
                                              "ret = [ dbus.ObjectPath('/com/test/legacy_app_instance') ]", NULL);
 
163
 
 
164
        DbusTestDbusMockObject* linstobj = dbus_test_dbus_mock_get_object(mock, "/com/test/legacy_app_instance",
 
165
                                                                          "com.ubuntu.Upstart0_6.Instance", NULL);
 
166
        dbus_test_dbus_mock_object_add_property(mock, linstobj, "name", G_VARIANT_TYPE_STRING,
 
167
                                                g_variant_new_string("multiple-2342345"), NULL);
 
168
        dbus_test_dbus_mock_object_add_property(mock, linstobj, "processes", G_VARIANT_TYPE("a(si)"),
 
169
                                                g_variant_new_parsed("[('main', 5678)]"), NULL);
 
170
 
 
171
        /*  Untrusted Helper */
 
172
        DbusTestDbusMockObject* uhelperobj =
 
173
            dbus_test_dbus_mock_get_object(mock, "/com/test/untrusted/helper", "com.ubuntu.Upstart0_6.Job", NULL);
 
174
 
 
175
        dbus_test_dbus_mock_object_add_method(mock, uhelperobj, "Start", G_VARIANT_TYPE("(asb)"), NULL,
 
176
                            "import os\n"
 
177
                            "import sys\n"
 
178
                            "import subprocess\n"
 
179
                            "target = open(\"/tmp/testHelper\", 'w')\n"
 
180
                            "exec_app=\"\"\n"
 
181
                            "for item in args[0]:\n"
 
182
                            "    keyVal = str(item)\n"
 
183
                            "    keyVal = keyVal.split(\"=\")\n"
 
184
                            "    if len(keyVal) == 2:\n"
 
185
                            "        os.environ[keyVal[0]] = keyVal[1]\n"
 
186
                            "        if keyVal[0] == \"APP_URIS\":\n"
 
187
                            "            exec_app = keyVal[1].replace(\"'\", '')\n"
 
188
                            "if (exec_app != \"\"):\n"
 
189
                            "    proc = subprocess.Popen(exec_app, shell=True, stdout=subprocess.PIPE)\n"
 
190
                            "target.close\n"
 
191
                            , NULL);
 
192
 
 
193
 
 
194
 
 
195
        dbus_test_dbus_mock_object_add_method(mock, uhelperobj, "Stop", G_VARIANT_TYPE("(asb)"), NULL, "", NULL);
 
196
 
 
197
        dbus_test_dbus_mock_object_add_method(mock, uhelperobj, "GetAllInstances", NULL, G_VARIANT_TYPE("ao"),
 
198
                                              "ret = [ dbus.ObjectPath('/com/test/untrusted/helper/instance'), "
 
199
                                              "dbus.ObjectPath('/com/test/untrusted/helper/multi_instance') ]",
 
200
                                              NULL);
 
201
 
 
202
        DbusTestDbusMockObject* uhelperinstance = dbus_test_dbus_mock_get_object(
 
203
            mock, "/com/test/untrusted/helper/instance", "com.ubuntu.Upstart0_6.Instance", NULL);
 
204
        dbus_test_dbus_mock_object_add_property(mock, uhelperinstance, "name", G_VARIANT_TYPE_STRING,
 
205
                                                g_variant_new_string("untrusted-type::com.foo_bar_43.23.12"), NULL);
 
206
 
 
207
        DbusTestDbusMockObject* unhelpermulti = dbus_test_dbus_mock_get_object(
 
208
            mock, "/com/test/untrusted/helper/multi_instance", "com.ubuntu.Upstart0_6.Instance", NULL);
 
209
        dbus_test_dbus_mock_object_add_property(
 
210
            mock, unhelpermulti, "name", G_VARIANT_TYPE_STRING,
 
211
            g_variant_new_string("backup-helper:24034582324132:com.bar_foo_8432.13.1"), NULL);
 
212
 
 
213
        /* Create the cgroup manager mock */
 
214
        cgmock = dbus_test_dbus_mock_new("org.test.cgmock");
 
215
        g_setenv("UBUNTU_APP_LAUNCH_CG_MANAGER_NAME", "org.test.cgmock", TRUE);
 
216
 
 
217
        DbusTestDbusMockObject* cgobject = dbus_test_dbus_mock_get_object(cgmock, "/org/linuxcontainers/cgmanager",
 
218
                                                                          "org.linuxcontainers.cgmanager0_0", NULL);
 
219
        dbus_test_dbus_mock_object_add_method(cgmock, cgobject, "GetTasksRecursive", G_VARIANT_TYPE("(ss)"),
 
220
                                              G_VARIANT_TYPE("ai"), "ret = [100, 200, 300]", NULL);
 
221
 
 
222
        /* Put it together */
 
223
        dbus_test_service_add_task(service, DBUS_TEST_TASK(mock));
 
224
        dbus_test_service_add_task(service, DBUS_TEST_TASK(cgmock));
 
225
        dbus_test_service_start_tasks(service);
 
226
 
 
227
        bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
 
228
        g_dbus_connection_set_exit_on_close(bus, FALSE);
 
229
        g_object_add_weak_pointer(G_OBJECT(bus), (gpointer*)&bus);
 
230
 
 
231
        /* Make sure we pretend the CG manager is just on our bus */
 
232
        g_setenv("UBUNTU_APP_LAUNCH_CG_MANAGER_SESSION_BUS", "YES", TRUE);
 
233
 
 
234
        ASSERT_TRUE(ubuntu_app_launch_observer_add_app_focus(focus_cb, this));
 
235
        ASSERT_TRUE(ubuntu_app_launch_observer_add_app_resume(resume_cb, this));
 
236
 
 
237
        registry = std::make_shared<ubuntu::app_launch::Registry>();
 
238
    }
 
239
 
 
240
    virtual void TearDown()
 
241
    {
 
242
        registry.reset();
 
243
 
 
244
        ubuntu_app_launch_observer_delete_app_focus(focus_cb, this);
 
245
        ubuntu_app_launch_observer_delete_app_resume(resume_cb, this);
 
246
 
 
247
        g_clear_object(&mock);
 
248
        g_clear_object(&cgmock);
 
249
        g_clear_object(&service);
 
250
 
 
251
        g_object_unref(bus);
 
252
 
 
253
        unsigned int cleartry = 0;
 
254
        while (bus != NULL && cleartry < 100)
 
255
        {
 
256
            pause(100);
 
257
            cleartry++;
 
258
        }
 
259
        ASSERT_EQ(nullptr, bus);
 
260
    }
 
261
 
 
262
    GVariant* find_env(GVariant* env_array, const gchar* var)
 
263
    {
 
264
        unsigned int i;
 
265
        GVariant* retval = nullptr;
 
266
 
 
267
        for (i = 0; i < g_variant_n_children(env_array); i++)
 
268
        {
 
269
            GVariant* child = g_variant_get_child_value(env_array, i);
 
270
            const gchar* envvar = g_variant_get_string(child, nullptr);
 
271
 
 
272
            if (g_str_has_prefix(envvar, var))
 
273
            {
 
274
                if (retval != nullptr)
 
275
                {
 
276
                    g_warning("Found the env var more than once!");
 
277
                    g_variant_unref(retval);
 
278
                    return nullptr;
 
279
                }
 
280
 
 
281
                retval = child;
 
282
            }
 
283
            else
 
284
            {
 
285
                g_variant_unref(child);
 
286
            }
 
287
        }
 
288
 
 
289
        if (!retval)
 
290
        {
 
291
            gchar* envstr = g_variant_print(env_array, FALSE);
 
292
            g_warning("Unable to find '%s' in '%s'", var, envstr);
 
293
            g_free(envstr);
 
294
        }
 
295
 
 
296
        return retval;
 
297
    }
 
298
 
 
299
    bool check_env(GVariant* env_array, const gchar* var, const gchar* value)
 
300
    {
 
301
        bool found = false;
 
302
        GVariant* val = find_env(env_array, var);
 
303
        if (val == nullptr)
 
304
        {
 
305
            return false;
 
306
        }
 
307
 
 
308
        const gchar* envvar = g_variant_get_string(val, nullptr);
 
309
 
 
310
        gchar* combined = g_strdup_printf("%s=%s", var, value);
 
311
        if (g_strcmp0(envvar, combined) == 0)
 
312
        {
 
313
            found = true;
 
314
        }
 
315
 
 
316
        g_variant_unref(val);
 
317
 
 
318
        return found;
 
319
    }
 
320
 
 
321
    void pause(guint time = 0)
 
322
    {
 
323
        if (time > 0)
 
324
        {
 
325
            GMainLoop* mainloop = g_main_loop_new(NULL, FALSE);
 
326
 
 
327
            g_timeout_add(time,
 
328
                          [](gpointer pmainloop) -> gboolean
 
329
                          {
 
330
                              g_main_loop_quit(static_cast<GMainLoop*>(pmainloop));
 
331
                              return G_SOURCE_REMOVE;
 
332
                          },
 
333
                          mainloop);
 
334
 
 
335
            g_main_loop_run(mainloop);
 
336
 
 
337
            g_main_loop_unref(mainloop);
 
338
        }
 
339
 
 
340
        while (g_main_pending())
 
341
        {
 
342
            g_main_iteration(TRUE);
 
343
        }
 
344
    }
 
345
};
 
346
 
 
347
TEST_F(LibUAL, StartHelper)
 
348
{
 
349
    DbusTestDbusMockObject* obj =
 
350
        dbus_test_dbus_mock_get_object(mock, "/com/test/untrusted/helper", "com.ubuntu.Upstart0_6.Job", NULL);
 
351
 
 
352
    BackupHelper helper("com.test.multiple_first_1.2.3");
 
353
 
 
354
    QSignalSpy spy(&helper, &BackupHelper::started);
 
355
 
 
356
    helper.start(1999);
 
357
 
 
358
    guint len = 0;
 
359
    auto calls = dbus_test_dbus_mock_object_get_method_calls(mock, obj, "Start", &len, NULL);
 
360
    EXPECT_NE(nullptr, calls);
 
361
    EXPECT_EQ(1, len);
 
362
 
 
363
    auto env = g_variant_get_child_value(calls->params, 0);
 
364
    EXPECT_TRUE(check_env(env, "APP_ID", "com.test.multiple_first_1.2.3"));
 
365
    EXPECT_TRUE(
 
366
        check_env(env, "APP_URIS", "'/tmp/test2.py' '1999'"));
 
367
    EXPECT_TRUE(check_env(env, "HELPER_TYPE", "backup-helper"));
 
368
    EXPECT_FALSE(check_env(env, "INSTANCE_ID", NULL));
 
369
    g_variant_unref(env);
 
370
 
 
371
    DbusTestDbusMockObject* objUpstart =
 
372
        dbus_test_dbus_mock_get_object(mock, "/com/ubuntu/Upstart", "com.ubuntu.Upstart0_6", NULL);
 
373
 
 
374
    /* Basic start */
 
375
    dbus_test_dbus_mock_object_emit_signal(
 
376
        mock, objUpstart, "EventEmitted", G_VARIANT_TYPE("(sas)"),
 
377
        g_variant_new_parsed("('started', ['JOB=untrusted-helper', 'INSTANCE=backup-helper::com.test.multiple_first_1.2.3'])"),
 
378
        NULL);
 
379
 
 
380
    // we set a timeout of 5 seconds waiting for the signal to be emitted,
 
381
    // which should never be reached
 
382
    ASSERT_TRUE(spy.wait(5000));
 
383
 
 
384
    // check that we've got exactly one signal
 
385
    ASSERT_EQ(spy.count(), 1);
 
386
 
 
387
    g_usleep(100000);
 
388
    while (g_main_pending())
 
389
    {
 
390
        g_main_iteration(TRUE);
 
391
    }
 
392
 
 
393
    helper.stop();
 
394
    return;
 
395
}
 
396
 
 
397
TEST_F(LibUAL, StopHelper)
 
398
{
 
399
    DbusTestDbusMockObject* obj =
 
400
        dbus_test_dbus_mock_get_object(mock, "/com/test/untrusted/helper", "com.ubuntu.Upstart0_6.Job", NULL);
 
401
 
 
402
    BackupHelper helper("com.bar_foo_8432.13.1");
 
403
    QSignalSpy spy(&helper, &BackupHelper::finished);
 
404
 
 
405
    helper.stop();
 
406
    ASSERT_EQ(dbus_test_dbus_mock_object_check_method_call(mock, obj, "Stop", NULL, NULL), 1);
 
407
 
 
408
    guint len = 0;
 
409
    auto calls = dbus_test_dbus_mock_object_get_method_calls(mock, obj, "Stop", &len, NULL);
 
410
    EXPECT_NE(nullptr, calls);
 
411
    EXPECT_EQ(1, len);
 
412
 
 
413
    EXPECT_STREQ("Stop", calls->name);
 
414
    EXPECT_EQ(2, g_variant_n_children(calls->params));
 
415
 
 
416
    auto block = g_variant_get_child_value(calls->params, 1);
 
417
    EXPECT_TRUE(g_variant_get_boolean(block));
 
418
    g_variant_unref(block);
 
419
 
 
420
    auto env = g_variant_get_child_value(calls->params, 0);
 
421
    EXPECT_TRUE(check_env(env, "APP_ID", "com.bar_foo_8432.13.1"));
 
422
    EXPECT_TRUE(check_env(env, "HELPER_TYPE", "backup-helper"));
 
423
    EXPECT_TRUE(check_env(env, "INSTANCE_ID", "24034582324132"));
 
424
    g_variant_unref(env);
 
425
 
 
426
    ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(mock, obj, NULL));
 
427
 
 
428
    DbusTestDbusMockObject* objUpstart =
 
429
        dbus_test_dbus_mock_get_object(mock, "/com/ubuntu/Upstart", "com.ubuntu.Upstart0_6", NULL);
 
430
 
 
431
    dbus_test_dbus_mock_object_emit_signal(
 
432
        mock, objUpstart, "EventEmitted", G_VARIANT_TYPE("(sas)"),
 
433
        g_variant_new_parsed(
 
434
            "('stopped', ['JOB=untrusted-helper', 'INSTANCE=backup-helper::com.bar_foo_8432.13.1'])"),
 
435
        NULL);
 
436
 
 
437
    // we set a timeout of 5 seconds waiting for the signal to be emitted,
 
438
    // which should never be reached
 
439
    ASSERT_TRUE(spy.wait(5000));
 
440
 
 
441
    // check that we've got exactly one signal
 
442
    ASSERT_EQ(spy.count(), 1);
 
443
 
 
444
    g_usleep(100000);
 
445
    while (g_main_pending())
 
446
    {
 
447
        g_main_iteration(TRUE);
 
448
    }
 
449
 
 
450
//    ASSERT_EQ(stop_data.count, 1);
 
451
 
 
452
    return;
 
453
}
 
454
 
 
455
typedef struct
 
456
{
 
457
    unsigned int count;
 
458
    const gchar* appid;
 
459
    const gchar* type;
 
460
    const gchar* instance;
 
461
} helper_observer_data_t;
 
462
 
 
463
static void helper_observer_cb(const gchar* appid, const gchar* instance, const gchar* type, gpointer user_data)
 
464
{
 
465
    helper_observer_data_t* data = (helper_observer_data_t*)user_data;
 
466
 
 
467
    if (g_strcmp0(data->appid, appid) == 0 && g_strcmp0(data->type, type) == 0 &&
 
468
        g_strcmp0(data->instance, instance) == 0)
 
469
    {
 
470
        data->count++;
 
471
    }
 
472
}
 
473
 
 
474
TEST_F(LibUAL, StartStopHelperObserver)
 
475
{
 
476
    helper_observer_data_t start_data = {
 
477
        .count = 0, .appid = "com.foo_foo_1.2.3", .type = "my-type-is-scorpio", .instance = nullptr};
 
478
    helper_observer_data_t stop_data = {
 
479
        .count = 0, .appid = "com.bar_bar_44.32", .type = "my-type-is-libra", .instance = "1234"};
 
480
 
 
481
    ASSERT_TRUE(ubuntu_app_launch_observer_add_helper_started(helper_observer_cb, "my-type-is-scorpio", &start_data));
 
482
    ASSERT_TRUE(ubuntu_app_launch_observer_add_helper_stop(helper_observer_cb, "my-type-is-libra", &stop_data));
 
483
 
 
484
    DbusTestDbusMockObject* obj =
 
485
        dbus_test_dbus_mock_get_object(mock, "/com/ubuntu/Upstart", "com.ubuntu.Upstart0_6", NULL);
 
486
 
 
487
    /* Basic start */
 
488
    dbus_test_dbus_mock_object_emit_signal(
 
489
        mock, obj, "EventEmitted", G_VARIANT_TYPE("(sas)"),
 
490
        g_variant_new_parsed("('started', ['JOB=untrusted-helper', 'INSTANCE=my-type-is-scorpio::com.foo_foo_1.2.3'])"),
 
491
        NULL);
 
492
 
 
493
    g_usleep(100000);
 
494
    while (g_main_pending())
 
495
    {
 
496
        g_main_iteration(TRUE);
 
497
    }
 
498
 
 
499
    ASSERT_EQ(start_data.count, 1);
 
500
 
 
501
    /* Basic stop */
 
502
    dbus_test_dbus_mock_object_emit_signal(
 
503
        mock, obj, "EventEmitted", G_VARIANT_TYPE("(sas)"),
 
504
        g_variant_new_parsed(
 
505
            "('stopped', ['JOB=untrusted-helper', 'INSTANCE=my-type-is-libra:1234:com.bar_bar_44.32'])"),
 
506
        NULL);
 
507
 
 
508
    g_usleep(100000);
 
509
    while (g_main_pending())
 
510
    {
 
511
        g_main_iteration(TRUE);
 
512
    }
 
513
 
 
514
    ASSERT_EQ(stop_data.count, 1);
 
515
 
 
516
 
 
517
    /* Remove */
 
518
    ASSERT_TRUE(
 
519
        ubuntu_app_launch_observer_delete_helper_started(helper_observer_cb, "my-type-is-scorpio", &start_data));
 
520
    ASSERT_TRUE(ubuntu_app_launch_observer_delete_helper_stop(helper_observer_cb, "my-type-is-libra", &stop_data));
 
521
}
 
522
 
 
523
int main(int argc, char** argv)
 
524
{
 
525
    QCoreApplication qt_app(argc, argv);
 
526
    ::testing::InitGoogleTest(&argc, argv);
 
527
    return RUN_ALL_TESTS();
 
528
}