1313# limitations under the License.
1414
1515import os
16+ import json
1617import time
1718import pathlib
1819import configparser
1920
20- from pytest import fixture
21+ from pytest import fixture , param , skip , exit
2122from testcontainers .core .container import DockerContainer
2223from gremlin_python .process .anonymous_traversal import traversal
2324from gremlin_python .driver .driver_remote_connection import DriverRemoteConnection
2425from 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' )
2780def 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
3490def 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
0 commit comments