From fb0beefefb7da656d65a91fc26a6036fa255bc5b Mon Sep 17 00:00:00 2001 From: Shubham Kulkarni Date: Tue, 2 Feb 2021 13:26:27 +0530 Subject: [PATCH] advanced_https_ota: Add example_test for partial HTTP download --- .../ota/advanced_https_ota/example_test.py | 51 +++++++++++++++++-- .../advanced_https_ota/main/Kconfig.projbuild | 14 +++++ .../main/advanced_https_ota_example.c | 4 ++ .../sdkconfig.ci.partial_download | 5 ++ 4 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 examples/system/ota/advanced_https_ota/sdkconfig.ci.partial_download diff --git a/examples/system/ota/advanced_https_ota/example_test.py b/examples/system/ota/advanced_https_ota/example_test.py index 145361605a..6be27e2de5 100644 --- a/examples/system/ota/advanced_https_ota/example_test.py +++ b/examples/system/ota/advanced_https_ota/example_test.py @@ -9,7 +9,8 @@ import subprocess from threading import Thread import ttfw_idf -from tiny_test_fw import DUT +from RangeHTTPServer import RangeRequestHandler +from tiny_test_fw import DUT, Utility server_cert = '-----BEGIN CERTIFICATE-----\n' \ 'MIIDXTCCAkWgAwIBAgIJAP4LF7E72HakMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n'\ @@ -99,7 +100,7 @@ def https_request_handler(): """ Returns a request handler class that handles broken pipe exception """ - class RequestHandler(http.server.SimpleHTTPRequestHandler): + class RequestHandler(RangeRequestHandler): def finish(self): try: if not self.wfile.closed: @@ -111,7 +112,7 @@ def https_request_handler(): def handle(self): try: - http.server.BaseHTTPRequestHandler.handle(self) + RangeRequestHandler.handle(self) except socket.error: pass @@ -511,6 +512,49 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(env, extra_d os.remove(anti_rollback_bin_name) +@ttfw_idf.idf_example_test(env_tag='Example_WIFI') +def test_examples_protocol_advanced_https_ota_example_partial_request(env, extra_data): + """ + This is a positive test case, to test OTA workflow with Range HTTP header. + steps: | + 1. join AP + 2. Fetch OTA image over HTTPS + 3. Reboot with the new OTA image + """ + dut1 = env.get_dut('advanced_https_ota_example', 'examples/system/ota/advanced_https_ota', dut_class=ttfw_idf.ESP32DUT, app_config_name='partial_download') + server_port = 8001 + # File to be downloaded. This file is generated after compilation + bin_name = 'advanced_https_ota.bin' + # check and log bin size + binary_file = os.path.join(dut1.app.binary_path, bin_name) + bin_size = os.path.getsize(binary_file) + ttfw_idf.log_performance('advanced_https_ota_bin_size', '{}KB'.format(bin_size // 1024)) + http_requests = int((bin_size / 50000) + 1) + # start test + host_ip = get_my_ip() + if (get_server_status(host_ip, server_port) is False): + thread1 = Thread(target=start_https_server, args=(dut1.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() + dut1.start_app() + dut1.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut1.expect(re.compile(r' sta ip: ([^,]+),'), timeout=30) + print('Connected to AP with IP: {}'.format(ip_address)) + except DUT.ExpectTimeout: + Utility.console_log('ENV_TEST_FAILURE: Cannot connect to AP') + raise + dut1.expect('Starting Advanced OTA example', timeout=30) + + print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) + dut1.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) + for _ in range(http_requests): + dut1.expect('Connection closed', timeout=60) + dut1.expect('Loaded app from partition at offset', timeout=60) + dut1.expect('Starting Advanced OTA example', timeout=30) + dut1.reset() + + if __name__ == '__main__': test_examples_protocol_advanced_https_ota_example() test_examples_protocol_advanced_https_ota_example_chunked() @@ -519,3 +563,4 @@ if __name__ == '__main__': test_examples_protocol_advanced_https_ota_example_truncated_header() test_examples_protocol_advanced_https_ota_example_random() test_examples_protocol_advanced_https_ota_example_anti_rollback() + test_examples_protocol_advanced_https_ota_example_partial_request() diff --git a/examples/system/ota/advanced_https_ota/main/Kconfig.projbuild b/examples/system/ota/advanced_https_ota/main/Kconfig.projbuild index 0c6d32510d..c47fb17f5f 100644 --- a/examples/system/ota/advanced_https_ota/main/Kconfig.projbuild +++ b/examples/system/ota/advanced_https_ota/main/Kconfig.projbuild @@ -28,4 +28,18 @@ menu "Example Configuration" help Maximum time for reception + config EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD + bool "Enable partial HTTP download" + default n + help + This enables use of Range header in esp_https_ota component. + Firmware image will be downloaded over multiple HTTP requests. + + config EXAMPLE_HTTP_REQUEST_SIZE + int "HTTP request size" + default MBEDTLS_SSL_IN_CONTENT_LEN + depends on EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD + help + This options specifies HTTP request size. Number of bytes specified + in this option will be downloaded in single HTTP request. endmenu diff --git a/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c b/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c index 257016f697..04b3b145a6 100644 --- a/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c +++ b/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c @@ -110,6 +110,10 @@ void advanced_ota_example_task(void *pvParameter) esp_https_ota_config_t ota_config = { .http_config = &config, .http_client_init_cb = _http_client_init_cb, // Register a callback to be invoked after esp_http_client is initialized +#ifdef CONFIG_EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD + .partial_http_download = true, + .max_http_request_size = CONFIG_EXAMPLE_HTTP_REQUEST_SIZE, +#endif }; esp_https_ota_handle_t https_ota_handle = NULL; diff --git a/examples/system/ota/advanced_https_ota/sdkconfig.ci.partial_download b/examples/system/ota/advanced_https_ota/sdkconfig.ci.partial_download new file mode 100644 index 0000000000..bf8a545515 --- /dev/null +++ b/examples/system/ota/advanced_https_ota/sdkconfig.ci.partial_download @@ -0,0 +1,5 @@ +CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN" +CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y +CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y +CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=3000 +CONFIG_EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD=y