# WaylandTest [WaylandTest](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/test/wayland_test.h;l=39;drc=5fd07430e5f69e88a7dbb5268fad686039f09aff) is a framework used to test the wayland protocol with server thread. ## Overview Wayland Test is the client side test but has a thread isolated from the client who acts like the server. This is not to test the server side behavior. On [SetUp](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/test/wayland_test.cc;l=56;drc=c3a7009be69ddc4492e8bb4e6dcb12bb0b1d3b71), it starts the server and initialize WaylandConnection. `window_` is created via [CreateWaylandWindow](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/test/mock_wayland_platform_window_delegate.cc;l=27;drc=c3a7009be69ddc4492e8bb4e6dcb12bb0b1d3b71) and show it. ### Post to Server [PostToServerAndWait](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/test/wayland_test.h;l=58;drc=5fd07430e5f69e88a7dbb5268fad686039f09aff) is a method to post `callback` to run on the server thread. ```cpp= // Ensure server processes pending requests. connection_->RoundTripQueue(); // Post the closure to the server's thread. server_.Post(std::move(closure)); // Wait for server thread to complete running posted tasks. server_.FlushForTesting(); // Flush all non-delayed tasks. task_environment_.RunUntilIdle(); ``` Firt it runs[RoundTripQueue](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/host/wayland_connection.cc;l=283;drc=c3a7009be69ddc4492e8bb4e6dcb12bb0b1d3b71) which calls `wl_display_roundtrip_queue` which blocks until all pending request are processed by the server. [`event_queue_`](https://source.chromium.org/chromium/chromium/src/+/main:remoting/host/linux/wayland_connection.h;l=54;drc=c3a7009be69ddc4492e8bb4e6dcb12bb0b1d3b71) stores the queue of the event, and RountTripQueue will wait for all reqests in this queue. Then post the given `callback` to the server thread by [Post](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/test/test_wayland_server_thread.cc;l=219;drc=c3a7009be69ddc4492e8bb4e6dcb12bb0b1d3b71). This will just runs `callback` on the server thread and then `wl_display_flush_clients`. Post is followed by [FlushForTesting](https://source.chromium.org/chromium/chromium/src/+/main:base/threading/thread.cc;l=247;drc=c3a7009be69ddc4492e8bb4e6dcb12bb0b1d3b71). This uses [WaitableEvent](https://source.chromium.org/chromium/chromium/src/+/main:base/synchronization/waitable_event.h;l=53;drc=750df4e0d466072c8f98bca78f0a6695c8019972) helper object to wait for the signal. Before completing, it waits for all non-delayed tasks to be done by `RunUntilIdle`. Note that this is different from RoundTripQueue. RoundTripQueue will wait for all requests processed by the server, but RunUntilIdle is jsut waiting for the already posted tasks. ### Send Configure [SendConfigureEvent](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/test/wayland_test.cc;l=148;drc=c3a7009be69ddc4492e8bb4e6dcb12bb0b1d3b71) is the method to mock the configure event. It sends the configure event for the given `surface_id`, given size and given states. Inside, it calls PostToServerAndWait and posts `xdg_toplevel_send_configure` or `xdg_popup_send_configure` followed by `xdg_surface_send_configure`. ## Test Server Thread [TestWaylandServerThread](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/test/test_wayland_server_thread.h;l=88;drc=c3a7009be69ddc4492e8bb4e6dcb12bb0b1d3b71) [Start](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/test/test_wayland_server_thread.cc;l=86;drc=c3a7009be69ddc4492e8bb4e6dcb12bb0b1d3b71) starts the test wayland server thread. This sets `WAYLAND_SOCKET` env var to the string of the file descriptor provided for the client to connect. Let's see what is does. It initializes `display_` by `wl_display_create()` and creates `event_loop_` with `display_`. It creates the socket pair to communicate betwene the client and server. ```cpp= int fd[2]; if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fd) < 0) return false; base::ScopedFD server_fd(fd[0]); base::ScopedFD client_fd(fd[1]); ``` After initializing many [GlobcalObject](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/test/global_object.h;l=22;drc=491b02870ad1f205defb1410c28a38f2a3bb8387)s such as compositor, output, seat, xdg_shell, zwp_text_inpu_manager_v1..., then it calls [`wl_client_create`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/wayland/src/src/wayland-server.c;l=521;drc=c3a7009be69ddc4492e8bb4e6dcb12bb0b1d3b71) with the fd `server_fd`. This becomes `client_`. `wl_client_create` gets a file descriptor corresponding to one end of a soecket and will create `wl_client` as if it had connected to the listening socket. The other end of the socket can be passed to `wl_display_connect_to_fd` or with `WAYLAND_SOCKET` env var on client side. In this testing thread, we us the latter way. ```cpp= setenv("WAYLAND_SOCKET", base::NumberToString(client_fd.release()).c_str(), 1); ```