Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 #include <sys/types.h>
0003 #include <sys/stat.h>
0004 #include <fcntl.h>
0005 #include <limits.h>
0006 #include <stdio.h>
0007 #include <stdlib.h>
0008 #include <string.h>
0009 #include <unistd.h>
0010 
0011 #include "debug.h"
0012 #include "tests.h"
0013 #include <api/io.h>
0014 #include <linux/kernel.h>
0015 
0016 #define TEMPL "/tmp/perf-test-XXXXXX"
0017 
0018 #define EXPECT_EQUAL(val, expected)                             \
0019 do {                                \
0020     if (val != expected) {                  \
0021         pr_debug("%s:%d: %d != %d\n",           \
0022             __FILE__, __LINE__, val, expected); \
0023         ret = -1;                   \
0024     }                           \
0025 } while (0)
0026 
0027 #define EXPECT_EQUAL64(val, expected)                           \
0028 do {                                \
0029     if (val != expected) {                  \
0030         pr_debug("%s:%d: %lld != %lld\n",       \
0031             __FILE__, __LINE__, val, expected); \
0032         ret = -1;                   \
0033     }                           \
0034 } while (0)
0035 
0036 static int make_test_file(char path[PATH_MAX], const char *contents)
0037 {
0038     ssize_t contents_len = strlen(contents);
0039     int fd;
0040 
0041     strcpy(path, TEMPL);
0042     fd = mkstemp(path);
0043     if (fd < 0) {
0044         pr_debug("mkstemp failed");
0045         return -1;
0046     }
0047     if (write(fd, contents, contents_len) < contents_len) {
0048         pr_debug("short write");
0049         close(fd);
0050         unlink(path);
0051         return -1;
0052     }
0053     close(fd);
0054     return 0;
0055 }
0056 
0057 static int setup_test(char path[PATH_MAX], const char *contents,
0058               size_t buf_size, struct io *io)
0059 {
0060     if (make_test_file(path, contents))
0061         return -1;
0062 
0063     io->fd = open(path, O_RDONLY);
0064     if (io->fd < 0) {
0065         pr_debug("Failed to open '%s'\n", path);
0066         unlink(path);
0067         return -1;
0068     }
0069     io->buf = malloc(buf_size);
0070     if (io->buf == NULL) {
0071         pr_debug("Failed to allocate memory");
0072         close(io->fd);
0073         unlink(path);
0074         return -1;
0075     }
0076     io__init(io, io->fd, io->buf, buf_size);
0077     return 0;
0078 }
0079 
0080 static void cleanup_test(char path[PATH_MAX], struct io *io)
0081 {
0082     free(io->buf);
0083     close(io->fd);
0084     unlink(path);
0085 }
0086 
0087 static int do_test_get_char(const char *test_string, size_t buf_size)
0088 {
0089     char path[PATH_MAX];
0090     struct io io;
0091     int ch, ret = 0;
0092     size_t i;
0093 
0094     if (setup_test(path, test_string, buf_size, &io))
0095         return -1;
0096 
0097     for (i = 0; i < strlen(test_string); i++) {
0098         ch = io__get_char(&io);
0099 
0100         EXPECT_EQUAL(ch, test_string[i]);
0101         EXPECT_EQUAL(io.eof, false);
0102     }
0103     ch = io__get_char(&io);
0104     EXPECT_EQUAL(ch, -1);
0105     EXPECT_EQUAL(io.eof, true);
0106 
0107     cleanup_test(path, &io);
0108     return ret;
0109 }
0110 
0111 static int test_get_char(void)
0112 {
0113     int i, ret = 0;
0114     size_t j;
0115 
0116     static const char *const test_strings[] = {
0117         "12345678abcdef90",
0118         "a\nb\nc\nd\n",
0119         "\a\b\t\v\f\r",
0120     };
0121     for (i = 0; i <= 10; i++) {
0122         for (j = 0; j < ARRAY_SIZE(test_strings); j++) {
0123             if (do_test_get_char(test_strings[j], 1 << i))
0124                 ret = -1;
0125         }
0126     }
0127     return ret;
0128 }
0129 
0130 static int do_test_get_hex(const char *test_string,
0131             __u64 val1, int ch1,
0132             __u64 val2, int ch2,
0133             __u64 val3, int ch3,
0134             bool end_eof)
0135 {
0136     char path[PATH_MAX];
0137     struct io io;
0138     int ch, ret = 0;
0139     __u64 hex;
0140 
0141     if (setup_test(path, test_string, 4, &io))
0142         return -1;
0143 
0144     ch = io__get_hex(&io, &hex);
0145     EXPECT_EQUAL64(hex, val1);
0146     EXPECT_EQUAL(ch, ch1);
0147 
0148     ch = io__get_hex(&io, &hex);
0149     EXPECT_EQUAL64(hex, val2);
0150     EXPECT_EQUAL(ch, ch2);
0151 
0152     ch = io__get_hex(&io, &hex);
0153     EXPECT_EQUAL64(hex, val3);
0154     EXPECT_EQUAL(ch, ch3);
0155 
0156     EXPECT_EQUAL(io.eof, end_eof);
0157 
0158     cleanup_test(path, &io);
0159     return ret;
0160 }
0161 
0162 static int test_get_hex(void)
0163 {
0164     int ret = 0;
0165 
0166     if (do_test_get_hex("12345678abcdef90",
0167                 0x12345678abcdef90, -1,
0168                 0, -1,
0169                 0, -1,
0170                 true))
0171         ret = -1;
0172 
0173     if (do_test_get_hex("1\n2\n3\n",
0174                 1, '\n',
0175                 2, '\n',
0176                 3, '\n',
0177                 false))
0178         ret = -1;
0179 
0180     if (do_test_get_hex("12345678ABCDEF90;a;b",
0181                 0x12345678abcdef90, ';',
0182                 0xa, ';',
0183                 0xb, -1,
0184                 true))
0185         ret = -1;
0186 
0187     if (do_test_get_hex("0x1x2x",
0188                 0, 'x',
0189                 1, 'x',
0190                 2, 'x',
0191                 false))
0192         ret = -1;
0193 
0194     if (do_test_get_hex("x1x",
0195                 0, -2,
0196                 1, 'x',
0197                 0, -1,
0198                 true))
0199         ret = -1;
0200 
0201     if (do_test_get_hex("10000000000000000000000000000abcdefgh99i",
0202                 0xabcdef, 'g',
0203                 0, -2,
0204                 0x99, 'i',
0205                 false))
0206         ret = -1;
0207 
0208     return ret;
0209 }
0210 
0211 static int do_test_get_dec(const char *test_string,
0212             __u64 val1, int ch1,
0213             __u64 val2, int ch2,
0214             __u64 val3, int ch3,
0215             bool end_eof)
0216 {
0217     char path[PATH_MAX];
0218     struct io io;
0219     int ch, ret = 0;
0220     __u64 dec;
0221 
0222     if (setup_test(path, test_string, 4, &io))
0223         return -1;
0224 
0225     ch = io__get_dec(&io, &dec);
0226     EXPECT_EQUAL64(dec, val1);
0227     EXPECT_EQUAL(ch, ch1);
0228 
0229     ch = io__get_dec(&io, &dec);
0230     EXPECT_EQUAL64(dec, val2);
0231     EXPECT_EQUAL(ch, ch2);
0232 
0233     ch = io__get_dec(&io, &dec);
0234     EXPECT_EQUAL64(dec, val3);
0235     EXPECT_EQUAL(ch, ch3);
0236 
0237     EXPECT_EQUAL(io.eof, end_eof);
0238 
0239     cleanup_test(path, &io);
0240     return ret;
0241 }
0242 
0243 static int test_get_dec(void)
0244 {
0245     int ret = 0;
0246 
0247     if (do_test_get_dec("12345678abcdef90",
0248                 12345678, 'a',
0249                 0, -2,
0250                 0, -2,
0251                 false))
0252         ret = -1;
0253 
0254     if (do_test_get_dec("1\n2\n3\n",
0255                 1, '\n',
0256                 2, '\n',
0257                 3, '\n',
0258                 false))
0259         ret = -1;
0260 
0261     if (do_test_get_dec("12345678;1;2",
0262                 12345678, ';',
0263                 1, ';',
0264                 2, -1,
0265                 true))
0266         ret = -1;
0267 
0268     if (do_test_get_dec("0x1x2x",
0269                 0, 'x',
0270                 1, 'x',
0271                 2, 'x',
0272                 false))
0273         ret = -1;
0274 
0275     if (do_test_get_dec("x1x",
0276                 0, -2,
0277                 1, 'x',
0278                 0, -1,
0279                 true))
0280         ret = -1;
0281 
0282     if (do_test_get_dec("10000000000000000000000000000000000000000000000000000000000123456789ab99c",
0283                 123456789, 'a',
0284                 0, -2,
0285                 99, 'c',
0286                 false))
0287         ret = -1;
0288 
0289     return ret;
0290 }
0291 
0292 static int test__api_io(struct test_suite *test __maybe_unused,
0293             int subtest __maybe_unused)
0294 {
0295     int ret = 0;
0296 
0297     if (test_get_char())
0298         ret = TEST_FAIL;
0299     if (test_get_hex())
0300         ret = TEST_FAIL;
0301     if (test_get_dec())
0302         ret = TEST_FAIL;
0303     return ret;
0304 }
0305 
0306 DEFINE_SUITE("Test api io", api_io);