Skip to content

Commit cfe6986

Browse files
committed
Change integration tests to pytest
So far I have added session/resources/meta tests
1 parent 8af4afd commit cfe6986

File tree

10 files changed

+197
-13
lines changed

10 files changed

+197
-13
lines changed

docker/irods_client/Dockerfile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ RUN apt-get update && \
2626
rm -rf /var/lib/apt/lists/* /tmp/*
2727

2828
RUN mkdir -p /root/.irods
29-
COPY docker/irods_client/irods_environment.json /root/.irods
30-
RUN mkdir -p /root/.ibridges
31-
COPY docker/irods_client/ibridges_config.json /root/.ibridges
29+
# COPY docker/irods_client/irods_environment.json /root/.irods
30+
# RUN mkdir -p /root/.ibridges
31+
# COPY docker/irods_client/ibridges_config.json /root/.ibridges
3232
RUN mkdir -p /tmp
3333
ADD docker/irods_client/testdata /tmp/testdata/
3434

@@ -41,11 +41,14 @@ RUN apt-get install -y python3 git
4141

4242
RUN wget https://bootstrap.pypa.io/get-pip.py
4343
RUN python3 get-pip.py
44-
RUN mkdir -p /ibridges
44+
RUN mkdir -p /ibridges/integration_test
4545
ADD ibridges /ibridges/ibridges
46+
ADD docker/irods_client/tests ibridges/integration_test
47+
ADD docker/irods_client/environments/plain-irods ibridges/integration_test/environment
4648
ADD .git /ibridges/.git
4749
COPY pyproject.toml /ibridges
4850
RUN /usr/local/bin/pip3 install /ibridges
51+
RUN /usr/local/bin/pip3 install pytest tomli
4952
# COPY requirements.txt /iBridges-Gui/requirements_docker.txt
5053
# RUN pip3 install -r /iBridges-Gui/requirements_docker.txt
5154
COPY docker/irods_client/integration_test.py /ibridges/integration_test.py

docker/irods_client/entrypoint.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ echo "iRODS is ready"
2525
# echo 'rods' | iinit
2626
# echo 'Authenticated as rods'
2727

28-
python3 /ibridges/integration_test.py || echo "Failed"
28+
# python3 /ibridges/integration_test.py || echo "Failed"
29+
cd /ibridges/integration_test
30+
pytest .
2931

3032
bash -c "until false; do sleep 2147483647d; done"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
password = "rods"
2+
server_version = "4.3.0"
3+
can_write_pam_pass = false
4+
resources = ["bundleResc", "demoResc"]
5+
free_resources = [false, false]

docker/irods_client/requirements.txt

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

docker/irods_client/tests/conftest.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import json
2+
from pathlib import Path
3+
4+
import pytest
5+
import tomli
6+
7+
from ibridges import Session
8+
9+
# def pytest_addoption(parser):
10+
# parser.addoption("--configdir", action="store")
11+
12+
13+
@pytest.fixture(scope="session")
14+
def config_dir(request):
15+
# config_dir_name = request.config.option.configdir
16+
# if config_dir_name is None:
17+
# pytest.skip()
18+
return Path("environment")
19+
20+
21+
@pytest.fixture(scope="session")
22+
def irods_env_file(config_dir):
23+
return config_dir / "irods_environment.json"
24+
25+
26+
@pytest.fixture(scope="session")
27+
def irods_env(irods_env_file):
28+
with open(irods_env_file, "r") as handle:
29+
ienv = json.load(handle)
30+
return ienv
31+
32+
33+
@pytest.fixture(scope="session")
34+
def config(config_dir):
35+
with open(config_dir / "config.toml", "rb") as handle:
36+
config_data = tomli.load(handle)
37+
return config_data
38+
39+
40+
@pytest.fixture(scope="session")
41+
def session(irods_env, config):
42+
session = Session(irods_env=irods_env, password=config["password"])
43+
yield session
44+
del session
45+
46+
47+
@pytest.fixture(scope="session")
48+
def testdata():
49+
return Path("/tmp/testdata")
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import pytest
2+
from pytest import mark
3+
4+
from ibridges.irodsconnector.data_operations import get_collection, get_dataobject, upload
5+
from ibridges.irodsconnector.meta import MetaData
6+
from ibridges.utils.path import IrodsPath
7+
8+
9+
@pytest.fixture(scope="module")
10+
def collection(session):
11+
return get_collection(session, IrodsPath("~"))
12+
13+
14+
@pytest.fixture(scope="module")
15+
def dataobject(session, testdata):
16+
ipath = IrodsPath(session, "~", "bunny.rtf")
17+
upload(session, testdata/"bunny.rtf", IrodsPath("~"), overwrite=True)
18+
yield get_dataobject(session, ipath)
19+
ipath.remove()
20+
21+
22+
@mark.parametrize("item_name", ["collection", "dataobject"])
23+
def test_meta(item_name, request):
24+
item = request.getfixturevalue(item_name)
25+
meta = MetaData(item)
26+
meta.clear()
27+
28+
assert len(str(meta)) == 0
29+
assert len(list(meta)) == 0
30+
31+
# Add key, value pair
32+
meta.add("x", "y")
33+
assert len(list(meta)) == 1
34+
assert list(meta)[0].name == "x"
35+
assert list(meta)[0].value == "y"
36+
assert list(meta)[0].units is None
37+
assert "x" in meta
38+
assert ("x", "y") in meta
39+
assert "y" not in meta
40+
assert ("x", "z") not in meta
41+
assert ("x", "y", "z") not in meta
42+
43+
# Same key, but different value
44+
meta.add("x", "z")
45+
assert len(list(meta)) == 2
46+
assert len(str(meta).split("\n")) == 3 #\n at the end
47+
assert ("x", "z") in meta
48+
49+
# Same key, value different units
50+
meta.add("x", "z", "m")
51+
assert len(list(meta)) == 3
52+
assert ("x", "z", "m") in meta
53+
54+
# Test that we cannot add the same metadata twice
55+
with pytest.raises(ValueError):
56+
meta.add("x", "y")
57+
with pytest.raises(ValueError):
58+
meta.add("x", "z", "m")
59+
60+
# Cannot delete value with different units
61+
assert ("x", "z", "kg") not in meta
62+
with pytest.raises(KeyError):
63+
meta.delete("x", "z", "kg")
64+
meta.delete("x", "z", "m")
65+
assert len(list(meta)) == 2
66+
67+
meta.delete("x", "z")
68+
assert len(list(meta)) == 1
69+
70+
meta.delete("x")
71+
assert len(list(meta)) == 0
72+
73+
meta.add("x", "y")
74+
meta.set("y", "x")
75+
assert "x" not in meta
76+
assert ("y", "x") in meta
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import irods
2+
3+
from ibridges.irodsconnector.resources import Resources
4+
5+
6+
def test_resources(session, config):
7+
resources = Resources(session)
8+
resc_dict = resources.resources(update=True)
9+
assert list(resc_dict) == config["resources"]
10+
for i_resc, resc_name in enumerate(list(resc_dict)):
11+
if config["free_resources"][i_resc]:
12+
assert resources.get_free_space(resc_name) > 0
13+
resc = resources.get_resource(resc_name)
14+
assert isinstance(resc, irods.resource.iRODSResource)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import pytest
2+
3+
from ibridges import Session
4+
5+
6+
def test_session(session, config, irods_env):
7+
assert session.has_valid_irods_session()
8+
assert ".".join(str(x) for x in session.server_version) == config["server_version"]
9+
assert session.home == irods_env["irods_home"]
10+
assert session.default_resc == irods_env["irods_default_resource"]
11+
assert session.host == irods_env["irods_host"]
12+
assert session.port == irods_env["irods_port"]
13+
assert session.username == irods_env["irods_user_name"]
14+
assert session.zone == irods_env["irods_zone_name"]
15+
16+
17+
def test_pam_password(session, config, irods_env):
18+
if not config["can_write_pam_pass"]:
19+
pytest.xfail("This iRods server cannot write pam passwords.")
20+
session._write_pam_password()
21+
test_session = Session(irods_env)
22+
assert test_session.has_valid_irods_session()

ibridges/irodsconnector/meta.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
""" metadata operations
22
"""
3-
from typing import Iterator, Optional
3+
from typing import Iterator, Optional, Sequence, Union
44

55
import irods.exception
66
import irods.meta
@@ -16,6 +16,21 @@ def __iter__(self) -> Iterator:
1616
for m in self.item.metadata.items():
1717
yield m
1818

19+
def __contains__(self, val: Union[str, Sequence]) -> bool:
20+
if isinstance(val, str):
21+
val = [val]
22+
all_attrs = ["name", "value", "units"][:len(val)]
23+
for meta in self:
24+
n_same = 0
25+
for i_attr, attr in enumerate(all_attrs):
26+
if getattr(meta, attr) == val[i_attr]:
27+
n_same += 1
28+
else:
29+
break
30+
if n_same == len(val):
31+
return True
32+
return False
33+
1934
def __repr__(self) -> str:
2035
"""Create a sorted representation of the metadata"""
2136

@@ -97,8 +112,12 @@ def delete(self, key: str, value: Optional[str], units: Optional[str] = None):
97112
else:
98113
self.item.metadata.remove(key, value, units)
99114
except irods.exception.CAT_SUCCESS_BUT_WITH_NO_INFO as error:
100-
raise ValueError(f"Cannot delete metadata with key '{key}', value '{value}'"
115+
raise KeyError(f"Cannot delete metadata with key '{key}', value '{value}'"
101116
f" and units '{units}' since it does not exist.") from error
102117
except irods.exception.CAT_NO_ACCESS_PERMISSION as error:
103118
raise ValueError("Cannot delete metadata due to insufficient permission for "
104119
"path '{item.path}'.") from error
120+
121+
def clear(self):
122+
for meta in self:
123+
self.item.metadata.remove(meta)

0 commit comments

Comments
 (0)