I want to run SchemaSpy container against PosgtreSQL database to generate the documentation. Here is the approach I came up with:
- Start PostgreSQL.
- Start SchemaSpy with overridden entrypoint (
/bin/sh
). - Run
execInContainer
to run the SchemaSpy app itself. - Run
execInContainer
to put the result changes in a tarball. - Run
copyFileFromContainer
to copy the tarball from the container to the OS.
Here is the source code:
@DBTest
class SchemaSpyTest extends IntegrationSuite {
private final GenericContainer<?> SCHEMA_SPY =
new GenericContainer<>(DockerImageName.parse("schemaspy/schemaspy:6.1.0"))
.withNetworkAliases("schemaspy")
.withCreateContainerCmdModifier(cmd -> cmd.withEntrypoint("/bin/sh"))
.withNetwork(NETWORK)
.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("SchemaSpy")));
@Test
@SneakyThrows
void test() {
SCHEMA_SPY.start();
SCHEMA_SPY.execInContainer(
"java -jar schemaspy-6.1.0.jar -t pgsql11 -db %s -host postgres -u %s -p %s -debug"
.formatted(POSTGRES.getDatabaseName(), POSTGRES.getUsername(), POSTGRES.getPassword())
);
SCHEMA_SPY.execInContainer("tar", "-czvf", "/output/output.tar.gz", "/output");
SCHEMA_SPY.copyFileFromContainer(
"/output/output.tar.gz",
Path.of(getClass().getResource("/").getPath(), "output.tar.gz")
.toAbsolutePath()
.toString()
);
SCHEMA_SPY.stop();
}
}
@Testcontainers
public class IntegrationSuite {
protected static final Network NETWORK = Network.newNetwork();
@Container
protected static final PostgreSQLContainer<?> POSTGRES =
new PostgreSQLContainer<>(DockerImageName.parse("postgres:13.5"))
.withNetworkAliases("postgres")
.withNetwork(NETWORK);
@DynamicPropertySource
static void setProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", POSTGRES::getJdbcUrl);
registry.add("spring.datasource.username", POSTGRES::getUsername);
registry.add("spring.datasource.password", POSTGRES::getPassword);
}
}
I expected that /bin/sh
entrypoint will make container run indefinitely until I manually stop it. Actually, that's what happens on SCHEMA_SPY.start()
row:
- Container starts.
/bin/sh
command executes.- Container stops.
So, execInContainer
operations fail because the container is already stopped in that moment.
Is there are any workaround to overcome this issue?