1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-16 18:22:22 +01:00

Merge branch 'archive_bug' into integration

This commit is contained in:
J. Nick Koston
2025-09-15 17:44:54 -05:00
3 changed files with 103 additions and 6 deletions

View File

@@ -1075,12 +1075,9 @@ class ArchiveRequestHandler(BaseHandler):
shutil.move(config_file, os.path.join(archive_path, configuration))
storage_json = StorageJSON.load(storage_path)
if storage_json is not None:
if storage_json is not None and storage_json.build_path:
# Delete build folder (if exists)
name = storage_json.name
build_folder = os.path.join(settings.config_dir, name)
if build_folder is not None:
shutil.rmtree(build_folder, os.path.join(archive_path, name))
shutil.rmtree(storage_json.build_path, ignore_errors=True)
class UnArchiveRequestHandler(BaseHandler):

View File

@@ -589,7 +589,7 @@ async def test_archive_request_handler_post(
mock_ext_storage_path: MagicMock,
tmp_path: Path,
) -> None:
"""Test ArchiveRequestHandler.post method."""
"""Test ArchiveRequestHandler.post method without storage_json."""
# Set up temp directories
config_dir = Path(get_fixture_path("conf"))
@@ -616,6 +616,97 @@ async def test_archive_request_handler_post(
).read_text() == "esphome:\n name: test_archive\n"
@pytest.mark.asyncio
async def test_archive_handler_with_build_folder(
dashboard: DashboardTestHelper,
mock_archive_storage_path: MagicMock,
mock_ext_storage_path: MagicMock,
mock_dashboard_settings: MagicMock,
mock_storage_json: MagicMock,
tmp_path: Path,
) -> None:
"""Test ArchiveRequestHandler.post with storage_json and build folder."""
config_dir = tmp_path / "config"
config_dir.mkdir()
archive_dir = tmp_path / "archive"
archive_dir.mkdir()
build_dir = tmp_path / "build"
build_dir.mkdir()
configuration = "test_device.yaml"
test_config = config_dir / configuration
test_config.write_text("esphome:\n name: test_device\n")
build_folder = build_dir / "test_device"
build_folder.mkdir()
(build_folder / "firmware.bin").write_text("binary content")
(build_folder / ".pioenvs").mkdir()
mock_dashboard_settings.config_dir = str(config_dir)
mock_dashboard_settings.rel_path.return_value = str(test_config)
mock_archive_storage_path.return_value = str(archive_dir)
mock_storage = MagicMock()
mock_storage.name = "test_device"
mock_storage.build_path = str(build_folder)
mock_storage_json.load.return_value = mock_storage
response = await dashboard.fetch(
"/archive",
method="POST",
body=f"configuration={configuration}",
headers={"Content-Type": "application/x-www-form-urlencoded"},
)
assert response.code == 200
assert not test_config.exists()
assert (archive_dir / configuration).exists()
assert not build_folder.exists()
assert not (archive_dir / "test_device").exists()
@pytest.mark.asyncio
async def test_archive_handler_no_build_folder(
dashboard: DashboardTestHelper,
mock_archive_storage_path: MagicMock,
mock_ext_storage_path: MagicMock,
mock_dashboard_settings: MagicMock,
mock_storage_json: MagicMock,
tmp_path: Path,
) -> None:
"""Test ArchiveRequestHandler.post with storage_json but no build folder."""
config_dir = tmp_path / "config"
config_dir.mkdir()
archive_dir = tmp_path / "archive"
archive_dir.mkdir()
configuration = "test_device.yaml"
test_config = config_dir / configuration
test_config.write_text("esphome:\n name: test_device\n")
mock_dashboard_settings.config_dir = str(config_dir)
mock_dashboard_settings.rel_path.return_value = str(test_config)
mock_archive_storage_path.return_value = str(archive_dir)
mock_storage = MagicMock()
mock_storage.name = "test_device"
mock_storage.build_path = None
mock_storage_json.load.return_value = mock_storage
response = await dashboard.fetch(
"/archive",
method="POST",
body=f"configuration={configuration}",
headers={"Content-Type": "application/x-www-form-urlencoded"},
)
assert response.code == 200
assert not test_config.exists()
assert (archive_dir / configuration).exists()
assert not (archive_dir / "test_device").exists()
@pytest.mark.skipif(os.name == "nt", reason="Unix sockets are not supported on Windows")
@pytest.mark.usefixtures("mock_trash_storage_path", "mock_archive_storage_path")
def test_start_web_server_with_unix_socket(tmp_path: Path) -> None:

View File

@@ -384,6 +384,9 @@ def test_preload_core_config_basic(setup_core: Path) -> None:
assert platform == "esp32"
assert KEY_CORE in CORE.data
assert CONF_BUILD_PATH in config[CONF_ESPHOME]
# Verify default build path is "build/<device_name>"
build_path = config[CONF_ESPHOME][CONF_BUILD_PATH]
assert build_path.endswith(os.path.join("build", "test_device"))
def test_preload_core_config_with_build_path(setup_core: Path) -> None:
@@ -418,6 +421,12 @@ def test_preload_core_config_env_build_path(setup_core: Path) -> None:
assert CONF_BUILD_PATH in config[CONF_ESPHOME]
assert "test_device" in config[CONF_ESPHOME][CONF_BUILD_PATH]
# Verify it uses the env var path with device name appended
build_path = config[CONF_ESPHOME][CONF_BUILD_PATH]
expected_path = os.path.join("/env/build", "test_device")
assert build_path == expected_path or build_path == expected_path.replace(
"/", os.sep
)
assert platform == "rp2040"