aboutsummaryrefslogtreecommitdiffstats
path: root/library/python/pytest/plugins/fixtures.py
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/python/pytest/plugins/fixtures.py
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/python/pytest/plugins/fixtures.py')
-rw-r--r--library/python/pytest/plugins/fixtures.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/library/python/pytest/plugins/fixtures.py b/library/python/pytest/plugins/fixtures.py
new file mode 100644
index 0000000000..6f7e0a27e4
--- /dev/null
+++ b/library/python/pytest/plugins/fixtures.py
@@ -0,0 +1,85 @@
+import os
+import pytest
+import six
+
+
+MAX_ALLOWED_LINKS_COUNT = 10
+
+
+@pytest.fixture
+def metrics(request):
+
+ class Metrics(object):
+ @classmethod
+ def set(cls, name, value):
+ assert len(name) <= 128, "Length of the metric name must less than 128"
+ assert type(value) in [int, float], "Metric value must be of type int or float"
+ test_name = request.node.nodeid
+ if test_name not in request.config.test_metrics:
+ request.config.test_metrics[test_name] = {}
+ request.config.test_metrics[test_name][name] = value
+
+ @classmethod
+ def set_benchmark(cls, benchmark_values):
+ # report of google has key 'benchmarks' which is a list of benchmark results
+ # yandex benchmark has key 'benchmark', which is a list of benchmark results
+ # use this to differentiate which kind of result it is
+ if 'benchmarks' in benchmark_values:
+ cls.set_gbenchmark(benchmark_values)
+ else:
+ cls.set_ybenchmark(benchmark_values)
+
+ @classmethod
+ def set_ybenchmark(cls, benchmark_values):
+ for benchmark in benchmark_values["benchmark"]:
+ name = benchmark["name"]
+ for key, value in six.iteritems(benchmark):
+ if key != "name":
+ cls.set("{}_{}".format(name, key), value)
+
+ @classmethod
+ def set_gbenchmark(cls, benchmark_values):
+ time_unit_multipliers = {"ns": 1, "us": 1000, "ms": 1000000}
+ time_keys = {"real_time", "cpu_time"}
+ ignore_keys = {"name", "run_name", "time_unit", "run_type", "repetition_index"}
+ for benchmark in benchmark_values["benchmarks"]:
+ name = benchmark["name"].replace('/', '_') # ci does not work properly with '/' in metric name
+ time_unit_mult = time_unit_multipliers[benchmark.get("time_unit", "ns")]
+ for k, v in six.iteritems(benchmark):
+ if k in time_keys:
+ cls.set("{}_{}".format(name, k), v * time_unit_mult)
+ elif k not in ignore_keys and isinstance(v, (float, int)):
+ cls.set("{}_{}".format(name, k), v)
+ return Metrics
+
+
+@pytest.fixture
+def links(request):
+
+ class Links(object):
+ @classmethod
+ def set(cls, name, path):
+
+ if len(request.config.test_logs[request.node.nodeid]) >= MAX_ALLOWED_LINKS_COUNT:
+ raise Exception("Cannot add more than {} links to test".format(MAX_ALLOWED_LINKS_COUNT))
+
+ reserved_names = ["log", "logsdir", "stdout", "stderr"]
+ if name in reserved_names:
+ raise Exception("Attachment name should not belong to the reserved list: {}".format(", ".join(reserved_names)))
+ output_dir = request.config.ya.output_dir
+
+ if not os.path.exists(path):
+ raise Exception("Path to be attached does not exist: {}".format(path))
+
+ if os.path.isabs(path) and ".." in os.path.relpath(path, output_dir):
+ raise Exception("Test attachment must be inside yatest.common.output_path()")
+
+ request.config.test_logs[request.node.nodeid][name] = path
+
+ @classmethod
+ def get(cls, name):
+ if name not in request.config.test_logs[request.node.nodeid]:
+ raise KeyError("Attachment with name '{}' does not exist".format(name))
+ return request.config.test_logs[request.node.nodeid][name]
+
+ return Links