@@ -22,8 +22,12 @@ def test_http_server_async_handler_multiple_long_requests(dut: Dut) -> None:
2222 # Parse IP address of Ethernet
2323 got_ip = dut .expect (r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]' , timeout = 30 )[1 ].decode ()
2424 got_port = 80 # Assuming the server is running on port 80
25- logging .info ('Got IP : {}' .format (got_ip ))
26- logging .info ('Connecting to server at {}:{}' .format (got_ip , got_port ))
25+ logging .info (f'Got IP : { got_ip } ' )
26+ dut .expect ('starting async req task worker' , timeout = 30 )
27+ dut .expect ('starting async req task worker' , timeout = 30 )
28+ dut .expect (f"Starting server on port: '{ got_port } '" , timeout = 30 )
29+ dut .expect ('Registering URI handlers' , timeout = 30 )
30+ logging .info (f'Connecting to server at { got_ip } :{ got_port } ' )
2731
2832 # Create two HTTP connections for long requests
2933 conn_long1 = http .client .HTTPConnection (got_ip , got_port , timeout = 30 )
@@ -73,8 +77,12 @@ def test_http_server_async_handler(dut: Dut) -> None:
7377 # Parse IP address of Ethernet
7478 got_ip = dut .expect (r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]' , timeout = 30 )[1 ].decode ()
7579 got_port = 80 # Assuming the server is running on port 80
76- logging .info ('Got IP : {}' .format (got_ip ))
77- logging .info ('Connecting to server at {}:{}' .format (got_ip , got_port ))
80+ logging .info (f'Got IP : { got_ip } ' )
81+ dut .expect ('starting async req task worker' , timeout = 30 )
82+ dut .expect ('starting async req task worker' , timeout = 30 )
83+ dut .expect (f"Starting server on port: '{ got_port } '" , timeout = 30 )
84+ dut .expect ('Registering URI handlers' , timeout = 30 )
85+ logging .info (f'Connecting to server at { got_ip } :{ got_port } ' )
7886
7987 # Create HTTP connection
8088 conn_long = http .client .HTTPConnection (got_ip , got_port , timeout = 15 )
@@ -102,3 +110,78 @@ def test_http_server_async_handler(dut: Dut) -> None:
102110 conn_quick .close ()
103111
104112 conn_long .close ()
113+
114+
115+ @pytest .mark .ethernet
116+ @idf_parametrize ('target' , ['esp32' ], indirect = ['target' ])
117+ def test_http_server_async_handler_same_session_sequential (dut : Dut ) -> None :
118+ """
119+ Test that verifies async completion fix:
120+ 1. Send /long request (async, 60 seconds)
121+ 2. Wait for completion
122+ 3. Send another request on same session
123+ 4. Verify second request works (doesn't get stuck)
124+ """
125+ # Get binary file
126+ binary_file = os .path .join (dut .app .binary_path , 'simple.bin' )
127+ bin_size = os .path .getsize (binary_file )
128+ logging .info (f'http_server_bin_size : { bin_size // 1024 } KB' )
129+ logging .info ('Waiting to connect with Ethernet' )
130+
131+ # Parse IP address of Ethernet
132+ got_ip = dut .expect (r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]' , timeout = 30 )[1 ].decode ()
133+ got_port = 80 # Assuming the server is running on port 80
134+ logging .info (f'Got IP : { got_ip } ' )
135+ dut .expect ('starting async req task worker' , timeout = 30 )
136+ dut .expect ('starting async req task worker' , timeout = 30 )
137+ dut .expect (f"Starting server on port: '{ got_port } '" , timeout = 30 )
138+ dut .expect ('Registering URI handlers' , timeout = 30 )
139+ logging .info (f'Connecting to server at { got_ip } :{ got_port } ' )
140+
141+ # Create HTTP connection for same session testing
142+ conn = http .client .HTTPConnection (got_ip , got_port , timeout = 70 ) # Longer timeout for async
143+
144+ # Test 1: Send /long request (async, 60 seconds)
145+ logging .info ('=== Test 1: Sending /long request (async) ===' )
146+ conn .request ('GET' , '/long?test=sequential1' )
147+
148+ # Verify request is received and processed
149+ dut .expect ('uri: /long' , timeout = 30 )
150+ dut .expect ('Found query string => test=sequential1' , timeout = 30 )
151+
152+ # Wait for async completion (60 seconds + buffer)
153+ logging .info ('Waiting for async /long request to complete (60 seconds)...' )
154+ start_time = time .time ()
155+
156+ # Get response (this will block until async handler completes)
157+ response_long = conn .getresponse ()
158+ completion_time = time .time () - start_time
159+
160+ logging .info (f'Response status for /long: { response_long .status } ' )
161+ logging .info (f'Async request completed in { completion_time :.2f} seconds' )
162+ assert response_long .status == 200 , 'Failed to access /long URI'
163+
164+ # Verify we got the full response (should contain 60 ticks)
165+ response_data = response_long .read ().decode ()
166+ assert 'req: 1' in response_data , 'Expected request count in response'
167+ assert '59' in response_data , 'Expected final tick (59) in response'
168+
169+ # Test 3: Send another /long request on same session
170+ logging .info ('=== Test 2: Sending another /long request on same session ===' )
171+ conn .request ('GET' , '/long?test=sequential3' )
172+
173+ # Verify third request is processed
174+ dut .expect ('uri: /long' , timeout = 30 )
175+ dut .expect ('Found query string => test=sequential3' , timeout = 30 )
176+
177+ # Get response for third request
178+ response_long2 = conn .getresponse ()
179+ logging .info (f'Response status for second /long: { response_long2 .status } ' )
180+ assert response_long2 .status == 200 , 'Failed to access second /long URI on same session'
181+
182+ # Verify we got the full response
183+ response_data2 = response_long2 .read ().decode ()
184+ assert 'req: 2' in response_data2 , 'Expected request count 2 in response'
185+
186+ conn .close ()
187+ logging .info ('=== Test completed successfully: Same session sequential requests work ===' )
0 commit comments