| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  | from __future__ import print_function, unicode_literals | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-20 15:37:40 +08:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  | import random | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  | import re | 
					
						
							|  |  |  | import socket | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  | import string | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  | from threading import Event, Thread | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ttfw_idf | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  | from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket | 
					
						
							|  |  |  | from tiny_test_fw import Utility | 
					
						
							| 
									
										
										
										
											2019-06-20 15:37:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | def get_my_ip(): | 
					
						
							|  |  |  |     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         # doesn't even have to be reachable | 
					
						
							|  |  |  |         s.connect(('10.255.255.255', 1)) | 
					
						
							|  |  |  |         IP = s.getsockname()[0] | 
					
						
							|  |  |  |     except Exception: | 
					
						
							|  |  |  |         IP = '127.0.0.1' | 
					
						
							|  |  |  |     finally: | 
					
						
							|  |  |  |         s.close() | 
					
						
							|  |  |  |     return IP | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  | class TestEcho(WebSocket): | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  |     def handleMessage(self): | 
					
						
							|  |  |  |         self.sendMessage(self.data) | 
					
						
							|  |  |  |         print('Server sent: {}'.format(self.data)) | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  |     def handleConnected(self): | 
					
						
							|  |  |  |         print('Connection from: {}'.format(self.address)) | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  |     def handleClose(self): | 
					
						
							|  |  |  |         print('{} closed the connection'.format(self.address)) | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  | # Simple Websocket server for testing purposes | 
					
						
							|  |  |  | class Websocket(object): | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def send_data(self, data): | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  |         for nr, conn in self.server.connections.items(): | 
					
						
							|  |  |  |             conn.sendMessage(data) | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  |     def run(self): | 
					
						
							|  |  |  |         self.server = SimpleWebSocketServer('', self.port, TestEcho) | 
					
						
							|  |  |  |         while not self.exit_event.is_set(): | 
					
						
							|  |  |  |             self.server.serveonce() | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  |     def __init__(self, port): | 
					
						
							|  |  |  |         self.port = port | 
					
						
							|  |  |  |         self.exit_event = Event() | 
					
						
							|  |  |  |         self.thread = Thread(target=self.run) | 
					
						
							|  |  |  |         self.thread.start() | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         return self | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  |     def __exit__(self, exc_type, exc_value, traceback): | 
					
						
							|  |  |  |         self.exit_event.set() | 
					
						
							|  |  |  |         self.thread.join(10) | 
					
						
							|  |  |  |         if self.thread.is_alive(): | 
					
						
							|  |  |  |             Utility.console_log('Thread cannot be joined', 'orange') | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test_echo(dut): | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |     dut.expect('WEBSOCKET_EVENT_CONNECTED') | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  |     for i in range(0, 10): | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |         dut.expect(re.compile(r'Received=hello (\d)'), timeout=30) | 
					
						
							|  |  |  |     print('All echos received') | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  | def test_close(dut): | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |     code = dut.expect(re.compile(r'WEBSOCKET: Received closed message with code=(\d*)'), timeout=60)[0] | 
					
						
							|  |  |  |     print('Received close frame with code {}'.format(code)) | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  | def test_recv_long_msg(dut, websocket, msg_len, repeats): | 
					
						
							|  |  |  |     send_msg = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(msg_len)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for _ in range(repeats): | 
					
						
							|  |  |  |         websocket.send_data(send_msg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         recv_msg = '' | 
					
						
							|  |  |  |         while len(recv_msg) < msg_len: | 
					
						
							|  |  |  |             # Filter out color encoding | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |             match = dut.expect(re.compile(r'Received=([a-zA-Z0-9]*).*\n'), timeout=30)[0] | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  |             recv_msg += match | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if recv_msg == send_msg: | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |             print('Sent message and received message are equal') | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |             raise ValueError('DUT received string do not match sent string, \nexpected: {}\nwith length {}\
 | 
					
						
							|  |  |  |                             \nreceived: {}\nwith length {}'.format(send_msg, len(send_msg), recv_msg, len(recv_msg))) | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  | @ttfw_idf.idf_example_test(env_tag='Example_WIFI') | 
					
						
							| 
									
										
										
										
											2019-06-20 15:37:40 +08:00
										 |  |  | def test_examples_protocol_websocket(env, extra_data): | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  |     steps: | 
					
						
							| 
									
										
										
										
											2019-06-20 15:37:40 +08:00
										 |  |  |       1. join AP | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  |       2. connect to uri specified in the config | 
					
						
							| 
									
										
										
										
											2019-06-20 15:37:40 +08:00
										 |  |  |       3. send and receive data | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |     dut1 = env.get_dut('websocket', 'examples/protocols/websocket', dut_class=ttfw_idf.ESP32DUT) | 
					
						
							| 
									
										
										
										
											2019-06-20 15:37:40 +08:00
										 |  |  |     # check and log bin size | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |     binary_file = os.path.join(dut1.app.binary_path, 'websocket-example.bin') | 
					
						
							| 
									
										
										
										
											2019-06-20 15:37:40 +08:00
										 |  |  |     bin_size = os.path.getsize(binary_file) | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |     ttfw_idf.log_performance('websocket_bin_size', '{}KB'.format(bin_size // 1024)) | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |         if 'CONFIG_WEBSOCKET_URI_FROM_STDIN' in dut1.app.get_sdkconfig(): | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  |             uri_from_stdin = True | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |             uri = dut1.app.get_sdkconfig()['CONFIG_WEBSOCKET_URI'].strip('"') | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  |             uri_from_stdin = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     except Exception: | 
					
						
							|  |  |  |         print('ENV_TEST_FAILURE: Cannot find uri settings in sdkconfig') | 
					
						
							|  |  |  |         raise | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-20 15:37:40 +08:00
										 |  |  |     # start test | 
					
						
							|  |  |  |     dut1.start_app() | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if uri_from_stdin: | 
					
						
							|  |  |  |         server_port = 4455 | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  |         with Websocket(server_port) as ws: | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |             uri = 'ws://{}:{}'.format(get_my_ip(), server_port) | 
					
						
							|  |  |  |             print('DUT connecting to {}'.format(uri)) | 
					
						
							|  |  |  |             dut1.expect('Please enter uri of websocket endpoint', timeout=30) | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  |             dut1.write(uri) | 
					
						
							|  |  |  |             test_echo(dut1) | 
					
						
							| 
									
										
										
										
											2019-11-14 18:09:38 +08:00
										 |  |  |             # Message length should exceed DUT's buffer size to test fragmentation, default is 1024 byte | 
					
						
							|  |  |  |             test_recv_long_msg(dut1, ws, 2000, 3) | 
					
						
							| 
									
										
										
										
											2020-07-21 16:04:25 +02:00
										 |  |  |             test_close(dut1) | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-01-26 10:49:01 +08:00
										 |  |  |         print('DUT connecting to {}'.format(uri)) | 
					
						
							| 
									
										
										
										
											2019-10-15 17:27:47 +08:00
										 |  |  |         test_echo(dut1) | 
					
						
							| 
									
										
										
										
											2019-06-20 15:37:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     test_examples_protocol_websocket() |