fixtures.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import os
  2. import pytest
  3. import six
  4. from library.python.pytest.plugins.metrics import test_metrics
  5. MAX_ALLOWED_LINKS_COUNT = 10
  6. @pytest.fixture
  7. def metrics(request):
  8. class Metrics(object):
  9. @classmethod
  10. def set(cls, name, value):
  11. assert len(name) <= 256, "Length of the metric name must less than 128"
  12. assert type(value) in [int, float], "Metric value must be of type int or float"
  13. test_name = request.node.nodeid
  14. if test_name not in test_metrics.metrics:
  15. test_metrics[test_name] = {}
  16. test_metrics[test_name][name] = value
  17. @classmethod
  18. def set_benchmark(cls, benchmark_values):
  19. # report of google has key 'benchmarks' which is a list of benchmark results
  20. # yandex benchmark has key 'benchmark', which is a list of benchmark results
  21. # use this to differentiate which kind of result it is
  22. if 'benchmarks' in benchmark_values:
  23. cls.set_gbenchmark(benchmark_values)
  24. else:
  25. cls.set_ybenchmark(benchmark_values)
  26. @classmethod
  27. def set_ybenchmark(cls, benchmark_values):
  28. for benchmark in benchmark_values["benchmark"]:
  29. name = benchmark["name"]
  30. for key, value in six.iteritems(benchmark):
  31. if key != "name":
  32. cls.set("{}_{}".format(name, key), value)
  33. @classmethod
  34. def set_gbenchmark(cls, benchmark_values):
  35. time_unit_multipliers = {"ns": 1, "us": 1000, "ms": 1000000}
  36. time_keys = {"real_time", "cpu_time"}
  37. ignore_keys = {"name", "run_name", "time_unit", "run_type", "repetition_index"}
  38. for benchmark in benchmark_values["benchmarks"]:
  39. name = benchmark["name"].replace('/', '_') # ci does not work properly with '/' in metric name
  40. time_unit_mult = time_unit_multipliers[benchmark.get("time_unit", "ns")]
  41. for k, v in six.iteritems(benchmark):
  42. if k in time_keys:
  43. cls.set("{}_{}".format(name, k), v * time_unit_mult)
  44. elif k not in ignore_keys and isinstance(v, (float, int)):
  45. cls.set("{}_{}".format(name, k), v)
  46. return Metrics
  47. @pytest.fixture
  48. def links(request):
  49. class Links(object):
  50. @classmethod
  51. def set(cls, name, path):
  52. if len(request.config.test_logs[request.node.nodeid]) >= MAX_ALLOWED_LINKS_COUNT:
  53. raise Exception("Cannot add more than {} links to test".format(MAX_ALLOWED_LINKS_COUNT))
  54. reserved_names = ["log", "logsdir", "stdout", "stderr"]
  55. if name in reserved_names:
  56. raise Exception("Attachment name should not belong to the reserved list: {}".format(", ".join(reserved_names)))
  57. output_dir = request.config.ya.output_dir
  58. if not os.path.exists(path):
  59. raise Exception("Path to be attached does not exist: {}".format(path))
  60. if os.path.isabs(path) and ".." in os.path.relpath(path, output_dir):
  61. raise Exception("Test attachment must be inside yatest.common.output_path()")
  62. request.config.test_logs[request.node.nodeid][name] = path
  63. @classmethod
  64. def get(cls, name):
  65. if name not in request.config.test_logs[request.node.nodeid]:
  66. raise KeyError("Attachment with name '{}' does not exist".format(name))
  67. return request.config.test_logs[request.node.nodeid][name]
  68. return Links