From e3a3305adb1a067cad1aecb6d000afe2824c00d5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 29 Jun 2025 18:44:02 -0500 Subject: [PATCH] delete --- .../web_server/test_multipart_ota.py | 182 ------------------ .../components/web_server/test_ota_readme.md | 70 ------- 2 files changed, 252 deletions(-) delete mode 100755 tests/components/web_server/test_multipart_ota.py delete mode 100644 tests/components/web_server/test_ota_readme.md diff --git a/tests/components/web_server/test_multipart_ota.py b/tests/components/web_server/test_multipart_ota.py deleted file mode 100755 index 84e3264e1b..0000000000 --- a/tests/components/web_server/test_multipart_ota.py +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env python3 -""" -Test script for ESP-IDF web server multipart OTA upload functionality. -This script can be run manually to test OTA uploads to a running device. -""" - -import argparse -from pathlib import Path -import sys -import time - -import requests - - -def test_multipart_ota_upload(host, port, firmware_path): - """Test OTA firmware upload using multipart/form-data""" - base_url = f"http://{host}:{port}" - - print(f"Testing OTA upload to {base_url}") - - # First check if server is reachable - try: - resp = requests.get(f"{base_url}/", timeout=5) - if resp.status_code != 200: - print(f"Error: Server returned status {resp.status_code}") - return False - print("✓ Server is reachable") - except requests.exceptions.RequestException as e: - print(f"Error: Cannot reach server - {e}") - return False - - # Check if firmware file exists - if not Path(firmware_path).exists(): - print(f"Error: Firmware file not found: {firmware_path}") - return False - - # Prepare multipart upload - print(f"Uploading firmware: {firmware_path}") - print(f"File size: {Path(firmware_path).stat().st_size} bytes") - - try: - with open(firmware_path, "rb") as f: - files = {"firmware": ("firmware.bin", f, "application/octet-stream")} - - # Send OTA update request - resp = requests.post(f"{base_url}/ota/upload", files=files, timeout=60) - - if resp.status_code in [200, 201, 204]: - print(f"✓ OTA upload successful (status: {resp.status_code})") - if resp.text: - print(f"Response: {resp.text}") - return True - else: - print(f"✗ OTA upload failed with status {resp.status_code}") - print(f"Response: {resp.text}") - return False - - except requests.exceptions.RequestException as e: - print(f"Error during upload: {e}") - return False - - -def test_ota_with_wrong_content_type(host, port): - """Test that OTA upload fails gracefully with wrong content type""" - base_url = f"http://{host}:{port}" - - print("\nTesting OTA with wrong content type...") - - try: - # Send plain text instead of multipart - headers = {"Content-Type": "text/plain"} - resp = requests.post( - f"{base_url}/ota/upload", - data="This is not a firmware file", - headers=headers, - timeout=10, - ) - - if resp.status_code >= 400: - print( - f"✓ Server correctly rejected wrong content type (status: {resp.status_code})" - ) - return True - else: - print(f"✗ Server accepted wrong content type (status: {resp.status_code})") - return False - - except requests.exceptions.RequestException as e: - print(f"Error: {e}") - return False - - -def test_ota_with_empty_file(host, port): - """Test that OTA upload fails gracefully with empty file""" - base_url = f"http://{host}:{port}" - - print("\nTesting OTA with empty file...") - - try: - # Send empty file - files = {"firmware": ("empty.bin", b"", "application/octet-stream")} - resp = requests.post(f"{base_url}/ota/upload", files=files, timeout=10) - - if resp.status_code >= 400: - print( - f"✓ Server correctly rejected empty file (status: {resp.status_code})" - ) - return True - else: - print(f"✗ Server accepted empty file (status: {resp.status_code})") - return False - - except requests.exceptions.RequestException as e: - print(f"Error: {e}") - return False - - -def create_test_firmware(size_kb=10): - """Create a dummy firmware file for testing""" - import tempfile - - with tempfile.NamedTemporaryFile(suffix=".bin", delete=False) as f: - # ESP32 firmware magic bytes - f.write(b"\xe9\x08\x02\x20") - # Add padding - f.write(b"\x00" * (size_kb * 1024 - 4)) - return f.name - - -def main(): - parser = argparse.ArgumentParser( - description="Test ESP-IDF web server OTA functionality" - ) - parser.add_argument("--host", default="localhost", help="Device hostname or IP") - parser.add_argument("--port", type=int, default=8080, help="Web server port") - parser.add_argument( - "--firmware", help="Path to firmware file (if not specified, creates test file)" - ) - parser.add_argument( - "--skip-error-tests", action="store_true", help="Skip error condition tests" - ) - - args = parser.parse_args() - - # Create test firmware if not specified - firmware_path = args.firmware - if not firmware_path: - print("Creating test firmware file...") - firmware_path = create_test_firmware(100) # 100KB test file - print(f"Created test firmware: {firmware_path}") - - all_passed = True - - # Test successful OTA upload - if not test_multipart_ota_upload(args.host, args.port, firmware_path): - all_passed = False - - # Test error conditions - if not args.skip_error_tests: - time.sleep(1) # Small delay between tests - - if not test_ota_with_wrong_content_type(args.host, args.port): - all_passed = False - - time.sleep(1) - - if not test_ota_with_empty_file(args.host, args.port): - all_passed = False - - # Clean up test firmware if we created it - if not args.firmware: - import os - - os.unlink(firmware_path) - print("\nCleaned up test firmware") - - print(f"\n{'All tests passed!' if all_passed else 'Some tests failed!'}") - return 0 if all_passed else 1 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tests/components/web_server/test_ota_readme.md b/tests/components/web_server/test_ota_readme.md deleted file mode 100644 index bb93db6e06..0000000000 --- a/tests/components/web_server/test_ota_readme.md +++ /dev/null @@ -1,70 +0,0 @@ -# Testing ESP-IDF Web Server OTA Functionality - -This directory contains tests for the ESP-IDF web server OTA (Over-The-Air) update functionality using multipart form uploads. - -## Test Files - -- `test_ota.esp32-idf.yaml` - ESPHome configuration with OTA enabled for ESP-IDF -- `test_no_ota.esp32-idf.yaml` - ESPHome configuration with OTA disabled -- `test_ota_disabled.esp32-idf.yaml` - ESPHome configuration with web_server ota: false -- `test_multipart_ota.py` - Manual test script for OTA functionality -- `test_esp_idf_ota.py` - Automated pytest for OTA functionality - -## Running the Tests - -### 1. Compile and Flash Test Device - -```bash -# Compile the OTA-enabled configuration -esphome compile tests/components/web_server/test_ota.esp32-idf.yaml - -# Flash to device -esphome upload tests/components/web_server/test_ota.esp32-idf.yaml -``` - -### 2. Run Manual Tests - -Once the device is running, you can test OTA functionality: - -```bash -# Test with default settings (creates test firmware) -python tests/components/web_server/test_multipart_ota.py --host - -# Test with real firmware file -python tests/components/web_server/test_multipart_ota.py --host --firmware - -# Skip error condition tests (useful for production devices) -python tests/components/web_server/test_multipart_ota.py --host --skip-error-tests -``` - -### 3. Run Automated Tests - -```bash -# Run pytest suite -pytest tests/component_tests/web_server/test_esp_idf_ota.py -``` - -## What's Being Tested - -1. **Multipart Upload**: Tests that firmware can be uploaded using multipart/form-data -2. **Error Handling**: - - Wrong content type rejection - - Empty file rejection - - Concurrent upload handling -3. **Large Files**: Tests chunked processing of larger firmware files -4. **Boundary Parsing**: Tests various multipart boundary formats - -## Implementation Details - -The ESP-IDF web server uses the `multipart-parser` library to handle multipart uploads. Key components: - -- `MultipartReader` class for parsing multipart data -- Chunked processing to handle large files without excessive memory use -- Integration with ESPHome's OTA component for actual firmware updates - -## Troubleshooting - -1. **Connection Refused**: Make sure the device is on the network and the IP is correct -2. **404 Not Found**: Ensure OTA is enabled in the configuration (`ota: true` in web_server) -3. **Upload Fails**: Check device logs for detailed error messages -4. **Timeout**: Large firmware files may take time, increase timeout if needed \ No newline at end of file