Merge lp:~kyrofa/go-ual/helper_observers into lp:go-ual

Proposed by Kyle Fazzari
Status: Merged
Approved by: dobey
Approved revision: 10
Merged at revision: 4
Proposed branch: lp:~kyrofa/go-ual/helper_observers
Merge into: lp:go-ual
Prerequisite: lp:~kyrofa/go-ual/observers_collection
Diff against target: 277 lines (+258/-0)
4 files modified
ual/gateway_observers.c (+27/-0)
ual/gateway_observers.h (+32/-0)
ual/helper_observers.go (+99/-0)
ual/helper_observers_test.go (+100/-0)
To merge this branch: bzr merge lp:~kyrofa/go-ual/helper_observers
Reviewer Review Type Date Requested Status
dobey (community) Approve
Review via email: mp+271406@code.launchpad.net

Commit message

Implement the bindings for helper observers.

Description of the change

Implement the bindings for helper observers.

This includes the C gateway observers.

To post a comment you must log in.
lp:~kyrofa/go-ual/helper_observers updated
2. By Kyle Fazzari

Implement bindings for various UAL helper methods.

Specifically, GetPrimaryPid(), StartSessionHelper()
and StopMultipleHelper().

Signed-off-by: Kyle Fazzari <email address hidden>

3. By Kyle Fazzari

Restrict the license header to version 3 of the GPL.

Signed-off-by: Kyle Fazzari <email address hidden>

4. By Kyle Fazzari

Change license to LGPLv3.

Signed-off-by: Kyle Fazzari <email address hidden>

5. By Kyle Fazzari

Add an Go-side observer tracker.

This is necessary due to Go's inability to pack functions into
C function pointers, so we'll have to make gateway functions
for them and track the Go side ourselves.

Signed-off-by: Kyle Fazzari <email address hidden>

6. By Kyle Fazzari

Restrict the license headers to version 3 of the GPL.

Signed-off-by: Kyle Fazzari <email address hidden>

7. By Kyle Fazzari

Change license to LGPLv3.

Signed-off-by: Kyle Fazzari <email address hidden>

8. By Kyle Fazzari

Implement the bindings for helper observers.

This includes the C gateway observers.

Signed-off-by: Kyle Fazzari <email address hidden>

9. By Kyle Fazzari

Restrict the license headers to version 3 of the GPL.

Signed-off-by: Kyle Fazzari <email address hidden>

10. By Kyle Fazzari

Change license to LGPLv3.

Signed-off-by: Kyle Fazzari <email address hidden>

Revision history for this message
dobey (dobey) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'ual/gateway_observers.c'
2--- ual/gateway_observers.c 1970-01-01 00:00:00 +0000
3+++ ual/gateway_observers.c 2015-09-17 18:08:12 +0000
4@@ -0,0 +1,27 @@
5+/* Copyright (C) 2015 Canonical Ltd.
6+ *
7+ * This file is part of go-ual.
8+ *
9+ * go-ual is free software: you can redistribute it and/or modify it under the
10+ * terms of the GNU Lesser General Public License version 3, as published by the
11+ * Free Software Foundation.
12+ *
13+ * go-ual is distributed in the hope that it will be useful, but WITHOUT ANY
14+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
16+ * details.
17+ *
18+ * You should have received a copy of the GNU Lesser General Public License
19+ * along with go-ual. If not, see <http://www.gnu.org/licenses/>.
20+ */
21+
22+#include "_cgo_export.h"
23+#include "gateway_observers.h"
24+
25+void gatewayHelperStopObserver(const gchar *appId, const gchar *instanceId,
26+ const gchar *helperType, gpointer userData)
27+{
28+ // Call the helper-stop observer dispatcher in Go
29+ callHelperStopObserver((char*)appId, (char*)instanceId,
30+ (char*)helperType, userData);
31+}
32
33=== added file 'ual/gateway_observers.h'
34--- ual/gateway_observers.h 1970-01-01 00:00:00 +0000
35+++ ual/gateway_observers.h 2015-09-17 18:08:12 +0000
36@@ -0,0 +1,32 @@
37+/* Copyright (C) 2015 Canonical Ltd.
38+ *
39+ * This file is part of go-ual.
40+ *
41+ * go-ual is free software: you can redistribute it and/or modify it under the
42+ * terms of the GNU Lesser General Public License version 3, as published by the
43+ * Free Software Foundation.
44+ *
45+ * go-ual is distributed in the hope that it will be useful, but WITHOUT ANY
46+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
47+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
48+ * details.
49+ *
50+ * You should have received a copy of the GNU Lesser General Public License
51+ * along with go-ual. If not, see <http://www.gnu.org/licenses/>.
52+ */
53+
54+#ifndef GATEWAY_OBSERVERS_H
55+#define GATEWAY_OBSERVERS_H
56+
57+#include <glib.h>
58+
59+/* A stand-in for the Go helper-stop observers.
60+ *
61+ * This function is necessary since Go functions can't be packed into a C
62+ * function pointer. So go-ual keeps track of the Go observers itself and uses
63+ * this function as a gateway for the real helper-stop observers.
64+ */
65+void gatewayHelperStopObserver(const gchar *appId, const gchar *instanceId,
66+ const gchar *helperType, gpointer userData);
67+
68+#endif
69
70=== added file 'ual/helper_observers.go'
71--- ual/helper_observers.go 1970-01-01 00:00:00 +0000
72+++ ual/helper_observers.go 2015-09-17 18:08:12 +0000
73@@ -0,0 +1,99 @@
74+/* Copyright (C) 2015 Canonical Ltd.
75+ *
76+ * This file is part of go-ual.
77+ *
78+ * go-ual is free software: you can redistribute it and/or modify it under the
79+ * terms of the GNU Lesser General Public License version 3, as published by the
80+ * Free Software Foundation.
81+ *
82+ * go-ual is distributed in the hope that it will be useful, but WITHOUT ANY
83+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
84+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
85+ * details.
86+ *
87+ * You should have received a copy of the GNU Lesser General Public License
88+ * along with go-ual. If not, see <http://www.gnu.org/licenses/>.
89+ */
90+
91+package ual
92+
93+// #cgo pkg-config: ubuntu-app-launch-2
94+// #include <stdlib.h>
95+// #include <ubuntu-app-launch.h>
96+//
97+// #include "gateway_observers.h"
98+import "C"
99+
100+import (
101+ "fmt"
102+ "unsafe"
103+)
104+
105+var helperStopObservers ObserversCollection
106+
107+//export callHelperStopObserver
108+func callHelperStopObserver(appId *C.char, instanceId *C.char, helperType *C.char, observerPointer unsafe.Pointer) {
109+ // Extract the real observer out of the user data
110+ observer := *(*Observer)(observerPointer)
111+
112+ // Call the observer
113+ observer(C.GoString(appId), C.GoString(instanceId), C.GoString(helperType))
114+}
115+
116+// ObserverAddHelperStop sets up a callback to be called each time a specific
117+// type of helper stops.
118+func ObserverAddHelperStop(helperType string, observer Observer) (ObserverId, error) {
119+ helperTypeCstring := (*C.gchar)(C.CString(helperType))
120+ defer C.free(unsafe.Pointer(helperTypeCstring))
121+
122+ id := helperStopObservers.AddObserver(helperType, observer)
123+ observerPointer, err := helperStopObservers.Observer(id)
124+ if err != nil {
125+ return 0, fmt.Errorf("Unable to retrieve observer from collection")
126+ }
127+
128+ added := int(C.ubuntu_app_launch_observer_add_helper_stop(
129+ (C.UbuntuAppLaunchHelperObserver)(C.gatewayHelperStopObserver),
130+ helperTypeCstring,
131+ (C.gpointer)(observerPointer))) != 0
132+
133+ if !added {
134+ // Make sure we remove it from our collection as well
135+ helperStopObservers.RemoveObserver(id)
136+ return 0, fmt.Errorf("Failed to add observer")
137+ }
138+
139+ return id, nil
140+}
141+
142+// ObserverDeleteHelperStop removes a previously-registered callback to ensure
143+// it no longer gets signaled.
144+func ObserverDeleteHelperStop(id ObserverId) error {
145+ observerPointer, err := helperStopObservers.Observer(id)
146+ if err != nil {
147+ return err
148+ }
149+
150+ helperType, err := helperStopObservers.ObserverHelperType(id)
151+ if err != nil {
152+ return err
153+ }
154+
155+ helperTypeCstring := (*C.gchar)(C.CString(helperType))
156+ defer C.free(unsafe.Pointer(helperTypeCstring))
157+
158+ removed := int(C.ubuntu_app_launch_observer_delete_helper_stop(
159+ (C.UbuntuAppLaunchHelperObserver)(C.gatewayHelperStopObserver),
160+ helperTypeCstring,
161+ (C.gpointer)(observerPointer))) != 0
162+
163+ if !removed {
164+ return fmt.Errorf("Failed to remove observer with ID %d", id)
165+ }
166+
167+ if !helperStopObservers.RemoveObserver(id) {
168+ return err
169+ }
170+
171+ return nil
172+}
173
174=== added file 'ual/helper_observers_test.go'
175--- ual/helper_observers_test.go 1970-01-01 00:00:00 +0000
176+++ ual/helper_observers_test.go 2015-09-17 18:08:12 +0000
177@@ -0,0 +1,100 @@
178+/* Copyright (C) 2015 Canonical Ltd.
179+ *
180+ * This file is part of go-ual.
181+ *
182+ * go-ual is free software: you can redistribute it and/or modify it under the
183+ * terms of the GNU Lesser General Public License version 3, as published by the
184+ * Free Software Foundation.
185+ *
186+ * go-ual is distributed in the hope that it will be useful, but WITHOUT ANY
187+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
188+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
189+ * details.
190+ *
191+ * You should have received a copy of the GNU Lesser General Public License
192+ * along with go-ual. If not, see <http://www.gnu.org/licenses/>.
193+ */
194+
195+package ual
196+
197+import (
198+ "testing"
199+ "time"
200+
201+ "github.com/godbus/dbus"
202+ "github.com/ziutek/glib"
203+)
204+
205+func keepTryingWithTimeout(function func() bool, duration time.Duration) bool {
206+ timeout := make(chan struct{})
207+ go func() {
208+ time.Sleep(duration)
209+ close(timeout)
210+ }()
211+
212+ for !function() {
213+ select {
214+ case <-timeout: // Timed out
215+ return false
216+ default:
217+ // Keep looping
218+ }
219+ }
220+
221+ return true
222+}
223+
224+// Test that helper stop observers can be added and removed, and are called at
225+// the right times.
226+func TestStopObservers(t *testing.T) {
227+ dbusConnection, err := dbus.SessionBus()
228+ if err != nil {
229+ t.Fatalf("Unable to connect to DBus session bus: %s", err)
230+ }
231+
232+ called := false
233+ id, err := ObserverAddHelperStop("foo", func(appId, instanceId, helperType string) {
234+ called = true
235+ if appId != "com.bar_bar_44.32" {
236+ t.Errorf(`appId was "%s", expected "com.bar_bar_44.32"`, appId)
237+ }
238+
239+ if instanceId != "1234" {
240+ t.Errorf(`instanceId was "%s", expected "1234"`, instanceId)
241+ }
242+
243+ if helperType != "foo" {
244+ t.Errorf(`helperType was "%s", expected "foo"`, helperType)
245+ }
246+ })
247+ if err != nil {
248+ t.Errorf("Unexpected error adding stop observer: %s", err)
249+ }
250+
251+ // Spoof an Upstart EventEmitted so UAL thinks "foo" has stopped
252+ err = dbusConnection.Emit("/com/ubuntu/Upstart",
253+ "com.ubuntu.Upstart0_6.EventEmitted",
254+ "stopped", []string{"JOB=untrusted-helper", "INSTANCE=foo:1234:com.bar_bar_44.32"})
255+ if err != nil {
256+ t.Error("Unexpected error emitting signal: %s", err)
257+ }
258+
259+ // Wait until there are pending events, but with a timeout
260+ context := glib.DefaultMainContext()
261+ if !keepTryingWithTimeout(context.Pending, 1*time.Second) {
262+ t.Fatal("Unexpected timeout: No glib events")
263+ }
264+
265+ for context.Pending() {
266+ context.Iteration(true)
267+ }
268+
269+ if !called {
270+ t.Error("Expected observer to be called")
271+ }
272+
273+ err = ObserverDeleteHelperStop(id)
274+ if err != nil {
275+ t.Errorf("Unexpected error removing stop observer: %s", err)
276+ }
277+}

Subscribers

People subscribed via source and target branches

to all changes: