1818c5d8cc721053be659c92b577217914905883Lloyd Pique/*
2818c5d8cc721053be659c92b577217914905883Lloyd Pique * Copyright © 2012 Intel Corporation
3818c5d8cc721053be659c92b577217914905883Lloyd Pique *
4818c5d8cc721053be659c92b577217914905883Lloyd Pique * Permission is hereby granted, free of charge, to any person obtaining
5818c5d8cc721053be659c92b577217914905883Lloyd Pique * a copy of this software and associated documentation files (the
6818c5d8cc721053be659c92b577217914905883Lloyd Pique * "Software"), to deal in the Software without restriction, including
7818c5d8cc721053be659c92b577217914905883Lloyd Pique * without limitation the rights to use, copy, modify, merge, publish,
8818c5d8cc721053be659c92b577217914905883Lloyd Pique * distribute, sublicense, and/or sell copies of the Software, and to
9818c5d8cc721053be659c92b577217914905883Lloyd Pique * permit persons to whom the Software is furnished to do so, subject to
10818c5d8cc721053be659c92b577217914905883Lloyd Pique * the following conditions:
11818c5d8cc721053be659c92b577217914905883Lloyd Pique *
12818c5d8cc721053be659c92b577217914905883Lloyd Pique * The above copyright notice and this permission notice (including the
13818c5d8cc721053be659c92b577217914905883Lloyd Pique * next paragraph) shall be included in all copies or substantial
14818c5d8cc721053be659c92b577217914905883Lloyd Pique * portions of the Software.
15818c5d8cc721053be659c92b577217914905883Lloyd Pique *
16818c5d8cc721053be659c92b577217914905883Lloyd Pique * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17818c5d8cc721053be659c92b577217914905883Lloyd Pique * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18818c5d8cc721053be659c92b577217914905883Lloyd Pique * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19818c5d8cc721053be659c92b577217914905883Lloyd Pique * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20818c5d8cc721053be659c92b577217914905883Lloyd Pique * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21818c5d8cc721053be659c92b577217914905883Lloyd Pique * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22818c5d8cc721053be659c92b577217914905883Lloyd Pique * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23818c5d8cc721053be659c92b577217914905883Lloyd Pique * SOFTWARE.
24818c5d8cc721053be659c92b577217914905883Lloyd Pique */
25818c5d8cc721053be659c92b577217914905883Lloyd Pique
26818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <math.h>
27818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <stdio.h>
28818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <stdlib.h>
29818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <stdarg.h>
30293a0fb21eafd159514a0ac98d687669f9bb55b1Dennis Kempin#include <stdint.h>
31818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <string.h>
32818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <assert.h>
33818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <sys/socket.h>
34818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <unistd.h>
35818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <errno.h>
36818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <sys/types.h>
37818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <sys/stat.h>
38818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <poll.h>
39818c5d8cc721053be659c92b577217914905883Lloyd Pique
40818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "wayland-private.h"
41818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "test-runner.h"
42818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "test-compositor.h"
43818c5d8cc721053be659c92b577217914905883Lloyd Pique
44818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic const char message[] = "Hello, world";
45818c5d8cc721053be659c92b577217914905883Lloyd Pique
46818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic struct wl_connection *
47818c5d8cc721053be659c92b577217914905883Lloyd Piquesetup(int *s)
48818c5d8cc721053be659c92b577217914905883Lloyd Pique{
49818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_connection *connection;
50818c5d8cc721053be659c92b577217914905883Lloyd Pique
51818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
52818c5d8cc721053be659c92b577217914905883Lloyd Pique
53818c5d8cc721053be659c92b577217914905883Lloyd Pique	connection = wl_connection_create(s[0]);
54818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(connection);
55818c5d8cc721053be659c92b577217914905883Lloyd Pique
56818c5d8cc721053be659c92b577217914905883Lloyd Pique	return connection;
57818c5d8cc721053be659c92b577217914905883Lloyd Pique}
58818c5d8cc721053be659c92b577217914905883Lloyd Pique
59818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_create)
60818c5d8cc721053be659c92b577217914905883Lloyd Pique{
61818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_connection *connection;
62818c5d8cc721053be659c92b577217914905883Lloyd Pique	int s[2];
63818c5d8cc721053be659c92b577217914905883Lloyd Pique
64818c5d8cc721053be659c92b577217914905883Lloyd Pique	connection = setup(s);
65818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_connection_destroy(connection);
66818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(s[0]);
67818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(s[1]);
68818c5d8cc721053be659c92b577217914905883Lloyd Pique}
69818c5d8cc721053be659c92b577217914905883Lloyd Pique
70818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_write)
71818c5d8cc721053be659c92b577217914905883Lloyd Pique{
72818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_connection *connection;
73818c5d8cc721053be659c92b577217914905883Lloyd Pique	int s[2];
74818c5d8cc721053be659c92b577217914905883Lloyd Pique	char buffer[64];
75818c5d8cc721053be659c92b577217914905883Lloyd Pique
76818c5d8cc721053be659c92b577217914905883Lloyd Pique	connection = setup(s);
77818c5d8cc721053be659c92b577217914905883Lloyd Pique
78818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_write(connection, message, sizeof message) == 0);
79818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_flush(connection) == sizeof message);
80818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(read(s[1], buffer, sizeof buffer) == sizeof message);
81818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(memcmp(message, buffer, sizeof message) == 0);
82818c5d8cc721053be659c92b577217914905883Lloyd Pique
83818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_connection_destroy(connection);
84818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(s[0]);
85818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(s[1]);
86818c5d8cc721053be659c92b577217914905883Lloyd Pique}
87818c5d8cc721053be659c92b577217914905883Lloyd Pique
88818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_data)
89818c5d8cc721053be659c92b577217914905883Lloyd Pique{
90818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_connection *connection;
91818c5d8cc721053be659c92b577217914905883Lloyd Pique	int s[2];
92818c5d8cc721053be659c92b577217914905883Lloyd Pique	char buffer[64];
93818c5d8cc721053be659c92b577217914905883Lloyd Pique
94818c5d8cc721053be659c92b577217914905883Lloyd Pique	connection = setup(s);
95818c5d8cc721053be659c92b577217914905883Lloyd Pique
96818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(write(s[1], message, sizeof message) == sizeof message);
97818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_read(connection) == sizeof message);
98818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_connection_copy(connection, buffer, sizeof message);
99818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(memcmp(message, buffer, sizeof message) == 0);
100818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_connection_consume(connection, sizeof message);
101818c5d8cc721053be659c92b577217914905883Lloyd Pique
102818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_connection_destroy(connection);
103818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(s[0]);
104818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(s[1]);
105818c5d8cc721053be659c92b577217914905883Lloyd Pique}
106818c5d8cc721053be659c92b577217914905883Lloyd Pique
107818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_queue)
108818c5d8cc721053be659c92b577217914905883Lloyd Pique{
109818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_connection *connection;
110818c5d8cc721053be659c92b577217914905883Lloyd Pique	int s[2];
111818c5d8cc721053be659c92b577217914905883Lloyd Pique	char buffer[64];
112818c5d8cc721053be659c92b577217914905883Lloyd Pique
113818c5d8cc721053be659c92b577217914905883Lloyd Pique	connection = setup(s);
114818c5d8cc721053be659c92b577217914905883Lloyd Pique
115818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* Test that wl_connection_queue() puts data in the output
116818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * buffer without flush it.  Verify that the data did get in
117818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * the buffer by writing another message and making sure that
118818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * we receive the two messages on the other fd. */
119818c5d8cc721053be659c92b577217914905883Lloyd Pique
120818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_queue(connection, message, sizeof message) == 0);
121818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_flush(connection) == 0);
122818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_write(connection, message, sizeof message) == 0);
123818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_flush(connection) == 2 * sizeof message);
124818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(read(s[1], buffer, sizeof buffer) == 2 * sizeof message);
125818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(memcmp(message, buffer, sizeof message) == 0);
126818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(memcmp(message, buffer + sizeof message, sizeof message) == 0);
127818c5d8cc721053be659c92b577217914905883Lloyd Pique
128818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_connection_destroy(connection);
129818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(s[0]);
130818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(s[1]);
131818c5d8cc721053be659c92b577217914905883Lloyd Pique}
132818c5d8cc721053be659c92b577217914905883Lloyd Pique
133818c5d8cc721053be659c92b577217914905883Lloyd Piquestruct marshal_data {
134818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_connection *read_connection;
135818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_connection *write_connection;
136818c5d8cc721053be659c92b577217914905883Lloyd Pique	int s[2];
137818c5d8cc721053be659c92b577217914905883Lloyd Pique	uint32_t buffer[10];
138818c5d8cc721053be659c92b577217914905883Lloyd Pique	union {
139818c5d8cc721053be659c92b577217914905883Lloyd Pique		uint32_t u;
140818c5d8cc721053be659c92b577217914905883Lloyd Pique		int32_t i;
141818c5d8cc721053be659c92b577217914905883Lloyd Pique		const char *s;
142818c5d8cc721053be659c92b577217914905883Lloyd Pique		int h;
143818c5d8cc721053be659c92b577217914905883Lloyd Pique	} value;
144818c5d8cc721053be659c92b577217914905883Lloyd Pique};
145818c5d8cc721053be659c92b577217914905883Lloyd Pique
146818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
147818c5d8cc721053be659c92b577217914905883Lloyd Piquesetup_marshal_data(struct marshal_data *data)
148818c5d8cc721053be659c92b577217914905883Lloyd Pique{
149818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(socketpair(AF_UNIX,
150818c5d8cc721053be659c92b577217914905883Lloyd Pique			  SOCK_STREAM | SOCK_CLOEXEC, 0, data->s) == 0);
151818c5d8cc721053be659c92b577217914905883Lloyd Pique	data->read_connection = wl_connection_create(data->s[0]);
152818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data->read_connection);
153818c5d8cc721053be659c92b577217914905883Lloyd Pique	data->write_connection = wl_connection_create(data->s[1]);
154818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data->write_connection);
155818c5d8cc721053be659c92b577217914905883Lloyd Pique}
156818c5d8cc721053be659c92b577217914905883Lloyd Pique
157818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
158818c5d8cc721053be659c92b577217914905883Lloyd Piquerelease_marshal_data(struct marshal_data *data)
159818c5d8cc721053be659c92b577217914905883Lloyd Pique{
160818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(wl_connection_destroy(data->read_connection));
161818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(wl_connection_destroy(data->write_connection));
162818c5d8cc721053be659c92b577217914905883Lloyd Pique}
163818c5d8cc721053be659c92b577217914905883Lloyd Pique
164818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
165818c5d8cc721053be659c92b577217914905883Lloyd Piquemarshal(struct marshal_data *data, const char *format, int size, ...)
166818c5d8cc721053be659c92b577217914905883Lloyd Pique{
167818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_closure *closure;
168818c5d8cc721053be659c92b577217914905883Lloyd Pique	static const uint32_t opcode = 4444;
169818c5d8cc721053be659c92b577217914905883Lloyd Pique	static struct wl_object sender = { NULL, NULL, 1234 };
170818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_message message = { "test", format, NULL };
171818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_list ap;
172818c5d8cc721053be659c92b577217914905883Lloyd Pique
173818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_start(ap, size);
174818c5d8cc721053be659c92b577217914905883Lloyd Pique	closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
175818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_end(ap);
176818c5d8cc721053be659c92b577217914905883Lloyd Pique
177818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(closure);
178818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_closure_send(closure, data->write_connection) == 0);
179818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_closure_destroy(closure);
180818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_flush(data->write_connection) == size);
181818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(read(data->s[0], data->buffer, sizeof data->buffer) == size);
182818c5d8cc721053be659c92b577217914905883Lloyd Pique
183818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data->buffer[0] == sender.id);
184818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data->buffer[1] == (opcode | (size << 16)));
185818c5d8cc721053be659c92b577217914905883Lloyd Pique}
186818c5d8cc721053be659c92b577217914905883Lloyd Pique
187818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_marshal)
188818c5d8cc721053be659c92b577217914905883Lloyd Pique{
189818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct marshal_data data;
190818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_object object;
191818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_array array;
192818c5d8cc721053be659c92b577217914905883Lloyd Pique	static const char text[] = "curry";
193818c5d8cc721053be659c92b577217914905883Lloyd Pique
194818c5d8cc721053be659c92b577217914905883Lloyd Pique	setup_marshal_data(&data);
195818c5d8cc721053be659c92b577217914905883Lloyd Pique
196818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "i", 12, 42);
197818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == 42);
198818c5d8cc721053be659c92b577217914905883Lloyd Pique
199818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "u", 12, 55);
200818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == 55);
201818c5d8cc721053be659c92b577217914905883Lloyd Pique
202818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "s", 20, "frappo");
203818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == 7);
204818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(strcmp((char *) &data.buffer[3], "frappo") == 0);
205818c5d8cc721053be659c92b577217914905883Lloyd Pique
206818c5d8cc721053be659c92b577217914905883Lloyd Pique	object.id = 557799;
207818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "o", 12, &object);
208818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == object.id);
209818c5d8cc721053be659c92b577217914905883Lloyd Pique
210818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "n", 12, &object);
211818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == object.id);
212818c5d8cc721053be659c92b577217914905883Lloyd Pique
213818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "?n", 12, NULL);
214818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == 0);
215818c5d8cc721053be659c92b577217914905883Lloyd Pique
216818c5d8cc721053be659c92b577217914905883Lloyd Pique	array.data = (void *) text;
217818c5d8cc721053be659c92b577217914905883Lloyd Pique	array.size = sizeof text;
218818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "a", 20, &array);
219818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == array.size);
220818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(memcmp(&data.buffer[3], text, array.size) == 0);
221818c5d8cc721053be659c92b577217914905883Lloyd Pique
222818c5d8cc721053be659c92b577217914905883Lloyd Pique	release_marshal_data(&data);
223818c5d8cc721053be659c92b577217914905883Lloyd Pique}
224818c5d8cc721053be659c92b577217914905883Lloyd Pique
225818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
226818c5d8cc721053be659c92b577217914905883Lloyd Piqueexpected_fail_marshal(int expected_error, const char *format, ...)
227818c5d8cc721053be659c92b577217914905883Lloyd Pique{
228818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_closure *closure;
229818c5d8cc721053be659c92b577217914905883Lloyd Pique	static const uint32_t opcode = 4444;
230818c5d8cc721053be659c92b577217914905883Lloyd Pique	static const struct wl_interface test_interface = {
231818c5d8cc721053be659c92b577217914905883Lloyd Pique		.name = "test_object"
232818c5d8cc721053be659c92b577217914905883Lloyd Pique	};
233818c5d8cc721053be659c92b577217914905883Lloyd Pique	static struct wl_object sender = { 0 };
234818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_message message = { "test", format, NULL };
235818c5d8cc721053be659c92b577217914905883Lloyd Pique
236818c5d8cc721053be659c92b577217914905883Lloyd Pique	sender.interface = &test_interface;
237818c5d8cc721053be659c92b577217914905883Lloyd Pique	sender.id = 1234;
238818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_list ap;
239818c5d8cc721053be659c92b577217914905883Lloyd Pique
240818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_start(ap, format);
241818c5d8cc721053be659c92b577217914905883Lloyd Pique	closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
242818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_end(ap);
243818c5d8cc721053be659c92b577217914905883Lloyd Pique
244818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(closure == NULL);
245818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(errno == expected_error);
246818c5d8cc721053be659c92b577217914905883Lloyd Pique}
247818c5d8cc721053be659c92b577217914905883Lloyd Pique
248818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
249818c5d8cc721053be659c92b577217914905883Lloyd Piqueexpected_fail_marshal_send(struct marshal_data *data, int expected_error,
250818c5d8cc721053be659c92b577217914905883Lloyd Pique			   const char *format, ...)
251818c5d8cc721053be659c92b577217914905883Lloyd Pique{
252818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_closure *closure;
253818c5d8cc721053be659c92b577217914905883Lloyd Pique	static const uint32_t opcode = 4444;
254818c5d8cc721053be659c92b577217914905883Lloyd Pique	static struct wl_object sender = { NULL, NULL, 1234 };
255818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_message message = { "test", format, NULL };
256818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_list ap;
257818c5d8cc721053be659c92b577217914905883Lloyd Pique
258818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_start(ap, format);
259818c5d8cc721053be659c92b577217914905883Lloyd Pique	closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
260818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_end(ap);
261818c5d8cc721053be659c92b577217914905883Lloyd Pique
262818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(closure);
263818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_closure_send(closure, data->write_connection) < 0);
264818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(errno == expected_error);
265818c5d8cc721053be659c92b577217914905883Lloyd Pique
266818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_closure_destroy(closure);
267818c5d8cc721053be659c92b577217914905883Lloyd Pique}
268818c5d8cc721053be659c92b577217914905883Lloyd Pique
269818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_marshal_nullables)
270818c5d8cc721053be659c92b577217914905883Lloyd Pique{
271818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct marshal_data data;
272818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_object object;
273818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_array array;
274818c5d8cc721053be659c92b577217914905883Lloyd Pique	const char text[] = "curry";
275818c5d8cc721053be659c92b577217914905883Lloyd Pique
276818c5d8cc721053be659c92b577217914905883Lloyd Pique	setup_marshal_data(&data);
277818c5d8cc721053be659c92b577217914905883Lloyd Pique
278818c5d8cc721053be659c92b577217914905883Lloyd Pique	expected_fail_marshal(EINVAL, "o", NULL);
279818c5d8cc721053be659c92b577217914905883Lloyd Pique	expected_fail_marshal(EINVAL, "s", NULL);
280818c5d8cc721053be659c92b577217914905883Lloyd Pique	expected_fail_marshal(EINVAL, "a", NULL);
281818c5d8cc721053be659c92b577217914905883Lloyd Pique
282818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "?o", 12, NULL);
283818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == 0);
284818c5d8cc721053be659c92b577217914905883Lloyd Pique
285818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "?a", 12, NULL);
286818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == 0);
287818c5d8cc721053be659c92b577217914905883Lloyd Pique
288818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "?s", 12, NULL);
289818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == 0);
290818c5d8cc721053be659c92b577217914905883Lloyd Pique
291818c5d8cc721053be659c92b577217914905883Lloyd Pique	object.id = 55293;
292818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "?o", 12, &object);
293818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == object.id);
294818c5d8cc721053be659c92b577217914905883Lloyd Pique
295818c5d8cc721053be659c92b577217914905883Lloyd Pique	array.data = (void *) text;
296818c5d8cc721053be659c92b577217914905883Lloyd Pique	array.size = sizeof text;
297818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "?a", 20, &array);
298818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == array.size);
299818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(memcmp(&data.buffer[3], text, array.size) == 0);
300818c5d8cc721053be659c92b577217914905883Lloyd Pique
301818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal(&data, "?s", 20, text);
302818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.buffer[2] == sizeof text);
303818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(strcmp((char *) &data.buffer[3], text) == 0);
304818c5d8cc721053be659c92b577217914905883Lloyd Pique
305818c5d8cc721053be659c92b577217914905883Lloyd Pique	release_marshal_data(&data);
306818c5d8cc721053be659c92b577217914905883Lloyd Pique}
307818c5d8cc721053be659c92b577217914905883Lloyd Pique
308818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
309818c5d8cc721053be659c92b577217914905883Lloyd Piquevalidate_demarshal_u(struct marshal_data *data,
310818c5d8cc721053be659c92b577217914905883Lloyd Pique		     struct wl_object *object, uint32_t u)
311818c5d8cc721053be659c92b577217914905883Lloyd Pique{
312818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data->value.u == u);
313818c5d8cc721053be659c92b577217914905883Lloyd Pique}
314818c5d8cc721053be659c92b577217914905883Lloyd Pique
315818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
316818c5d8cc721053be659c92b577217914905883Lloyd Piquevalidate_demarshal_i(struct marshal_data *data,
317818c5d8cc721053be659c92b577217914905883Lloyd Pique		     struct wl_object *object, int32_t i)
318818c5d8cc721053be659c92b577217914905883Lloyd Pique{
319818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data->value.i == i);
320818c5d8cc721053be659c92b577217914905883Lloyd Pique}
321818c5d8cc721053be659c92b577217914905883Lloyd Pique
322818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
323818c5d8cc721053be659c92b577217914905883Lloyd Piquevalidate_demarshal_s(struct marshal_data *data,
324818c5d8cc721053be659c92b577217914905883Lloyd Pique		     struct wl_object *object, const char *s)
325818c5d8cc721053be659c92b577217914905883Lloyd Pique{
326818c5d8cc721053be659c92b577217914905883Lloyd Pique	if (data->value.s != NULL)
327818c5d8cc721053be659c92b577217914905883Lloyd Pique		assert(strcmp(data->value.s, s) == 0);
328818c5d8cc721053be659c92b577217914905883Lloyd Pique	else
329818c5d8cc721053be659c92b577217914905883Lloyd Pique		assert(s == NULL);
330818c5d8cc721053be659c92b577217914905883Lloyd Pique}
331818c5d8cc721053be659c92b577217914905883Lloyd Pique
332818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
333818c5d8cc721053be659c92b577217914905883Lloyd Piquevalidate_demarshal_h(struct marshal_data *data,
334818c5d8cc721053be659c92b577217914905883Lloyd Pique		     struct wl_object *object, int fd)
335818c5d8cc721053be659c92b577217914905883Lloyd Pique{
336818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct stat buf1, buf2;
337818c5d8cc721053be659c92b577217914905883Lloyd Pique
338818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(fd != data->value.h);
339818c5d8cc721053be659c92b577217914905883Lloyd Pique	fstat(fd, &buf1);
340818c5d8cc721053be659c92b577217914905883Lloyd Pique	fstat(data->value.h, &buf2);
341818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(buf1.st_dev == buf2.st_dev);
342818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(buf1.st_ino == buf2.st_ino);
343818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(fd);
344818c5d8cc721053be659c92b577217914905883Lloyd Pique	close(data->value.h);
345818c5d8cc721053be659c92b577217914905883Lloyd Pique}
346818c5d8cc721053be659c92b577217914905883Lloyd Pique
347818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
348818c5d8cc721053be659c92b577217914905883Lloyd Piquevalidate_demarshal_f(struct marshal_data *data,
349818c5d8cc721053be659c92b577217914905883Lloyd Pique		     struct wl_object *object, wl_fixed_t f)
350818c5d8cc721053be659c92b577217914905883Lloyd Pique{
351818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data->value.i == f);
352818c5d8cc721053be659c92b577217914905883Lloyd Pique}
353818c5d8cc721053be659c92b577217914905883Lloyd Pique
354818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
355818c5d8cc721053be659c92b577217914905883Lloyd Piquedemarshal(struct marshal_data *data, const char *format,
356818c5d8cc721053be659c92b577217914905883Lloyd Pique	  uint32_t *msg, void (*func)(void))
357818c5d8cc721053be659c92b577217914905883Lloyd Pique{
358818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_message message = { "test", format, NULL };
359818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_closure *closure;
360818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_map objects;
361818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_object object = { NULL, &func, 0 };
362818c5d8cc721053be659c92b577217914905883Lloyd Pique	int size = msg[1];
363818c5d8cc721053be659c92b577217914905883Lloyd Pique
364818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(write(data->s[1], msg, size) == size);
365818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_read(data->read_connection) == size);
366818c5d8cc721053be659c92b577217914905883Lloyd Pique
367818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_map_init(&objects, WL_MAP_SERVER_SIDE);
368818c5d8cc721053be659c92b577217914905883Lloyd Pique	object.id = msg[0];
369818c5d8cc721053be659c92b577217914905883Lloyd Pique	closure = wl_connection_demarshal(data->read_connection,
370818c5d8cc721053be659c92b577217914905883Lloyd Pique					  size, &objects, &message);
371818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(closure);
372818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER, &object, 0, data);
373818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_closure_destroy(closure);
374818c5d8cc721053be659c92b577217914905883Lloyd Pique}
375818c5d8cc721053be659c92b577217914905883Lloyd Pique
376818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_demarshal)
377818c5d8cc721053be659c92b577217914905883Lloyd Pique{
378818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct marshal_data data;
379818c5d8cc721053be659c92b577217914905883Lloyd Pique	uint32_t msg[10];
380818c5d8cc721053be659c92b577217914905883Lloyd Pique
381818c5d8cc721053be659c92b577217914905883Lloyd Pique	setup_marshal_data(&data);
382818c5d8cc721053be659c92b577217914905883Lloyd Pique
383818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.u = 8000;
384818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[0] = 400200;	/* object id */
385818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[1] = 12;		/* size = 12, opcode = 0 */
386818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[2] = data.value.u;
387818c5d8cc721053be659c92b577217914905883Lloyd Pique	demarshal(&data, "u", msg, (void *) validate_demarshal_u);
388818c5d8cc721053be659c92b577217914905883Lloyd Pique
389818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.i = -557799;
390818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[0] = 400200;
391818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[1] = 12;
392818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[2] = data.value.i;
393818c5d8cc721053be659c92b577217914905883Lloyd Pique	demarshal(&data, "i", msg, (void *) validate_demarshal_i);
394818c5d8cc721053be659c92b577217914905883Lloyd Pique
395818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.s = "superdude";
396818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[0] = 400200;
397818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[1] = 24;
398818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[2] = 10;
399818c5d8cc721053be659c92b577217914905883Lloyd Pique	memcpy(&msg[3], data.value.s, msg[2]);
400818c5d8cc721053be659c92b577217914905883Lloyd Pique	demarshal(&data, "s", msg, (void *) validate_demarshal_s);
401818c5d8cc721053be659c92b577217914905883Lloyd Pique
402818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.s = "superdude";
403818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[0] = 400200;
404818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[1] = 24;
405818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[2] = 10;
406818c5d8cc721053be659c92b577217914905883Lloyd Pique	memcpy(&msg[3], data.value.s, msg[2]);
407818c5d8cc721053be659c92b577217914905883Lloyd Pique	demarshal(&data, "?s", msg, (void *) validate_demarshal_s);
408818c5d8cc721053be659c92b577217914905883Lloyd Pique
409818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.i = wl_fixed_from_double(-90000.2390);
410818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[0] = 400200;
411818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[1] = 12;
412818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[2] = data.value.i;
413818c5d8cc721053be659c92b577217914905883Lloyd Pique	demarshal(&data, "f", msg, (void *) validate_demarshal_f);
414818c5d8cc721053be659c92b577217914905883Lloyd Pique
415818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.s = NULL;
416818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[0] = 400200;
417818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[1] = 12;
418818c5d8cc721053be659c92b577217914905883Lloyd Pique	msg[2] = 0;
419818c5d8cc721053be659c92b577217914905883Lloyd Pique	demarshal(&data, "?s", msg, (void *) validate_demarshal_s);
420818c5d8cc721053be659c92b577217914905883Lloyd Pique
421818c5d8cc721053be659c92b577217914905883Lloyd Pique	release_marshal_data(&data);
422818c5d8cc721053be659c92b577217914905883Lloyd Pique}
423818c5d8cc721053be659c92b577217914905883Lloyd Pique
424818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
425818c5d8cc721053be659c92b577217914905883Lloyd Piquemarshal_demarshal(struct marshal_data *data,
426818c5d8cc721053be659c92b577217914905883Lloyd Pique		  void (*func)(void), int size, const char *format, ...)
427818c5d8cc721053be659c92b577217914905883Lloyd Pique{
428818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_closure *closure;
429818c5d8cc721053be659c92b577217914905883Lloyd Pique	static const int opcode = 4444;
430818c5d8cc721053be659c92b577217914905883Lloyd Pique	static struct wl_object sender = { NULL, NULL, 1234 };
431818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_message message = { "test", format, NULL };
432818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_map objects;
433818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_object object = { NULL, &func, 0 };
434818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_list ap;
435818c5d8cc721053be659c92b577217914905883Lloyd Pique	uint32_t msg[1] = { 1234 };
436818c5d8cc721053be659c92b577217914905883Lloyd Pique
437818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_start(ap, format);
438818c5d8cc721053be659c92b577217914905883Lloyd Pique	closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
439818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_end(ap);
440818c5d8cc721053be659c92b577217914905883Lloyd Pique
441818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(closure);
442818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_closure_send(closure, data->write_connection) == 0);
443818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_closure_destroy(closure);
444818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_flush(data->write_connection) == size);
445818c5d8cc721053be659c92b577217914905883Lloyd Pique
446818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_connection_read(data->read_connection) == size);
447818c5d8cc721053be659c92b577217914905883Lloyd Pique
448818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_map_init(&objects, WL_MAP_SERVER_SIDE);
449818c5d8cc721053be659c92b577217914905883Lloyd Pique	object.id = msg[0];
450818c5d8cc721053be659c92b577217914905883Lloyd Pique	closure = wl_connection_demarshal(data->read_connection,
451818c5d8cc721053be659c92b577217914905883Lloyd Pique					  size, &objects, &message);
452818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(closure);
453818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER, &object, 0, data);
454818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_closure_destroy(closure);
455818c5d8cc721053be659c92b577217914905883Lloyd Pique}
456818c5d8cc721053be659c92b577217914905883Lloyd Pique
457818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_marshal_demarshal)
458818c5d8cc721053be659c92b577217914905883Lloyd Pique{
459818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct marshal_data data;
460818c5d8cc721053be659c92b577217914905883Lloyd Pique	char f[] = "/tmp/wayland-tests-XXXXXX";
461818c5d8cc721053be659c92b577217914905883Lloyd Pique
462818c5d8cc721053be659c92b577217914905883Lloyd Pique	setup_marshal_data(&data);
463818c5d8cc721053be659c92b577217914905883Lloyd Pique
464818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.u = 889911;
465818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal_demarshal(&data, (void *) validate_demarshal_u,
466818c5d8cc721053be659c92b577217914905883Lloyd Pique			  12, "u", data.value.u);
467818c5d8cc721053be659c92b577217914905883Lloyd Pique
468818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.i = -13;
469818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal_demarshal(&data, (void *) validate_demarshal_i,
470818c5d8cc721053be659c92b577217914905883Lloyd Pique			  12, "i", data.value.i);
471818c5d8cc721053be659c92b577217914905883Lloyd Pique
472818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.s = "cookie robots";
473818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal_demarshal(&data, (void *) validate_demarshal_s,
474818c5d8cc721053be659c92b577217914905883Lloyd Pique			  28, "s", data.value.s);
475818c5d8cc721053be659c92b577217914905883Lloyd Pique
476818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.s = "cookie robots";
477818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal_demarshal(&data, (void *) validate_demarshal_s,
478818c5d8cc721053be659c92b577217914905883Lloyd Pique			  28, "?s", data.value.s);
479818c5d8cc721053be659c92b577217914905883Lloyd Pique
480818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.h = mkstemp(f);
481818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(data.value.h >= 0);
482818c5d8cc721053be659c92b577217914905883Lloyd Pique	unlink(f);
483818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal_demarshal(&data, (void *) validate_demarshal_h,
484818c5d8cc721053be659c92b577217914905883Lloyd Pique			  8, "h", data.value.h);
485818c5d8cc721053be659c92b577217914905883Lloyd Pique
486818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.i = wl_fixed_from_double(1234.5678);
487818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal_demarshal(&data, (void *) validate_demarshal_f,
488818c5d8cc721053be659c92b577217914905883Lloyd Pique	                  12, "f", data.value.i);
489818c5d8cc721053be659c92b577217914905883Lloyd Pique
490818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.i = wl_fixed_from_double(-90000.2390);
491818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal_demarshal(&data, (void *) validate_demarshal_f,
492818c5d8cc721053be659c92b577217914905883Lloyd Pique	                  12, "f", data.value.i);
493818c5d8cc721053be659c92b577217914905883Lloyd Pique
494818c5d8cc721053be659c92b577217914905883Lloyd Pique	data.value.i = wl_fixed_from_double((1 << 23) - 1 + 0.0941);
495818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal_demarshal(&data, (void *) validate_demarshal_f,
496818c5d8cc721053be659c92b577217914905883Lloyd Pique	                  12, "f", data.value.i);
497818c5d8cc721053be659c92b577217914905883Lloyd Pique
498818c5d8cc721053be659c92b577217914905883Lloyd Pique	release_marshal_data(&data);
499818c5d8cc721053be659c92b577217914905883Lloyd Pique}
500818c5d8cc721053be659c92b577217914905883Lloyd Pique
501818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_marshal_alot)
502818c5d8cc721053be659c92b577217914905883Lloyd Pique{
503818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct marshal_data data;
504818c5d8cc721053be659c92b577217914905883Lloyd Pique	char f[64];
505818c5d8cc721053be659c92b577217914905883Lloyd Pique	int i;
506818c5d8cc721053be659c92b577217914905883Lloyd Pique
507818c5d8cc721053be659c92b577217914905883Lloyd Pique	setup_marshal_data(&data);
508818c5d8cc721053be659c92b577217914905883Lloyd Pique
509818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* We iterate enough to make sure we wrap the circular buffers
510818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * for both regular data an fds. */
511818c5d8cc721053be659c92b577217914905883Lloyd Pique
512818c5d8cc721053be659c92b577217914905883Lloyd Pique	for (i = 0; i < 2000; i++) {
513818c5d8cc721053be659c92b577217914905883Lloyd Pique		strcpy(f, "/tmp/wayland-tests-XXXXXX");
514818c5d8cc721053be659c92b577217914905883Lloyd Pique		data.value.h = mkstemp(f);
515818c5d8cc721053be659c92b577217914905883Lloyd Pique		assert(data.value.h >= 0);
516818c5d8cc721053be659c92b577217914905883Lloyd Pique		unlink(f);
517818c5d8cc721053be659c92b577217914905883Lloyd Pique		marshal_demarshal(&data, (void *) validate_demarshal_h,
518818c5d8cc721053be659c92b577217914905883Lloyd Pique				  8, "h", data.value.h);
519818c5d8cc721053be659c92b577217914905883Lloyd Pique	}
520818c5d8cc721053be659c92b577217914905883Lloyd Pique
521818c5d8cc721053be659c92b577217914905883Lloyd Pique	release_marshal_data(&data);
522818c5d8cc721053be659c92b577217914905883Lloyd Pique}
523818c5d8cc721053be659c92b577217914905883Lloyd Pique
524818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(connection_marshal_too_big)
525818c5d8cc721053be659c92b577217914905883Lloyd Pique{
526818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct marshal_data data;
527818c5d8cc721053be659c92b577217914905883Lloyd Pique	char *big_string = malloc(5000);
528818c5d8cc721053be659c92b577217914905883Lloyd Pique
529818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(big_string);
530818c5d8cc721053be659c92b577217914905883Lloyd Pique
531818c5d8cc721053be659c92b577217914905883Lloyd Pique	memset(big_string, ' ', 4999);
532818c5d8cc721053be659c92b577217914905883Lloyd Pique	big_string[4999] = '\0';
533818c5d8cc721053be659c92b577217914905883Lloyd Pique
534818c5d8cc721053be659c92b577217914905883Lloyd Pique	setup_marshal_data(&data);
535818c5d8cc721053be659c92b577217914905883Lloyd Pique
536818c5d8cc721053be659c92b577217914905883Lloyd Pique	expected_fail_marshal_send(&data, E2BIG, "s", big_string);
537818c5d8cc721053be659c92b577217914905883Lloyd Pique
538818c5d8cc721053be659c92b577217914905883Lloyd Pique	release_marshal_data(&data);
539818c5d8cc721053be659c92b577217914905883Lloyd Pique	free(big_string);
540818c5d8cc721053be659c92b577217914905883Lloyd Pique}
541818c5d8cc721053be659c92b577217914905883Lloyd Pique
542818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
543818c5d8cc721053be659c92b577217914905883Lloyd Piquemarshal_helper(const char *format, void *handler, ...)
544818c5d8cc721053be659c92b577217914905883Lloyd Pique{
545818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_closure *closure;
546818c5d8cc721053be659c92b577217914905883Lloyd Pique	static struct wl_object sender = { NULL, NULL, 1234 };
547818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_object object = { NULL, &handler, 0 };
548818c5d8cc721053be659c92b577217914905883Lloyd Pique	static const int opcode = 4444;
549818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_message message = { "test", format, NULL };
550818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_list ap;
551818c5d8cc721053be659c92b577217914905883Lloyd Pique	int done;
552818c5d8cc721053be659c92b577217914905883Lloyd Pique
553818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_start(ap, handler);
554818c5d8cc721053be659c92b577217914905883Lloyd Pique	closure = wl_closure_vmarshal(&sender, opcode, ap, &message);
555818c5d8cc721053be659c92b577217914905883Lloyd Pique	va_end(ap);
556818c5d8cc721053be659c92b577217914905883Lloyd Pique
557818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(closure);
558818c5d8cc721053be659c92b577217914905883Lloyd Pique	done = 0;
559818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER, &object, 0, &done);
560818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_closure_destroy(closure);
561818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(done);
562818c5d8cc721053be659c92b577217914905883Lloyd Pique}
563818c5d8cc721053be659c92b577217914905883Lloyd Pique
564818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
565818c5d8cc721053be659c92b577217914905883Lloyd Piquesuu_handler(void *data, struct wl_object *object,
566818c5d8cc721053be659c92b577217914905883Lloyd Pique	    const char *s, uint32_t u1, uint32_t u2)
567818c5d8cc721053be659c92b577217914905883Lloyd Pique{
568818c5d8cc721053be659c92b577217914905883Lloyd Pique	int *done = data;
569818c5d8cc721053be659c92b577217914905883Lloyd Pique
570818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(strcmp(s, "foo") == 0);
571818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(u1 = 500);
572818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(u2 = 404040);
573818c5d8cc721053be659c92b577217914905883Lloyd Pique	*done = 1;
574818c5d8cc721053be659c92b577217914905883Lloyd Pique}
575818c5d8cc721053be659c92b577217914905883Lloyd Pique
576818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(invoke_closure)
577818c5d8cc721053be659c92b577217914905883Lloyd Pique{
578818c5d8cc721053be659c92b577217914905883Lloyd Pique	marshal_helper("suu", suu_handler, "foo", 500, 404040);
579818c5d8cc721053be659c92b577217914905883Lloyd Pique}
580818c5d8cc721053be659c92b577217914905883Lloyd Pique
581818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
582818c5d8cc721053be659c92b577217914905883Lloyd Piqueleak_closure(void)
583818c5d8cc721053be659c92b577217914905883Lloyd Pique{
584818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_callback *cb;
585818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct pollfd pfd;
586818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct client *c = client_connect();
587818c5d8cc721053be659c92b577217914905883Lloyd Pique
588818c5d8cc721053be659c92b577217914905883Lloyd Pique	cb = wl_display_sync(c->wl_display);
589818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(cb);
590818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_display_flush(c->wl_display) > 0);
591818c5d8cc721053be659c92b577217914905883Lloyd Pique
592818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* we don't need it, it is referenced */
593818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_callback_destroy(cb);
594818c5d8cc721053be659c92b577217914905883Lloyd Pique
595818c5d8cc721053be659c92b577217914905883Lloyd Pique	pfd.fd = wl_display_get_fd(c->wl_display);
596818c5d8cc721053be659c92b577217914905883Lloyd Pique	pfd.events = POLLIN;
597818c5d8cc721053be659c92b577217914905883Lloyd Pique
598818c5d8cc721053be659c92b577217914905883Lloyd Pique	test_set_timeout(2);
599818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(poll(&pfd, 1, -1) == 1);
600818c5d8cc721053be659c92b577217914905883Lloyd Pique
601818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* read events, but do not dispatch them */
602818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_display_prepare_read(c->wl_display) == 0);
603818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_display_read_events(c->wl_display) == 0);
604818c5d8cc721053be659c92b577217914905883Lloyd Pique
605818c5d8cc721053be659c92b577217914905883Lloyd Pique	/*
606818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * now we have wl_callback.done and wl_display.delete_id queued;
607818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * if we now release the queue (in wl_display_disconnect())
608818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * we should not leak memory
609818c5d8cc721053be659c92b577217914905883Lloyd Pique	 */
610818c5d8cc721053be659c92b577217914905883Lloyd Pique
611818c5d8cc721053be659c92b577217914905883Lloyd Pique	client_disconnect(c);
612818c5d8cc721053be659c92b577217914905883Lloyd Pique}
613818c5d8cc721053be659c92b577217914905883Lloyd Pique
614818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(closure_leaks)
615818c5d8cc721053be659c92b577217914905883Lloyd Pique{
616818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct display *d = display_create();
617818c5d8cc721053be659c92b577217914905883Lloyd Pique
618eed3fcdc3cd245a2acfa4bb72ac4dac683c4cf62Dennis Kempin	client_create_noarg(d, leak_closure);
619818c5d8cc721053be659c92b577217914905883Lloyd Pique	display_run(d);
620818c5d8cc721053be659c92b577217914905883Lloyd Pique
621818c5d8cc721053be659c92b577217914905883Lloyd Pique	display_destroy(d);
622818c5d8cc721053be659c92b577217914905883Lloyd Pique}
623818c5d8cc721053be659c92b577217914905883Lloyd Pique
624818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
625818c5d8cc721053be659c92b577217914905883Lloyd Piqueleak_after_error(void)
626818c5d8cc721053be659c92b577217914905883Lloyd Pique{
627818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct client *c = client_connect();
628818c5d8cc721053be659c92b577217914905883Lloyd Pique
629818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* this should return -1, because we'll send error
630818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * from server. */
631818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(stop_display(c, 1) == -1);
632818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_display_dispatch_pending(c->wl_display) == -1);
633818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_display_get_error(c->wl_display) == ENOMEM);
634818c5d8cc721053be659c92b577217914905883Lloyd Pique
635818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* after we got error, we have display_resume event
636818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * in the queue. It should be freed in wl_display_disconnect().
637818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * Let's see! */
638818c5d8cc721053be659c92b577217914905883Lloyd Pique
639818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_proxy_destroy((struct wl_proxy *) c->tc);
640818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_display_disconnect(c->wl_display);
641818c5d8cc721053be659c92b577217914905883Lloyd Pique	free(c);
642818c5d8cc721053be659c92b577217914905883Lloyd Pique}
643818c5d8cc721053be659c92b577217914905883Lloyd Pique
644818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(closure_leaks_after_error)
645818c5d8cc721053be659c92b577217914905883Lloyd Pique{
646818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct display *d = display_create();
647818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct client_info *cl;
648818c5d8cc721053be659c92b577217914905883Lloyd Pique
649eed3fcdc3cd245a2acfa4bb72ac4dac683c4cf62Dennis Kempin	cl = client_create_noarg(d, leak_after_error);
650818c5d8cc721053be659c92b577217914905883Lloyd Pique	display_run(d);
651818c5d8cc721053be659c92b577217914905883Lloyd Pique
652818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_client_post_no_memory(cl->wl_client);
653818c5d8cc721053be659c92b577217914905883Lloyd Pique	display_resume(d);
654818c5d8cc721053be659c92b577217914905883Lloyd Pique
655818c5d8cc721053be659c92b577217914905883Lloyd Pique	display_destroy(d);
656818c5d8cc721053be659c92b577217914905883Lloyd Pique}
657