testcontainers oracle database container starts before database user is created

Simon :

I want to have automated tests for testing import commands from datasource A (oracle) to datasource B (postgres). Both datasources should be created with testcontainers.

The basic setup is done but the problem is:

testcontainers oracleContainer starts before the entrypoint defined in the Dokerfile has a change to finish up and create the user needed for the tests.

After the container is running, some sql scripts are executed creating tables and filling them with data. Those scripts fail because the user mentioned in the script is not created yet.

testcontainers is not waiting for the complete setup.


I've setup the container like this:

        OracleContainer oracleContainer = new OracleContainer("webdizz/oracle-xe-11g-sa:latest")
            .withStartupTimeoutSeconds(10000)
            .withEnv("DATABASES", "xyz");

The database is definitely created, but after a rather long time (tested by running the test forever and checking the database with docker exec)

I tried to set a wait strategy for the container multiple ways, for example like this:

        oracleContainer.setWaitStrategy(new LogMessageWaitStrategy().withRegEx("*.Enjoy!*"));

but it didn't result in anything.


By checking the logs with:

Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(LOGGER);
    oracleContainer.followOutput(logConsumer);

I can see that testcontainers never waits for it to finish.

All I found online regarding this "bug" or "problem" is this BugReport on github: https://github.com/testcontainers/testcontainers-java/issues/1292

and it seems like the user is even using the same container as me. However the solution mentioned in the issue didn't work for me.

Simon :

I solved this problem by creating a script (actually two, but can be put into one) that checks if the database user "XYZ" exists and returns 0 if it does.

wait_check.sh:

#!/usr/bin/env bash
while :
do
    echo "waiting for user to exist"
    if $(/bin/bash /check_db_user.sh | grep -q XYZ); then
        echo "user XYZ exists"
        exit 0
    fi
done

and check_db_user.sh:

#!/usr/bin/env bash
sqlplus -s /nolog <<EOF
connect username/password
select username from dba_users where username = 'XYZ';
quit
EOF

and then I run the wait_check.sh with:

oracleContainer.copyFileToContainer(
        MountableFile.forClasspathResource("/helper/wait_check.sh"),
        "/wait_check.sh");
oracleContainer.copyFileToContainer(
        MountableFile.forClasspathResource("/helper/check_db_user.sh"),
        "/check_db_user.sh");

try {
    Container.ExecResult result = oracleContainer.execInContainer("./wait_check.sh");
    log.debug(result.getStdout());
} catch (IOException | InterruptedException e) {
    log.error(e.getMessage());
}

This works because oracleContainer.execInContainer doesn't time out on default. It just waits until whatever you do finishes. I discovered this while debugging and the solution works for me.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=161784&siteId=1