Skip to content

Add execInArtemis helper to ArtemisContainer (#11589) - #11955

Draft
klouds27 wants to merge 1 commit into
testcontainers:mainfrom
klouds27:feat/11589-artemis-exec-helper
Draft

Add execInArtemis helper to ArtemisContainer (#11589)#11955
klouds27 wants to merge 1 commit into
testcontainers:mainfrom
klouds27:feat/11589-artemis-exec-helper

Conversation

@klouds27

@klouds27 klouds27 commented Aug 1, 2026

Copy link
Copy Markdown

Closes #11589

Invoking the Artemis CLI from a container required callers to hard-code the internal binary path and manually append --user/--password on every call. execInArtemis wraps execInContainer, prepending the binary path and injecting the configured credentials automatically.

ExecResult result = artemis.execInArtemis(
    "queue", "create", "--name=myqueue", "--auto-create-address", "--anycast", "--silent"
);

The binary path and credentials are always resolved from the container's current configuration, so multiple CLI commands can be chained without any extra setup.

…tainers#11589)

Adds a convenience method that wraps execInContainer, prepending the
Artemis CLI binary path and auto-injecting the configured user and
password credentials, so callers no longer have to hard-code the
container path or manually pass --user/--password on every invocation.

Signed-off-by: klouds27 <adalwolf@gmail.com>

@renechoi renechoi left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking at the ActiveMQ module and ran this locally. It's still a draft, so I'd rather flag these now than after you've polished it.

Setup: PR head 7a658e0f on top of 2ac3c977 (current main), JDK 21.0.9, Docker on linux/arm64, both apache/activemq-artemis:2.32.0-alpine and apache/artemis:2.53.0-alpine pulled natively.

What already works. ./gradlew :testcontainers-activemq:test is green on the PR head: 10 tests, 0 failures (4 in ActiveMQContainerTest, 6 in ArtemisContainerTest). I also checked /var/lib/artemis-instance/bin/artemis on apache/artemis:2.53.0-alpine, since a hard-coded path looked image-specific and that image is in the compatibility matrix. The image ships the CLI at /opt/artemis/bin/artemis, but its entrypoint creates the broker instance at /var/lib/artemis-instance, so the constant resolves on both supported images. No problem there.

Four things below.

1. ./gradlew check will fail on formatting

Both changed files violate the module's prettier config (printWidth 120):

> Task :testcontainers-activemq:spotlessJavaCheck FAILED
  The following files had format violations:
      src/main/java/org/testcontainers/activemq/ArtemisContainer.java
      src/test/java/org/testcontainers/activemq/ArtemisContainerTest.java

./gradlew :testcontainers-activemq:spotlessApply fixes both. Worth doing before you mark it ready for review, since CI runs check.

2. A caller can no longer pass explicit credentials

The credentials are appended unconditionally, so supplying your own is a hard error rather than an override:

artemis.execInArtemis("queue", "create", "--name=q", "--auto-create-address", "--anycast", "--silent",
                      "--user=someone", "--password=secret");
exit=1
stdout=Usage: artemis help [<args>...]
stderr=option '--user' (<user>) should be specified only once

This matters for a broker. Checking what a non-admin user is allowed to do is an ordinary Artemis test, and the helper currently removes that option with an error that doesn't point at the cause. Injecting only when the caller hasn't already supplied them keeps the sugar and drops the trap:

List<String> fullCommand = new ArrayList<>();
fullCommand.add(ARTEMIS_CLI);
fullCommand.addAll(Arrays.asList(command));
if (Stream.of(command).noneMatch(arg -> arg.startsWith("--user"))) {
    fullCommand.add("--user=" + getUser());
}
if (Stream.of(command).noneMatch(arg -> arg.startsWith("--password"))) {
    fullCommand.add("--password=" + getPassword());
}

I ran that guard locally. Explicit --user=artemis --password=artemis creates the queue (exit 0), and explicit wrong credentials now fail with the broker's own error (AMQ229031: Unable to validate user ... Username: nope) rather than a CLI usage error. Treat the snippet as a sketch: the prefix match wants more care than startsWith if you go this way.

3. getExitCode() == 0 does not prove the queue was created

In fairness, the assertion is not empty. Run the same command with no credentials and it exits 1 (AMQ229031 ... Username: null), so exit code 0 does pin down the credential injection, which is the point of the PR.

What it doesn't pin down is the command itself. artemis queue create exits 0 when the create fails:

execInArtemis("queue", "create", "--silent")
exit=0
stderr=Failed to create queue . Reason: AMQ229216: Invalid queue name:

So a regression that mangles the command arguments while still passing credentials through would leave this test green. Asserting on the queue costs nothing on the container the test already started:

execInArtemis("queue", "stat", "--queueName=exec-test-queue")
  |NAME           |ADDRESS        |CONSUMER_COUNT|...
  |exec-test-queue|exec-test-queue|0             |...

execInArtemis("queue", "stat", "--queueName=no-such-queue")
  |NAME|ADDRESS|CONSUMER_COUNT|...          <- header row only

Both exit 0, so the assertion has to read stdout.

Related, and your call rather than a request: every other module under modules/ that shells out to a CLI checks the exit code itself and then throws or logs (SolrContainer, RabbitMQContainer, SolaceContainer, MongoDBContainer). This is the first public helper here that hands back a raw ExecResult. Keeping it raw is defensible, but given the measurement above, the javadoc probably shouldn't leave callers assuming exit 0 means the command did what they asked. Note that the example in #11589 throws on a non-zero exit, which wouldn't have caught the case above either.

4. The new API isn't in the docs

docs/modules/activemq.md pulls every existing ArtemisContainer feature out of the test file with <!--codeinclude--> and inside_block: (container, settingCredentials, enableAnonymousLogin). The new test carries no such markers and the docs aren't touched, so execInArtemis won't appear anywhere a user would look for it. #11589 asks for that directly ("It'd also be a nice way to promote that feature in the API"), so a // execInArtemis { block plus a short docs section would close the issue more completely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement]: Ease the invocation of the Artemis CLI

2 participants