Merge lp:~ted/ubuntu-app-launch/second-exec-test into lp:ubuntu-app-launch/13.10

Proposed by Ted Gould
Status: Merged
Approved by: Charles Kerr
Approved revision: 107
Merged at revision: 71
Proposed branch: lp:~ted/ubuntu-app-launch/second-exec-test
Merge into: lp:ubuntu-app-launch/13.10
Prerequisite: lp:~ted/ubuntu-app-launch/window-focus-request
Diff against target: 453 lines (+353/-12)
8 files modified
CMakeLists.txt (+1/-1)
second-exec-core.c (+9/-11)
second-exec-core.h (+24/-0)
second-exec.c (+38/-0)
tests/CMakeLists.txt (+13/-0)
tests/second-exec-test.cc (+211/-0)
tests/upstart-app-launch-mock.c (+39/-0)
tests/upstart-app-launch-mock.h (+18/-0)
To merge this branch: bzr merge lp:~ted/ubuntu-app-launch/second-exec-test
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+188122@code.launchpad.net

Commit message

Testing of the second exec logic.

Description of the change

Testing of the second exec logic.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

Looks very good! I only have a couple of trivial issues.

- if you're going to init resume_timeout to 0 in its declaration, you need to pass -std=c++11 to gcc

- last_resume_appid and last_focus_appid are leaked when the test ends -- a std::string might be better here

Revision history for this message
Ted Gould (ted) wrote :

On Mon, 2013-09-30 at 16:57 +0000, Charles Kerr wrote:

> - if you're going to init resume_timeout to 0 in its declaration, you need to pass -std=c++11 to gcc

Fixed r106.

> - last_resume_appid and last_focus_appid are leaked when the test ends -- a std::string might be better here

Fixed r107.

106. By Ted Gould

Update the C++ standard to allow initializing variables

107. By Ted Gould

Switch to std::string to get a free destructor

Revision history for this message
Charles Kerr (charlesk) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-09-26 21:27:06 +0000
3+++ CMakeLists.txt 2013-09-30 17:16:20 +0000
4@@ -161,7 +161,7 @@
5 # second-exec
6 #######################
7
8-add_executable(second-exec second-exec.c)
9+add_executable(second-exec second-exec.c second-exec-core.c second-exec-core.h)
10 set_target_properties(second-exec PROPERTIES OUTPUT_NAME "second-exec")
11 target_link_libraries(second-exec helpers upstart-launcher)
12 install(TARGETS second-exec RUNTIME DESTINATION "${pkglibexecdir}")
13
14=== renamed file 'second-exec.c' => 'second-exec-core.c'
15--- second-exec.c 2013-09-27 14:11:43 +0000
16+++ second-exec-core.c 2013-09-30 17:16:20 +0000
17@@ -22,6 +22,7 @@
18 #include <libnih-dbus.h>
19 #include "libupstart-app-launch/upstart-app-launch.h"
20 #include "helpers.h"
21+#include "second-exec-core.h"
22
23 /* Globals */
24 GPid app_pid = 0;
25@@ -301,16 +302,11 @@
26 return;
27 }
28
29-int
30-main (int argc, char * argv[])
31+gboolean
32+second_exec (const gchar * app_id, const gchar * appuris)
33 {
34- if (argc != 1) {
35- g_error("Should be called as: %s", argv[0]);
36- return 1;
37- }
38-
39- appid = g_getenv("APP_ID");
40- input_uris = g_getenv("APP_URIS");
41+ appid = app_id;
42+ input_uris = appuris;
43
44 /* DBus tell us! */
45 GError * error = NULL;
46@@ -318,7 +314,7 @@
47 if (error != NULL) {
48 g_error("Unable to get session bus");
49 g_error_free(error);
50- return 1;
51+ return FALSE;
52 }
53
54 /* Allocate main loop */
55@@ -390,6 +386,7 @@
56 /* Clean up */
57 if (app_data != NULL) {
58 g_variant_unref(app_data);
59+ app_data = NULL;
60 }
61
62 g_main_loop_unref(mainloop);
63@@ -397,7 +394,8 @@
64
65 if (dbus_path != NULL) {
66 nih_free(dbus_path);
67+ dbus_path = NULL;
68 }
69
70- return 0;
71+ return TRUE;
72 }
73
74=== added file 'second-exec-core.h'
75--- second-exec-core.h 1970-01-01 00:00:00 +0000
76+++ second-exec-core.h 2013-09-30 17:16:20 +0000
77@@ -0,0 +1,24 @@
78+
79+/*
80+ * Copyright 2013 Canonical Ltd.
81+ *
82+ * This program is free software: you can redistribute it and/or modify it
83+ * under the terms of the GNU General Public License version 3, as published
84+ * by the Free Software Foundation.
85+ *
86+ * This program is distributed in the hope that it will be useful, but
87+ * WITHOUT ANY WARRANTY; without even the implied warranties of
88+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
89+ * PURPOSE. See the GNU General Public License for more details.
90+ *
91+ * You should have received a copy of the GNU General Public License along
92+ * with this program. If not, see <http://www.gnu.org/licenses/>.
93+ *
94+ * Authors:
95+ * Ted Gould <ted.gould@canonical.com>
96+ */
97+
98+#include <glib.h>
99+
100+gboolean second_exec (const gchar * app_id, const gchar * appuris);
101+
102
103=== added file 'second-exec.c'
104--- second-exec.c 1970-01-01 00:00:00 +0000
105+++ second-exec.c 2013-09-30 17:16:20 +0000
106@@ -0,0 +1,38 @@
107+/*
108+ * Copyright 2013 Canonical Ltd.
109+ *
110+ * This program is free software: you can redistribute it and/or modify it
111+ * under the terms of the GNU General Public License version 3, as published
112+ * by the Free Software Foundation.
113+ *
114+ * This program is distributed in the hope that it will be useful, but
115+ * WITHOUT ANY WARRANTY; without even the implied warranties of
116+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
117+ * PURPOSE. See the GNU General Public License for more details.
118+ *
119+ * You should have received a copy of the GNU General Public License along
120+ * with this program. If not, see <http://www.gnu.org/licenses/>.
121+ *
122+ * Authors:
123+ * Ted Gould <ted.gould@canonical.com>
124+ */
125+
126+#include "second-exec-core.h"
127+
128+int
129+main (int argc, char * argv[])
130+{
131+ if (argc != 1) {
132+ g_error("Should be called as: %s", argv[0]);
133+ return 1;
134+ }
135+
136+ const gchar * appid = g_getenv("APP_ID");
137+ const gchar * appuris = g_getenv("APP_URIS");
138+
139+ if (second_exec(appid, appuris)) {
140+ return 0;
141+ } else {
142+ return 1;
143+ }
144+}
145
146=== modified file 'tests/CMakeLists.txt'
147--- tests/CMakeLists.txt 2013-09-24 02:48:57 +0000
148+++ tests/CMakeLists.txt 2013-09-30 17:16:20 +0000
149@@ -1,4 +1,6 @@
150
151+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
152+
153 # Google Test
154
155 include_directories(${GTEST_INCLUDE_DIR})
156@@ -15,3 +17,14 @@
157
158 add_test (helper-test helper-test)
159
160+# Second Exec Test
161+
162+include_directories("${CMAKE_SOURCE_DIR}/libupstart-app-launch")
163+
164+add_executable (second-exec-test
165+ second-exec-test.cc
166+ "${CMAKE_SOURCE_DIR}/second-exec-core.c"
167+ upstart-app-launch-mock.c)
168+target_link_libraries (second-exec-test helpers gtest ${GTEST_LIBS} ${LIBUPSTART_LIBRARIES} upstart-launcher)
169+add_test (second-exec-test second-exec-test)
170+
171
172=== added file 'tests/second-exec-test.cc'
173--- tests/second-exec-test.cc 1970-01-01 00:00:00 +0000
174+++ tests/second-exec-test.cc 2013-09-30 17:16:20 +0000
175@@ -0,0 +1,211 @@
176+/*
177+ * Copyright 2013 Canonical Ltd.
178+ *
179+ * This program is free software: you can redistribute it and/or modify it
180+ * under the terms of the GNU General Public License version 3, as published
181+ * by the Free Software Foundation.
182+ *
183+ * This program is distributed in the hope that it will be useful, but
184+ * WITHOUT ANY WARRANTY; without even the implied warranties of
185+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
186+ * PURPOSE. See the GNU General Public License for more details.
187+ *
188+ * You should have received a copy of the GNU General Public License along
189+ * with this program. If not, see <http://www.gnu.org/licenses/>.
190+ *
191+ * Authors:
192+ * Ted Gould <ted.gould@canonical.com>
193+ */
194+
195+#include <gtest/gtest.h>
196+#include <gio/gio.h>
197+
198+extern "C" {
199+#include "../second-exec-core.h"
200+#include "upstart-app-launch.h"
201+#include "upstart-app-launch-mock.h"
202+}
203+
204+class SecondExecTest : public ::testing::Test
205+{
206+ private:
207+ GTestDBus * testbus = NULL;
208+
209+ protected:
210+ std::string last_focus_appid;
211+ std::string last_resume_appid;
212+ guint resume_timeout = 0;
213+
214+ private:
215+ static void focus_cb (const gchar * appid, gpointer user_data) {
216+ SecondExecTest * _this = static_cast<SecondExecTest *>(user_data);
217+ _this->last_focus_appid = appid;
218+ }
219+
220+ static void resume_cb (const gchar * appid, gpointer user_data) {
221+ SecondExecTest * _this = static_cast<SecondExecTest *>(user_data);
222+ _this->last_resume_appid = appid;
223+
224+ if (_this->resume_timeout > 0) {
225+ _this->pause(_this->resume_timeout);
226+ }
227+ }
228+
229+ protected:
230+ virtual void SetUp() {
231+ testbus = g_test_dbus_new(G_TEST_DBUS_NONE);
232+ g_test_dbus_up(testbus);
233+
234+ upstart_app_launch_observer_add_app_focus(focus_cb, this);
235+ upstart_app_launch_observer_add_app_resume(resume_cb, this);
236+
237+ return;
238+ }
239+ virtual void TearDown() {
240+ upstart_app_launch_observer_delete_app_focus(focus_cb, this);
241+ upstart_app_launch_observer_delete_app_resume(resume_cb, this);
242+
243+ g_test_dbus_down(testbus);
244+ g_object_unref(testbus);
245+
246+ return;
247+ }
248+
249+ static gboolean pause_helper (gpointer pmainloop) {
250+ g_main_loop_quit((GMainLoop *)pmainloop);
251+ return G_SOURCE_REMOVE;
252+ }
253+
254+ void pause (guint time) {
255+ if (time > 0) {
256+ GMainLoop * mainloop = g_main_loop_new(NULL, FALSE);
257+ guint timer = g_timeout_add(time, pause_helper, mainloop);
258+
259+ g_main_loop_run(mainloop);
260+
261+ g_source_remove(timer);
262+ g_main_loop_unref(mainloop);
263+ }
264+
265+ while (g_main_pending()) {
266+ g_main_iteration(TRUE);
267+ }
268+
269+ return;
270+ }
271+};
272+
273+TEST_F(SecondExecTest, AppIdTest)
274+{
275+ ASSERT_TRUE(second_exec("foo", NULL));
276+ pause(0); /* Ensure all the events come through */
277+ ASSERT_STREQ(this->last_focus_appid.c_str(), "foo");
278+ ASSERT_STREQ(this->last_resume_appid.c_str(), "foo");
279+}
280+
281+GDBusMessage *
282+filter_func_good (GDBusConnection * conn, GDBusMessage * message, gboolean incomming, gpointer user_data)
283+{
284+ if (!incomming) {
285+ return message;
286+ }
287+
288+ if (g_strcmp0(g_dbus_message_get_path(message), (gchar *)user_data) == 0) {
289+ GDBusMessage * reply = g_dbus_message_new_method_reply(message);
290+ g_dbus_connection_send_message(conn, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL);
291+ g_object_unref(message);
292+ return NULL;
293+ }
294+
295+ return message;
296+}
297+
298+TEST_F(SecondExecTest, UrlSendTest)
299+{
300+ upstart_app_launch_mock_set_primary_pid(getpid());
301+
302+ GDBusConnection * session = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
303+ guint filter = g_dbus_connection_add_filter(session,
304+ filter_func_good,
305+ (gpointer)"/foo",
306+ NULL);
307+
308+ ASSERT_TRUE(second_exec("foo", "http://www.test.com"));
309+ pause(100); /* Ensure all the events come through */
310+
311+ ASSERT_STREQ(this->last_focus_appid.c_str(), "foo");
312+ ASSERT_STREQ(this->last_resume_appid.c_str(), "foo");
313+
314+ g_dbus_connection_remove_filter(session, filter);
315+ g_object_unref(session);
316+}
317+
318+TEST_F(SecondExecTest, UrlSendNoObjectTest)
319+{
320+ upstart_app_launch_mock_set_primary_pid(getpid());
321+
322+ ASSERT_TRUE(second_exec("foo", "http://www.test.com"));
323+ pause(100); /* Ensure all the events come through */
324+
325+ ASSERT_STREQ(this->last_focus_appid.c_str(), "foo");
326+ ASSERT_STREQ(this->last_resume_appid.c_str(), "foo");
327+}
328+
329+TEST_F(SecondExecTest, UnityTimeoutTest)
330+{
331+ this->resume_timeout = 100;
332+
333+ ASSERT_TRUE(second_exec("foo", NULL));
334+ pause(100); /* Ensure all the events come through */
335+ ASSERT_STREQ(this->last_focus_appid.c_str(), "foo");
336+ ASSERT_STREQ(this->last_resume_appid.c_str(), "foo");
337+}
338+
339+TEST_F(SecondExecTest, UnityTimeoutUriTest)
340+{
341+ this->resume_timeout = 200;
342+
343+ ASSERT_TRUE(second_exec("foo", "http://www.test.com"));
344+ pause(100); /* Ensure all the events come through */
345+ ASSERT_STREQ(this->last_focus_appid.c_str(), "foo");
346+ ASSERT_STREQ(this->last_resume_appid.c_str(), "foo");
347+}
348+
349+GDBusMessage *
350+filter_respawn (GDBusConnection * conn, GDBusMessage * message, gboolean incomming, gpointer user_data)
351+{
352+ if (g_strcmp0(g_dbus_message_get_member(message), "UnityResumeResponse") == 0) {
353+ g_object_unref(message);
354+ return NULL;
355+ }
356+
357+ return message;
358+}
359+
360+TEST_F(SecondExecTest, UnityLostTest)
361+{
362+ upstart_app_launch_mock_set_primary_pid(getpid());
363+
364+ GDBusConnection * session = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
365+ guint filter = g_dbus_connection_add_filter(session,
366+ filter_respawn,
367+ NULL,
368+ NULL);
369+
370+ guint start = g_get_monotonic_time();
371+
372+ ASSERT_TRUE(second_exec("foo", "http://www.test.com"));
373+
374+ guint end = g_get_monotonic_time();
375+
376+ ASSERT_LT(end - start, 600 * 1000);
377+
378+ pause(100); /* Ensure all the events come through */
379+ ASSERT_STREQ(this->last_focus_appid.c_str(), "foo");
380+ ASSERT_STREQ(this->last_resume_appid.c_str(), "foo");
381+
382+ g_dbus_connection_remove_filter(session, filter);
383+ g_object_unref(session);
384+}
385+
386+
387
388=== added file 'tests/upstart-app-launch-mock.c'
389--- tests/upstart-app-launch-mock.c 1970-01-01 00:00:00 +0000
390+++ tests/upstart-app-launch-mock.c 2013-09-30 17:16:20 +0000
391@@ -0,0 +1,39 @@
392+/*
393+ * Copyright 2013 Canonical Ltd.
394+ *
395+ * This program is free software: you can redistribute it and/or modify it
396+ * under the terms of the GNU General Public License version 3, as published
397+ * by the Free Software Foundation.
398+ *
399+ * This program is distributed in the hope that it will be useful, but
400+ * WITHOUT ANY WARRANTY; without even the implied warranties of
401+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
402+ * PURPOSE. See the GNU General Public License for more details.
403+ *
404+ * You should have received a copy of the GNU General Public License along
405+ * with this program. If not, see <http://www.gnu.org/licenses/>.
406+ *
407+ * Authors:
408+ * Ted Gould <ted.gould@canonical.com>
409+ */
410+
411+#include "upstart-app-launch.h"
412+#include "upstart-app-launch-mock.h"
413+
414+static GPid primary_pid = 0;
415+static gchar * primary_pid_appid = NULL;
416+
417+GPid
418+upstart_app_launch_get_primary_pid (const gchar * appid)
419+{
420+ g_free(primary_pid_appid);
421+ primary_pid_appid = g_strdup(appid);
422+ return primary_pid;
423+}
424+
425+void
426+upstart_app_launch_mock_set_primary_pid (GPid pid)
427+{
428+ primary_pid = pid;
429+ return;
430+}
431
432=== added file 'tests/upstart-app-launch-mock.h'
433--- tests/upstart-app-launch-mock.h 1970-01-01 00:00:00 +0000
434+++ tests/upstart-app-launch-mock.h 2013-09-30 17:16:20 +0000
435@@ -0,0 +1,18 @@
436+/*
437+ * Copyright 2013 Canonical Ltd.
438+ *
439+ * This program is free software: you can redistribute it and/or modify it
440+ * under the terms of the GNU General Public License version 3, as published
441+ * by the Free Software Foundation.
442+ *
443+ * This program is distributed in the hope that it will be useful, but
444+ * WITHOUT ANY WARRANTY; without even the implied warranties of
445+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
446+ * PURPOSE. See the GNU General Public License for more details.
447+ *
448+ * You should have received a copy of the GNU General Public License along
449+ * with this program. If not, see <http://www.gnu.org/licenses/>.
450+ */
451+
452+void upstart_app_launch_mock_set_primary_pid (GPid pid);
453+

Subscribers

People subscribed via source and target branches