You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

linebuf_test.c 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. /** @file
  25. *
  26. * Line buffer self-tests
  27. *
  28. */
  29. /* Forcibly enable assertions */
  30. #undef NDEBUG
  31. #include <string.h>
  32. #include <assert.h>
  33. #include <ipxe/linebuf.h>
  34. #include <ipxe/test.h>
  35. /** Define inline raw data */
  36. #define DATA(...) { __VA_ARGS__ }
  37. /** Define inline lines */
  38. #define LINES(...) { __VA_ARGS__ }
  39. /** A line buffer test */
  40. struct linebuf_test {
  41. /** Raw data */
  42. const void *data;
  43. /** Length of raw data */
  44. size_t len;
  45. /** Expected sequence of lines */
  46. const char **lines;
  47. /** Number of expected lines */
  48. unsigned int count;
  49. };
  50. /** Line buffer test expected failure indicator */
  51. static const char linebuf_failure[1];
  52. /**
  53. * Define a line buffer test
  54. *
  55. * @v name Test name
  56. * @v DATA Raw data
  57. * @v LINES Expected sequence of lines
  58. * @ret test Line buffer test
  59. */
  60. #define LINEBUF_TEST( name, DATA, LINES ) \
  61. static const char name ## _data[] = DATA; \
  62. static const char * name ## _lines[] = LINES; \
  63. static struct linebuf_test name = { \
  64. .data = name ## _data, \
  65. .len = ( sizeof ( name ## _data ) - 1 /* NUL */ ), \
  66. .lines = name ## _lines, \
  67. .count = ( sizeof ( name ## _lines ) / \
  68. sizeof ( name ## _lines[0] ) ), \
  69. }
  70. /** Simple line buffer test */
  71. LINEBUF_TEST ( simple,
  72. ( "HTTP/1.1 200 OK\r\n"
  73. "Content-Length: 123\r\n"
  74. "Content-Type: text/plain\r\n"
  75. "\r\n" ),
  76. LINES ( "HTTP/1.1 200 OK",
  77. "Content-Length: 123",
  78. "Content-Type: text/plain",
  79. "" ) );
  80. /** Mixed line terminators */
  81. LINEBUF_TEST ( mixed,
  82. ( "LF only\n" "CRLF\r\n" "\n" "\n" "\r\n" "\r\n" "CR only\r" ),
  83. LINES ( "LF only", "CRLF", "", "", "", "",
  84. NULL /* \r should not be treated as a terminator */ ) );
  85. /** Split consumption: part 1 */
  86. LINEBUF_TEST ( split_1,
  87. ( "This line was" ),
  88. LINES ( NULL ) );
  89. /** Split consumption: part 2 */
  90. LINEBUF_TEST ( split_2,
  91. ( " split across" ),
  92. LINES ( NULL ) );
  93. /** Split consumption: part 3 */
  94. LINEBUF_TEST ( split_3,
  95. ( " multiple calls\r\nand so was this one\r" ),
  96. LINES ( "This line was split across multiple calls", NULL ) );
  97. /** Split consumption: part 4 */
  98. LINEBUF_TEST ( split_4,
  99. ( "\nbut not this one\r\n" ),
  100. LINES ( "and so was this one", "but not this one" ) );
  101. /** Split consumption: part 5 */
  102. LINEBUF_TEST ( split_5,
  103. ( "" ),
  104. LINES ( NULL ) );
  105. /** Split consumption: part 6 */
  106. LINEBUF_TEST ( split_6,
  107. ( "This line came after a zero-length call\r\n" ),
  108. LINES ( "This line came after a zero-length call" ) );
  109. /** Embedded NULs */
  110. LINEBUF_TEST ( embedded_nuls,
  111. ( "This\r\ntest\r\nincludes\r\n\r\nsome\0binary\0data\r\n" ),
  112. LINES ( "This", "test", "includes", "", linebuf_failure ) );
  113. /**
  114. * Report line buffer initialisation test result
  115. *
  116. * @v linebuf Line buffer
  117. * @v file Test code file
  118. * @v line Test code line
  119. */
  120. static void linebuf_init_okx ( struct line_buffer *linebuf,
  121. const char *file, unsigned int line ) {
  122. /* Initialise line buffer */
  123. memset ( linebuf, 0, sizeof ( *linebuf ) );
  124. okx ( buffered_line ( linebuf ) == NULL, file, line );
  125. }
  126. #define linebuf_init_ok( linebuf ) \
  127. linebuf_init_okx ( linebuf, __FILE__, __LINE__ )
  128. /**
  129. * Report line buffer consumption test result
  130. *
  131. * @v test Line buffer test
  132. * @v linebuf Line buffer
  133. * @v file Test code file
  134. * @v line Test code line
  135. */
  136. static void linebuf_consume_okx ( struct linebuf_test *test,
  137. struct line_buffer *linebuf,
  138. const char *file, unsigned int line ) {
  139. const char *data = test->data;
  140. size_t remaining = test->len;
  141. int len;
  142. unsigned int i;
  143. const char *expected;
  144. char *actual;
  145. int rc;
  146. DBGC ( test, "LINEBUF %p:\n", test );
  147. DBGC_HDA ( test, 0, data, remaining );
  148. /* Consume data one line at a time */
  149. for ( i = 0 ; i < test->count ; i++ ) {
  150. /* Add data to line buffer */
  151. len = line_buffer ( linebuf, data, remaining );
  152. /* Get buffered line, if any */
  153. actual = buffered_line ( linebuf );
  154. if ( len < 0 ) {
  155. rc = len;
  156. DBGC ( test, "LINEBUF %p %s\n", test, strerror ( rc ) );
  157. } else if ( actual != NULL ) {
  158. DBGC ( test, "LINEBUF %p \"%s\" (consumed %d)\n",
  159. test, actual, len );
  160. } else {
  161. DBGC ( test, "LINEBUF %p unterminated (consumed %d)\n",
  162. test, len );
  163. }
  164. /* Check for success/failure */
  165. expected = test->lines[i];
  166. if ( expected == linebuf_failure ) {
  167. rc = len;
  168. okx ( rc < 0, file, line );
  169. okx ( remaining > 0, file, line );
  170. return;
  171. }
  172. okx ( len >= 0, file, line );
  173. okx ( ( ( size_t ) len ) <= remaining, file, line );
  174. /* Check expected result */
  175. if ( expected == NULL ) {
  176. okx ( actual == NULL, file, line );
  177. } else {
  178. okx ( actual != NULL, file, line );
  179. okx ( strcmp ( actual, expected ) == 0, file, line );
  180. }
  181. /* Consume data */
  182. data += len;
  183. remaining -= len;
  184. }
  185. /* Check that all data was consumed */
  186. okx ( remaining == 0, file, line );
  187. }
  188. #define linebuf_consume_ok( test, linebuf ) \
  189. linebuf_consume_okx ( test, linebuf, __FILE__, __LINE__ )
  190. /**
  191. * Report line buffer accumulation test result
  192. *
  193. * @v test Line buffer test
  194. * @v linebuf Line buffer
  195. * @v file Test code file
  196. * @v line Test code line
  197. */
  198. static void linebuf_accumulated_okx ( struct linebuf_test *test,
  199. struct line_buffer *linebuf,
  200. const char *file, unsigned int line ) {
  201. const char *actual;
  202. const char *expected;
  203. unsigned int i;
  204. /* Check each accumulated line */
  205. actual = linebuf->data;
  206. for ( i = 0 ; i < test->count ; i++ ) {
  207. /* Check accumulated line */
  208. okx ( actual != NULL, file, line );
  209. okx ( actual >= linebuf->data, file, line );
  210. expected = test->lines[i];
  211. if ( ( expected == NULL ) || ( expected == linebuf_failure ) )
  212. return;
  213. okx ( strcmp ( actual, expected ) == 0, file, line );
  214. /* Move to next line */
  215. actual += ( strlen ( actual ) + 1 /* NUL */ );
  216. okx ( actual <= ( linebuf->data + linebuf->len ), file, line );
  217. }
  218. }
  219. #define linebuf_accumulated_ok( test, linebuf ) \
  220. linebuf_accumulated_okx ( test, linebuf, __FILE__, __LINE__ )
  221. /**
  222. * Report line buffer emptying test result
  223. *
  224. * @v linebuf Line buffer
  225. * @v file Test code file
  226. * @v line Test code line
  227. */
  228. static void linebuf_empty_okx ( struct line_buffer *linebuf,
  229. const char *file, unsigned int line ) {
  230. /* Empty line buffer */
  231. empty_line_buffer ( linebuf );
  232. okx ( buffered_line ( linebuf ) == NULL, file, line );
  233. }
  234. #define linebuf_empty_ok( linebuf ) \
  235. linebuf_empty_okx ( linebuf, __FILE__, __LINE__ )
  236. /**
  237. * Report line buffer combined test result
  238. *
  239. * @v test Line buffer test
  240. * @v file Test code file
  241. * @v line Test code line
  242. */
  243. static void linebuf_okx ( struct linebuf_test *test, const char *file,
  244. unsigned int line ) {
  245. struct line_buffer linebuf;
  246. linebuf_init_okx ( &linebuf, file, line );
  247. linebuf_consume_okx ( test, &linebuf, file, line );
  248. linebuf_accumulated_okx ( test, &linebuf, file, line );
  249. linebuf_empty_okx ( &linebuf, file, line );
  250. }
  251. #define linebuf_ok( test ) \
  252. linebuf_okx ( test, __FILE__, __LINE__ )
  253. /**
  254. * Perform line buffer self-tests
  255. *
  256. */
  257. static void linebuf_test_exec ( void ) {
  258. struct line_buffer linebuf;
  259. /* Basic tests */
  260. linebuf_ok ( &simple );
  261. linebuf_ok ( &mixed );
  262. /* Split consumption test */
  263. linebuf_init_ok ( &linebuf );
  264. linebuf_consume_ok ( &split_1, &linebuf );
  265. linebuf_consume_ok ( &split_2, &linebuf );
  266. linebuf_consume_ok ( &split_3, &linebuf );
  267. linebuf_consume_ok ( &split_4, &linebuf );
  268. linebuf_consume_ok ( &split_5, &linebuf );
  269. linebuf_consume_ok ( &split_6, &linebuf );
  270. linebuf_empty_ok ( &linebuf );
  271. /* Embedded NULs */
  272. linebuf_ok ( &embedded_nuls );
  273. }
  274. /** Line buffer self-test */
  275. struct self_test linebuf_test __self_test = {
  276. .name = "linebuf",
  277. .exec = linebuf_test_exec,
  278. };