16
16
Tracing '/**/src/<package>/__init__.py'
17
17
"""
18
18
19
+ import json
19
20
import os
20
21
import shutil
21
- import subprocess
22
22
import tempfile
23
23
import warnings
24
24
25
25
from collections .abc import Generator
26
- from datetime import datetime , timedelta
27
26
from pathlib import Path
27
+ from urllib .request import HTTPError , urlopen
28
28
29
29
import pytest
30
30
import yaml
35
35
from ansible_dev_environment .config import Config
36
36
37
37
38
- TESTING_CACHE = Path (__file__ ).parent .parent / ".cache" / ".galaxy_cache"
38
+ GALAXY_CACHE = Path (__file__ ).parent .parent / ".cache" / ".galaxy_cache"
39
+ REQS_FILE_NAME = "requirements.yml"
40
+
41
+
42
+ @pytest .fixture ()
43
+ def galaxy_cache () -> Path :
44
+ """Return the galaxy cache directory.
45
+
46
+ Returns:
47
+ The galaxy cache directory.
48
+ """
49
+ return GALAXY_CACHE
50
+
51
+
52
+ def check_download_collection (name : str , dest : Path ) -> None :
53
+ """Download a collection if necessary.
54
+
55
+ Args:
56
+ name: The collection name.
57
+ dest: The destination directory.
58
+ """
59
+ namespace , name = name .split ("." )
60
+ base_url = "https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections"
61
+
62
+ url = f"{ base_url } /index/{ namespace } /{ name } /versions/?is_highest=true"
63
+ try :
64
+ with urlopen (url ) as response : # noqa: S310
65
+ body = response .read ()
66
+ except HTTPError :
67
+ err = f"Failed to check collection version: { name } "
68
+ pytest .fail (err )
69
+ with urlopen (url ) as response : # noqa: S310
70
+ body = response .read ()
71
+ json_response = json .loads (body )
72
+ version = json_response ["data" ][0 ]["version" ]
73
+ file_name = f"{ namespace } -{ name } -{ version } .tar.gz"
74
+ file_path = dest / file_name
75
+ if file_path .exists ():
76
+ return
77
+ for found_file in dest .glob (f"{ namespace } -{ name } -*" ):
78
+ found_file .unlink ()
79
+ url = f"{ base_url } /artifacts/{ file_name } "
80
+ warnings .warn (f"Downloading collection: { file_name } " , stacklevel = 0 )
81
+ try :
82
+ with urlopen (url ) as response , file_path .open (mode = "wb" ) as file : # noqa: S310
83
+ file .write (response .read ())
84
+ except HTTPError :
85
+ err = f"Failed to download collection: { name } "
86
+ pytest .fail (err )
39
87
40
88
41
89
def pytest_sessionstart (session : pytest .Session ) -> None :
@@ -50,46 +98,19 @@ def pytest_sessionstart(session: pytest.Session) -> None:
50
98
if os .environ .get ("PYTEST_XDIST_WORKER" ):
51
99
return
52
100
53
- if not TESTING_CACHE .exists ():
54
- TESTING_CACHE .mkdir (parents = True , exist_ok = True )
55
-
56
- warnings .warn (f"Checking the galaxy cache: { TESTING_CACHE } " , stacklevel = 0 )
57
- update_needed = not any (TESTING_CACHE .iterdir ())
58
- warnings .warn (f"Update needed: { update_needed } " , stacklevel = 0 )
59
- tz = datetime .now ().astimezone ().tzinfo
60
- one_week_ago = datetime .now (tz ) - timedelta (weeks = 1 )
61
-
62
- if not update_needed :
63
- for file in TESTING_CACHE .glob ("*" ):
64
- file_creation = datetime .fromtimestamp (file .stat ().st_mtime , tz = tz )
65
- warnings .warn (f"File: { file .name } , created: { file_creation } " , stacklevel = 0 )
66
- if file_creation < one_week_ago :
67
- update_needed = True
68
- break
69
-
70
- if not update_needed :
71
- warnings .warn ("Galaxy cache is up to date." , stacklevel = 0 )
72
- return
101
+ if not GALAXY_CACHE .exists ():
102
+ GALAXY_CACHE .mkdir (parents = True , exist_ok = True )
73
103
74
- warnings .warn ("Updating the galaxy cache." , stacklevel = 0 )
75
- shutil .rmtree (TESTING_CACHE , ignore_errors = True )
76
- TESTING_CACHE .mkdir (parents = True , exist_ok = True )
104
+ for collection in ("ansible.utils" , "ansible.scm" , "ansible.posix" ):
105
+ check_download_collection (collection , GALAXY_CACHE )
77
106
78
- command = (
79
- "ansible-galaxy collection download"
80
- f" ansible.utils ansible.scm ansible.posix -p { TESTING_CACHE } / -vvv"
81
- )
82
- warnings .warn (f"Running: { command } " , stacklevel = 0 )
83
- subprocess .run (command , shell = True , check = True )
107
+ reqs : dict [str , list [dict [str , str ]]] = {"collections" : []}
84
108
85
- files = "," . join ( str ( f . name ) for f in list ( TESTING_CACHE .glob ("*" )))
86
- warnings . warn ( f"Galaxy cache updated, contains: { files } " , stacklevel = 0 )
109
+ for found_file in GALAXY_CACHE .glob ("*.tar.gz" ):
110
+ reqs [ "collections" ]. append ({ "name" : str ( found_file )} )
87
111
88
- requirements = TESTING_CACHE / "requirements.yml"
89
- contents = yaml .load (requirements .read_text (), Loader = yaml .SafeLoader )
90
- for collection in contents ["collections" ]:
91
- collection ["name" ] = f"file://{ TESTING_CACHE / collection ['name' ]} "
92
- requirements .write_text (yaml .dump (contents ))
112
+ requirements = GALAXY_CACHE / REQS_FILE_NAME
113
+ requirements .write_text (yaml .dump (reqs ))
93
114
94
115
95
116
@pytest .fixture (name = "monkey_session" , scope = "session" )
@@ -139,7 +160,7 @@ def session_venv(session_dir: Path, monkey_session: pytest.MonkeyPatch) -> Confi
139
160
"ade" ,
140
161
"install" ,
141
162
"-r" ,
142
- str (TESTING_CACHE / "requirements.yml" ),
163
+ str (GALAXY_CACHE / REQS_FILE_NAME ),
143
164
"--venv" ,
144
165
str (venv_path ),
145
166
"--ll" ,
@@ -159,3 +180,48 @@ def session_venv(session_dir: Path, monkey_session: pytest.MonkeyPatch) -> Confi
159
180
with pytest .raises (SystemExit ):
160
181
cli .run ()
161
182
return cli .config
183
+
184
+
185
+ @pytest .fixture ()
186
+ def function_venv (tmp_path : Path , monkeypatch : pytest .MonkeyPatch ) -> Config :
187
+ """Create a temporary venv for the session.
188
+
189
+ Add some common collections to the venv.
190
+
191
+ Since this is a session level fixture, care should be taken to not manipulate it
192
+ or the resulting config in a way that would affect other tests.
193
+
194
+ Args:
195
+ tmp_path: Temporary directory.
196
+ monkeypatch: Pytest monkeypatch fixture.
197
+
198
+ Returns:
199
+ The configuration object for the venv.
200
+ """
201
+ venv_path = tmp_path / "venv"
202
+ monkeypatch .setattr (
203
+ "sys.argv" ,
204
+ [
205
+ "ade" ,
206
+ "install" ,
207
+ "-r" ,
208
+ str (GALAXY_CACHE / REQS_FILE_NAME ),
209
+ "--venv" ,
210
+ str (venv_path ),
211
+ "--ll" ,
212
+ "debug" ,
213
+ "--la" ,
214
+ "true" ,
215
+ "--lf" ,
216
+ str (tmp_path / "ade.log" ),
217
+ "-vvv" ,
218
+ ],
219
+ )
220
+ cli = Cli ()
221
+ cli .parse_args ()
222
+ cli .init_output ()
223
+ cli .args_sanity ()
224
+ cli .ensure_isolated ()
225
+ with pytest .raises (SystemExit ):
226
+ cli .run ()
227
+ return cli .config
0 commit comments