2
2
3
3
import asyncio
4
4
import errno
5
- from pathlib import Path
5
+ import logging
6
+ from pathlib import Path , PurePath
6
7
from unittest .mock import AsyncMock , patch
7
8
8
- from pytest import LogCaptureFixture , raises
9
+ import pytest
9
10
11
+ from supervisor .backups .backup import Backup
12
+ from supervisor .backups .const import BackupType
10
13
from supervisor .const import CoreState
11
14
from supervisor .coresys import CoreSys
12
15
from supervisor .docker .interface import DockerInterface
13
16
from supervisor .exceptions import (
14
17
HomeAssistantBackupError ,
15
18
HomeAssistantWSConnectionError ,
16
19
)
20
+ from supervisor .homeassistant .module import HomeAssistant
17
21
from supervisor .homeassistant .secrets import HomeAssistantSecrets
18
22
from supervisor .homeassistant .websocket import HomeAssistantWebSocket
23
+ from supervisor .utils .dt import utcnow
19
24
20
25
21
26
async def test_load (
22
27
coresys : CoreSys , tmp_supervisor_data : Path , ha_ws_client : AsyncMock
23
28
):
24
29
"""Test homeassistant module load."""
25
- with open (tmp_supervisor_data / "homeassistant" / "secrets.yaml" , "w" ) as secrets :
30
+ with open (
31
+ tmp_supervisor_data / "homeassistant" / "secrets.yaml" , "w" , encoding = "utf-8"
32
+ ) as secrets :
26
33
secrets .write ("hello: world\n " )
27
34
28
35
# Unwrap read_secrets to prevent throttling between tests
@@ -32,7 +39,7 @@ async def test_load(
32
39
patch .object (
33
40
HomeAssistantSecrets ,
34
41
"_read_secrets" ,
35
- new = HomeAssistantSecrets ._read_secrets .__wrapped__ ,
42
+ new = HomeAssistantSecrets ._read_secrets .__wrapped__ , # pylint: disable=protected-access,no-member
36
43
),
37
44
):
38
45
await coresys .homeassistant .load ()
@@ -59,7 +66,7 @@ async def test_get_users_none(coresys: CoreSys, ha_ws_client: AsyncMock):
59
66
)
60
67
61
68
62
- def test_write_pulse_error (coresys : CoreSys , caplog : LogCaptureFixture ):
69
+ def test_write_pulse_error (coresys : CoreSys , caplog : pytest . LogCaptureFixture ):
63
70
"""Test errors writing pulse config."""
64
71
with patch (
65
72
"supervisor.homeassistant.module.Path.write_text" ,
@@ -87,15 +94,15 @@ async def test_begin_backup_ws_error(coresys: CoreSys):
87
94
)
88
95
with (
89
96
patch .object (HomeAssistantWebSocket , "_can_send" , return_value = True ),
90
- raises (
97
+ pytest . raises (
91
98
HomeAssistantBackupError ,
92
99
match = "Preparing backup of Home Assistant Core failed. Check HA Core logs." ,
93
100
),
94
101
):
95
102
await coresys .homeassistant .begin_backup ()
96
103
97
104
98
- async def test_end_backup_ws_error (coresys : CoreSys , caplog : LogCaptureFixture ):
105
+ async def test_end_backup_ws_error (coresys : CoreSys , caplog : pytest . LogCaptureFixture ):
99
106
"""Test WS error when ending backup."""
100
107
# pylint: disable-next=protected-access
101
108
coresys .homeassistant .websocket ._client .async_send_command .side_effect = (
@@ -108,3 +115,67 @@ async def test_end_backup_ws_error(coresys: CoreSys, caplog: LogCaptureFixture):
108
115
"Error resuming normal operations after backup of Home Assistant Core. Check HA Core logs."
109
116
in caplog .text
110
117
)
118
+
119
+
120
+ @pytest .mark .parametrize (
121
+ ("filename" , "exclude_db" , "expect_excluded" , "subfolder" ),
122
+ [
123
+ ("home-assistant.log" , False , True , None ),
124
+ ("home-assistant.log.1" , False , True , None ),
125
+ ("home-assistant.log.fault" , False , True , None ),
126
+ ("home-assistant.log" , False , False , "subfolder" ),
127
+ ("OZW_Log.txt" , False , True , None ),
128
+ ("OZW_Log.txt" , False , False , "subfolder" ),
129
+ ("home-assistant_v2.db-shm" , False , True , None ),
130
+ ("home-assistant_v2.db-shm" , False , False , "subfolder" ),
131
+ ("home-assistant_v2.db" , False , False , None ),
132
+ ("home-assistant_v2.db" , True , True , None ),
133
+ ("home-assistant_v2.db" , True , False , "subfolder" ),
134
+ ("home-assistant_v2.db-wal" , False , False , None ),
135
+ ("home-assistant_v2.db-wal" , True , True , None ),
136
+ ("home-assistant_v2.db-wal" , True , False , "subfolder" ),
137
+ ("test.tar" , False , True , "backups" ),
138
+ ("test.tar" , False , False , "subfolder/backups" ),
139
+ ("test.tar" , False , True , "tmp_backups" ),
140
+ ("test.tar" , False , False , "subfolder/tmp_backups" ),
141
+ ("test" , False , True , "tts" ),
142
+ ("test" , False , False , "subfolder/tts" ),
143
+ ("test.cpython-312.pyc" , False , True , "__pycache__" ),
144
+ ("test.cpython-312.pyc" , False , True , "subfolder/__pycache__" ),
145
+ (".DS_Store" , False , True , None ),
146
+ (".DS_Store" , False , True , "subfolder" ),
147
+ ],
148
+ )
149
+ @pytest .mark .usefixtures ("tmp_supervisor_data" )
150
+ async def test_backup_excludes (
151
+ coresys : CoreSys ,
152
+ caplog : pytest .LogCaptureFixture ,
153
+ filename : str ,
154
+ exclude_db : bool ,
155
+ expect_excluded : bool ,
156
+ subfolder : str | None ,
157
+ ):
158
+ """Test excludes in backup."""
159
+ parent = coresys .config .path_homeassistant
160
+ if subfolder :
161
+ test_path = PurePath (subfolder , filename )
162
+ parent = coresys .config .path_homeassistant / subfolder
163
+ parent .mkdir (parents = True )
164
+ else :
165
+ test_path = PurePath (filename )
166
+
167
+ (parent / filename ).touch ()
168
+
169
+ backup = Backup (coresys , coresys .config .path_backup / "test.tar" , "test" , None )
170
+ backup .new ("test" , utcnow ().isoformat (), BackupType .PARTIAL )
171
+ async with backup .create ():
172
+ with (
173
+ patch .object (HomeAssistant , "begin_backup" ),
174
+ patch .object (HomeAssistant , "end_backup" ),
175
+ caplog .at_level (logging .DEBUG , logger = "supervisor.homeassistant.module" ),
176
+ ):
177
+ await backup .store_homeassistant (exclude_database = exclude_db )
178
+
179
+ assert (
180
+ f"Ignoring data/{ test_path .as_posix ()} because of " in caplog .text
181
+ ) is expect_excluded
0 commit comments