Johan Klokkhammer Helsing f6dd4ab120 Create a new type of mock compositor for client tests
There are a number of issues with the current client testing:

- Adding new compositor functionality is cumbersome (need to add compositor
  send method, command, implementation, not to mention creating new wrapper
  objects.
- Customizing available globals and their versions is not possible and would be
  hard to implement. I.e. how to test that functionality works with old and new
  versions of an interface? Handle globals being destroyed. We did this with
  wl_output, but it was painfully cumbersome.
- Hard to verify that the compositor state is clean between tests. It is
  currently done in some tests, but requires boiler plate code which needs to
  be added and maintained for each test.
- In general lots of boiler-plate for new tests. (We have to have separate
  tests as long as Qt has global/static state. I.e. if one shell extension has
  been initialized, we can't deinitialize and initialize another one, so tests
  have to be separate.)
- Dispatching server events tied to the client event loop sometimes makes it
  hard to write tests without deadlocks.
- Abstraction, encapsulation and automatic behavior that can't be disabled
  makes it hard to test low-level functionality like surface exposure.

So, in an attempt to mitigate these issues, I wrote a new testing framework.

- Compositor dispatch is running continuously in it's own thread, access to
  compositor state is guarded by a mutex on the compositor, locking this will
  make dispatching stop, so the test can safely access internals. Although a
  bit cumbersome at first this makes it much easier to directly use server
  protocol commands from the test itself, i.e. no need to create commands for
  every single thing we want to test.
- The CoreCompositor::exec template method can accept a lambda that will be run
  with dispatching stopped. It can also return a value, conveniently letting us
  safely extract or modify compositor state from tests.
- This framework also takes full advantage of the qtwaylandscanner, using
  wrapper classes for everything, reducing boiler plate considerably.
- The compositor parts are designed to do as little as possible automatically,
  but still provide easy ways to enable common functionality, like releasing
  buffers automatically, configuring shell surfaces etc.
- Compositor globals are pluggable, use add<GlobalClass>() and
  remove<GlobalClass>() to add new global interfaces. I.e. easy to create a
  compositor with or without data_device_manager for instance.
- DefaultCompositor provides a sensible default set of functionality and
  convenience methods for most test-cases. Custom ones can still be made by
  inheriting from CoreCompositor directly instead or by removing or adding
  globals to DefaultCompositor.
- Globals have an isClean() method. Implement it to verify that the client
  didn't leave any objects lying around from the previous test.
  CoreCompositor::isClean calls isClean on the globals so a single call is all
  that's needed.

In short, we've traded mock compositor encapsulation and thread safety
guarantees for less boiler-plate, easier and more convenient access to
internals.

Anything accessing compositor state should go into a exec() call, or through
the wrapper macros QCOMPOSITOR_VERIFY and QCOMPOSITOR_COMPARE (or the TRY
versions). I've also tried to make the compositor print warnings if compositor
state is accessed in an unsafe way.

The mock compositor is currently built once per test due to CI limitations
(same thing as with the old tests).

Change-Id: Ia3feb80ce175d3814292b7f4768a0cc719f8b0e8
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
2018-12-11 15:46:49 +00:00
Description
Qt Base (Core, Gui, Widgets, Network, ...)
822 MiB
Languages
C++ 84.3%
HTML 4.9%
C 3.9%
CMake 3.6%
Objective-C++ 2%
Other 0.8%