pytest_http_server_simple.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #!/usr/bin/env python
  2. #
  3. # SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
  4. # SPDX-License-Identifier: Apache-2.0
  5. from __future__ import division, print_function, unicode_literals
  6. import logging
  7. import os
  8. import random
  9. import socket
  10. import string
  11. import sys
  12. import threading
  13. import time
  14. from builtins import range
  15. import pytest
  16. try:
  17. from idf_http_server_test import client
  18. except ModuleNotFoundError:
  19. sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', 'tools', 'ci', 'python_packages'))
  20. from idf_http_server_test import client
  21. from pytest_embedded import Dut
  22. class http_client_thread(threading.Thread):
  23. def __init__(self, ip: str, port: int, delay: int) -> None:
  24. threading.Thread.__init__(self)
  25. self.ip = ip
  26. self.port = port
  27. self.delay = delay
  28. self.exc = 0
  29. # Thread function used to open a socket and wait for specific amount of time before returning
  30. def open_connection(self, ip: str, port: int, delay: int) -> None:
  31. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  32. s.settimeout(delay)
  33. s.connect((ip, port))
  34. time.sleep(delay)
  35. def run(self) -> None:
  36. try:
  37. self.open_connection(self.ip, self.port, self.delay)
  38. except socket.timeout:
  39. self.exc = 1
  40. def join(self, timeout=None): # type: ignore
  41. threading.Thread.join(self)
  42. if self.exc:
  43. raise socket.timeout
  44. # When running on local machine execute the following before running this script
  45. # > make app bootloader
  46. # > make print_flash_cmd | tail -n 1 > build/download.config
  47. @pytest.mark.esp32
  48. @pytest.mark.esp32c3
  49. @pytest.mark.esp32s2
  50. @pytest.mark.esp32s3
  51. @pytest.mark.wifi
  52. def test_examples_protocol_http_server_simple(dut: Dut) -> None:
  53. # Get binary file
  54. binary_file = os.path.join(dut.app.binary_path, 'simple.bin')
  55. bin_size = os.path.getsize(binary_file)
  56. logging.info('http_server_bin_size : {}KB'.format(bin_size // 1024))
  57. # Upload binary and start testing
  58. logging.info('Starting http_server simple test app')
  59. # Parse IP address of STA
  60. logging.info('Waiting to connect with AP')
  61. got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode()
  62. got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode()
  63. logging.info('Got IP : {}'.format(got_ip))
  64. logging.info('Got Port : {}'.format(got_port))
  65. # Expected Logs
  66. dut.expect('Registering URI handlers', timeout=30)
  67. # Run test script
  68. # If failed raise appropriate exception
  69. logging.info('Test /hello GET handler')
  70. if not client.test_get_handler(got_ip, str(got_port)):
  71. raise RuntimeError
  72. # Acquire host IP. Need a way to check it
  73. dut.expect(r'(?:[\s\S]*)Found header => Host: (\d+.\d+.\d+.\d+)', timeout=30)
  74. # Match additional headers sent in the request
  75. dut.expect('Found header => Test-Header-2: Test-Value-2', timeout=30)
  76. dut.expect('Found header => Test-Header-1: Test-Value-1', timeout=30)
  77. dut.expect('Found URL query parameter => query1=value1', timeout=30)
  78. dut.expect('Found URL query parameter => query3=value3', timeout=30)
  79. dut.expect('Found URL query parameter => query2=value2', timeout=30)
  80. dut.expect('Request headers lost', timeout=30)
  81. logging.info('Test /ctrl PUT handler and realtime handler de/registration')
  82. if not client.test_put_handler(got_ip, got_port):
  83. raise RuntimeError
  84. dut.expect('Unregistering /hello and /echo URIs', timeout=30)
  85. dut.expect('Registering /hello and /echo URIs', timeout=30)
  86. # Generate random data of 10KB
  87. random_data = ''.join(string.printable[random.randint(0,len(string.printable)) - 1] for _ in range(10 * 1024))
  88. logging.info('Test /echo POST handler with random data')
  89. if not client.test_post_handler(got_ip, got_port, random_data):
  90. raise RuntimeError
  91. query = 'http://foobar'
  92. logging.info('Test /hello with custom query : {}'.format(query))
  93. if not client.test_custom_uri_query(got_ip, got_port, query):
  94. raise RuntimeError
  95. dut.expect('Found URL query => ' + query, timeout=30)
  96. query = 'abcd+1234%20xyz'
  97. logging.info('Test /hello with custom query : {}'.format(query))
  98. if not client.test_custom_uri_query(got_ip, got_port, query):
  99. raise RuntimeError
  100. dut.expect_exact('Found URL query => ' + query, timeout=30)
  101. @pytest.mark.esp32
  102. @pytest.mark.esp32c3
  103. @pytest.mark.esp32s2
  104. @pytest.mark.esp32s3
  105. @pytest.mark.wifi
  106. def test_examples_protocol_http_server_lru_purge_enable(dut: Dut) -> None:
  107. # Get binary file
  108. binary_file = os.path.join(dut.app.binary_path, 'simple.bin')
  109. bin_size = os.path.getsize(binary_file)
  110. logging.info('http_server_bin_size : {}KB'.format(bin_size // 1024))
  111. # Upload binary and start testing
  112. logging.info('Starting http_server simple test app')
  113. # Parse IP address of STA
  114. logging.info('Waiting to connect with AP')
  115. got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode()
  116. got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode()
  117. logging.info('Got IP : {}'.format(got_ip))
  118. logging.info('Got Port : {}'.format(got_port))
  119. # Expected Logs
  120. dut.expect('Registering URI handlers', timeout=30)
  121. threads = []
  122. # Open 20 sockets, one from each thread
  123. for _ in range(20):
  124. try:
  125. thread = http_client_thread(got_ip, (int(got_port)), 20)
  126. thread.start()
  127. threads.append(thread)
  128. except OSError as err:
  129. logging.info('Error: unable to start thread, {}'.format(err))
  130. for t in threads:
  131. t.join()