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