[PATCH v2] Add regression test for button event state for touch emulation

Chase Douglas chase.douglas at canonical.com
Thu Jul 12 13:17:33 PDT 2012


On 07/11/2012 11:26 PM, Peter Hutterer wrote:
> On Mon, Jul 09, 2012 at 05:13:15PM -0700, Chase Douglas wrote:
>> When a touch begin is pointer emulated, the initial motion and button
>> press events should not have the first button set in the button mask.
>> The button mask represents the state of the buttons *before* the event.
>>
>> Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
>> ---
>
> only comment: the TEST_P should be a TEST_F since you don't use the range.

I purposely leave everything as TEST_P. This way we are sure each test 
passes no matter what version of Xinput the client speaks. It does mean 
we triple the run time, but that seems like a worthwhile tradeoff.

With that in mind, do you still think we should switch to TEST_F?

> Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
>
> otherwise. also, man am I glad we can have tests for this stuff now...
>
> Cheers,
>    Peter
>
>
>>   .../recordings/intellimouse/device.prop            |   24 ++++
>>   .../recordings/intellimouse/move_right.record      |    2 +
>>   test/integration/xi2.cpp                           |  132 ++++++++++++++++++++
>>   3 files changed, 158 insertions(+)
>>   create mode 100644 test/integration/recordings/intellimouse/device.prop
>>   create mode 100644 test/integration/recordings/intellimouse/move_right.record
>>
>> diff --git a/test/integration/recordings/intellimouse/device.prop b/test/integration/recordings/intellimouse/device.prop
>> new file mode 100644
>> index 0000000..9fa8b75
>> --- /dev/null
>> +++ b/test/integration/recordings/intellimouse/device.prop
>> @@ -0,0 +1,24 @@
>> +N: Microsoft Microsoft IntelliMouse® Optical (Virtual Test Device)
>> +I: 0003 045e 0029 0100
>> +P: 00 00 00 00 00 00 00 00
>> +B: 00 17 00 00 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 01 00 00 1f 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 01 00 00 00 00 00 00 00 00
>> +B: 02 03 01 00 00 00 00 00 00
>> +B: 03 00 00 00 00 00 00 00 00
>> +B: 04 10 00 00 00 00 00 00 00
>> +B: 05 00 00 00 00 00 00 00 00
>> +B: 11 00 00 00 00 00 00 00 00
>> +B: 12 00 00 00 00 00 00 00 00
>> +B: 15 00 00 00 00 00 00 00 00
>> +B: 15 00 00 00 00 00 00 00 00
>> diff --git a/test/integration/recordings/intellimouse/move_right.record b/test/integration/recordings/intellimouse/move_right.record
>> new file mode 100644
>> index 0000000..944ce4a
>> --- /dev/null
>> +++ b/test/integration/recordings/intellimouse/move_right.record
>> @@ -0,0 +1,2 @@
>> +E: 1327542640.244087 0002 0000 1
>> +E: 1327542640.244088 0000 0000 0
>> diff --git a/test/integration/xi2.cpp b/test/integration/xi2.cpp
>> index 1cbbe05..f2af071 100644
>> --- a/test/integration/xi2.cpp
>> +++ b/test/integration/xi2.cpp
>> @@ -1,4 +1,6 @@
>> +#include <list>
>>   #include <stdexcept>
>> +#include <sstream>
>>
>>   #include <xorg/gtest/xorg-gtest.h>
>>
>> @@ -353,4 +355,134 @@ TEST_P(XInput2Test, DisableDeviceEndTouches)
>>                                      XI_TouchEnd));
>>   }
>>
>> +namespace {
>> +
>> +/**
>> + * Helper function for TouchEmulatedButtonState test
>> + */
>> +void CheckButtonState(::Display* display, int xi2_opcode,
>> +                      std::list<std::pair<int, bool> >& expect)
>> +{
>> +    for (std::list<std::pair<int, bool> >::iterator it = expect.begin();
>> +         it != expect.end();
>> +         ++it) {
>> +        ASSERT_TRUE(WaitForEventOfType(display, GenericEvent, xi2_opcode,
>> +                                       it->first));
>> +
>> +        XEvent event;
>> +        ASSERT_EQ(Success, XNextEvent(display, &event));
>> +
>> +        XGenericEventCookie *xcookie = &event.xcookie;
>> +        ASSERT_TRUE(XGetEventData(display, xcookie));
>> +
>> +        XIDeviceEvent *device_event =
>> +            reinterpret_cast<XIDeviceEvent*>(xcookie->data);
>> +
>> +        std::stringstream msg;
>> +        msg << "Failed for ";
>> +        switch (it->first) {
>> +        case XI_Motion:
>> +            msg << "XI_Motion ";
>> +            break;
>> +        case XI_ButtonPress:
>> +            msg << "XI_ButtonPress ";
>> +            break;
>> +        case XI_ButtonRelease:
>> +            msg << "XI_ButtonRelease ";
>> +            break;
>> +        }
>> +        msg << "event";
>> +
>> +        EXPECT_EQ(it->second,
>> +                  static_cast<bool>(XIMaskIsSet(device_event->buttons.mask, 1)))
>> +            << msg.str();
>> +
>> +        XFreeEventData(display, xcookie);
>> +    }
>> +}
>> +
>> +}
>> +
>> +/**
>> + * The button state should represent the logical state of the buttons before the
>> + * event. Thus, a button press should not have any button state under normal
>> + * circumstances. This holds for touch events emulated as motion and button
>> + * events as well.
>> + */
>> +TEST_P(XInput2Test, TouchEmulatedButtonState)
>> +{
>> +    XIEventMask mask;
>> +    mask.deviceid = XIAllDevices;
>> +    mask.mask_len = XIMaskLen(XI_HierarchyChanged);
>> +    mask.mask = reinterpret_cast<unsigned char*>(calloc(mask.mask_len, 1));
>> +    XISetMask(mask.mask, XI_HierarchyChanged);
>> +
>> +    ASSERT_EQ(Success,
>> +              XISelectEvents(Display(), DefaultRootWindow(Display()), &mask,
>> +                             1));
>> +
>> +    mask.deviceid = XIAllMasterDevices;
>> +    XIClearMask(mask.mask, XI_HierarchyChanged);
>> +    XISetMask(mask.mask, XI_ButtonPress);
>> +    XISetMask(mask.mask, XI_ButtonRelease);
>> +    XISetMask(mask.mask, XI_Motion);
>> +
>> +    ASSERT_EQ(Success,
>> +              XISelectEvents(Display(), DefaultRootWindow(Display()), &mask,
>> +                             1));
>> +
>> +    free(mask.mask);
>> +
>> +    XFlush(Display());
>> +
>> +    std::auto_ptr<xorg::testing::evemu::Device> touchscreen;
>> +    std::auto_ptr<xorg::testing::evemu::Device> mouse;
>> +    try {
>> +      touchscreen = std::auto_ptr<xorg::testing::evemu::Device>(
>> +          new xorg::testing::evemu::Device(
>> +              TEST_ROOT_DIR "recordings/ntrig_dell_xt2/device.prop"));
>> +      mouse = std::auto_ptr<xorg::testing::evemu::Device>(
>> +          new xorg::testing::evemu::Device(
>> +              TEST_ROOT_DIR "recordings/intellimouse/device.prop"));
>> +    } catch (std::runtime_error &error) {
>> +      std::cerr << "Failed to create evemu device, skipping test.\n";
>> +      return;
>> +    }
>> +
>> +    ASSERT_TRUE(WaitForDevice(Display(),
>> +                              "N-Trig MultiTouch (Virtual Test Device)"));
>> +    ASSERT_TRUE(
>> +        WaitForDevice(Display(),
>> +            "Microsoft Microsoft IntelliMouse® Optical (Virtual Test Device)"));
>> +
>> +    std::list<std::pair<int, bool> > expect;
>> +
>> +    SCOPED_TRACE("Testing touch begin");
>> +    touchscreen->Play(
>> +        TEST_ROOT_DIR "recordings/ntrig_dell_xt2/touch_1_begin.record");
>> +    expect.push_back(std::make_pair(XI_Motion, false));
>> +    expect.push_back(std::make_pair(XI_ButtonPress, false));
>> +    CheckButtonState(Display(), xi2_opcode_, expect);
>> +    expect.clear();
>> +
>> +    SCOPED_TRACE("Testing mouse motion while touch is active");
>> +    mouse->Play(TEST_ROOT_DIR "recordings/intellimouse/move_right.record");
>> +    expect.push_back(std::make_pair(XI_Motion, true));
>> +    CheckButtonState(Display(), xi2_opcode_, expect);
>> +    expect.clear();
>> +
>> +    SCOPED_TRACE("Testing touch end");
>> +    touchscreen->Play(
>> +        TEST_ROOT_DIR "recordings/ntrig_dell_xt2/touch_1_end.record");
>> +    expect.push_back(std::make_pair(XI_ButtonRelease, true));
>> +    CheckButtonState(Display(), xi2_opcode_, expect);
>> +    expect.clear();
>> +
>> +    SCOPED_TRACE("Testing mouse motion after touch has ended");
>> +    mouse->Play(TEST_ROOT_DIR "recordings/intellimouse/move_right.record");
>> +    expect.push_back(std::make_pair(XI_Motion, false));
>> +    CheckButtonState(Display(), xi2_opcode_, expect);
>> +    expect.clear();
>> +}
>> +
>>   INSTANTIATE_TEST_CASE_P(, XInput2Test, ::testing::Range(0, 3));
>> --
>> 1.7.10.4
>>
>



More information about the xorg-devel mailing list