Skip to content

Commit 5cedbd0

Browse files
committed
support for cross testing the package against multiple JanusGraph versions
Signed-off-by: pm-osc <[email protected]>
1 parent d97d5aa commit 5cedbd0

File tree

6 files changed

+126
-47
lines changed

6 files changed

+126
-47
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ of JanusGraph-Python:
6666
| JanusGraph-Python | JanusGraph |
6767
| ----------------- | ---------------------- |
6868
| 1.0.z | 1.0.z |
69-
| 1.1.z | 1.1.z |
69+
| 1.1.z | (1.0.z,) 1.1.z |
7070

7171
While it should also be possible to use JanusGraph-Python with other versions of
7272
JanusGraph than mentioned here, compatibility is not tested and some

tests/integration/Text_test.py

+9
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def test_text_contains_given_search_text(self, search_text, expected_count):
3737
param('shouldNotBeFound', 3),
3838
]
3939
)
40+
@mark.minimum_janusgraph_version("1.1.0")
4041
def test_text_not_contains_given_search_text(self, search_text, expected_count):
4142
count = self.g.E().has('reason', Text.text_not_contains(search_text)).count().next()
4243
assert count == expected_count
@@ -61,6 +62,7 @@ def test_text_contains_prefix_given_search_text(self, search_text, expected_coun
6162
param('shouldNotBeFound', 3),
6263
]
6364
)
65+
@mark.minimum_janusgraph_version("1.1.0")
6466
def test_text_contains_not_prefix_given_search_text(self, search_text, expected_count):
6567
count = self.g.E().has('reason', Text.text_not_contains_prefix(search_text)).count().next()
6668
assert count == expected_count
@@ -85,6 +87,7 @@ def test_text_contains_regex_given_search_text(self, search_text, expected_count
8587
param('shouldNotBeFound', 3),
8688
]
8789
)
90+
@mark.minimum_janusgraph_version("1.1.0")
8891
def test_text_not_contains_regex_given_search_text(self, search_text, expected_count):
8992
count = self.g.E().has('reason', Text.text_not_contains_regex(search_text)).count().next()
9093
assert count == expected_count
@@ -107,6 +110,7 @@ def test_text_contains_fuzzy_given_search_text(self, search_text, expected_count
107110
param('shouldNotBeFound', 3),
108111
]
109112
)
113+
@mark.minimum_janusgraph_version("1.1.0")
110114
def test_text_not_contains_fuzzy_given_search_text(self, search_text, expected_count):
111115
count = self.g.E().has('reason', Text.text_not_contains_fuzzy(search_text)).count().next()
112116
assert count == expected_count
@@ -120,6 +124,7 @@ def test_text_not_contains_fuzzy_given_search_text(self, search_text, expected_c
120124
param('should not be found', 0),
121125
]
122126
)
127+
@mark.minimum_janusgraph_version("1.1.0")
123128
def test_text_contains_phrase_given_search_text(self, search_text, expected_count):
124129
count = self.g.E().has('reason', Text.text_contains_phrase(search_text)).count().next()
125130
assert count == expected_count
@@ -133,6 +138,7 @@ def test_text_contains_phrase_given_search_text(self, search_text, expected_coun
133138
param('should not be found', 3),
134139
]
135140
)
141+
@mark.minimum_janusgraph_version("1.1.0")
136142
def test_text_not_contains_phrase_given_search_text(self, search_text, expected_count):
137143
count = self.g.E().has('reason', Text.text_not_contains_phrase(search_text)).count().next()
138144
assert count == expected_count
@@ -157,6 +163,7 @@ def test_text_prefix_given_search_text(self, search_text, expected_count):
157163
param('shouldNotBeFound', 12),
158164
]
159165
)
166+
@mark.minimum_janusgraph_version("1.1.0")
160167
def test_text_not_prefix_given_search_text(self, search_text, expected_count):
161168
count = self.g.V().has('name', Text.text_not_prefix(search_text)).count().next()
162169
assert count == expected_count
@@ -181,6 +188,7 @@ def test_text_regex_given_search_text(self, search_text, expected_count):
181188
param('shouldNotBeFound', 12),
182189
]
183190
)
191+
@mark.minimum_janusgraph_version("1.1.0")
184192
def test_text_not_regex_given_search_text(self, search_text, expected_count):
185193
count = self.g.V().has('name', Text.text_not_regex(search_text)).count().next()
186194
assert count == expected_count
@@ -205,6 +213,7 @@ def test_text_fuzzy_given_search_text(self, search_text, expected_count):
205213
param('shouldNotBeFound', 12),
206214
]
207215
)
216+
@mark.minimum_janusgraph_version("1.1.0")
208217
def test_text_not_fuzzy_given_search_text(self, search_text, expected_count):
209218
count = self.g.V().has('name', Text.text_not_fuzzy(search_text)).count().next()
210219
assert count == expected_count

tests/integration/config.ini

-2
This file was deleted.

tests/integration/config.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"dockerRepository": "janusgraph/janusgraph",
3+
"dockerTags": ["1.0.1", "1.1.0"]
4+
}

tests/integration/conftest.py

+105-43
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,79 @@
1313
# limitations under the License.
1414

1515
import os
16+
import json
1617
import time
1718
import pathlib
1819
import configparser
1920

20-
from pytest import fixture
21+
from pytest import fixture, param, skip, exit
2122
from testcontainers.core.container import DockerContainer
2223
from gremlin_python.process.anonymous_traversal import traversal
2324
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
2425
from janusgraph_python.driver.serializer import JanusGraphSONSerializersV3d0
2526

27+
current_path = pathlib.Path(__file__).parent.resolve()
28+
JANUSGRAPH_REPOSITORY = None
29+
JANUSGRAPH_VERSION_PARAMS = []
30+
31+
# read integration tests config from JSON
32+
with open(os.path.join(current_path, "config.json")) as f:
33+
config = json.load(f)
34+
JANUSGRAPH_REPOSITORY = config.get("dockerRepository", None)
35+
docker_tags = config.get("dockerTags", [])
36+
JANUSGRAPH_VERSION_PARAMS = [param(t, id=t) for t in docker_tags]
37+
38+
def pytest_configure(config):
39+
# registering custom marker to be able to skip integration tests
40+
# that are incompatible with older JanusGraph version
41+
config.addinivalue_line(
42+
"markers", "minimum_janusgraph_version(version): mark integration test with minimum required JanusGraph version"
43+
)
44+
45+
# this fixture should be used for all test methods in the integration tests
46+
@fixture(autouse=True, scope='function')
47+
def janusgraph_compatibility(request):
48+
"""
49+
Fixture to check if a given integration test is allowed to run on a given
50+
JanusGraph version. If the version is not satisfied, the test will be skipped.
51+
"""
52+
# get minimum desired JanusGraph version for the test if defined
53+
marker = request.node.get_closest_marker("minimum_janusgraph_version")
54+
# if no minimum desired JanusGraph version is defined, no need to check compatibility
55+
if not marker or not marker.args:
56+
return
57+
58+
min_jg_version = marker.args[0]
59+
60+
# get version of JanusGraph used by the current test run
61+
if len(request.fixturenames) == 0:
62+
exit("Fixtures are not used on the expected way")
63+
64+
top_fixture = request.fixturenames[0]
65+
current_jg_version = request.node.callspec.params.get(top_fixture)
66+
if not current_jg_version:
67+
exit(f"{top_fixture} fixture needs to be parametrized with the list of JanusGraph versions to test with")
68+
69+
if current_jg_version == min_jg_version:
70+
return
71+
72+
jg_v_list = [int(num) for num in current_jg_version.split('.')]
73+
min_v_list = [int(num) for num in min_jg_version.split('.')]
74+
75+
for jg_v, min_v in zip(jg_v_list, min_v_list):
76+
if jg_v < min_v:
77+
return skip(f"not compatible with JanusGraph {current_jg_version}")
78+
2679
@fixture(scope='session')
2780
def graph_connection_graphson(request, graph_container):
2881
"""
2982
Fixture for creating connection with JanusGraphSONSerializersV3d0 serializer
3083
to the JanusGraph container
3184
"""
32-
return graph_connection(request, graph_container, JanusGraphSONSerializersV3d0())
85+
# NOTE: this is a workaround to be able to pass the session fixture param
86+
# to the graph_container fixture
87+
container = graph_container(request)
88+
return graph_connection(request, container, JanusGraphSONSerializersV3d0())
3389

3490
def graph_connection(request, graph_container, serializer):
3591
"""
@@ -58,49 +114,55 @@ def graph_container(request):
58114
Fixture for creating JanusGraph container before first test and dropping
59115
container after last test in the test session
60116
"""
61-
container = None
62-
current_path = pathlib.Path(__file__).parent.resolve()
63-
64-
def is_server_ready():
65-
"""
66-
Method to test if JanusGraph server is up and running and filled with test data
67-
"""
68-
connection = None
69-
70-
while True:
71-
try:
72-
connection = DriverRemoteConnection(
73-
f'ws://{container.get_container_host_ip()}:{container.get_exposed_port(8182)}/gremlin',
74-
'g',
75-
message_serializer=JanusGraphSONSerializersV3d0()
76-
)
77-
g = traversal().with_remote(connection)
78-
79-
if g.V().has('name', 'hercules').has_next():
80-
break
81-
except Exception as e:
82-
pass
83-
finally:
84-
if connection:
85-
connection.close()
117+
118+
def create_container(passed_request):
119+
container = None
120+
121+
def is_server_ready():
122+
"""
123+
Method to test if JanusGraph server is up and running and filled with test data
124+
"""
125+
connection = None
86126

87-
time.sleep(2)
127+
while True:
128+
try:
129+
connection = DriverRemoteConnection(
130+
f'ws://{container.get_container_host_ip()}:{container.get_exposed_port(8182)}/gremlin',
131+
'g',
132+
message_serializer=JanusGraphSONSerializersV3d0()
133+
)
134+
g = traversal().with_remote(connection)
88135

89-
config = configparser.ConfigParser()
90-
config.read(os.path.join(current_path, 'config.ini'))
136+
if g.V().has('name', 'hercules').has_next():
137+
break
138+
except Exception as e:
139+
pass
140+
finally:
141+
if connection:
142+
connection.close()
91143

92-
container = (
93-
DockerContainer(config['docker']['image'])
94-
.with_name('janusgraph')
95-
.with_exposed_ports(8182)
96-
.with_volume_mapping(os.path.join(current_path, 'load_data.groovy'), '/docker-entrypoint-initdb.d/load_data.groovy')
97-
.start()
98-
)
99-
is_server_ready()
144+
time.sleep(2)
100145

101-
def drop_container():
102-
container.stop()
103-
104-
request.addfinalizer(drop_container)
146+
if not hasattr(passed_request, "param"):
147+
top_fixture = passed_request.fixturenames[0]
148+
exit(f"{top_fixture} fixture needs to be parametrized with the list of JanusGraph versions to test with")
149+
150+
tag = passed_request.param
151+
image = f"{JANUSGRAPH_REPOSITORY}:{tag}"
152+
153+
container = (
154+
DockerContainer(image)
155+
.with_name(f'janusgraph_{tag}')
156+
.with_exposed_ports(8182)
157+
.with_volume_mapping(os.path.join(current_path, 'load_data.groovy'), '/docker-entrypoint-initdb.d/load_data.groovy')
158+
.start()
159+
)
160+
is_server_ready()
161+
162+
def drop_container():
163+
container.stop()
164+
165+
request.addfinalizer(drop_container)
105166

106-
return container
167+
return container
168+
return create_container

tests/integration/io/test_graphsonV3d0.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,16 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from pytest import fixture
15+
from pytest import fixture, mark
1616

1717
from integration.RelationIdentifier_test import _RelationIdentifierSerializer, _RelationIdentifierDeserializer
1818
from integration.Text_test import _TextTests
19+
from ..conftest import JANUSGRAPH_VERSION_PARAMS
20+
21+
# parametrize all integration tests to run against various JanusGraph versions
22+
pytestmark = mark.parametrize(
23+
"graph_connection_graphson", JANUSGRAPH_VERSION_PARAMS, indirect=True
24+
)
1925

2026
class TestGraphSONRelationIdentifierSerializer(_RelationIdentifierSerializer):
2127
@fixture(autouse=True)

0 commit comments

Comments
 (0)