gstlal 1.13.0
Loading...
Searching...
No Matches
testtools.py
1"""Test utilities. Common functions used across various GstLAL unittests
2"""
3
4import gi
5
6gi.require_version('Gst', '1.0')
7from gi.repository import GObject, Gst
8
9GObject.threads_init()
10Gst.init(None)
11import os
12import pathlib
13import string
14import sys
15import tempfile
16import types
17from typing import Tuple, Dict
18from unittest import mock
19
20import pytest
21
22PLATFORM = sys.platform
23
24DEFAULT_MOCK_PATCHES = (
25 # Ordered mapping of (target, {kwarg: value}) for passing into unittest.mock.patch
26 ('gstlal.datafind.load_frame_cache', {'return_value': [1, 2, 3]}),
27)
28CLEAN_TRANSLATION = {ord(c): None for c in string.whitespace}
29
30
31def clean_str(c: str):
32 """Clean a copyright string before comparison"""
33 return c.translate(CLEAN_TRANSLATION)
34
35
36def is_osx(platform: str = PLATFORM):
37 """Check is OSX"""
38 return platform.lower() == 'darwin'
39
40
41def skip_osx(f: types.FunctionType) -> types.FunctionType:
42 """Decorator wrapping pytest.skipif"""
43 return pytest.mark.skipif(is_osx(), reason='Test not supported on OSX')(f)
44
45
46def requires_full_build(f: types.FunctionType):
47 return pytest.mark.requires_full_build(f)
48
49
50def broken(reason: str):
51 def wrapper(f: types.FunctionType):
52 func = pytest.mark.skip(f, reason)
53 func = pytest.mark.broken(func)
54 return func
55
56 return wrapper
57
58
59def impl_deprecated(f):
60 return broken('Underlying implementation not included in build')(f)
61
62
64 """Context manager for GstLAL tests"""
65
66 def __init__(self, patch_info: Tuple[Dict[str, Dict]] = DEFAULT_MOCK_PATCHES, env_overrides: dict = None, with_pipeline: bool = False):
67 self.tmp_dir = tempfile.TemporaryDirectory()
68 self.tmp_path = pathlib.Path(self.tmp_dir.name)
69 self.patch_info = patch_info
70 self._patches = []
71 self._env_originals = {}
72 self._env_overrides = {} if env_overrides is None else env_overrides
73 self._with_pipeline = with_pipeline
74
75 def __enter__(self):
76 """Enter the GstLAL testing context"""
77
78 # Create temporary directory
79 self.tmp_dir.__enter__()
80
81 # Set all mocks
82 for target, kwargs in self.patch_info:
83 p = mock.patch(target, **kwargs)
84 self._patches.append(p)
85 p.__enter__()
86
87 # Set env overrides
88 keys = list(self._env_overrides.keys())
89 for k in keys:
90 self.override_env_var(k, self._env_overrides[k])
91
92 # Set pipeline
93 self.set_pipeline()
94
95 return self
96
97 def __exit__(self, exc_type, exc_val, exc_tb):
98 """Exit GstLAL context"""
99
100 # Remove tmp dir
101 self.tmp_dir.__exit__(exc_type, exc_val, exc_tb)
102
103 # Unset all mocks
104 for p in self._patches:
105 p.__exit__(exc_type, exc_val, exc_tb)
106
107 # Undo all env overrides
108 keys = list(self._env_originals.keys())
109 for k in keys:
110 self.reset_env_var(k)
111
112 @property
113 def cache_path(self):
114 """Cache path"""
115 return (self.tmp_path / 'cache.txt').as_posix()
116
117 def override_env_var(self, key: str, val: str):
118 if key in self._env_originals:
119 raise ValueError('That env var is already overridden')
120 self._env_originals[key] = os.environ.get(key, None)
121 self._env_overrides[key] = val
122 os.environ[key] = val
123
124 def reset_env_var(self, key: str):
125 if key not in self._env_originals:
126 raise ValueError('Unable to reset var: {}'.format(key))
127 val = self._env_originals.pop(key)
128 if val is None:
129 os.environ.pop(key)
130 else:
131 os.environ[key] = val
132 if key in self._env_overrides:
133 self._env_overrides.pop(key)
134
135 def set_pipeline(self):
136 if self._with_pipeline:
137 self.pipeline = Gst.Pipeline(name=os.path.split(sys.argv[0])[1])
138 else:
139 self.pipeline = None
__exit__(self, exc_type, exc_val, exc_tb)
Definition testtools.py:97
types.FunctionType skip_osx(types.FunctionType f)
Definition testtools.py:41
is_osx(str platform=PLATFORM)
Definition testtools.py:36