Skip to content

Commit cb1cb7a

Browse files
committed
TST: create nodes for all tests in a dedicated 'root' folder
1 parent 993fd74 commit cb1cb7a

File tree

5 files changed

+197
-245
lines changed

5 files changed

+197
-245
lines changed

tests/common.py

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
user_username, user_password = "user", "userPass"
99
read_username, read_password = "johndoe", "1234"
1010

11+
# Unit tests will create this folder and add nodes only inside this folder.
12+
# This folder will be deleted after each test to ensure clean state.
13+
root_folder_node_name = "unit-test-root-folder"
14+
1115

1216
def _is_async(library):
1317
if library == "ASYNC":
@@ -44,6 +48,24 @@ def _select_auth(*, SR, usesetauth):
4448
return auth
4549

4650

51+
def create_root_folder():
52+
"""
53+
Create the root folder for unit tests if it does not exist. The folder
54+
is created using 'admin' user. Unit tests are not expected to delete it.
55+
The function is expected to be called at the beginning of the tests.
56+
It is expected that the folder does not exist, so the created folder is empty.
57+
58+
Returns
59+
-------
60+
str
61+
Unique ID of the root folder.
62+
"""
63+
with SaveRestoreAPI(base_url=base_url, timeout=2) as SR:
64+
SR.auth_set(username=admin_username, password=admin_password)
65+
res = SR.node_add(SR.ROOT_NODE_UID, name=root_folder_node_name, nodeType="FOLDER")
66+
return res["uniqueId"]
67+
68+
4769
@pytest.fixture
4870
def clear_sar():
4971
"""
@@ -55,24 +77,33 @@ def _clear():
5577
Remove all nodes from the database.
5678
"""
5779
with SaveRestoreAPI(base_url=base_url, timeout=2) as SR:
58-
SR.auth_set(username=user_username, password=user_password)
59-
60-
# Create all nodes. Children always follow the parent
61-
n_uid = 0
62-
uids = [SR.ROOT_NODE_UID]
63-
while n_uid < len(uids):
64-
uid = uids[n_uid]
65-
res_1 = SR.node_get(uid)
66-
if res_1["nodeType"] == "FOLDER":
67-
res_2 = SR.node_get_children(uid)
68-
ch_uids = [_["uniqueId"] for _ in res_2]
69-
if ch_uids:
70-
uids.extend(ch_uids)
71-
n_uid += 1
72-
73-
# Delete all nodes starting with children
74-
for uid in reversed(uids[1:]):
75-
SR.nodes_delete([uid])
80+
SR.auth_set(username=admin_username, password=admin_password)
81+
82+
# Check if the root folder for unit tests exists
83+
res = SR.node_get_children(SR.ROOT_NODE_UID)
84+
root_folder_uid = None
85+
for node in res:
86+
if node["name"] == root_folder_node_name and node["nodeType"] == "FOLDER":
87+
root_folder_uid = node["uniqueId"]
88+
break
89+
90+
if root_folder_uid is not None:
91+
# Create all nodes. Children always follow the parent
92+
n_uid = 0
93+
uids = [root_folder_uid]
94+
while n_uid < len(uids):
95+
uid = uids[n_uid]
96+
res_1 = SR.node_get(uid)
97+
if res_1["nodeType"] == "FOLDER":
98+
res_2 = SR.node_get_children(uid)
99+
ch_uids = [_["uniqueId"] for _ in res_2]
100+
if ch_uids:
101+
uids.extend(ch_uids)
102+
n_uid += 1
103+
104+
# Delete all nodes starting with children, including the root folder
105+
for uid in reversed(uids):
106+
SR.nodes_delete([uid])
76107

77108
_clear()
78109
yield

tests/test_config_control.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
_select_auth,
1111
base_url,
1212
clear_sar, # noqa: F401
13+
create_root_folder,
1314
user_password, # noqa: F401
1415
user_username,
1516
)
@@ -28,6 +29,8 @@ def test_config_create_01(clear_sar, library, usesetauth): # noqa: F811
2829
Tests for the 'config_create' and 'config_get' API.
2930
"""
3031

32+
root_folder_uid = create_root_folder()
33+
3134
pv_list = [
3235
{
3336
"pvName": "13SIM1:{SimDetector-Cam:1}cam1:BinX"
@@ -62,7 +65,7 @@ def test_config_create_01(clear_sar, library, usesetauth): # noqa: F811
6265
with SaveRestoreAPI_Threads(base_url=base_url, timeout=2) as SR:
6366
auth = _select_auth(SR=SR, usesetauth=usesetauth)
6467

65-
response = SR.node_add(SR.ROOT_NODE_UID, name="Child Folder", nodeType="FOLDER", **auth)
68+
response = SR.node_add(root_folder_uid, name="Child Folder", nodeType="FOLDER", **auth)
6669
folder_uid = response["uniqueId"]
6770

6871

@@ -91,7 +94,7 @@ async def testing():
9194
async with SaveRestoreAPI_Async(base_url=base_url, timeout=2) as SR:
9295
auth = _select_auth(SR=SR, usesetauth=usesetauth)
9396

94-
response = await SR.node_add(SR.ROOT_NODE_UID, name="Child Folder", nodeType="FOLDER", **auth)
97+
response = await SR.node_add(root_folder_uid, name="Child Folder", nodeType="FOLDER", **auth)
9598
folder_uid = response["uniqueId"]
9699

97100
response = await SR.config_create(
@@ -126,14 +129,16 @@ def test_config_update_01(clear_sar, library, usesetauth): # noqa: F811
126129
Tests for the 'config_update' API.
127130
"""
128131

132+
root_folder_uid = create_root_folder()
133+
129134
pv_list1 = [{"pvName": "13SIM1:{SimDetector-Cam:1}cam1:BinY"}]
130135
pv_list2 = [{"pvName": "13SIM1:{SimDetector-Cam:1}cam1:BinX"}]
131136

132137
if not _is_async(library):
133138
with SaveRestoreAPI_Threads(base_url=base_url, timeout=2) as SR:
134139
auth = _select_auth(SR=SR, usesetauth=usesetauth)
135140

136-
response = SR.node_add(SR.ROOT_NODE_UID, name="Child Folder", nodeType="FOLDER", **auth)
141+
response = SR.node_add(root_folder_uid, name="Child Folder", nodeType="FOLDER", **auth)
137142
folder_uid = response["uniqueId"]
138143

139144
response = SR.config_create(
@@ -179,7 +184,7 @@ async def testing():
179184
async with SaveRestoreAPI_Async(base_url=base_url, timeout=2) as SR:
180185
auth = _select_auth(SR=SR, usesetauth=usesetauth)
181186

182-
response = await SR.node_add(SR.ROOT_NODE_UID, name="Child Folder", nodeType="FOLDER", **auth)
187+
response = await SR.node_add(root_folder_uid, name="Child Folder", nodeType="FOLDER", **auth)
183188
folder_uid = response["uniqueId"]
184189

185190
response = await SR.config_create(

tests/test_misc.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
from __future__ import annotations
2+
3+
import asyncio
4+
import importlib.metadata
5+
6+
import pytest
7+
8+
import save_and_restore_api
9+
from save_and_restore_api import SaveRestoreAPI as SaveRestoreAPI_Threads
10+
from save_and_restore_api.aio import SaveRestoreAPI as SaveRestoreAPI_Async
11+
12+
from .common import (
13+
_is_async,
14+
admin_password,
15+
admin_username,
16+
base_url,
17+
clear_sar, # noqa: F401
18+
read_password,
19+
read_username,
20+
user_password,
21+
user_username,
22+
)
23+
24+
25+
def test_version_01():
26+
"""
27+
Test that the versioning works correctly.
28+
"""
29+
assert importlib.metadata.version("save_and_restore_api") == save_and_restore_api.__version__
30+
31+
32+
# # fmt: off
33+
# @pytest.mark.parametrize("library", ["THREADS", "ASYNC"])
34+
# # fmt: on
35+
# def test_api_call_01(library):
36+
# """
37+
# Test generic API call
38+
# """
39+
# username, password = user_username, user_password
40+
41+
# if not _is_async(library):
42+
# SR = SaveRestoreAPI_Threads(base_url=base_url, timeout=2)
43+
# SR.auth_set(username=user_username, password=user_password)
44+
# SR.open()
45+
# response = SR.login(username=username, password=password)
46+
# assert response["userName"] == username
47+
# SR.close()
48+
# SR.open()
49+
# response = SR.login(username=username, password=password)
50+
# assert response["userName"] == username
51+
# SR.close()
52+
# else:
53+
# async def testing():
54+
# SR = SaveRestoreAPI_Async(base_url=base_url, timeout=2)
55+
# SR.auth_set(username=user_username, password=user_password)
56+
# SR.open()
57+
# response = await SR.login(username=username, password=password)
58+
# assert response["userName"] == username
59+
# await SR.close()
60+
# SR.open()
61+
# response = await SR.login(username=username, password=password)
62+
# assert response["userName"] == username
63+
# await SR.close()
64+
65+
# asyncio.run(testing())
66+
67+
68+
# fmt: off
69+
@pytest.mark.parametrize("library", ["THREADS", "ASYNC"])
70+
@pytest.mark.parametrize("username, password, roles, code", [
71+
(admin_username, admin_password, ["ROLE_SAR-ADMIN"], 200),
72+
(user_username, user_password, ["ROLE_SAR-USER"], 200),
73+
(read_username, read_password, [], 200),
74+
(user_username, read_password, [], 401), # Incorrect password
75+
(user_username + "_a", user_password, [], 401), # Incorrect login
76+
])
77+
# fmt: on
78+
def test_login_01(username, password, roles, library, code):
79+
"""
80+
Tests for the 'login' API.
81+
"""
82+
if not _is_async(library):
83+
with SaveRestoreAPI_Threads(base_url=base_url, timeout=2) as SR:
84+
if code == 200:
85+
response = SR.login(username=username, password=password)
86+
assert response["userName"] == username
87+
assert response["roles"] == roles
88+
else:
89+
with pytest.raises(SR.HTTPClientError, match=f"{code}"):
90+
SR.login(username=username, password=password)
91+
else:
92+
async def testing():
93+
async with SaveRestoreAPI_Async(base_url=base_url, timeout=2) as SR:
94+
if code == 200:
95+
response = await SR.login(username=username, password=password)
96+
assert response["userName"] == username
97+
assert response["roles"] == roles
98+
else:
99+
with pytest.raises(SR.HTTPClientError, match=f"{code}"):
100+
await SR.login(username=username, password=password)
101+
102+
asyncio.run(testing())

0 commit comments

Comments
 (0)