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