test_http_server.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdlib.h>
  7. #include <stdbool.h>
  8. #include <esp_system.h>
  9. #include <esp_http_server.h>
  10. #include "unity.h"
  11. #include "test_utils.h"
  12. int pre_start_mem, post_stop_mem, post_stop_min_mem;
  13. bool basic_sanity = true;
  14. esp_err_t null_func(httpd_req_t *req)
  15. {
  16. return ESP_OK;
  17. }
  18. httpd_uri_t handler_limit_uri (char* path)
  19. {
  20. httpd_uri_t uri = {
  21. .uri = path,
  22. .method = HTTP_GET,
  23. .handler = null_func,
  24. .user_ctx = NULL,
  25. };
  26. return uri;
  27. };
  28. static inline unsigned num_digits(unsigned x)
  29. {
  30. unsigned digits = 1;
  31. while ((x = x/10) != 0) {
  32. digits++;
  33. }
  34. return digits;
  35. }
  36. #define HTTPD_TEST_MAX_URI_HANDLERS 8
  37. void test_handler_limit(httpd_handle_t hd)
  38. {
  39. int i;
  40. char x[HTTPD_TEST_MAX_URI_HANDLERS+1][num_digits(HTTPD_TEST_MAX_URI_HANDLERS)+1];
  41. httpd_uri_t uris[HTTPD_TEST_MAX_URI_HANDLERS+1];
  42. for (i = 0; i < HTTPD_TEST_MAX_URI_HANDLERS + 1; i++) {
  43. sprintf(x[i],"%d",i);
  44. uris[i] = handler_limit_uri(x[i]);
  45. }
  46. /* Register multiple instances of the same handler for MAX URI Handlers */
  47. for (i = 0; i < HTTPD_TEST_MAX_URI_HANDLERS; i++) {
  48. TEST_ASSERT(httpd_register_uri_handler(hd, &uris[i]) == ESP_OK);
  49. }
  50. /* Register the MAX URI + 1 Handlers should fail */
  51. TEST_ASSERT(httpd_register_uri_handler(hd, &uris[HTTPD_TEST_MAX_URI_HANDLERS]) != ESP_OK);
  52. /* Unregister the one of the Handler should pass */
  53. TEST_ASSERT(httpd_unregister_uri_handler(hd, uris[0].uri, uris[0].method) == ESP_OK);
  54. /* Unregister non added Handler should fail */
  55. TEST_ASSERT(httpd_unregister_uri_handler(hd, uris[0].uri, uris[0].method) != ESP_OK);
  56. /* Register the MAX URI Handler should pass */
  57. TEST_ASSERT(httpd_register_uri_handler(hd, &uris[0]) == ESP_OK);
  58. /* Reregister same instance of handler should fail */
  59. TEST_ASSERT(httpd_register_uri_handler(hd, &uris[0]) != ESP_OK);
  60. /* Register the MAX URI + 1 Handlers should fail */
  61. TEST_ASSERT(httpd_register_uri_handler(hd, &uris[HTTPD_TEST_MAX_URI_HANDLERS]) != ESP_OK);
  62. /* Unregister the same handler for MAX URI Handlers */
  63. for (i = 0; i < HTTPD_TEST_MAX_URI_HANDLERS; i++) {
  64. TEST_ASSERT(httpd_unregister_uri_handler(hd, uris[i].uri, uris[i].method) == ESP_OK);
  65. }
  66. basic_sanity = false;
  67. }
  68. /********************* Test Handler Limit End *******************/
  69. httpd_handle_t test_httpd_start(uint16_t id)
  70. {
  71. httpd_handle_t hd;
  72. httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  73. config.max_uri_handlers = HTTPD_TEST_MAX_URI_HANDLERS;
  74. config.server_port += id;
  75. config.ctrl_port += id;
  76. TEST_ASSERT(httpd_start(&hd, &config) == ESP_OK)
  77. return hd;
  78. }
  79. #define SERVER_INSTANCES 2
  80. /* Currently this only tests for the number of tasks.
  81. * Heap leakage is not tested as LWIP allocates memory
  82. * which may not be freed immedietly causing erroneous
  83. * evaluation. Another test to implement would be the
  84. * monitoring of open sockets, but LWIP presently provides
  85. * no such API for getting the number of open sockets.
  86. */
  87. TEST_CASE("Leak Test", "[HTTP SERVER]")
  88. {
  89. httpd_handle_t hd[SERVER_INSTANCES];
  90. unsigned task_count;
  91. bool res = true;
  92. test_case_uses_tcpip();
  93. task_count = uxTaskGetNumberOfTasks();
  94. printf("Initial task count: %d\n", task_count);
  95. pre_start_mem = esp_get_free_heap_size();
  96. for (int i = 0; i < SERVER_INSTANCES; i++) {
  97. hd[i] = test_httpd_start(i);
  98. vTaskDelay(10);
  99. unsigned num_tasks = uxTaskGetNumberOfTasks();
  100. task_count++;
  101. if (num_tasks != task_count) {
  102. printf("Incorrect task count (starting): %d expected %d\n",
  103. num_tasks, task_count);
  104. res = false;
  105. }
  106. }
  107. for (int i = 0; i < SERVER_INSTANCES; i++) {
  108. if (httpd_stop(hd[i]) != ESP_OK) {
  109. printf("Failed to stop httpd task %d\n", i);
  110. res = false;
  111. }
  112. vTaskDelay(10);
  113. unsigned num_tasks = uxTaskGetNumberOfTasks();
  114. task_count--;
  115. if (num_tasks != task_count) {
  116. printf("Incorrect task count (stopping): %d expected %d\n",
  117. num_tasks, task_count);
  118. res = false;
  119. }
  120. }
  121. post_stop_mem = esp_get_free_heap_size();
  122. TEST_ASSERT(res == true);
  123. }
  124. TEST_CASE("Basic Functionality Tests", "[HTTP SERVER]")
  125. {
  126. httpd_handle_t hd;
  127. httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  128. test_case_uses_tcpip();
  129. TEST_ASSERT(httpd_start(&hd, &config) == ESP_OK);
  130. test_handler_limit(hd);
  131. TEST_ASSERT(httpd_stop(hd) == ESP_OK);
  132. }
  133. TEST_CASE("URI Wildcard Matcher Tests", "[HTTP SERVER]")
  134. {
  135. struct uritest {
  136. const char *template;
  137. const char *uri;
  138. bool matches;
  139. };
  140. struct uritest uris[] = {
  141. {"/", "/", true},
  142. {"", "", true},
  143. {"/", "", false},
  144. {"/wrong", "/", false},
  145. {"/", "/wrong", false},
  146. {"/asdfghjkl/qwertrtyyuiuioo", "/asdfghjkl/qwertrtyyuiuioo", true},
  147. {"/path", "/path", true},
  148. {"/path", "/path/", false},
  149. {"/path/", "/path", false},
  150. {"?", "", false}, // this is not valid, but should not crash
  151. {"?", "sfsdf", false},
  152. {"/path/?", "/pa", false},
  153. {"/path/?", "/path", true},
  154. {"/path/?", "/path/", true},
  155. {"/path/?", "/path/alalal", false},
  156. {"/path/*", "/path", false},
  157. {"/path/*", "/", false},
  158. {"/path/*", "/path/", true},
  159. {"/path/*", "/path/blabla", true},
  160. {"*", "", true},
  161. {"*", "/", true},
  162. {"*", "/aaa", true},
  163. {"/path/?*", "/pat", false},
  164. {"/path/?*", "/pathb", false},
  165. {"/path/?*", "/pathxx", false},
  166. {"/path/?*", "/pathblabla", false},
  167. {"/path/?*", "/path", true},
  168. {"/path/?*", "/path/", true},
  169. {"/path/?*", "/path/blabla", true},
  170. {"/path/*?", "/pat", false},
  171. {"/path/*?", "/pathb", false},
  172. {"/path/*?", "/pathxx", false},
  173. {"/path/*?", "/path", true},
  174. {"/path/*?", "/path/", true},
  175. {"/path/*?", "/path/blabla", true},
  176. {"/path/*/xxx", "/path/", false},
  177. {"/path/*/xxx", "/path/*/xxx", true},
  178. {}
  179. };
  180. struct uritest *ut = &uris[0];
  181. while(ut->template != 0) {
  182. bool match = httpd_uri_match_wildcard(ut->template, ut->uri, strlen(ut->uri));
  183. TEST_ASSERT(match == ut->matches);
  184. ut++;
  185. }
  186. }
  187. TEST_CASE("Max Allowed Sockets Test", "[HTTP SERVER]")
  188. {
  189. test_case_uses_tcpip();
  190. httpd_handle_t hd;
  191. httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  192. /* Starting server with default config options should pass */
  193. TEST_ASSERT(httpd_start(&hd, &config) == ESP_OK);
  194. TEST_ASSERT(httpd_stop(hd) == ESP_OK);
  195. /* Default value of max_open_sockets is already set as per
  196. * maximum limit imposed by LWIP. Increasing this beyond the
  197. * maximum allowed value, without increasing LWIP limit,
  198. * should fail */
  199. config.max_open_sockets += 1;
  200. TEST_ASSERT(httpd_start(&hd, &config) != ESP_OK);
  201. }