api-io.c 5.3 KB

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