Skip to content

Commit 1d1d6c1

Browse files
Merge pull request #11 from shashank-boyapally/fmatch
fmatch unit tests and github actions
2 parents 506f606 + 0bfdf8e commit 1d1d6c1

File tree

5 files changed

+324
-2
lines changed

5 files changed

+324
-2
lines changed

.github/workflows/unit_test.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Run pytest on Pull Request
2+
3+
on: [push,pull_request]
4+
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
9+
env:
10+
ES_SERVER: ${{ secrets.ES_SERVER }}
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v2
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v2
18+
with:
19+
python-version: 3.11
20+
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install -r fmatch/requirements.txt
25+
26+
- name: Run pytest
27+
run: |
28+
python -m pytest fmatch/tests --cov --random-order

fmatch/matcher.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ def burner_results(self, uuid, uuids, index):
173173
Returns:
174174
_type_: _description_
175175
"""
176-
if len(uuids) > 1:
176+
if len(uuids) >= 1:
177177
if len(uuid) > 0:
178178
uuids.remove(uuid)
179179
if len(uuids) < 1:

fmatch/requirements.txt

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,53 @@
1+
astroid==3.0.2
2+
asttokens==2.4.1
3+
cbor2==5.5.1
14
certifi==2023.11.17
5+
charset-normalizer==3.3.2
6+
click==8.1.7
7+
coverage==7.4.0
8+
dill==0.3.7
9+
docutils==0.20.1
210
elastic-transport==8.11.0
311
elasticsearch==8.11.1
412
elasticsearch7==7.13.0
5-
numpy==1.26.3
13+
idna==3.6
14+
importlib-metadata==7.0.1
15+
iniconfig==2.0.0
16+
isort==5.13.2
17+
jaraco.classes==3.3.0
18+
keyring==24.3.0
19+
markdown-it-py==3.0.0
20+
mccabe==0.7.0
21+
mdurl==0.1.2
22+
more-itertools==10.2.0
23+
nh3==0.2.15
24+
numpy==1.24.0
25+
packaging==23.2
626
pandas==2.1.4
27+
pip-name==1.0.2
28+
pkginfo==1.9.6
29+
platformdirs==4.1.0
30+
pluggy==1.3.0
31+
pycodestyle==2.11.1
32+
pycryptodome==3.20.0
33+
pyflakes==3.2.0
34+
Pygments==2.17.2
35+
pylint==3.0.3
36+
pytest==7.4.4
37+
pytest-cov==4.1.0
38+
pytest-random-order==1.1.0
739
python-dateutil==2.8.2
840
pytz==2023.3.post1
41+
PyYAML==6.0.1
42+
readme-renderer==42.0
43+
requests==2.31.0
44+
requests-toolbelt==1.0.0
45+
rfc3986==2.0.0
46+
rich==13.7.0
947
six==1.16.0
48+
tomlkit==0.12.3
49+
twine==4.0.2
1050
tzdata==2023.4
1151
urllib3==1.26.18
52+
vyper==0.3.10
53+
zipp==3.17.0

fmatch/tests/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
This is __init__.py file for tests of fmatch
3+
"""

fmatch/tests/test_matcher.py

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
"""
2+
Unit Test file for fmatch.py
3+
"""
4+
#pylint: disable = redefined-outer-name
5+
#pylint: disable = missing-function-docstring
6+
#pylint: disable = import-error
7+
import os
8+
9+
from elasticsearch.exceptions import NotFoundError
10+
import pytest
11+
import pandas as pd
12+
13+
#pylint: disable = import-error
14+
from fmatch.matcher import Matcher
15+
16+
17+
@pytest.fixture
18+
def matcher_instance():
19+
sample_output = {
20+
"hits": {
21+
"hits": [
22+
{"_source": {"uuid": "uuid1", "field1": "value1"}},
23+
{"_source": {"uuid": "uuid2", "field1": "value2"}},
24+
]
25+
}
26+
}
27+
match = Matcher(index="perf-scale-ci")
28+
match.es.search = lambda *args, **kwargs: sample_output
29+
return match
30+
31+
32+
def test_get_metadata_by_uuid_found(matcher_instance):
33+
uuid = "test_uuid"
34+
result = matcher_instance.get_metadata_by_uuid(uuid)
35+
expected = {"uuid": "uuid1", "field1": "value1"}
36+
assert result == expected
37+
38+
39+
def test_get_metadata_by_uuid_not_found(matcher_instance):
40+
def raise_exception():
41+
raise NotFoundError(404, "index_not_found_exception", "no such index [sample]")
42+
43+
# Mock Elasticsearch response for testing NotFoundError
44+
matcher_instance.es.search = lambda *args, **kwargs: raise_exception()
45+
uuid = "nonexistent_uuid"
46+
result = matcher_instance.get_metadata_by_uuid(uuid=uuid, index="sample index")
47+
expected = {}
48+
assert result == expected
49+
50+
51+
def test_query_index(matcher_instance):
52+
index = "test_uuid"
53+
query = "test_query"
54+
result = matcher_instance.query_index(index, query)
55+
expected = {
56+
"hits": {
57+
"hits": [
58+
{"_source": {"uuid": "uuid1", "field1": "value1"}},
59+
{"_source": {"uuid": "uuid2", "field1": "value2"}},
60+
]
61+
}
62+
}
63+
assert result == expected
64+
65+
66+
def test_get_uuid_by_metadata(matcher_instance):
67+
matcher_instance.es.search = lambda *args, **kwargs: {
68+
"hits": {
69+
"hits": [{"_source": {"uuid": "uuid1"}}, {"_source": {"uuid": "uuid2"}}]
70+
}
71+
}
72+
meta = {"field1": "value1", "ocpVersion": "4.15"}
73+
result = matcher_instance.get_uuid_by_metadata(meta)
74+
expected = ["uuid1", "uuid2"]
75+
assert result == expected
76+
77+
78+
def test_match_k8s_netperf(matcher_instance):
79+
result = matcher_instance.match_k8s_netperf(["uuid1"])
80+
expected = [
81+
{"uuid": "uuid1", "field1": "value1"},
82+
{"uuid": "uuid2", "field1": "value2"},
83+
]
84+
assert result == expected
85+
86+
87+
def test_match_kube_bruner(matcher_instance):
88+
result = matcher_instance.match_kube_burner(["uuid1"])
89+
expected = [
90+
{"uuid": "uuid1", "field1": "value1"},
91+
{"uuid": "uuid2", "field1": "value2"},
92+
]
93+
assert result == expected
94+
95+
96+
def test_burner_results(matcher_instance):
97+
result = matcher_instance.burner_results(
98+
"uuid1", ["uuid1", "uuid1"], "sample_index"
99+
)
100+
expected = [
101+
{"uuid": "uuid1", "field1": "value1"},
102+
{"uuid": "uuid2", "field1": "value2"},
103+
]
104+
assert result == expected
105+
106+
107+
def test_burner_results_single_element(matcher_instance):
108+
result = matcher_instance.burner_results("uuid1", ["uuid1"], "sample_index")
109+
expected = []
110+
assert result == expected
111+
112+
113+
def test_burner_cpu_results(matcher_instance):
114+
matcher_instance.parse_burner_cpu_results = lambda *args, **kwargs: {}
115+
result = matcher_instance.burner_cpu_results(
116+
["uuid1", "uuid2"], "sample_namespace", "sample_index"
117+
)
118+
expected = {}
119+
assert result == expected
120+
121+
122+
def test_filter_runs(matcher_instance):
123+
mock_data = [
124+
{
125+
"timestamp": "2024-01-15T20:00:46.307453873Z",
126+
"endTimestamp": "2024-01-15T20:30:57.853708171Z",
127+
"elapsedTime": 1812,
128+
"uuid": "90189fbf-7181-4129-8ca5-3cc8d656b595",
129+
"metricName": "jobSummary",
130+
"jobConfig": {
131+
"jobIterations": 216,
132+
"name": "cluster-density-v2",
133+
"jobType": "create",
134+
"qps": 20,
135+
"burst": 20,
136+
"namespace": "cluster-density-v2",
137+
"maxWaitTimeout": 14400000000000,
138+
"waitForDeletion": True,
139+
"waitWhenFinished": True,
140+
"cleanup": True,
141+
"namespacedIterations": True,
142+
"iterationsPerNamespace": 1,
143+
"verifyObjects": True,
144+
"errorOnVerify": True,
145+
"preLoadImages": True,
146+
"preLoadPeriod": 15000000000,
147+
"churn": True,
148+
"churnPercent": 10,
149+
"churnDuration": 1200000000000,
150+
"churnDelay": 120000000000,
151+
},
152+
"metadata": {
153+
"k8sVersion": "v1.28.5+c84a6b8",
154+
"ocpMajorVersion": "4.15",
155+
"ocpVersion": "4.15.0-0.nightly-2024-01-15-022811",
156+
"platform": "AWS",
157+
"sdnType": "OVNKubernetes",
158+
"totalNodes": 30,
159+
},
160+
"version": "1.7.12@f0b89ccdbeb2a7d65512f5970d5a25a82ec386b2",
161+
},
162+
{
163+
"timestamp": "2024-01-15T20:32:11.681417765Z",
164+
"endTimestamp": "2024-01-15T20:37:24.591361376Z",
165+
"elapsedTime": 313,
166+
"uuid": "90189fbf-7181-4129-8ca5-3cc8d656b595",
167+
"metricName": "jobSummary",
168+
"jobConfig": {"name": "garbage-collection"},
169+
"metadata": {
170+
"k8sVersion": "v1.28.5+c84a6b8",
171+
"ocpMajorVersion": "4.15",
172+
"ocpVersion": "4.15.0-0.nightly-2024-01-15-022811",
173+
"platform": "AWS",
174+
"sdnType": "OVNKubernetes",
175+
"totalNodes": 30,
176+
},
177+
"version": "1.7.12@f0b89ccdbeb2a7d65512f5970d5a25a82ec386b2",
178+
},
179+
]
180+
result = matcher_instance.filter_runs(mock_data, mock_data)
181+
expected = ["90189fbf-7181-4129-8ca5-3cc8d656b595"]
182+
assert result == expected
183+
184+
185+
def test_parse_burner_cpu_results(matcher_instance):
186+
mock_data = {"aggregations": {"time": {"buckets": []}, "uuid": {"buckets": []}}}
187+
mock_data["aggregations"]["time"]["buckets"] = [
188+
{
189+
"key": "90189fbf-7181-4129-8ca5-3cc8d656b595",
190+
"doc_count": 1110,
191+
"time": {
192+
"value": 1705349944941.3918,
193+
"value_as_string": "2024-01-15T20:19:04.941Z",
194+
},
195+
}
196+
]
197+
mock_data["aggregations"]["uuid"]["buckets"] = [
198+
{
199+
"key": "90189fbf-7181-4129-8ca5-3cc8d656b595",
200+
"doc_count": 1110,
201+
"cpu": {"value": 10.818089329872935},
202+
}
203+
]
204+
expected = [
205+
{
206+
"uuid": "90189fbf-7181-4129-8ca5-3cc8d656b595",
207+
"timestamp": "2024-01-15T20:19:04.941Z",
208+
"cpu_avg": 10.818089329872935,
209+
}
210+
]
211+
result = matcher_instance.parse_burner_cpu_results(mock_data)
212+
assert result == expected
213+
214+
215+
def test_convert_to_df(matcher_instance):
216+
mock_data = [
217+
{
218+
"uuid": "90189fbf-7181-4129-8ca5-3cc8d656b595",
219+
"timestamp": "2024-01-15T20:19:04.941Z",
220+
"cpu_avg": 10.818089329872935,
221+
}
222+
]
223+
odf = pd.json_normalize(mock_data)
224+
expected = odf.sort_values(by=["timestamp"])
225+
result = matcher_instance.convert_to_df(
226+
mock_data, columns=["uuid", "timestamp", "cpu_avg"]
227+
)
228+
assert result.equals(expected)
229+
230+
231+
def test_save_results(matcher_instance):
232+
mock_data = [
233+
{
234+
"uuid": "90189fbf-7181-4129-8ca5-3cc8d656b595",
235+
"timestamp": "2024-01-15T20:19:04.941Z",
236+
"cpu_avg": 10.818089329872935,
237+
}
238+
]
239+
mock_file_name = "test_output.csv"
240+
mock_df = pd.json_normalize(mock_data)
241+
matcher_instance.save_results(
242+
mock_df, csv_file_path=mock_file_name, columns=["uuid", "timestamp", "cpu_avg"]
243+
)
244+
assert os.path.isfile(mock_file_name)
245+
os.remove(mock_file_name)
246+
247+
248+
if __name__ == "__main__":
249+
pytest.main()

0 commit comments

Comments
 (0)