16
16
import platform
17
17
import signal
18
18
import shutil
19
+ import time
19
20
from pathlib import Path
20
21
21
22
import pytest
22
23
import simplejson as json
23
24
from invoke import Local
24
25
from invoke .context import Context
25
26
import tempfile
27
+ from filelock import FileLock
26
28
27
29
from .common import Board
28
30
@@ -54,22 +56,32 @@ def data_dir(tmpdir_factory):
54
56
if platform .system () == "Windows" :
55
57
with tempfile .TemporaryDirectory () as tmp :
56
58
yield tmp
57
- shutil .rmtree (tmp , ignore_errors = True )
59
+ # shutil.rmtree(tmp, ignore_errors=True)
58
60
else :
59
61
data = tmpdir_factory .mktemp ("ArduinoTest" )
60
62
yield str (data )
61
- shutil .rmtree (data , ignore_errors = True )
63
+ # shutil.rmtree(data, ignore_errors=True)
62
64
63
65
64
66
@pytest .fixture (scope = "session" )
65
- def downloads_dir (tmpdir_factory ):
67
+ def downloads_dir (tmpdir_factory , worker_id ):
66
68
"""
67
69
To save time and bandwidth, all the tests will access
68
70
the same download cache folder.
69
71
"""
70
- download_dir = tmpdir_factory .mktemp ("ArduinoTest" )
72
+ download_dir = tmpdir_factory .mktemp ("ArduinoTest" , numbered = False )
73
+
74
+ # This folders should be created only once per session, if we're running
75
+ # tests in parallel using multiple processes we need to make sure this
76
+ # this fixture is executed only once, thus the use of the lockfile
77
+ if not worker_id == "master" :
78
+ lock = Path (download_dir / "lock" )
79
+ with FileLock (lock ):
80
+ if not lock .is_file ():
81
+ lock .touch ()
82
+
71
83
yield str (download_dir )
72
- shutil .rmtree (download_dir , ignore_errors = True )
84
+ # shutil.rmtree(download_dir, ignore_errors=True)
73
85
74
86
75
87
@pytest .fixture (scope = "function" )
@@ -81,7 +93,7 @@ def working_dir(tmpdir_factory):
81
93
"""
82
94
work_dir = tmpdir_factory .mktemp ("ArduinoTestWork" )
83
95
yield str (work_dir )
84
- shutil .rmtree (work_dir , ignore_errors = True )
96
+ # shutil.rmtree(work_dir, ignore_errors=True)
85
97
86
98
87
99
@pytest .fixture (scope = "function" )
@@ -208,61 +220,16 @@ def copy_sketch(working_dir):
208
220
209
221
210
222
@pytest .fixture (scope = "function" )
211
- def core_update_index (run_command , data_dir , downloads_dir , working_dir , tmpdir_factory ):
212
- """
213
- To save time and bandwidth we install and cache cores indexes and copy them to each individual test environment
214
- """
215
-
216
- def _update_index ():
217
- index_dir = tmpdir_factory .getbasetemp () / "core-indexes"
218
- if not index_dir .exists ():
219
- index_dir .mkdir ()
220
- env = {
221
- "ARDUINO_DATA_DIR" : str (index_dir ),
222
- "ARDUINO_DOWNLOADS_DIR" : downloads_dir ,
223
- }
224
- run_command ("core update-index" , working_dir , env )
225
- shutil .copytree (index_dir , data_dir , dirs_exist_ok = True )
226
-
227
- return _update_index
228
-
229
-
230
- @pytest .fixture (scope = "function" )
231
- def lib_update_index (run_command , data_dir , downloads_dir , working_dir , tmpdir_factory ):
232
- """
233
- To save time and bandwidth we install and cache libraries indexes and copy them to each individual test environment
234
- """
235
-
236
- def _update_index ():
237
- index_dir = tmpdir_factory .getbasetemp () / "lib-indexes"
238
- if not index_dir .exists ():
239
- index_dir .mkdir ()
240
- env = {
241
- "ARDUINO_DATA_DIR" : str (index_dir ),
242
- "ARDUINO_DOWNLOADS_DIR" : downloads_dir ,
243
- }
244
- run_command ("lib update-index" , working_dir , env )
245
- shutil .copyfile (index_dir / "library_index.json" , Path (data_dir ) / "library_index.json" )
246
-
247
- return _update_index
248
-
249
-
250
- @pytest .fixture (scope = "function" )
251
- def core_install (run_command , data_dir , downloads_dir , working_dir , tmpdir_factory ):
252
- """
253
- To save time and bandwidth we install and cache cores and copy them to each individual test environment
254
- """
255
- data_dir = Path (data_dir ) / "packages"
256
-
257
- def _install (core ):
258
- core_dir = tmpdir_factory .getbasetemp () / core .replace (":" , "" )
259
- if not core_dir .exists ():
260
- core_dir .mkdir ()
261
- env = {
262
- "ARDUINO_DATA_DIR" : str (core_dir ),
263
- "ARDUINO_DOWNLOADS_DIR" : downloads_dir ,
264
- }
265
- run_command (f"core install { core } " , working_dir , env )
266
- shutil .copytree (core_dir / "packages" , data_dir , dirs_exist_ok = True )
267
-
268
- return _install
223
+ def wait_for_board (run_command ):
224
+ def _waiter (seconds = 10 ):
225
+ # Waits for the specified amount of second for a board to be visible.
226
+ # This is necessary since it might happen that a board is not immediately
227
+ # available after a test upload and subsequent tests might consequently fail.
228
+ time_end = time .time () + seconds
229
+ while time .time () < time_end :
230
+ result = run_command ("board list --format json" )
231
+ ports = json .loads (result .stdout )
232
+ if len ([p .get ("boards" , []) for p in ports ]) > 0 :
233
+ break
234
+
235
+ return _waiter
0 commit comments