0001
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);