55
66import java .net .URL ;
77import java .util .Arrays ;
8+ import java .util .Collections ;
89import java .util .List ;
10+ import java .util .Map ;
911import java .util .concurrent .CompletableFuture ;
1012import java .util .concurrent .ExecutionException ;
1113import java .util .concurrent .Future ;
@@ -98,6 +100,7 @@ public class TarantoolCartridgeContainer extends GenericContainer<TarantoolCartr
98100 private static final String ENV_TARANTOOL_WORKDIR = "TARANTOOL_WORKDIR" ;
99101 private static final String ENV_TARANTOOL_RUNDIR = "TARANTOOL_RUNDIR" ;
100102 private static final String ENV_TARANTOOL_DATADIR = "TARANTOOL_DATADIR" ;
103+ private boolean useFixedPorts = false ;
101104
102105 private String routerHost = ROUTER_HOST ;
103106 private int routerPort = ROUTER_PORT ;
@@ -106,7 +109,6 @@ public class TarantoolCartridgeContainer extends GenericContainer<TarantoolCartr
106109 private String routerPassword = CARTRIDGE_PASSWORD ;
107110 private String directoryResourcePath = SCRIPT_RESOURCE_DIRECTORY ;
108111 private String instanceDir = INSTANCE_DIR ;
109- private final String instancesFile ;
110112 private final CartridgeConfigParser instanceFileParser ;
111113 private final String topologyConfigurationFile ;
112114 private final TarantoolContainerClientHelper clientHelper ;
@@ -119,7 +121,7 @@ public class TarantoolCartridgeContainer extends GenericContainer<TarantoolCartr
119121 * @param topologyConfigurationFile path to a topology bootstrap script, relative to the classpath resources
120122 */
121123 public TarantoolCartridgeContainer (String instancesFile , String topologyConfigurationFile ) {
122- this (withArguments ( buildImage ()) , instancesFile , topologyConfigurationFile );
124+ this (DOCKERFILE , instancesFile , topologyConfigurationFile );
123125 }
124126
125127 /**
@@ -130,7 +132,7 @@ public TarantoolCartridgeContainer(String instancesFile, String topologyConfigur
130132 * @param topologyConfigurationFile path to a topology bootstrap script, relative to the classpath resources
131133 */
132134 public TarantoolCartridgeContainer (String dockerFile , String instancesFile , String topologyConfigurationFile ) {
133- this (withArguments ( buildImage ( dockerFile )) , instancesFile , topologyConfigurationFile );
135+ this (dockerFile , "" , instancesFile , topologyConfigurationFile );
134136 }
135137
136138 /**
@@ -145,21 +147,43 @@ public TarantoolCartridgeContainer(String dockerFile, String instancesFile, Stri
145147 */
146148 public TarantoolCartridgeContainer (String dockerFile , String buildImageName ,
147149 String instancesFile , String topologyConfigurationFile ) {
148- this (withArguments (buildImage (dockerFile , buildImageName )), instancesFile , topologyConfigurationFile );
150+ this (dockerFile , buildImageName , instancesFile , topologyConfigurationFile , Collections .emptyMap ());
151+ }
152+
153+
154+ /**
155+ * Create a container with specified image and specified instances file from the classpath resources. By providing
156+ * the result Cartridge container image name, you can cache the image and avoid rebuilding on each test run (the
157+ * image is tagged with the provided name and not deleted after tests finishing).
158+ *
159+ * @param dockerFile URL resource path to a Dockerfile which configures Cartridge
160+ * and other necessary services
161+ * @param buildImageName Specify a stable image name for the test container to prevent rebuilds
162+ * @param instancesFile URL resource path to instances.yml relative in the classpath
163+ * @param topologyConfigurationFile URL resource path to a topology bootstrap script in the classpath
164+ * @param buildArgs a map of arguments that will be passed to docker ARG commands on image build.
165+ * This values can be overriden by environment.
166+ */
167+ public TarantoolCartridgeContainer (String dockerFile , String buildImageName , String instancesFile ,
168+ String topologyConfigurationFile , final Map <String , String > buildArgs ) {
169+ this (withArguments (buildImage (dockerFile , buildImageName ), buildArgs ),
170+ instancesFile , topologyConfigurationFile );
149171 }
150172
151173 private TarantoolCartridgeContainer (Future <String > image , String instancesFile , String topologyConfigurationFile ) {
152174 super (image );
153175 if (instancesFile == null || instancesFile .isEmpty ()) {
154176 throw new IllegalArgumentException ("Instance file name must not be null or empty" );
155177 }
156- this .instancesFile = instancesFile ;
157178 this .instanceFileParser = new CartridgeConfigParser (instancesFile );
158179 this .topologyConfigurationFile = topologyConfigurationFile ;
159180 this .clientHelper = new TarantoolContainerClientHelper (this );
160181 }
161182
162- private static Future <String > withArguments (ImageFromDockerfile image ) {
183+ private static Future <String > withArguments (ImageFromDockerfile image , final Map <String , String > buildArgs ) {
184+ if (!buildArgs .isEmpty ()) {
185+ image .withBuildArgs (buildArgs );
186+ }
163187 for (String envVariable : Arrays .asList (
164188 ENV_TARANTOOL_VERSION ,
165189 ENV_TARANTOOL_SERVER_USER ,
@@ -178,17 +202,12 @@ private static Future<String> withArguments(ImageFromDockerfile image) {
178202 return image ;
179203 }
180204
181- private static ImageFromDockerfile buildImage () {
182- return buildImage (DOCKERFILE );
183- }
184-
185- private static ImageFromDockerfile buildImage (String dockerFile ) {
186- return new ImageFromDockerfile ().withFileFromClasspath ("Dockerfile" , dockerFile );
187- }
188-
189205 private static ImageFromDockerfile buildImage (String dockerFile , String buildImageName ) {
190- return new ImageFromDockerfile (buildImageName , false )
191- .withFileFromClasspath ("Dockerfile" , dockerFile );
206+ if (buildImageName != null && !buildImageName .isEmpty ()) {
207+ return new ImageFromDockerfile (buildImageName , false )
208+ .withFileFromClasspath ("Dockerfile" , dockerFile );
209+ }
210+ return new ImageFromDockerfile ().withFileFromClasspath ("Dockerfile" , dockerFile );
192211 }
193212
194213 /**
@@ -206,6 +225,9 @@ public String getRouterHost() {
206225 * @return router mapped port
207226 */
208227 public int getRouterPort () {
228+ if (useFixedPorts ) {
229+ return routerPort ;
230+ }
209231 return getMappedPort (routerPort );
210232 }
211233
@@ -312,9 +334,23 @@ public TarantoolCartridgeContainer withDirectoryBinding(String directoryResource
312334 * @return HTTP API port
313335 */
314336 public int getAPIPort () {
337+ if (useFixedPorts ) {
338+ return apiPort ;
339+ }
315340 return getMappedPort (apiPort );
316341 }
317342
343+ /**
344+ * Use fixed ports binding.
345+ * Defaults to false.
346+ *
347+ * @return HTTP API port
348+ */
349+ public TarantoolCartridgeContainer withUseFixedPorts (boolean useFixedPorts ) {
350+ this .useFixedPorts = useFixedPorts ;
351+ return this ;
352+ }
353+
318354 /**
319355 * Set Cartridge router hostname
320356 *
@@ -377,8 +413,17 @@ public TarantoolCartridgeContainer withRouterPassword(String routerPassword) {
377413
378414 @ Override
379415 protected void configure () {
380- withFileSystemBind (getDirectoryBinding (), getInstanceDir (), BindMode .READ_WRITE );
381- withExposedPorts (instanceFileParser .getExposablePorts ());
416+ if (!getDirectoryBinding ().isEmpty ()) {
417+ withFileSystemBind (getDirectoryBinding (), getInstanceDir (), BindMode .READ_WRITE );
418+ }
419+
420+ if (useFixedPorts ) {
421+ for (Integer port : instanceFileParser .getExposablePorts ()) {
422+ addFixedExposedPort (port , port );
423+ }
424+ } else {
425+ withExposedPorts (instanceFileParser .getExposablePorts ());
426+ }
382427 }
383428
384429 @ Override
0 commit comments