Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1// SPDX-License-Identifier: GPL-2.0-only
  2#include <sys/types.h>
  3#include <sys/stat.h>
  4#include <fcntl.h>
  5#include <limits.h>
  6#include <stdio.h>
  7#include <stdlib.h>
  8#include <string.h>
  9#include <unistd.h>
 10
 11#include "debug.h"
 12#include "tests.h"
 13#include <api/io.h>
 14#include <linux/kernel.h>
 15#include <linux/zalloc.h>
 16
 17#define TEMPL "/tmp/perf-test-XXXXXX"
 18
 19#define EXPECT_EQUAL(val, expected)                             \
 20do {								\
 21	if (val != expected) {					\
 22		pr_debug("%s:%d: %d != %d\n",			\
 23			__FILE__, __LINE__, val, expected);	\
 24		ret = -1;					\
 25	}							\
 26} while (0)
 27
 28#define EXPECT_EQUAL64(val, expected)                           \
 29do {								\
 30	if (val != expected) {					\
 31		pr_debug("%s:%d: %lld != %lld\n",		\
 32			__FILE__, __LINE__, val, expected);	\
 33		ret = -1;					\
 34	}							\
 35} while (0)
 36
 37static int make_test_file(char path[PATH_MAX], const char *contents)
 38{
 39	ssize_t contents_len = strlen(contents);
 40	int fd;
 41
 42	strcpy(path, TEMPL);
 43	fd = mkstemp(path);
 44	if (fd < 0) {
 45		pr_debug("mkstemp failed");
 46		return -1;
 47	}
 48	if (write(fd, contents, contents_len) < contents_len) {
 49		pr_debug("short write");
 50		close(fd);
 51		unlink(path);
 52		return -1;
 53	}
 54	close(fd);
 55	return 0;
 56}
 57
 58static int setup_test(char path[PATH_MAX], const char *contents,
 59		      size_t buf_size, struct io *io)
 60{
 61	if (make_test_file(path, contents))
 62		return -1;
 63
 64	io->fd = open(path, O_RDONLY);
 65	if (io->fd < 0) {
 66		pr_debug("Failed to open '%s'\n", path);
 67		unlink(path);
 68		return -1;
 69	}
 70	io->buf = malloc(buf_size);
 71	if (io->buf == NULL) {
 72		pr_debug("Failed to allocate memory");
 73		close(io->fd);
 74		unlink(path);
 75		return -1;
 76	}
 77	io__init(io, io->fd, io->buf, buf_size);
 78	return 0;
 79}
 80
 81static void cleanup_test(char path[PATH_MAX], struct io *io)
 82{
 83	zfree(&io->buf);
 84	close(io->fd);
 85	unlink(path);
 86}
 87
 88static int do_test_get_char(const char *test_string, size_t buf_size)
 89{
 90	char path[PATH_MAX];
 91	struct io io;
 92	int ch, ret = 0;
 93	size_t i;
 94
 95	if (setup_test(path, test_string, buf_size, &io))
 96		return -1;
 97
 98	for (i = 0; i < strlen(test_string); i++) {
 99		ch = io__get_char(&io);
100
101		EXPECT_EQUAL(ch, test_string[i]);
102		EXPECT_EQUAL(io.eof, false);
103	}
104	ch = io__get_char(&io);
105	EXPECT_EQUAL(ch, -1);
106	EXPECT_EQUAL(io.eof, true);
107
108	cleanup_test(path, &io);
109	return ret;
110}
111
112static int test_get_char(void)
113{
114	int i, ret = 0;
115	size_t j;
116
117	static const char *const test_strings[] = {
118		"12345678abcdef90",
119		"a\nb\nc\nd\n",
120		"\a\b\t\v\f\r",
121	};
122	for (i = 0; i <= 10; i++) {
123		for (j = 0; j < ARRAY_SIZE(test_strings); j++) {
124			if (do_test_get_char(test_strings[j], 1 << i))
125				ret = -1;
126		}
127	}
128	return ret;
129}
130
131static int do_test_get_hex(const char *test_string,
132			__u64 val1, int ch1,
133			__u64 val2, int ch2,
134			__u64 val3, int ch3,
135			bool end_eof)
136{
137	char path[PATH_MAX];
138	struct io io;
139	int ch, ret = 0;
140	__u64 hex;
141
142	if (setup_test(path, test_string, 4, &io))
143		return -1;
144
145	ch = io__get_hex(&io, &hex);
146	EXPECT_EQUAL64(hex, val1);
147	EXPECT_EQUAL(ch, ch1);
148
149	ch = io__get_hex(&io, &hex);
150	EXPECT_EQUAL64(hex, val2);
151	EXPECT_EQUAL(ch, ch2);
152
153	ch = io__get_hex(&io, &hex);
154	EXPECT_EQUAL64(hex, val3);
155	EXPECT_EQUAL(ch, ch3);
156
157	EXPECT_EQUAL(io.eof, end_eof);
158
159	cleanup_test(path, &io);
160	return ret;
161}
162
163static int test_get_hex(void)
164{
165	int ret = 0;
166
167	if (do_test_get_hex("12345678abcdef90",
168				0x12345678abcdef90, -1,
169				0, -1,
170				0, -1,
171				true))
172		ret = -1;
173
174	if (do_test_get_hex("1\n2\n3\n",
175				1, '\n',
176				2, '\n',
177				3, '\n',
178				false))
179		ret = -1;
180
181	if (do_test_get_hex("12345678ABCDEF90;a;b",
182				0x12345678abcdef90, ';',
183				0xa, ';',
184				0xb, -1,
185				true))
186		ret = -1;
187
188	if (do_test_get_hex("0x1x2x",
189				0, 'x',
190				1, 'x',
191				2, 'x',
192				false))
193		ret = -1;
194
195	if (do_test_get_hex("x1x",
196				0, -2,
197				1, 'x',
198				0, -1,
199				true))
200		ret = -1;
201
202	if (do_test_get_hex("10000000000000000000000000000abcdefgh99i",
203				0xabcdef, 'g',
204				0, -2,
205				0x99, 'i',
206				false))
207		ret = -1;
208
209	return ret;
210}
211
212static int do_test_get_dec(const char *test_string,
213			__u64 val1, int ch1,
214			__u64 val2, int ch2,
215			__u64 val3, int ch3,
216			bool end_eof)
217{
218	char path[PATH_MAX];
219	struct io io;
220	int ch, ret = 0;
221	__u64 dec;
222
223	if (setup_test(path, test_string, 4, &io))
224		return -1;
225
226	ch = io__get_dec(&io, &dec);
227	EXPECT_EQUAL64(dec, val1);
228	EXPECT_EQUAL(ch, ch1);
229
230	ch = io__get_dec(&io, &dec);
231	EXPECT_EQUAL64(dec, val2);
232	EXPECT_EQUAL(ch, ch2);
233
234	ch = io__get_dec(&io, &dec);
235	EXPECT_EQUAL64(dec, val3);
236	EXPECT_EQUAL(ch, ch3);
237
238	EXPECT_EQUAL(io.eof, end_eof);
239
240	cleanup_test(path, &io);
241	return ret;
242}
243
244static int test_get_dec(void)
245{
246	int ret = 0;
247
248	if (do_test_get_dec("12345678abcdef90",
249				12345678, 'a',
250				0, -2,
251				0, -2,
252				false))
253		ret = -1;
254
255	if (do_test_get_dec("1\n2\n3\n",
256				1, '\n',
257				2, '\n',
258				3, '\n',
259				false))
260		ret = -1;
261
262	if (do_test_get_dec("12345678;1;2",
263				12345678, ';',
264				1, ';',
265				2, -1,
266				true))
267		ret = -1;
268
269	if (do_test_get_dec("0x1x2x",
270				0, 'x',
271				1, 'x',
272				2, 'x',
273				false))
274		ret = -1;
275
276	if (do_test_get_dec("x1x",
277				0, -2,
278				1, 'x',
279				0, -1,
280				true))
281		ret = -1;
282
283	if (do_test_get_dec("10000000000000000000000000000000000000000000000000000000000123456789ab99c",
284				123456789, 'a',
285				0, -2,
286				99, 'c',
287				false))
288		ret = -1;
289
290	return ret;
291}
292
293static int test_get_line(void)
294{
295	char path[PATH_MAX];
296	struct io io;
297	char test_string[1024];
298	char *line = NULL;
299	size_t i, line_len = 0;
300	size_t buf_size = 128;
301	int ret = 0;
302
303	for (i = 0; i < 512; i++)
304		test_string[i] = 'a';
305	test_string[512] = '\n';
306	for (i = 513; i < 1023; i++)
307		test_string[i] = 'b';
308	test_string[1023] = '\0';
309
310	if (setup_test(path, test_string, buf_size, &io))
311		return -1;
312
313	EXPECT_EQUAL((int)io__getline(&io, &line, &line_len), 513);
314	EXPECT_EQUAL((int)strlen(line), 513);
315	for (i = 0; i < 512; i++)
316		EXPECT_EQUAL(line[i], 'a');
317	EXPECT_EQUAL(line[512], '\n');
318	EXPECT_EQUAL((int)io__getline(&io, &line, &line_len), 510);
319	for (i = 0; i < 510; i++)
320		EXPECT_EQUAL(line[i], 'b');
321
322	free(line);
323	cleanup_test(path, &io);
324	return ret;
325}
326
327static int test__api_io(struct test_suite *test __maybe_unused,
328			int subtest __maybe_unused)
329{
330	int ret = 0;
331
332	if (test_get_char())
333		ret = TEST_FAIL;
334	if (test_get_hex())
335		ret = TEST_FAIL;
336	if (test_get_dec())
337		ret = TEST_FAIL;
338	if (test_get_line())
339		ret = TEST_FAIL;
340	return ret;
341}
342
343DEFINE_SUITE("Test api io", api_io);