Merge lp:~chasedouglas/grail/atomic-timeout-test into lp:grail

Proposed by Chase Douglas
Status: Merged
Merged at revision: 200
Proposed branch: lp:~chasedouglas/grail/atomic-timeout-test
Merge into: lp:grail
Prerequisite: lp:~chasedouglas/grail/cleanup-recordings
Diff against target: 328 lines (+307/-1)
3 files modified
test/Makefile.am (+2/-1)
test/recordings/ntrig_dell_xt2/2_tap.record (+20/-0)
test/x11/atomic-timeout.cpp (+285/-0)
To merge this branch: bzr merge lp:~chasedouglas/grail/atomic-timeout-test
Reviewer Review Type Date Requested Status
Daniel d'Andrada (community) Approve
Review via email: mp+98023@code.launchpad.net

Description of the change

Add atomic tap timeout test. This test checks for two issues:

* Tap gesture events are generated
* The correct events are generated

The first issue will fail if the atomic gesture timeout is not calculated
properly. The second issue is just a general check that the right events
are generated.

To post a comment you must log in.
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'test/Makefile.am'
2--- test/Makefile.am 2012-03-14 19:25:27 +0000
3+++ test/Makefile.am 2012-03-16 23:19:22 +0000
4@@ -33,7 +33,8 @@
5 x11/no-tap-after-drag.cpp \
6 x11/twodrag.cpp \
7 x11/dragthresh.cpp \
8- x11/timeout.cpp
9+ x11/timeout.cpp \
10+ x11/atomic-timeout.cpp
11 endif
12
13 CXXFLAGS += \
14
15=== added file 'test/recordings/ntrig_dell_xt2/2_tap.record'
16--- test/recordings/ntrig_dell_xt2/2_tap.record 1970-01-01 00:00:00 +0000
17+++ test/recordings/ntrig_dell_xt2/2_tap.record 2012-03-16 23:19:22 +0000
18@@ -0,0 +1,20 @@
19+E: 1327542640.244087 0003 0000 2745
20+E: 1327542640.244089 0003 0001 1639
21+E: 1327542640.244090 0003 0035 2745
22+E: 1327542640.244091 0003 0036 1639
23+E: 1327542640.244092 0003 0034 0
24+E: 1327542640.244093 0003 0030 468
25+E: 1327542640.244094 0003 0031 306
26+E: 1327542640.244095 0000 0002 0
27+E: 1327542640.244090 0003 0035 2845
28+E: 1327542640.244091 0003 0036 1639
29+E: 1327542640.244092 0003 0034 0
30+E: 1327542640.244093 0003 0030 468
31+E: 1327542640.244094 0003 0031 306
32+E: 1327542640.244095 0000 0002 0
33+E: 1327542640.244251 0001 014d 1
34+E: 1327542640.244251 0001 014a 1
35+E: 1327542640.244253 0000 0000 0
36+E: 1327542640.244253 0001 014d 0
37+E: 1327542640.244253 0001 014a 0
38+E: 1327542640.244253 0000 0000 0
39
40=== added file 'test/x11/atomic-timeout.cpp'
41--- test/x11/atomic-timeout.cpp 1970-01-01 00:00:00 +0000
42+++ test/x11/atomic-timeout.cpp 2012-03-16 23:19:22 +0000
43@@ -0,0 +1,285 @@
44+/*****************************************************************************
45+ *
46+ * grail - Gesture Recognition And Instantiation Library
47+ *
48+ * Copyright (C) 2012 Canonical Ltd.
49+ *
50+ * This program is free software: you can redistribute it and/or modify it
51+ * under the terms of the GNU General Public License as published by the
52+ * Free Software Foundation, either version 3 of the License, or (at your
53+ * option) any later version.
54+ *
55+ * This program is distributed in the hope that it will be useful, but
56+ * WITHOUT ANY WARRANTY; without even the implied warranty of
57+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
58+ * General Public License for more details.
59+ *
60+ * You should have received a copy of the GNU General Public License along
61+ * with this program. If not, see <http://www.gnu.org/licenses/>.
62+ *
63+ ****************************************************************************/
64+
65+/**
66+ * @internal
67+ * @file Atomic Timout Test
68+ *
69+ * This test plays a two-touch tap and checks that the appropriate events are
70+ * generated for a two-touch atomic tap subscription.
71+ *
72+ * Regression test for lp:949855 and lp:957437.
73+ */
74+
75+#include <cmath>
76+#include <map>
77+#include <memory>
78+#include <stdexcept>
79+#include <future>
80+
81+#include <gtest/gtest.h>
82+
83+#include "device.h"
84+#include "events.h"
85+#include "recording.h"
86+#include "x11/fixture.h"
87+#include "utouch/frame_x11.h"
88+
89+using namespace utouch::grail::x11::testing;
90+
91+class AtomicTap : public Test {
92+ public:
93+ AtomicTap() : device_(NULL), step_(0) {}
94+
95+ protected:
96+ static utouch::grail::testing::Events events_;
97+
98+ virtual void ProcessFrameEvents();
99+ virtual void ProcessGrailEvents();
100+ void Subscribe();
101+ void CheckSlice(UGSlice);
102+
103+ UFDevice device_;
104+ unsigned int step_;
105+};
106+
107+void AtomicTap::ProcessFrameEvents() {
108+ UFEvent event;
109+
110+ UFStatus status;
111+ while ((status = frame_get_event(frame_handle(), &event)) == UFStatusSuccess) {
112+ grail_process_frame_event(grail_handle(), event);
113+
114+ if (frame_event_get_type(event) == UFEventTypeDeviceAdded) {
115+ UFDevice device;
116+ ASSERT_EQ(UFStatusSuccess,
117+ frame_event_get_property(event, UFEventPropertyDevice,
118+ &device));
119+
120+ const char* name;
121+ ASSERT_EQ(UFStatusSuccess,
122+ frame_device_get_property(device, UFDevicePropertyName, &name));
123+ if (strcmp(name, "N-Trig MultiTouch (Virtual Test Device)") == 0) {
124+ EXPECT_EQ(NULL, device_);
125+ device_ = device;
126+ Subscribe();
127+ }
128+ }
129+
130+ frame_event_unref(event);
131+ }
132+
133+ EXPECT_EQ(UFStatusErrorNoEvent, status);
134+}
135+
136+void AtomicTap::ProcessGrailEvents() {
137+ UGEvent event;
138+
139+ UGStatus status;
140+ while ((status = grail_get_event(grail_handle(), &event)) == UGStatusSuccess) {
141+ ASSERT_EQ(UGEventTypeSlice, grail_event_get_type(event));
142+
143+ UGSlice slice;
144+ status = grail_event_get_property(event, UGEventPropertySlice, &slice);
145+ ASSERT_EQ(UGStatusSuccess, status);
146+
147+ CheckSlice(slice);
148+
149+ grail_event_unref(event);
150+ }
151+
152+ EXPECT_EQ(UGStatusErrorNoEvent, status);
153+}
154+
155+void AtomicTap::Subscribe() {
156+ UGSubscription subscription;
157+ UGStatus status = grail_subscription_new(&subscription);
158+ ASSERT_EQ(UGStatusSuccess, status);
159+
160+ status = grail_subscription_set_property(subscription,
161+ UGSubscriptionPropertyDevice,
162+ &device_);
163+ ASSERT_EQ(UGStatusSuccess, status);
164+
165+ const UFWindowId window_id =
166+ frame_x11_create_window_id(DefaultRootWindow(Display()));
167+ status = grail_subscription_set_property(subscription,
168+ UGSubscriptionPropertyWindow,
169+ &window_id);
170+ ASSERT_EQ(UGStatusSuccess, status);
171+
172+ const UGGestureTypeMask mask = UGGestureTypeTap;
173+ status = grail_subscription_set_property(subscription,
174+ UGSubscriptionPropertyMask,
175+ &mask);
176+ ASSERT_EQ(UGStatusSuccess, status);
177+
178+ const int atomic = true;
179+ status = grail_subscription_set_property(subscription,
180+ UGSubscriptionPropertyAtomicGestures,
181+ &atomic);
182+
183+ status = grail_subscription_activate(grail_handle(), subscription);
184+ ASSERT_EQ(UGStatusSuccess, status);
185+}
186+
187+void AtomicTap::CheckSlice(UGSlice slice) {
188+ ASSERT_LT(step_, events_.size()) << "Received too many frame events";
189+
190+ /* Ensure we got a device addition event first */
191+ if (step_ == 0)
192+ EXPECT_NE(nullptr, device_);
193+
194+ if (!events_[step_].skip) {
195+ EXPECT_EQ(events_[step_].id, grail_slice_get_id(slice)) << "step " << step_;
196+ EXPECT_EQ(events_[step_].state, grail_slice_get_state(slice)) << "step "
197+ << step_;
198+ EXPECT_EQ(events_[step_].recognized, grail_slice_get_recognized(slice))
199+ << "step " << step_;
200+ EXPECT_EQ(events_[step_].num_touches, grail_slice_get_num_touches(slice))
201+ << "step " << step_;
202+ }
203+
204+ if (grail_slice_get_state(slice) == UGGestureStateEnd) {
205+ UGSubscription subscription = grail_slice_get_subscription(slice);
206+ grail_subscription_deactivate(grail_handle(), subscription);
207+ grail_subscription_delete(subscription);
208+ }
209+
210+ ++step_;
211+}
212+
213+TEST_F(AtomicTap, Recording) {
214+ utouch::evemu::Device device("recordings/ntrig_dell_xt2/device.prop");
215+
216+ /* Pump once to ensure the X server has initialized the device */
217+ PumpEvents();
218+ ASSERT_NE(nullptr, device_) << "X server failed to initialize touchscreen";
219+
220+ utouch::evemu::Recording recording(device,
221+ "recordings/ntrig_dell_xt2/2_tap.record");
222+
223+ /* We use the c++11 future module so any exceptions thrown by the thread can
224+ * be caught later on. If we used the thread module, exceptions would take the
225+ * whole thing down. */
226+ std::future<void> future = std::async(std::launch::async,
227+ &utouch::evemu::Recording::Play,
228+ &recording);
229+
230+ PumpEvents();
231+
232+ future.wait();
233+
234+ EXPECT_EQ(events_.size(), step_) << "Failed to receive all frame events for "
235+ "touchscreen";
236+}
237+
238+/* Construct the expected events */
239+namespace {
240+
241+using namespace utouch::grail::testing;
242+
243+const Events ConstructEvents() {
244+ Events events;
245+
246+ {
247+ Slice slice = {
248+ false, /* skip */
249+ 0, /* UGSlicePropertyID */
250+ UGGestureStateBegin, /* UGSlicePropertyState */
251+ 0, /* UGSlicePropertyRecognized */
252+ 2, /* UGSlicePropertyNumTouches */
253+ 0, /* UGSlicePropertyOriginalCenterX */
254+ 0, /* UGSlicePropertyOriginalCenterY */
255+ 0, /* UGSlicePropertyOriginalRadius */
256+ {}, /* UGSlicePropertyTransform */
257+ {}, /* UGSlicePropertyCumulativeTransform */
258+ 0, /* UGSlicePropertyCenterOfRotationX */
259+ 0, /* UGSlicePropertyCenterOfRotationY */
260+ false, /* UGSlicePropertyConstructionFinished */
261+ };
262+ events.push_back(slice);
263+ }
264+
265+ {
266+ Slice slice = {
267+ false, /* skip */
268+ 0, /* UGSlicePropertyID */
269+ UGGestureStateUpdate, /* UGSlicePropertyState */
270+ 0, /* UGSlicePropertyRecognized */
271+ 2, /* UGSlicePropertyNumTouches */
272+ 0, /* UGSlicePropertyOriginalCenterX */
273+ 0, /* UGSlicePropertyOriginalCenterY */
274+ 0, /* UGSlicePropertyOriginalRadius */
275+ {}, /* UGSlicePropertyTransform */
276+ {}, /* UGSlicePropertyCumulativeTransform */
277+ 0, /* UGSlicePropertyCenterOfRotationX */
278+ 0, /* UGSlicePropertyCenterOfRotationY */
279+ false, /* UGSlicePropertyConstructionFinished */
280+ };
281+ events.push_back(slice);
282+ }
283+
284+ {
285+ Slice slice = {
286+ false, /* skip */
287+ 0, /* UGSlicePropertyID */
288+ UGGestureStateUpdate, /* UGSlicePropertyState */
289+ UGGestureTypeTap, /* UGSlicePropertyRecognized */
290+ 2, /* UGSlicePropertyNumTouches */
291+ 0, /* UGSlicePropertyOriginalCenterX */
292+ 0, /* UGSlicePropertyOriginalCenterY */
293+ 0, /* UGSlicePropertyOriginalRadius */
294+ {}, /* UGSlicePropertyTransform */
295+ {}, /* UGSlicePropertyCumulativeTransform */
296+ 0, /* UGSlicePropertyCenterOfRotationX */
297+ 0, /* UGSlicePropertyCenterOfRotationY */
298+ false, /* UGSlicePropertyConstructionFinished */
299+ };
300+ events.push_back(slice);
301+ }
302+
303+ {
304+ Slice slice = {
305+ false, /* skip */
306+ 0, /* UGSlicePropertyID */
307+ UGGestureStateEnd, /* UGSlicePropertyState */
308+ UGGestureTypeTap, /* UGSlicePropertyRecognized */
309+ 2, /* UGSlicePropertyNumTouches */
310+ 0, /* UGSlicePropertyOriginalCenterX */
311+ 0, /* UGSlicePropertyOriginalCenterY */
312+ 0, /* UGSlicePropertyOriginalRadius */
313+ {}, /* UGSlicePropertyTransform */
314+ {}, /* UGSlicePropertyCumulativeTransform */
315+ 0, /* UGSlicePropertyCenterOfRotationX */
316+ 0, /* UGSlicePropertyCenterOfRotationY */
317+ true, /* UGSlicePropertyConstructionFinished */
318+ };
319+ events.push_back(slice);
320+ }
321+
322+ return events;
323+}
324+
325+} // namespace
326+
327+/* Now initialize the static test fixture member */
328+utouch::grail::testing::Events AtomicTap::events_(ConstructEvents());

Subscribers

People subscribed via source and target branches