Last active
April 8, 2024 17:28
-
-
Save bukzor/2023fe0f7d8a0a500f5b0bd028c2b6f0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"name": "metadata", | |
"description": "test metadata, from test_metadata.py", | |
"fields": [ | |
{ | |
"name": "cwd", | |
"description": "current working directory", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "host", | |
"description": "fully-qualified hostname", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "env", | |
"description": "select environment variables -- especially PWD, HOME, USER, and GITHUB_*", | |
"type": "JSON", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "home", | |
"description": "user's home directory", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "username", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "uid", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "group", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "gid", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "test-data", | |
"description": "raw data collected from pytest-json-report plugin", | |
"fields": [ | |
{ | |
"name": "created", | |
"description": "Report creation date. (Unix time)", | |
"type": "FLOAT", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "duration", | |
"description": "Session duration in seconds.", | |
"type": "FLOAT", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "exitcode", | |
"description": "Process exit code as listed in the pytest docs. The exit code is a quick way to tell if any tests failed, an internal error occurred, etc.", | |
"type": "INTEGER", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "root", | |
"description": "Absolute root path from which the session was started.", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "summary", | |
"description": "Number of outcomes per category and the total number of test items.", | |
"type": "RECORD", | |
"mode": "REQUIRED", | |
"fields": [ | |
{ | |
"name": "collected", | |
"description": "Total number of tests collected.", | |
"type": "INTEGER", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "passed", | |
"description": "(absent if number is zero)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "failed", | |
"description": "(absent if number is zero)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "xfailed", | |
"description": "(absent if number is zero)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "xpassed", | |
"description": "(absent if number is zero)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "error", | |
"description": "(absent if number is zero)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "skipped", | |
"description": "(absent if number is zero)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "total", | |
"description": "Total number of tests run.", | |
"type": "INTEGER", | |
"mode": "REQUIRED" | |
} | |
] | |
}, | |
{ | |
"name": "environment", | |
"description": "The environment section is provided by pytest-metadata. All metadata given by that plugin will be added here, so you need to make sure it is JSON-serializable.", | |
"type": "RECORD", | |
"mode": "REQUIRED", | |
"fields": [] | |
}, | |
{ | |
"name": "collectors", | |
"description": "A list of collector nodes. These are useful to check what tests are available without running them, or to debug an error during test discovery.", | |
"type": "RECORD", | |
"mode": "REPEATED", | |
"fields": [ | |
{ | |
"name": "nodeid", | |
"description": "ID of the collector node. (See docs) The root node has an empty node ID.", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "outcome", | |
"description": "Outcome of the collection. (Not the test outcome!)", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "result", | |
"description": "Nodes collected by the collector.", | |
"type": "RECORD", | |
"mode": "REPEATED", | |
"fields": [ | |
{ | |
"name": "nodeid", | |
"description": "ID of the node.", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "type", | |
"description": "Type of the collected node.", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "lineno", | |
"description": "Line number. (absent if not applicable)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "deselected", | |
"description": "true if the test is deselected. (absent if not deselected)", | |
"type": "BOOL", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "longrepr", | |
"description": "Representation of the collection error. (absent if no error occurred)", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "tests", | |
"description": "A list of test nodes. Each completed test stage produces a stage object (setup, call, teardown) with its own outcome.", | |
"type": "RECORD", | |
"mode": "REPEATED", | |
"fields": [ | |
{ | |
"name": "nodeid", | |
"description": "ID of the test node.", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "lineno", | |
"description": "Line number where the test starts.", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "keywords", | |
"description": "List of keywords and markers associated with the test.", | |
"type": "STRING", | |
"mode": "REPEATED" | |
}, | |
{ | |
"name": "outcome", | |
"description": "Outcome of the test run.", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "setup", | |
"description": "Test stage entry. To find the error in a failed test you need to check all stages. (absent if stage didn't run)", | |
"type": "RECORD", | |
"mode": "NULLABLE", | |
"fields": [ | |
{ | |
"name": "duration", | |
"description": "Duration of the test stage in seconds.", | |
"type": "FLOAT", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "outcome", | |
"description": "Outcome of the test stage. (can be different from the overall test outcome)", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "crash", | |
"description": "Crash entry. (absent if no error occurred)", | |
"type": "RECORD", | |
"mode": "NULLABLE", | |
"fields": [ | |
{ | |
"name": "path", | |
"description": "path associated with the stack frame", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "lineno", | |
"description": "Line number. (absent if not applicable)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "message", | |
"description": "message associated with the stack frame", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "traceback", | |
"description": "List of traceback entries. (absent if no error occurred; affected by --tb option)", | |
"type": "RECORD", | |
"mode": "REPEATED", | |
"fields": [ | |
{ | |
"name": "path", | |
"description": "path associated with the stack frame", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "lineno", | |
"description": "Line number. (absent if not applicable)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "message", | |
"description": "message associated with the stack frame", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "stdout", | |
"description": "Standard output. (absent if none available)", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "stderr", | |
"description": "Standard error. (absent if none available)", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "log", | |
"description": "Log entry. (absent if none available)", | |
"type": "JSON", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "longrepr", | |
"description": "Representation of the error. (absent if no error occurred; format affected by --tb option)", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "call", | |
"description": "Test stage entry. To find the error in a failed test you need to check all stages. (absent if stage didn't run)", | |
"type": "RECORD", | |
"mode": "NULLABLE", | |
"fields": [ | |
{ | |
"name": "duration", | |
"description": "Duration of the test stage in seconds.", | |
"type": "FLOAT", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "outcome", | |
"description": "Outcome of the test stage. (can be different from the overall test outcome)", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "crash", | |
"description": "Crash entry. (absent if no error occurred)", | |
"type": "RECORD", | |
"mode": "NULLABLE", | |
"fields": [ | |
{ | |
"name": "path", | |
"description": "path associated with the stack frame", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "lineno", | |
"description": "Line number. (absent if not applicable)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "message", | |
"description": "message associated with the stack frame", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "traceback", | |
"description": "List of traceback entries. (absent if no error occurred; affected by --tb option)", | |
"type": "RECORD", | |
"mode": "REPEATED", | |
"fields": [ | |
{ | |
"name": "path", | |
"description": "path associated with the stack frame", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "lineno", | |
"description": "Line number. (absent if not applicable)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "message", | |
"description": "message associated with the stack frame", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "stdout", | |
"description": "Standard output. (absent if none available)", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "stderr", | |
"description": "Standard error. (absent if none available)", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "log", | |
"description": "Log entry. (absent if none available)", | |
"type": "JSON", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "longrepr", | |
"description": "Representation of the error. (absent if no error occurred; format affected by --tb option)", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "teardown", | |
"description": "Test stage entry. To find the error in a failed test you need to check all stages. (absent if stage didn't run)", | |
"type": "RECORD", | |
"mode": "NULLABLE", | |
"fields": [ | |
{ | |
"name": "duration", | |
"description": "Duration of the test stage in seconds.", | |
"type": "FLOAT", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "outcome", | |
"description": "Outcome of the test stage. (can be different from the overall test outcome)", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "crash", | |
"description": "Crash entry. (absent if no error occurred)", | |
"type": "RECORD", | |
"mode": "NULLABLE", | |
"fields": [ | |
{ | |
"name": "path", | |
"description": "path associated with the stack frame", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "lineno", | |
"description": "Line number. (absent if not applicable)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "message", | |
"description": "message associated with the stack frame", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "traceback", | |
"description": "List of traceback entries. (absent if no error occurred; affected by --tb option)", | |
"type": "RECORD", | |
"mode": "REPEATED", | |
"fields": [ | |
{ | |
"name": "path", | |
"description": "path associated with the stack frame", | |
"type": "STRING", | |
"mode": "REQUIRED" | |
}, | |
{ | |
"name": "lineno", | |
"description": "Line number. (absent if not applicable)", | |
"type": "INTEGER", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "message", | |
"description": "message associated with the stack frame", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "stdout", | |
"description": "Standard output. (absent if none available)", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "stderr", | |
"description": "Standard error. (absent if none available)", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "log", | |
"description": "Log entry. (absent if none available)", | |
"type": "JSON", | |
"mode": "NULLABLE" | |
}, | |
{ | |
"name": "longrepr", | |
"description": "Representation of the error. (absent if no error occurred; format affected by --tb option)", | |
"type": "STRING", | |
"mode": "NULLABLE" | |
} | |
] | |
}, | |
{ | |
"name": "metadata", | |
"description": "Metadata item. (absent if no metadata)", | |
"type": "JSON", | |
"mode": "NULLABLE" | |
} | |
] | |
} | |
] | |
} | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cwd": "/Users/buck/repo/buckevan-tmp-2024-03-29--pytest-data-collection", | |
"host": "jnpyxr75kj.lan", | |
"uid": 501, | |
"username": "buck", | |
"home": "/Users/buck", | |
"gid": 20, | |
"group": "staff", | |
"env": { | |
"CAML_LD_LIBRARY_PATH": "/Users/buck/.opam/default/lib/stublibs:/Users/buck/.opam/default/lib/ocaml/stublibs:/Users/buck/.opam/default/lib/ocaml", | |
"GEM_HOME": "/Users/buck/libxec/rubygems", | |
"GOPATH": "/Users/buck/libexec/gopath", | |
"HOME": "/Users/buck", | |
"HOMEBREW": "/opt/homebrew/bin/brew", | |
"HOMEBREW_CELLAR": "/opt/homebrew/Cellar", | |
"HOMEBREW_DEVELOPER": "1", | |
"HOMEBREW_EVAL_ALL": "1", | |
"HOMEBREW_MAKE_JOBS": "30", | |
"HOMEBREW_PREFIX": "/opt/homebrew", | |
"HOMEBREW_REPOSITORY": "/opt/homebrew", | |
"HOMEBREW_VERBOSE": "1", | |
"INFOPATH": "/opt/homebrew/share/info:/opt/homebrew/libexec/gnuinfo:/opt/homebrew/share/info:/opt/homebrew/libexec/gnuinfo:", | |
"LOGNAME": "buck", | |
"MANPATH": "/opt/homebrew/share/man:/opt/homebrew/libexec/gnuman:/usr/share/man:/usr/local/share/man:/opt/homebrew/share/man:/opt/homebrew/libexec/gnuman:/Applications/kitty.app/Contents/Resources/man:", | |
"OCAML_TOPLEVEL_PATH": "/Users/buck/.opam/default/lib/toplevel", | |
"PATH": "/Users/buck/.pyenv/versions/3.12.1/bin:/opt/homebrew/Cellar/pyenv/2.3.36/libexec:/opt/homebrew/Cellar/pyenv/2.3.36/plugins/python-build/bin:/Users/buck/.opam/default/bin:/Users/buck/.pyenv/shims:/Users/buck/.volta/bin:/Users/buck/.local/bin:/Users/buck/private-dotfiles/bin:/Users/buck/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/opt/homebrew/libexec/gnubin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/opt/homebrew/bin:/Applications/VMware Fusion.app/Contents/Public:/opt/salt:/Users/buck/.cargo/bin:/Applications/kitty.app/Contents/MacOS:/Users/buck/libexec/pnpm:/Users/buck/.local/share/sentry-devenv/bin", | |
"PNPM_HOME": "/Users/buck/libexec/pnpm", | |
"PWD": "/Users/buck/repo/buckevan-tmp-2024-03-29--pytest-data-collection", | |
"PYENV_HOOK_PATH": "/Users/buck/.pyenv/pyenv.d:/opt/homebrew/Cellar/pyenv/2.3.36/pyenv.d:/opt/homebrew/etc/pyenv.d:/etc/pyenv.d:/usr/lib/pyenv/hooks", | |
"PYTHONBREAKPOINT": "pudb.set_trace", | |
"PYTHONPATH": "/Users/buck/repo/buckevan-tmp-2024-03-29--pytest-data-collection/lib/python:/Users/buck/lib/python:/Users/buck/lib/python", | |
"PYTHONSTARTUP": "/Users/buck/.pythonrc.py", | |
"TMPDIR": "/var/folders/cc/xr5l1jgd4tz3w1d7tvkwq5sw0000gn/T", | |
"USER": "buck", | |
"VOLTA_HOME": "/Users/buck/.volta", | |
"XDG_CACHE_HOME": "/Users/buck/.cache", | |
"XDG_CONFIG_DIRS": "/etc/xdg", | |
"XDG_CONFIG_HOME": "/Users/buck/.config", | |
"XDG_DATA_DIRS": "/usr/local/share/:/usr/share/", | |
"XDG_DATA_HOME": "/Users/buck/.local/share", | |
"XDG_RUNTIME_DIR": "/var/folders/cc/xr5l1jgd4tz3w1d7tvkwq5sw0000gn/T/runtime-buck-1711903691", | |
"__orig_PATH": "/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/opt/homebrew/bin:/Applications/VMware Fusion.app/Contents/Public:/opt/salt:/Users/buck/.cargo/bin:/Applications/kitty.app/Contents/MacOS" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import grp | |
import os | |
import pwd | |
import socket | |
Environ = dict[str, str] | |
def relevant_env_var(var: str) -> bool: | |
# prefixes and suffixes of environment vars that we may want during | |
# debugging, test-result analysis, or traceback normalization | |
return var.endswith(("HOME", "PATH")) or var.startswith( | |
( | |
"USER", | |
"HOME", | |
"HOST", | |
"XDG", | |
"LOG", | |
"PWD", | |
"TMP", | |
"PYTHON", | |
"GITHUB", | |
"RUNNER", | |
"CI", | |
) | |
) | |
def get_env(env: Environ) -> Environ: | |
"""Keep the relevant parts of the environment variables.""" | |
relevant_vars = sorted(var for var in env if relevant_env_var(var)) | |
return {var: env[var] for var in relevant_vars} | |
def test_metadata(): | |
uid = os.getuid() | |
gid = os.getgid() | |
pw = pwd.getpwuid(uid) | |
gr = grp.getgrgid(gid) | |
return { | |
"cwd": os.getcwd(), | |
"host": socket.getfqdn(), | |
"uid": uid, | |
"username": pw.pw_name, | |
"home": pw.pw_dir, | |
"gid": gid, | |
"group": gr.gr_name, | |
"env": get_env(dict(os.environ)), | |
} | |
def main(): | |
import json | |
print(json.dumps(test_metadata(), indent=2)) | |
if __name__ == "__main__": | |
raise SystemExit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment