diff options
author | Andres Gomez <agomez@igalia.com> | 2020-07-29 23:24:04 +0300 |
---|---|---|
committer | Andres Gomez <agomez@igalia.com> | 2020-11-02 22:16:11 +0200 |
commit | faed7620ec69a63af78a5c7cb097b80ba0fe8e85 (patch) | |
tree | b537d0894bb73c56b6cbc21b9490e39e3205ad33 /framework | |
parent | bda3ad0a3bf7ec50a3dacff4a6368907def8ebd6 (diff) |
framework/replay: add programs module
v2:
- Updated the README.md
- Improved the documentation of the calls parameter
for the dump command.
- Added missing parameter in the dump program inner call.
v3:
- Make it compatible with python 3.6.
v4:
- Directly return the inner function return value in the compare
program.
v5:
- Remove extra empty line (Dylan).
Signed-off-by: Andres Gomez <agomez@igalia.com>
Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Part-of: <https://gitlab.freedesktop.org/mesa/piglit/-/merge_requests/353>
Diffstat (limited to 'framework')
-rw-r--r-- | framework/replay/README.md | 200 | ||||
-rw-r--r-- | framework/replay/programs/__init__.py | 0 | ||||
-rw-r--r-- | framework/replay/programs/checksum.py (renamed from framework/replay/parsers.py) | 41 | ||||
-rw-r--r-- | framework/replay/programs/compare.py | 108 | ||||
-rw-r--r-- | framework/replay/programs/download.py | 58 | ||||
-rw-r--r-- | framework/replay/programs/dump.py | 74 | ||||
-rw-r--r-- | framework/replay/programs/parsers.py | 85 | ||||
-rw-r--r-- | framework/replay/programs/query.py | 119 |
8 files changed, 568 insertions, 117 deletions
diff --git a/framework/replay/README.md b/framework/replay/README.md index f8d3cfaa2..9028fb80a 100644 --- a/framework/replay/README.md +++ b/framework/replay/README.md @@ -1,7 +1,5 @@ -Tracie - Mesa Traces Continuous Integration System -================================================== - -Home of the Mesa trace testing effort. +Replayer +======== ### Traces definition file @@ -27,140 +25,142 @@ traces: ``` The `traces-db` entry can be absent, in which case it is assumed that -the traces can be found in the `CWD/traces-db` directory. +the traces can be found in the `CWD/replayer-db` directory. Traces that don't have an expectation for the current device are skipped during trace replay. -Adding a new trace to the list involves commiting the trace to the git repo and -adding an entry to the `traces` list. The reference checksums can be calculated -with the [image_checksum.py](.gitlab-ci/tracie/image_checksum.py) script. -Alternatively, an arbitrary checksum can be used, and during replay (see below) -the scripts will report the mismatch and expected checksum. +Adding a new trace to the list involves uploading the trace to the +remote `traces-db` and adding an entry to the `traces` list. The +reference checksums can be calculated with the `checksum` command. +Alternatively, an arbitrary checksum can be used, and during replay +(see below) the scripts will report the mismatch and expected +checksum. ### Trace-db download urls The trace-db:download-url property contains an HTTPS url from which traces can be downloaded, by appending traces:path properties to it. -### Enabling trace testing on a new device - -To enable trace testing on a new device: - -1. Create a new job in .gitlab-ci.yml. The job will need to be tagged - to run on runners with the appropriate hardware. - - 1. If you mean to test GL traces, use the `.traces-test-gl` - template jobs as a base, and make sure you set a unique value for the - `DEVICE_NAME` variable: - - ```yaml - my-hardware-gl-traces: - extends: .traces-test-gl - variables: - DEVICE_NAME: "gl-myhardware" - ``` - - 2. If you mean to test Vulkan traces, use the `.traces-test-vk` - template jobs as a base, set the `VK_DRIVER` variable, and make - sure you set a unique value for the `DEVICE_NAME` variable: - - ```yaml - my-hardware-vk-traces: - extends: .traces-test-vk - variables: - VK_DRIVER: "radeon" - DEVICE_NAME: "vk-myhardware" - ``` - -2. Update the .gitlab-ci/traces.yml file with expectations for the new device. - Ensure that the device name used in the expectations matches the one - set in the job. For more information, and tips about how to calculate - the checksums, see the section describing the trace definition files. - ### Trace files -Tracie supports renderdoc (.rdc), apitrace (.trace) and gfxreconstruct -(.gfxr) files. Trace files need to have the correct extension so that -tracie can detect them properly. +replayer supports renderdoc (.rdc), apitrace (.trace, .trace-dxgi) and +gfxreconstruct (.gfxr) files. Trace files need to have the correct +extension so that replayer can detect them properly. -The trace files that are contained in public traces-db repositories must be -legally redistributable. This is typically true for FOSS games and -applications. Traces for proprietary games and application are typically not -redistributable, unless specific redistribution rights have been granted by the -publisher. +The trace files that are contained in public `traces-db` stores must +be legally redistributable. This is typically true for FOSS games and +applications. Traces for proprietary games and application are +typically not redistributable, unless specific redistribution rights +have been granted by the publisher. -Trace files in a given repository are expected to be immutable once committed -for the first time, so any changes need to be accompanied by a change in the -file name (eg. by appending a _v2 suffix to the file). +In order to have reliable comparisons, trace files in a given store +are expected to be immutable. Any change to a trace file means that it +needs to be renamed and updated in the traces definition file (eg. by +appending a _v2 suffix to the file). ### Replaying traces -Mesa traces CI uses a set of scripts to replay traces and check the output -against reference checksums. +replayer features a series of commands to deal with traces: + * `checksum`: will calculate the checksum for a given image file. + * `compare`: will download a trace or all the traces in a traces + definition file for a given device, replay them and compare their + checksum against the expected ones. + * `download`: will download a file, given a relative path, from a + remote url. + * `dump`: will dump as images the last call or specified calls from a + trace file, given a specific device. + * `query`: will return the queried information from a given traces + definition file. + +You can get a more complete help running: -The high level script [tracie.py](.gitlab-ci/tracie/tracie.py) accepts -commands to use a `yaml` traces definition file, `query` for data from -a traces definition file, or the description of an individual `trace`: + ```sh + $ replayer.py <command> --help + ``` Examples: ```sh - $ tracie.py yaml \ - --device-name gl-vmware-llvmpipe \ - --file .gitlab-ci/traces.yml + $ replayer.py checksum ./vkcube.gfxr-9.png ``` ```sh - $ tracie.py query \ - --file .gitlab-ci/traces.yml \ - traces \ - --device-name gl-vmware-llvmpipe \ - --trace-types apitrace,renderdoc \ - --checksum + $ replayer.py compare trace \ + --output ./results \ + --device-name gl-vmware-llvmpipe \ + --download-url https://minio-packet.freedesktop.org/mesa-tracie-public/ \ + glmark2/desktop-blur-radius=5:effect=blur:passes=1:separable=true:windows=4.rdc \ + 8867f3a41f180626d0d4b7661ff5c0f4 ``` ```sh - $ tracie.py trace \ - --device-name gl-vmware-llvmpipe \ - --download-url https://minio-packet.freedesktop.org/mesa-tracie-public/ \ - --path glmark2/jellyfish.rdc \ - --expected-checksum d82267c25a0decdad7b563c56bb81106 + $ replayer.py compare yaml \ + --yaml-file ./traces.yml \ + --device-name gl-vmware-llvmpipe \ + --keep-image ``` -tracie.py copies the produced artifacts to the `$CI_PROJECT_DIR/result` -directory. By default, created images from traces are only stored in case of a -checksum mismatch. The `TRACIE_STORE_IMAGES` CI/environment variable can be set -to `1` to force storing images, e.g., to get a complete set of reference -images. - -At a lower level the -[dump_trace_images.py](.gitlab-ci/tracie/dump_trace_images.py) script is -called, which replays a trace, dumping a set of images in the process. By -default only the image corresponding to the last frame of the trace is dumped, -but this can be changed with the `--calls` parameter. The dumped images are -stored in a subdirectory `test/<device-name>` next to the trace file itself, -with names of the form `tracefilename-callnum.png`. The full log of any -commands used while dumping the images is also saved in a file in the -'test/<device-name>' subdirectory, named after the trace name with '.log' -appended. + ```sh + $ replayer.py download \ + --download-url https://minio-packet.freedesktop.org/mesa-tracie-public/ \ + --db-path ./traces-db \ + --force-download \ + glmark2/desktop-blur-radius=5:effect=blur:passes=1:separable=true:windows=4.rdc + ``` -Examples: + ```sh + $ replayer.py dump \ + --config ./piglit.conf \ + --output ./results \ + --device-name gl-vmware-llvmpipe \ + --calls "3,8,9" \ + glmark2/desktop-blur-radius=5:effect=blur:passes=1:separable=true:windows=4.rdc + ``` + + ```sh + $ replayer.py query \ + --yaml-file ./traces.yml \ + checksum \ + --device-name gl-vmware-llvmpipe \ + glmark2/desktop-blur-radius=5:effect=blur:passes=1:separable=true:windows=4.rdc + ``` ```sh - $ python3 dump_traces_images.py --device-name=gl-vmware-llvmpipe mytrace.trace + $ replayer.py query \ + --yaml-file ./traces.yml \ + traces \ + --device-name gl-vmware-llvmpipe \ + --trace-types "apitrace,renderdoc" + --checksum ``` ```sh - $ python3 dump_traces_images.py --device-name=gl-vmware-llvmpipe --calls=2075,3300 mytrace.trace + $ replayer.py query \ + --yaml-file ./traces.yml \ + traces_db_download_url ``` -### Running the replay scripts locally +Unless specified when comparing or dumping, replayer places the +produced artifacts at the `CWD/results` directory. By default, created +images from traces are only stored in case of a checksum +mismatch. This can be overriden with the `--keep-image` parameter to +force storing images, e.g., to get a complete set of reference images. + +By default when dumping, only the image corresponding to the last frame +of the trace is created. This can be changed with the `--calls` +parameter. + +Unless specified with the `--output` parameter, the dumped images are +stored in the subdirectory `./test/<device-name>/<trace_file_path/` , +with names of the form `trace_file_name-call_num.png`. The full log +of any commands used while dumping the images is also saved in a file +in the 'test/<device-name>' subdirectory, named after the trace name +with '.log' appended. -It's often useful, especially during development, to be able to run the scripts -locally. +### Specific dependencies for dumping depending of the trace type -Depending on the target 3D API, the scripts require a recent version +Depending on the target 3D API, replayer requires a recent version of apitrace (and eglretrace) being in the path, and also the renderdoc python module being available, for GL traces. @@ -170,7 +170,7 @@ and `LD_LIBRARY_PATH` to point to the location of `librenderdoc.so`. In the renderdoc build tree, both of these are in `renderdoc/<builddir>/lib`. Note that renderdoc doesn't install the `renderdoc.so` python module. -In the case of Vulkan traces, the scripts need a recent version of +In the case of Vulkan traces, replayer needs a recent version of gfxrecon-info and gfxrecon-replay being in the path, and also the `VK_LAYER_LUNARG_screenshot` Vulkan layer from LunarG's VulkanTools. @@ -179,7 +179,7 @@ to set `VK_LAYER_PATH` to point to the location of `VkLayer_screenshot.json` and `LD_LIBRARY_PATH` to point to the location of `libVkLayer_screenshot.so`. -In the case of DXGI traces, the scripts require Wine, a recent version +In the case of DXGI traces, replayer requires Wine, a recent version of DXVK installed in the default `WINEPREFIX`, and a recent binary version of apitrace (and d3dretrace) for Windows which should be reachable through Windows' `PATH` environment variable. diff --git a/framework/replay/programs/__init__.py b/framework/replay/programs/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/framework/replay/programs/__init__.py diff --git a/framework/replay/parsers.py b/framework/replay/programs/checksum.py index 8d0c2531a..81e08f690 100644 --- a/framework/replay/parsers.py +++ b/framework/replay/programs/checksum.py @@ -1,6 +1,5 @@ # coding=utf-8 # -# Copyright (c) 2015-2016, 2019 Intel Corporation # Copyright © 2020 Valve Corporation. # # Permission is hereby granted, free of charge, to any person obtaining a @@ -25,20 +24,28 @@ import argparse +from framework import exceptions +from framework.replay import image_checksum -DEVICE = argparse.ArgumentParser(add_help=False) -DEVICE.add_argument( - '-d', '--device-name', - dest="device_name", - required=False, - default="", - help='the name of the graphics device used to replay traces') - -YAML = argparse.ArgumentParser(add_help=False) -YAML.add_argument( - '-f', '--file', - dest="yaml_file", - required=True, - type=argparse.FileType("r"), - help=('the name of the traces.yml file listing traces ' - 'and their checksums for each device')) + +__all__ = ['checksum'] + + +def _hexdigest_from_image(args): + print(image_checksum.hexdigest_from_image(args.file_path)) + + +@exceptions.handler +def checksum(input_): + """ Parser for replayer checksum command """ + parser = argparse.ArgumentParser() + + parser.add_argument( + 'file_path', + help=('the path to the image file ' + 'from which to calculate its checksum')) + parser.set_defaults(func=_hexdigest_from_image) + + args = parser.parse_args(input_) + + args.func(args) diff --git a/framework/replay/programs/compare.py b/framework/replay/programs/compare.py new file mode 100644 index 000000000..6647422a7 --- /dev/null +++ b/framework/replay/programs/compare.py @@ -0,0 +1,108 @@ +# coding=utf-8 +# +# Copyright © 2020 Valve Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +import argparse + +from framework import exceptions +from framework.replay import compare_replay +from framework.replay import options +from framework.programs import parsers as piglit_parsers +from . import parsers + + +__all__ = ['compare'] + + +def _from_yaml(args): + options.OPTIONS.device_name = args.device_name + options.OPTIONS.keep_image = args.keep_image + options.OPTIONS.download['force'] = args.force_download + options.OPTIONS.db_path = args.db_path + options.OPTIONS.results_path = args.output + + return compare_replay.from_yaml(args.yaml_file) + + +def _trace(args): + options.OPTIONS.device_name = args.device_name + options.OPTIONS.keep_image = args.keep_image + options.OPTIONS.set_download_url(args.download_url) + options.OPTIONS.download['force'] = args.force_download + options.OPTIONS.db_path = args.db_path + options.OPTIONS.results_path = args.output + + return compare_replay.trace(args.file_path, args.expected_checksum) + + +@exceptions.handler +def compare(input_): + """ Parser for replayer compare command """ + unparsed = piglit_parsers.parse_config(input_)[1] + + try: + # Set the parent of the config to add the -f/--config message + parser = argparse.ArgumentParser(parents=[piglit_parsers.CONFIG]) + # The "required" keyword is only available since python >= 3.7 + subparsers = parser.add_subparsers(dest='command', required=True) + except TypeError: + parser = argparse.ArgumentParser(parents=[piglit_parsers.CONFIG]) + # Add a destination due to + # https://github.com/python/cpython/pull/3027#issuecomment-330910633 + subparsers = parser.add_subparsers(dest='command') + + parser_trace = subparsers.add_parser( + 'trace', + parents=[parsers.DEVICE, + parsers.KEEP_IMAGE, + parsers.DOWNLOAD_URL, + parsers.DOWNLOAD_FORCE, + parsers.DB_PATH, + parsers.RESULTS_PATH], + help=('Compares a specific trace given a checksum and a device.')) + parser_trace.add_argument( + 'file_path', + help=('the relative path to the trace file inside the db path. ' + 'If not present and given that an URL has been provided ' + 'for its download, the relative path to the file in such URL.')) + parser_trace.add_argument( + 'expected_checksum', + help=('the expected checksum value to obtain ' + 'when replaying a trace in a specific device')) + parser_trace.set_defaults(func=_trace) + + parser_yaml = subparsers.add_parser( + 'yaml', + parents=[parsers.DEVICE, + parsers.KEEP_IMAGE, + parsers.YAML, + parsers.DOWNLOAD_FORCE, + parsers.DB_PATH, + parsers.RESULTS_PATH], + help=('Compares from a traces description file listing traces ' + 'and their checksums for a given device.')) + parser_yaml.set_defaults(func=_from_yaml) + + args = parser.parse_args(unparsed) + + return args.func(args) diff --git a/framework/replay/programs/download.py b/framework/replay/programs/download.py new file mode 100644 index 000000000..2a7311d81 --- /dev/null +++ b/framework/replay/programs/download.py @@ -0,0 +1,58 @@ +# coding=utf-8 +# +# Copyright © 2020 Valve Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +import argparse + +from framework import exceptions +from framework.replay import download_utils +from framework.replay import options +from . import parsers + + +__all__ = ['download'] + + +def _ensure_file(args): + options.OPTIONS.set_download_url(args.download_url) + options.OPTIONS.download['force'] = args.force_download + options.OPTIONS.db_path = args.db_path + + return download_utils.ensure_file(args.file_path) + + +@exceptions.handler +def download(input_): + """ Parser for replayer download command """ + parser = argparse.ArgumentParser(parents=[parsers.DOWNLOAD_URL, + parsers.DOWNLOAD_FORCE, + parsers.DB_PATH]) + parser.add_argument( + 'file_path', + help=('the path to the file ' + 'at the provided URL from which to download')) + parser.set_defaults(func=_ensure_file) + + args = parser.parse_args(input_) + + args.func(args) diff --git a/framework/replay/programs/dump.py b/framework/replay/programs/dump.py new file mode 100644 index 000000000..7a52ea0ac --- /dev/null +++ b/framework/replay/programs/dump.py @@ -0,0 +1,74 @@ +# coding=utf-8 +# +# Copyright © 2020 Valve Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +import argparse + +from framework import exceptions +from framework.replay import dump_trace_images +from framework.replay import options +from framework.programs import parsers as piglit_parsers +from . import parsers + + +__all__ = ['dump'] + + +def _dump_from_trace(args): + options.OPTIONS.device_name = args.device_name + options.OPTIONS.results_path = args.output + + if args.calls is not None: + calls = args.calls.split(",") + else: + calls = [] + + return dump_trace_images.dump_from_trace(args.file_path, args.output, + calls) + + +@exceptions.handler +def dump(input_): + """ Parser for replayer dump command """ + unparsed = piglit_parsers.parse_config(input_)[1] + + # Set the parent of the config to add the -f/--config message + parser = argparse.ArgumentParser(parents=[piglit_parsers.CONFIG, + parsers.DEVICE, + parsers.RESULTS_PATH]) + parser.add_argument( + '-c', '--calls', + dest='calls', + required=False, + default=None, + help=('a comma separated list of call numbers from the trace to dump ' + '(default: last frame).')) + parser.add_argument( + 'file_path', + help=('the path to the local trace file ' + 'from which to dump images.')) + parser.set_defaults(func=_dump_from_trace) + + args = parser.parse_args(unparsed) + + return 0 if args.func(args) else 1 diff --git a/framework/replay/programs/parsers.py b/framework/replay/programs/parsers.py new file mode 100644 index 000000000..70ada2147 --- /dev/null +++ b/framework/replay/programs/parsers.py @@ -0,0 +1,85 @@ +# coding=utf-8 +# +# Copyright (c) 2015-2016, 2019 Intel Corporation +# Copyright © 2020 Valve Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +import argparse + + +DEVICE = argparse.ArgumentParser(add_help=False) +DEVICE.add_argument( + '-d', '--device-name', + dest='device_name', + required=False, + default=None, + help='the name of the graphics device used to replay traces') + +KEEP_IMAGE = argparse.ArgumentParser(add_help=False) +KEEP_IMAGE.add_argument( + '-k', '--keep-image', + dest='keep_image', + action='store_true', + help=('forces keeping the image generated ' + 'for the comparison.')) + +YAML = argparse.ArgumentParser(add_help=False) +YAML.add_argument( + '-y', '--yaml-file', + dest='yaml_file', + required=True, + type=argparse.FileType('r'), + help=('the name of the traces YAML description file listing traces ' + 'and their checksums for each device')) + +DOWNLOAD_URL = argparse.ArgumentParser(add_help=False) +DOWNLOAD_URL.add_argument( + '-u', '--download-url', + dest='download_url', + required=False, + default=None, + help=('the URL from which to download the files')) + +DOWNLOAD_FORCE = argparse.ArgumentParser(add_help=False) +DOWNLOAD_FORCE.add_argument( + '-w', '--force-download', + dest='force_download', + action='store_true', + help=('forces downloading ' + 'even if the destination file already exists')) + +DB_PATH = argparse.ArgumentParser(add_help=False) +DB_PATH.add_argument( + '-p', '--db-path', + dest='db_path', + required=False, + default='./replayer-db/', + help=('the path to the objects db or where it will be created. ' + 'Defaults to "./replayer-db/".')) + +RESULTS_PATH = argparse.ArgumentParser(add_help=False) +RESULTS_PATH.add_argument( + '-o', '--output', + dest='output', + required=False, + default='./results/', + help=('the path in which to place the results. Defaults to "./results/"')) diff --git a/framework/replay/programs/query.py b/framework/replay/programs/query.py new file mode 100644 index 000000000..ba9b40585 --- /dev/null +++ b/framework/replay/programs/query.py @@ -0,0 +1,119 @@ +# coding=utf-8 +# +# Copyright (c) 2019 Collabora Ltd +# Copyright © 2020 Valve Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +import argparse + +from framework import exceptions +from framework.replay import query_traces_yaml as qty +from . import parsers + + +__all__ = ['query'] + + +def _traces_db_download_url(args): + y = qty.load_yaml(args.yaml_file) + + url = qty.download_url(y) or "" + + print(url) + + +def _traces(args): + y = qty.load_yaml(args.yaml_file) + + t_list = qty.traces(y, + trace_types=args.trace_types, + device_name=args.device_name, + checksum=args.checksum) + + if args.checksum: + print('\n'.join(((t['path'] + '\n' + t['checksum']) + for t in t_list))) + else: + print('\n'.join((t['path'] for t in t_list))) + + +def _checksum(args): + y = qty.load_yaml(args.yaml_file) + + traces = y['traces'] + try: + trace = next(t for t in traces if t['path'] == args.file_path) + except StopIteration: + print("") + return + + print(qty.trace_checksum(trace, args.device_name)) + + +@exceptions.handler +def query(input_): + """ Parser for replayer query command """ + try: + parser = argparse.ArgumentParser(parents=[parsers.YAML]) + # The "required" keyword is only available since python >= 3.7 + subparsers = parser.add_subparsers(dest='command', required=True) + except TypeError: + parser = argparse.ArgumentParser(parents=[parsers.YAML]) + # Add a destination due to + # https://github.com/python/cpython/pull/3027#issuecomment-330910633 + subparsers = parser.add_subparsers(dest='command') + + parser_checksum = subparsers.add_parser( + 'checksum', + parents=[parsers.DEVICE], + help=('Outputs, if available, the checksum that a specific device ' + 'should produce for a specified trace file.')) + parser_checksum.add_argument( + 'file_path', + help=('the path to a trace file.')) + parser_checksum.set_defaults(func=_checksum) + + parser_traces = subparsers.add_parser( + 'traces', + parents=[parsers.DEVICE], + help=('Outputs the trace files filtered by the optional arguments.')) + parser_traces.add_argument( + '-t', '--trace-types', + required=False, + default=None, + help=('a comma separated list of trace types to look for ' + 'in recursive dir walks. ' + 'If none are provide, all types are used by default')) + parser_traces.add_argument( + '-c', '--checksum', + action='store_true', + help='whether to print the checksum below every trace') + parser_traces.set_defaults(func=_traces) + + parser_traces_db_download_url = subparsers.add_parser( + 'traces_db_download_url', + help=('Outputs, if available, the download URL.')) + parser_traces_db_download_url.set_defaults(func=_traces_db_download_url) + + args = parser.parse_args(input_) + + args.func(args) |