linux/tools/perf/tests/api-io.c
<<
>>
Prefs
   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)                             \
  19do {                                                            \
  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)                           \
  28do {                                                            \
  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
  36static 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
  57static 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
  80static void cleanup_test(char path[PATH_MAX], struct io *io)
  81{
  82        free(io->buf);
  83        close(io->fd);
  84        unlink(path);
  85}
  86
  87static 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
 111static 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
 130static 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
 162static 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
 211static 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
 243static 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
 292int 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}
 305