tests: implement client_destroy()
It turns out that if the client is not explicitly destroyed, it will remain connected until the compositor shuts down because there is no more a client process that would terminate. Usually this is not a problem, but if a test file has multiple screenshooting tests, the windows from earlier tests in the file will remain on screen. That is not wanted, hence implement client destruction. To properly destroy a client, we also need a list of outputs. They used to be simply leaked. This does not fix wl_registry.global_remove for wl_outputs, that is left for a time when a test will actually need that. This patch makes only ivi-shell-app test use the new client_destroy() to show that it actually works. The added log scopes prove it: destroy requests get sent. Sprinkling client_destroy() around in all other tests is left for a time when it is actually necessary. ivi-shell-app is a nicely simple test doing little else, hence I picked it. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
444f1a8e22
commit
080d85b8fb
@ -41,6 +41,7 @@ fixture_setup(struct weston_test_harness *harness)
|
||||
compositor_setup_defaults(&setup);
|
||||
setup.shell = SHELL_IVI;
|
||||
setup.config_file = TESTSUITE_IVI_CONFIG_PATH;
|
||||
setup.logging_scopes = "log,test-harness-plugin,proto";
|
||||
|
||||
return weston_test_harness_execute_as_client(harness, &setup);
|
||||
}
|
||||
@ -84,4 +85,6 @@ TEST(ivi_application_exists)
|
||||
client_roundtrip(client);
|
||||
|
||||
testlog("Successful bind: %p\n", iviapp);
|
||||
|
||||
client_destroy(client);
|
||||
}
|
||||
|
@ -724,6 +724,15 @@ static const struct wl_output_listener output_listener = {
|
||||
output_handle_scale,
|
||||
};
|
||||
|
||||
static void
|
||||
output_destroy(struct output *output)
|
||||
{
|
||||
assert(wl_proxy_get_version((struct wl_proxy *)output->wl_output) >= 3);
|
||||
wl_output_release(output->wl_output);
|
||||
wl_list_remove(&output->link);
|
||||
free(output);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_global(void *data, struct wl_registry *registry,
|
||||
uint32_t id, const char *interface, uint32_t version)
|
||||
@ -741,6 +750,13 @@ handle_global(void *data, struct wl_registry *registry,
|
||||
global->version = version;
|
||||
wl_list_insert(client->global_list.prev, &global->link);
|
||||
|
||||
/* We deliberately bind all globals with the maximum (advertised)
|
||||
* version, because this test suite must be kept up-to-date with
|
||||
* Weston. We must always implement at least the version advertised
|
||||
* by Weston. This is not ok for normal clients, but it is ok in
|
||||
* this test suite.
|
||||
*/
|
||||
|
||||
if (strcmp(interface, "wl_compositor") == 0) {
|
||||
client->wl_compositor =
|
||||
wl_registry_bind(registry, id,
|
||||
@ -766,6 +782,7 @@ handle_global(void *data, struct wl_registry *registry,
|
||||
&wl_output_interface, version);
|
||||
wl_output_add_listener(output->wl_output,
|
||||
&output_listener, output);
|
||||
wl_list_insert(&client->output_list, &output->link);
|
||||
client->output = output;
|
||||
} else if (strcmp(interface, "weston_test") == 0) {
|
||||
test = xzalloc(sizeof *test);
|
||||
@ -805,6 +822,14 @@ client_find_input_with_name(struct client *client, uint32_t name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
global_destroy(struct global *global)
|
||||
{
|
||||
wl_list_remove(&global->link);
|
||||
free(global->interface);
|
||||
free(global);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
|
||||
{
|
||||
@ -824,9 +849,9 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
|
||||
}
|
||||
}
|
||||
|
||||
wl_list_remove(&global->link);
|
||||
free(global->interface);
|
||||
free(global);
|
||||
/* XXX: handle wl_output */
|
||||
|
||||
global_destroy(global);
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
@ -916,6 +941,7 @@ create_client(void)
|
||||
assert(client->wl_display);
|
||||
wl_list_init(&client->global_list);
|
||||
wl_list_init(&client->inputs);
|
||||
wl_list_init(&client->output_list);
|
||||
|
||||
/* setup registry so we can bind to interfaces */
|
||||
client->wl_registry = wl_display_get_registry(client->wl_display);
|
||||
@ -965,6 +991,16 @@ create_test_surface(struct client *client)
|
||||
return surface;
|
||||
}
|
||||
|
||||
void
|
||||
surface_destroy(struct surface *surface)
|
||||
{
|
||||
if (surface->wl_surface)
|
||||
wl_surface_destroy(surface->wl_surface);
|
||||
if (surface->buffer)
|
||||
buffer_destroy(surface->buffer);
|
||||
free(surface);
|
||||
}
|
||||
|
||||
struct client *
|
||||
create_client_and_test_surface(int x, int y, int width, int height)
|
||||
{
|
||||
@ -999,6 +1035,46 @@ create_client_and_test_surface(int x, int y, int width, int height)
|
||||
return client;
|
||||
}
|
||||
|
||||
void
|
||||
client_destroy(struct client *client)
|
||||
{
|
||||
if (client->surface)
|
||||
surface_destroy(client->surface);
|
||||
|
||||
while (!wl_list_empty(&client->inputs)) {
|
||||
input_destroy(container_of(client->inputs.next,
|
||||
struct input, link));
|
||||
}
|
||||
|
||||
while (!wl_list_empty(&client->output_list)) {
|
||||
output_destroy(container_of(client->output_list.next,
|
||||
struct output, link));
|
||||
}
|
||||
|
||||
while (!wl_list_empty(&client->global_list)) {
|
||||
global_destroy(container_of(client->global_list.next,
|
||||
struct global, link));
|
||||
}
|
||||
|
||||
if (client->test) {
|
||||
weston_test_destroy(client->test->weston_test);
|
||||
free(client->test);
|
||||
}
|
||||
|
||||
if (client->wl_shm)
|
||||
wl_shm_destroy(client->wl_shm);
|
||||
if (client->wl_compositor)
|
||||
wl_compositor_destroy(client->wl_compositor);
|
||||
if (client->wl_registry)
|
||||
wl_registry_destroy(client->wl_registry);
|
||||
|
||||
client_roundtrip(client);
|
||||
|
||||
if (client->wl_display)
|
||||
wl_display_disconnect(client->wl_display);
|
||||
free(client);
|
||||
}
|
||||
|
||||
static const char*
|
||||
output_path(void)
|
||||
{
|
||||
|
@ -57,6 +57,7 @@ struct client {
|
||||
int has_argb;
|
||||
struct wl_list global_list;
|
||||
bool has_wl_drm;
|
||||
struct wl_list output_list; /* struct output::link */
|
||||
};
|
||||
|
||||
struct global {
|
||||
@ -145,6 +146,7 @@ struct touch {
|
||||
|
||||
struct output {
|
||||
struct wl_output *wl_output;
|
||||
struct wl_list link; /* struct client::output_list */
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
@ -161,7 +163,7 @@ struct buffer {
|
||||
|
||||
struct surface {
|
||||
struct wl_surface *wl_surface;
|
||||
struct output *output;
|
||||
struct output *output; /* not owned */
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
@ -184,9 +186,15 @@ struct range {
|
||||
struct client *
|
||||
create_client(void);
|
||||
|
||||
void
|
||||
client_destroy(struct client *client);
|
||||
|
||||
struct surface *
|
||||
create_test_surface(struct client *client);
|
||||
|
||||
void
|
||||
surface_destroy(struct surface *surface);
|
||||
|
||||
struct client *
|
||||
create_client_and_test_surface(int x, int y, int width, int height);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user