Skip to content

Commit 7d61840

Browse files
committed
Tests: Make test suite clean up its provisioned assets from Grafana
1 parent c7f42ce commit 7d61840

File tree

9 files changed

+202
-145
lines changed

9 files changed

+202
-145
lines changed

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ in progress
99
- Tests: Improve fixture ``create_datasource`` to clean up afterwards
1010
- Tests: Add fixture ``create_dashboard`` to create dashboards at runtime
1111
- Tests: Disable caching in test mode
12+
- Tests: Make test suite clean up its provisioned assets from Grafana
1213

1314

1415
2022-02-03 0.13.1

doc/backlog.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,20 @@ grafana-wtf backlog
77
Prio 1
88
******
99
- [o] With Grafana >8.3, resolve datasource name and add to ``{'type': 'influxdb', 'uid': 'PDF2762CDFF14A314'}``
10+
- [o] Move test harness Grafana to a different port than 3000
1011

1112

1213
*********
1314
Prio 1.25
1415
*********
1516
- [o] Statistics reports for data sources and panels: https://github.com/panodata/grafana-wtf/issues/18
1617
- [o] Finding invalid data sources: https://github.com/panodata/grafana-wtf/issues/19
17-
- [o] Add test fixture for adding dashboards at runtime from branch ``amo/test-dashboard-runtime``
1818

1919

2020
********
2121
Prio 1.5
2222
********
2323
- [o] Search through more Grafana entities (users, organizations, teams)
24-
- [o] Add test fixture which completely resets everything in Grafana before running the test harness.
25-
Move to a different port than 3000 then!
2624
- [o] Improve output format handling and error cases
2725
- [o] Introduce paging to reach beyond the 5000 results limit,
2826
see https://grafana.com/docs/http_api/folder_dashboard_search/
@@ -63,3 +61,6 @@ Done
6361
- Display number of dashboards, folders, users, and playlists
6462
- [x] Blackify
6563
- [x] Dockerize
64+
- [x] Add test fixture for adding dashboards at runtime from branch ``amo/test-dashboard-runtime``
65+
- [x] Improve test suite wrt. test case isolation vs. Grafana resources
66+
- [x] Add test fixture which completely resets everything in Grafana before running the test harness.

tests/conftest.py

Lines changed: 111 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ def create_datasource(docker_grafana):
5151
Create a Grafana data source from a test case.
5252
After the test case finished, it will remove the data source again.
5353
54-
https://docs.pytest.org/en/4.6.x/fixture.html#factories-as-fixtures
54+
- https://grafana.com/docs/grafana/latest/http_api/data_source/
55+
- https://docs.pytest.org/en/4.6.x/fixture.html#factories-as-fixtures
5556
"""
5657

5758
# Reference to `grafana-client`.
@@ -60,14 +61,16 @@ def create_datasource(docker_grafana):
6061
# Keep track of the datasource ids in order to delete them afterwards.
6162
datasource_ids = []
6263

63-
def _create_datasource(name: str, type: str, access: str):
64+
def _create_datasource(name: str, type: str, access: str, **kwargs):
65+
datasource = dict(name=name, type=type, access=access)
66+
datasource.update(kwargs)
6467
try:
65-
response = grafana.datasource.create_datasource(dict(name=name, type=type, access=access))
68+
response = grafana.datasource.create_datasource(datasource)
6669
datasource_id = response["datasource"]["id"]
6770
datasource_ids.append(datasource_id)
6871
except GrafanaClientError as ex:
69-
# TODO: Mimic the original response `{'datasource': {'id': 5, 'uid': 'u9wNRyEnk', 'orgId': 1, ...`.
70-
# in order to make the removal work.
72+
# TODO: Mimic the original response in order to make the removal work.
73+
# `{'datasource': {'id': 5, 'uid': 'u9wNRyEnk', 'orgId': 1, ...`.
7174
if not re.match(
7275
"Client Error 409: Data source with (the )?same name already exists", str(ex), re.IGNORECASE
7376
):
@@ -80,13 +83,77 @@ def _create_datasource(name: str, type: str, access: str):
8083
grafana.datasource.delete_datasource_by_id(datasource_id)
8184

8285

86+
@pytest.fixture
87+
def create_folder(docker_grafana):
88+
"""
89+
Create a Grafana folder from a test case.
90+
After the test case finished, it will remove the dashboard again.
91+
92+
- https://grafana.com/docs/grafana/latest/http_api/folder/
93+
- https://docs.pytest.org/en/4.6.x/fixture.html#factories-as-fixtures
94+
"""
95+
96+
# Reference to `grafana-client`.
97+
grafana = GrafanaWtf.grafana_client_factory(docker_grafana)
98+
99+
# Keep track of the dashboard uids in order to delete them afterwards.
100+
folder_uids = []
101+
102+
# https://docs.pytest.org/en/4.6.x/fixture.html#factories-as-fixtures
103+
def _create_folder(title: str, uid: str = None):
104+
105+
# Create dashboard in Grafana.
106+
try:
107+
response = grafana.folder.create_folder(title=title, uid=uid)
108+
folder_id = response["id"]
109+
folder_uid = response["uid"]
110+
111+
# Response is like:
112+
"""
113+
{
114+
"id": 44,
115+
"uid": "iga1UrEnz",
116+
"title": "Testdrive",
117+
"url": "/dashboards/f/iga1UrEnz/testdrive",
118+
"hasAcl": false,
119+
"canSave": true,
120+
"canEdit": true,
121+
"canAdmin": true,
122+
"createdBy": "admin",
123+
"created": "2022-03-22T23:44:38Z",
124+
"updatedBy": "admin",
125+
"updated": "2022-03-22T23:44:38Z",
126+
"version": 1
127+
}
128+
"""
129+
130+
folder_uids.append(folder_uid)
131+
return folder_id
132+
except GrafanaClientError as ex:
133+
# TODO: Mimic the original response in order to make the removal work.
134+
if not re.match(
135+
"Client Error 409: a folder or dashboard in the general folder with the same name already exists",
136+
str(ex),
137+
re.IGNORECASE,
138+
):
139+
raise
140+
141+
yield _create_folder
142+
143+
# Delete dashboard again.
144+
if folder_uids:
145+
for folder_uid in folder_uids:
146+
grafana.folder.delete_folder(uid=folder_uid)
147+
148+
83149
@pytest.fixture
84150
def create_dashboard(docker_grafana):
85151
"""
86152
Create a Grafana dashboard from a test case.
87153
After the test case finished, it will remove the dashboard again.
88154
89-
https://docs.pytest.org/en/4.6.x/fixture.html#factories-as-fixtures
155+
- https://grafana.com/docs/grafana/latest/http_api/dashboard/
156+
- https://docs.pytest.org/en/4.6.x/fixture.html#factories-as-fixtures
90157
"""
91158

92159
# Reference to `grafana-client`.
@@ -96,11 +163,15 @@ def create_dashboard(docker_grafana):
96163
dashboard_uids = []
97164

98165
# https://docs.pytest.org/en/4.6.x/fixture.html#factories-as-fixtures
99-
def _create_dashboard(title: str, datasource: str):
166+
def _create_dashboard(dashboard: dict = None, folder_id: str = None, folder_uid: str = None):
100167

101168
# Create dashboard in Grafana.
102-
dashboard = mkdashboard(title=title, datasource=datasource)
103-
response = grafana.dashboard.update_dashboard(dashboard={"dashboard": dashboard, "overwrite": True})
169+
payload = {"dashboard": dashboard, "overwrite": True}
170+
if folder_id:
171+
payload["folderId"] = folder_id
172+
if folder_uid:
173+
payload["folderUid"] = folder_uid
174+
response = grafana.dashboard.update_dashboard(dashboard=payload)
104175

105176
# Response is like:
106177
# {'id': 3, 'slug': 'foo', 'status': 'success', 'uid': 'iO0xgE2nk', 'url': '/d/iO0xgE2nk/foo', 'version': 1}
@@ -116,6 +187,37 @@ def _create_dashboard(title: str, datasource: str):
116187
grafana.dashboard.delete_dashboard(dashboard_uid=dashboard_uid)
117188

118189

190+
@pytest.fixture
191+
def ldi_resources(create_datasource, create_folder, create_dashboard):
192+
"""
193+
Create a Grafana dashboard from a test case.
194+
After the test case finished, it will remove the dashboard again.
195+
196+
https://docs.pytest.org/en/4.6.x/fixture.html#factories-as-fixtures
197+
"""
198+
199+
# Create LDI datasource.
200+
create_datasource(
201+
name="ldi_v2",
202+
type="influxdb",
203+
access="proxy",
204+
url="http://localhost:8086/",
205+
user="root",
206+
password="root",
207+
database="ldi_v2",
208+
secureJsonData={"password": "root"},
209+
)
210+
211+
# Create folder.
212+
folder_id = create_folder(title="Testdrive", uid="testdrive")
213+
214+
# Create LDI dashboards.
215+
for file in Path("tests/grafana/dashboards").glob("*.json"):
216+
with open(file, "r") as f:
217+
dashboard = json.load(f)
218+
create_dashboard(dashboard=dashboard, folder_id=folder_id)
219+
220+
119221
def mkdashboard(title: str, datasource: str):
120222
"""
121223
Build dashboard with single panel.

tests/docker-compose.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@ services:
44
grafana:
55
container_name: grafana-wtf-test
66
image: grafana/grafana:${GRAFANA_VERSION}
7-
volumes:
8-
- ./grafana/datasources:/etc/grafana/provisioning/datasources/
9-
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards/
107
ports:
118
- "3000:3000"
129
environment:
1310
GF_LOG_LEVEL: info
1411
#GF_LOG_LEVEL: debug
15-
#GF_PATHS_PROVISIONING: /etc/grafana/provisioning

tests/grafana/dashboards/all.yml

Lines changed: 0 additions & 28 deletions
This file was deleted.

tests/grafana/dashboards/ldi-v27.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"editable": true,
1717
"gnetId": null,
1818
"graphTooltip": 0,
19+
"id": null,
1920
"iteration": 1632507348685,
2021
"links": [
2122
{

tests/grafana/dashboards/ldi-v33.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"editable": true,
2323
"fiscalYearStartMonth": 0,
2424
"graphTooltip": 0,
25-
"id": 3,
25+
"id": null,
2626
"iteration": 1642798659207,
2727
"links": [
2828
{

tests/grafana/datasources/all.yml

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)