61 Resolve the given path to an absolute path,
62 expanding environment variables.
63 If path looks relative and does not point to anything
66 if isinstance(path, Path):
68 path = os.path.expandvars(path)
73 path, suffix = path.rsplit(
":", 1)
76 if not os.path.isabs(path):
77 base_dir = file_path_for_class(cls).parent
78 possible_path = str((base_dir / path).resolve())
79 if os.path.exists(possible_path):
136 Collect stack trace from a running process using the available debugger.
137 Uses lldb on macOS and gdb on Linux. Returns a message if no debugger
142 if sys.platform ==
"darwin":
144 if not shutil.which(
"lldb"):
145 return "(lldb not available for stack trace collection)"
157 if not shutil.which(
"gdb"):
158 return "(gdb not available for stack trace collection)"
164 "--eval-command=thread apply all backtrace",
166 debugger = subprocess.Popen(
167 cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
169 return debugger.communicate()[0].decode(
"utf-8", errors=
"backslashreplace")
188 Run the specified program and capture its output.
190 start_time = datetime.now()
193 proc = subprocess.Popen(
195 stdout=subprocess.PIPE,
196 stderr=subprocess.PIPE,
201 stdout_chunks, stderr_chunks = [], []
203 exceeded_stream = stack_trace = run_exception =
None
205 proc.stdout.fileno(): (stdout_chunks,
"stdout"),
206 proc.stderr.fileno(): (stderr_chunks,
"stderr"),
210 nonlocal stdout, stderr, exceeded_stream
211 while not exceeded_stream
and proc.poll()
is None:
212 readable, _, _ = select.select(streams.keys(), [], [], cls.
timeout)
213 for fileno
in readable:
214 data = os.read(fileno, 1024)
215 chunks, stream_name = streams[fileno]
217 if sum(len(chunk)
for chunk
in chunks) > STDOUT_LIMIT:
218 exceeded_stream = stream_name
221 stdout = b
"".join(stdout_chunks)
222 stderr = b
"".join(stderr_chunks)
224 thread = threading.Thread(target=read_output)
228 if thread.is_alive():
231 elif exceeded_stream:
233 "Stream exceeded size limit", exceeded_stream
236 end_time = datetime.now()
238 completed_process = subprocess.CompletedProcess(
240 returncode=proc.returncode,
251 env_to_record.extend(
252 env[name]
for name
in env
if re.match(
r"GAUDI_ENV_TO_RECORD(_\d+)?", name)
256 for key, value
in env.items()
257 if any(re.match(exp, key)
for exp
in env_to_record)
260 completed_process=completed_process,
261 start_time=start_time,
263 run_exception=run_exception,
265 expanded_command=command,
285 record_property: Callable[[str, str],
None],
286 fixture_result: FixtureResult,
287 reference_path: Optional[Path],
290 Record properties and handle any failures during fixture setup.
292 for key, value
in fixture_result.to_dict().items():
293 if value
is not None:
294 record_property(key, value)
296 record_property(
"reference_file", str(reference_path))
298 if fixture_result.run_exception:
299 pytest.fail(f
"{fixture_result.run_exception}")