-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Refactor Testcontainers configuration to allow config by env var * Add Image substitution mechanism Builds upon #3021 and #3411: * adds a pluggable image substitution mechanism using ServiceLoader, enabling users to perform custom substitution/auditing of images being used by their tests * provides a default implementation that behaves similarly to legacy `TestcontainersConfiguration` approach (`testcontainers.properties`) Notes: * behaviour is similar but not quite identical to `TestcontainersConfiguration`: use of a configured custom image for, e.g. Kafka/Pulsar that does not have a tag specified causes the substitution to take effect for all usages. It seems very unlikely that people would be using a mix of the config file image overrides in some places _and_ specific images specified in code in others. * Duplication of default image names in modules vs `TestcontainersConfiguration` class is intentional: specifying image overrides in `testcontainers.properties` should be removed in the future. * ~Add log deprecation warnings when `testcontainers.properties` image overrides are used.~ Defer to a future release? * Remove extraneous change * Un-ignore docs example test by implementing a 'reversing' image name substitutor * Use configuration, not service loader, to select an ImageNameSubstitutor * Add check for order of config setting precedence * Extract classpath scanner and support finding of multiple resources * Introduce deterministic merging of classpath properties files * Update docs * Update docs * Remove service loader reference * Chain substitution through default and configured implementations * Small tweaks following review * Fix test compile error * Add UnstableAPI annotation * Move TestSpecificImageNameSubstitutor back to original package and remove duplicate use of default substitutor
- Loading branch information
Showing
39 changed files
with
936 additions
and
123 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
core/src/main/java/org/testcontainers/utility/ClasspathScanner.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package org.testcontainers.utility; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
import org.jetbrains.annotations.Nullable; | ||
import org.jetbrains.annotations.VisibleForTesting; | ||
|
||
import java.net.URL; | ||
import java.util.Collections; | ||
import java.util.Comparator; | ||
import java.util.Objects; | ||
import java.util.stream.Stream; | ||
|
||
/** | ||
* Utility for identifying resource files on classloaders. | ||
*/ | ||
@Slf4j | ||
class ClasspathScanner { | ||
|
||
@VisibleForTesting | ||
static Stream<URL> scanFor(final String name, ClassLoader... classLoaders) { | ||
return Stream | ||
.of(classLoaders) | ||
.flatMap(classLoader -> getAllPropertyFilesOnClassloader(classLoader, name)) | ||
.filter(Objects::nonNull) | ||
.sorted( | ||
Comparator | ||
.comparing(ClasspathScanner::filesFileSchemeFirst) // resolve 'local' files first | ||
.thenComparing(URL::toString) // sort alphabetically for the sake of determinism | ||
) | ||
.distinct(); | ||
} | ||
|
||
private static Integer filesFileSchemeFirst(final URL t) { | ||
return t.getProtocol().equals("file") ? 0 : 1; | ||
} | ||
|
||
/** | ||
* @param name the resource name to search for | ||
* @return distinct, ordered stream of resources found by searching this class' classloader and the current thread's | ||
* context classloader. Results are currently alphabetically sorted. | ||
*/ | ||
static Stream<URL> scanFor(final String name) { | ||
return scanFor( | ||
name, | ||
ClasspathScanner.class.getClassLoader(), | ||
Thread.currentThread().getContextClassLoader() | ||
); | ||
} | ||
|
||
@Nullable | ||
private static Stream<URL> getAllPropertyFilesOnClassloader(final ClassLoader it, final String s) { | ||
try { | ||
return Collections.list(it.getResources(s)).stream(); | ||
} catch (Exception e) { | ||
log.error("Unable to read configuration from classloader {} - this is probably a bug", it, e); | ||
return Stream.empty(); | ||
} | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
core/src/main/java/org/testcontainers/utility/ConfigurationFileImageNameSubstitutor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package org.testcontainers.utility; | ||
|
||
import com.google.common.annotations.VisibleForTesting; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
/** | ||
* {@link ImageNameSubstitutor} which takes replacement image names from configuration. | ||
* See {@link TestcontainersConfiguration} for the subset of image names which can be substituted using this mechanism. | ||
*/ | ||
@Slf4j | ||
final class ConfigurationFileImageNameSubstitutor extends ImageNameSubstitutor { | ||
|
||
private final TestcontainersConfiguration configuration; | ||
|
||
public ConfigurationFileImageNameSubstitutor() { | ||
this(TestcontainersConfiguration.getInstance()); | ||
} | ||
|
||
@VisibleForTesting | ||
ConfigurationFileImageNameSubstitutor(TestcontainersConfiguration configuration) { | ||
this.configuration = configuration; | ||
} | ||
|
||
@Override | ||
public DockerImageName apply(final DockerImageName original) { | ||
final DockerImageName result = configuration | ||
.getConfiguredSubstituteImage(original) | ||
.asCompatibleSubstituteFor(original); | ||
|
||
if (!result.equals(original)) { | ||
log.warn("Image name {} was substituted by configuration to {}. This approach is deprecated and will be removed in the future", | ||
original, | ||
result | ||
); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
@Override | ||
protected String getDescription() { | ||
return getClass().getSimpleName(); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
core/src/main/java/org/testcontainers/utility/DefaultImageNameSubstitutor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package org.testcontainers.utility; | ||
|
||
import com.google.common.annotations.VisibleForTesting; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
/** | ||
* Testcontainers' default implementation of {@link ImageNameSubstitutor}. | ||
* Delegates to {@link ConfigurationFileImageNameSubstitutor}. | ||
*/ | ||
@Slf4j | ||
final class DefaultImageNameSubstitutor extends ImageNameSubstitutor { | ||
|
||
private final ConfigurationFileImageNameSubstitutor configurationFileImageNameSubstitutor; | ||
|
||
public DefaultImageNameSubstitutor() { | ||
configurationFileImageNameSubstitutor = new ConfigurationFileImageNameSubstitutor(); | ||
} | ||
|
||
@VisibleForTesting | ||
DefaultImageNameSubstitutor( | ||
final ConfigurationFileImageNameSubstitutor configurationFileImageNameSubstitutor | ||
) { | ||
this.configurationFileImageNameSubstitutor = configurationFileImageNameSubstitutor; | ||
} | ||
|
||
@Override | ||
public DockerImageName apply(final DockerImageName original) { | ||
return configurationFileImageNameSubstitutor.apply(original); | ||
} | ||
|
||
@Override | ||
protected String getDescription() { | ||
return "DefaultImageNameSubstitutor (" + configurationFileImageNameSubstitutor.getDescription() + ")"; | ||
} | ||
} |
Oops, something went wrong.