"codebase property already set" when running ESIntegTestCase

We're attempting an upgrade to ES 6.2.

Previously, we'd integration tested code by using NodeBuilder and running up a local ES node. I'd rather swap this out for the ESIntegTestCase usage if possible.

However, when I try to run an integration test I get the following error:

	at org.elasticsearch.bootstrap.BootstrapForTesting.<clinit>(BootstrapForTesting.java:164)
	at org.elasticsearch.test.ESTestCase.<clinit>(ESTestCase.java:190)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at com.carrotsearch.randomizedtesting.RandomizedRunner$2.run(RandomizedRunner.java:592)
Caused by: java.lang.IllegalStateException: codebase property already set: codebase.metrics-core -> file:/Users/me/.m2/repository/io/dropwizard/metrics/metrics-core/3.1.0/metrics-core-3.1.0.jar, cannot set to file:/Users/me/.m2/repository/com/yammer/metrics/metrics-core/2.2.0/metrics-core-2.2.0.jar
	at org.elasticsearch.bootstrap.Security.readPolicy(Security.java:236)
	at org.elasticsearch.bootstrap.BootstrapForTesting.<clinit>(BootstrapForTesting.java:139)
	... 4 more

What does this mean, and how I can I fix it?

My test class is annotated with: @RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) and extends ESIntegTestCase if that helps at all.

Thank you for any help anyone can offer!

You can not run elasticsearch embedded. Read this blog post.

Note that to run integration tests (not unit tests) you would probably prefer running that in something close to a production environment, like a real elasticsearch server instance. I shared some ideas about integration testing in this thread: In memory testing with RestHighLevelClient

JPersonally I disagree with running the tests I want to run against a like-live environment. Our live environment is massive. I don’t need a replica to test that our storm bolts/spouts are querying and updating correctly.

I just want to be able to test that, when I update to using the HighLevelRestClient, the query is formulated correctly and bringing back what is expected. I don’t want to run up an entire es instance to check that. Apparently, this is what ESIntegTestCase is for, no?

Thanks for the links. I’ll check them out ASAP.

I just found this: https://github.com/elastic/elasticsearch/issues/21544 :disappointed:

I might try your test-containers module...

@dadoonet Your testcontainers-elasticsearch project looks like it could be just the thing.

What's the default cluster name? I'd assumed it was elasticsearch, but I can't connect:

[Test worker] INFO org.testcontainers.dockerclient.UnixSocketClientProviderStrategy - Accessing docker with local Unix socket
[Test worker] INFO org.testcontainers.dockerclient.DockerClientProviderStrategy - Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
[Test worker] INFO org.testcontainers.DockerClientFactory - Docker host IP address is localhost
[Test worker] INFO org.testcontainers.DockerClientFactory - Connected to docker: 
  Server Version: 18.03.1-ce
  API Version: 1.37
  Operating System: Docker for Mac
  Total Memory: 1998 MB
[Test worker] INFO org.testcontainers.DockerClientFactory - Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
        ℹ︎ Checking the system...
        ✔ Docker version should be at least 1.6.0
        ✔ Docker environment should have more than 2GB free disk space
        ✔ File should be mountable
[Test worker] INFO 🐳 [alpine:3.5] - Starting an elasticsearch container using version [6.2.4] from [docker.elastic.co/elasticsearch/elasticsearch-oss]
[Test worker] INFO 🐳 [testcontainers/y3nd2g5lax66fcsf] - Creating container for image: testcontainers/y3nd2g5lax66fcsf
[Test worker] INFO 🐳 [testcontainers/y3nd2g5lax66fcsf] - Starting container with ID: d41f2500b444ba90ec784a3ede74f3cab4fbd807653b96c7ec217fb5981fb4d0
[Test worker] INFO 🐳 [testcontainers/y3nd2g5lax66fcsf] - Container testcontainers/y3nd2g5lax66fcsf is starting: d41f2500b444ba90ec784a3ede74f3cab4fbd807653b96c7ec217fb5981fb4d0
[Test worker] INFO 🐳 [testcontainers/y3nd2g5lax66fcsf] - Container testcontainers/y3nd2g5lax66fcsf started
[Test worker] INFO 🐳 [testcontainers/y3nd2g5lax66fcsf] - Starting an elasticsearch container using version [6.2.4] from [docker.elastic.co/elasticsearch/elasticsearch-oss]
[Test worker] INFO 🐳 [testcontainers/9p7edvq6inujmw92] - Creating container for image: testcontainers/9p7edvq6inujmw92
[Test worker] INFO 🐳 [testcontainers/9p7edvq6inujmw92] - Starting container with ID: 366a1bf5ba2bd755eae0f80acbd47b2149d8a497555a38576a5c47ec78b3d281
[Test worker] INFO 🐳 [testcontainers/9p7edvq6inujmw92] - Container testcontainers/9p7edvq6inujmw92 is starting: 366a1bf5ba2bd755eae0f80acbd47b2149d8a497555a38576a5c47ec78b3d281
[Test worker] INFO 🐳 [testcontainers/9p7edvq6inujmw92] - Container testcontainers/9p7edvq6inujmw92 started
[Test worker] INFO com.cameraforensics.elasticsearch.ElasticSearchMonitor - Checking availability of nodes for connection: ElasticSearchConnection{ host=http://localhost:32775, clusterName=elasticsearch, port=9300}
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'log4j2.debug' to show Log4j2 internal initialization logging.
[Test worker] INFO com.cameraforensics.elasticsearch.ElasticSearchMonitor - Received NoNodeAvailableException. Returning false.

setup:

    @Rule
    public ElasticsearchResource elasticsearch = new ElasticsearchResource(
            "docker.elastic.co/elasticsearch/elasticsearch-oss",
            "6.2.4",
            null,
            new ArrayList<>(),
            null);

Probably you are using then the TransportClient. You should switch to the Rest Client as Transport Client will be removed at some point.

That's why I'm not exposing IIRC the port 9300.

I’d heard that wasn’t happening until ES 7.
Given the level of faff to upgrade to 6 I doubt we’ll be doing that for ages.

If I fork it, I guess I can expose that port?

This is becoming so, SO painful!

Sure but as it has been deprecated in 6.x at least, I'd move away from it.

Anyway, I forgot that this has been added: https://github.com/dadoonet/testcontainers-java-module-elasticsearch/commit/faac07e7cfb831a512837a8bd2f97ab9d46b37d0#diff-46ce0828f1433f996e5ef2501c4bcae6

But I did not release a new version yet.

1 Like

The alternative is that’s i have to refactor a load of code to use the low level api to perform admin requests, because the high level rest api doesn’t support them yet.

So we’re in a place between having the transport client for admin requests, but everyone saying not to use it, and having the high level rest api that doesn’t do admin requests but will one day.

Why would I spend my time developing low level api requests when the transport client does it and the high level api will? It doesn’t make any sense.

Phew! That’s good news!
I will move away from the transport client, you have my word. Just not today :blush:

Ps: that project is really really nice. Good work

Thank you. I'm on the way to move it officially under testcontainers umbrella.

Forgot to say that you can also launch Elasticsearch from maven as well (and gradle I guess).

Here is a sample project: https://github.com/dadoonet/elasticsearch-integration-tests/tree/05-cloud

That's good to know. This particular project uses gradle, but one of our other ones is maven, so I'll definitely need that. Are you going to release a new version to maven central?

Are you going to release a new version to maven central?

Definitely yes. Question is when? :smiley:

For now I can build and deploy it to our local repo.

I'm having a strange issue at the moment whereby it's starting two containers. The first one doesn't respond on any ports (curl: (52) Empty reply from server) the second one does, but the ElasticSearchResource is pointing at the first one. That's currently why I can't connect.

[Test worker] INFO 🐳 [alpine:3.5] - Starting an elasticsearch container using version [6.2.4] from [docker.elastic.co/elasticsearch/elasticsearch-oss]
[Test worker] INFO 🐳 [testcontainers/imqt7qlwihxlzacq] - Creating container for image: testcontainers/imqt7qlwihxlzacq
[Test worker] INFO 🐳 [testcontainers/imqt7qlwihxlzacq] - Starting container with ID: afd6bba62d2846d49d74dd502cf4c63e31f6e0101ad497df0174c9ed4d852574
[Test worker] INFO 🐳 [testcontainers/imqt7qlwihxlzacq] - Container testcontainers/imqt7qlwihxlzacq is starting: afd6bba62d2846d49d74dd502cf4c63e31f6e0101ad497df0174c9ed4d852574
[Test worker] INFO 🐳 [testcontainers/imqt7qlwihxlzacq] - Container testcontainers/imqt7qlwihxlzacq started
[Test worker] INFO 🐳 [testcontainers/imqt7qlwihxlzacq] - Starting an elasticsearch container using version [6.2.4] from [docker.elastic.co/elasticsearch/elasticsearch-oss]
[Test worker] INFO 🐳 [testcontainers/rhayznm8q37v9ng6] - Creating container for image: testcontainers/rhayznm8q37v9ng6
[Test worker] INFO 🐳 [testcontainers/rhayznm8q37v9ng6] - Starting container with ID: 2ba9d3ba1465eafb74f923a17ecf165a118e5545e3602a7b9aba0e7d26a436da
[Test worker] INFO 🐳 [testcontainers/rhayznm8q37v9ng6] - Container testcontainers/rhayznm8q37v9ng6 is starting: 2ba9d3ba1465eafb74f923a17ecf165a118e5545e3602a7b9aba0e7d26a436da
[Test worker] INFO 🐳 [testcontainers/rhayznm8q37v9ng6] - Container testcontainers/rhayznm8q37v9ng6 started
[Test worker] INFO com.cameraforensics.elasticsearch.ElasticSearchMonitor - Checking availability of nodes for connection: ElasticSearchConnection{ restHost=http://localhost:32815, transportHost=http://localhost:32814, clusterName=elasticsearch}

docker ps:

CONTAINER ID        IMAGE                             COMMAND                  CREATED                  STATUS              PORTS                                              NAMES
2ba9d3ba1465        testcontainers/rhayznm8q37v9ng6   "/usr/local/bin/dock…"   Less than a second ago   Up 4 seconds        0.0.0.0:32815->9200/tcp, 0.0.0.0:32814->9300/tcp   naughty_blackwell
afd6bba62d28        testcontainers/imqt7qlwihxlzacq   "/usr/local/bin/dock…"   19 seconds ago           Up 24 seconds       0.0.0.0:32813->9200/tcp, 0.0.0.0:32812->9300/tcp   loving_vaughan
0db246b7c0a8        bsideup/moby-ryuk:0.2.2           "/app"                   21 seconds ago           Up 25 seconds       0.0.0.0:32811->8080/tcp                            testcontainers-ryuk-f5d95521-3921-4c03-b597-471727ff80cb

curl localhost:32814 = curl: (52) Empty reply from server

curl localhost:32812 = This is not a HTTP port%

What am I doing wrong?

More helpful information:

    @Rule
    public ElasticsearchResource elasticsearch = new ElasticsearchResource(
            "docker.elastic.co/elasticsearch/elasticsearch-oss",
            "6.2.4",
            null,
            new ArrayList<>(),
            new HashMap<>(),
            null);

    public ElasticSearchConnection elasticSearchConnection;

    public String clusterName = "elasticsearch";

    @Before
    public void setup() {
        elasticsearch.getContainer().start();
        HttpHost transportHost = new HttpHost(elasticsearch.getContainer().getContainerIpAddress(), elasticsearch.getContainer().getMappedPort(DEFAULT_TRANSPORT_PORT));


        elasticSearchConnection = new ElasticSearchConnection(elasticsearch.getHost(), transportHost, clusterName);
    }

    @After
    public void shutdown() {
        elasticSearchConnection.close();
        elasticSearchConnection = null;
        elasticsearch.getContainer().stop();
    }

Is it because I'm calling start()? Is that even necessary?

Update: If I remove the start() call, then only one container gets started, but still won't respond on any ports.

REST client works...

I think it's related to this: No node available : Elasticsearch Transport Client can't connect to Docker container

and that I need to check the container's ES config for network.host/bind_host?

Yeah. It's not needed. See GitHub - dadoonet/testcontainers-java-module-elasticsearch: Dockerized Elasticsearch container for testing under Testcontainers

but still won't respond on any ports.

Could you get the logs?