Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ElasticSearch in-memory for testing

Tags:

I would like to write some integration with ElasticSearch. For testing I would like to run in-memory ES.

I found some information in documentation, but without example how to write those kind of test. Elasticsearch Reference [1.6] » Testing » Java Testing Framework » integration tests « unit tests

Also I found following article, but it's out of data. Easy JUnit testing with Elastic Search

I looking example how to start and run ES in-memory and access to it over REST API.

like image 531
MicTech Avatar asked Jul 14 '15 07:07

MicTech


People also ask

How do I test Elasticsearch?

Verify elasticsearch is running by typing $ smarts/bin/sm_service show. 2. Verify elasticsearch is serving requests from a browser on the same machine in Windows or using a tool like curl on Linux. A page specific to the browser will appear.

How do you mock in Elasticsearch?

The best way to mock Elasticsearch with the official clients is to replace the Connection component since it has very few responsibilities and it does not interact with other internal components other than getting requests and returning responses.

What is embedded Elasticsearch?

Small utility for creating integration tests that use Elasticsearch. Instead of using Node it downloads Elasticsearch in specified version and starts it in a separate process. It also allows you to install required plugins which is not possible when using NodeBuilder .

Is Elasticsearch in Java?

Elasticsearch is a NoSQL Database, which is developed in Java programming language. It is a real-time, distributed, and analysis engine that is designed for storing logs. It is a highly scalable document storage engine. Similar to the MongoDB, it stores the data in document format.


1 Answers

Based on the second link you provided, I created this abstract test class:

@RunWith(SpringJUnit4ClassRunner.class)
public abstract class AbstractElasticsearchTest {

    private static final String HTTP_PORT = "9205";
    private static final String HTTP_TRANSPORT_PORT = "9305";
    private static final String ES_WORKING_DIR = "target/es";

    private static Node node;

    @BeforeClass
    public static void startElasticsearch() throws Exception {    
        removeOldDataDir(ES_WORKING_DIR + "/" + clusterName);

        Settings settings = Settings.builder()
                .put("path.home", ES_WORKING_DIR)
                .put("path.conf", ES_WORKING_DIR)
                .put("path.data", ES_WORKING_DIR)
                .put("path.work", ES_WORKING_DIR)
                .put("path.logs", ES_WORKING_DIR)
                .put("http.port", HTTP_PORT)
                .put("transport.tcp.port", HTTP_TRANSPORT_PORT)
                .put("index.number_of_shards", "1")
                .put("index.number_of_replicas", "0")
                .put("discovery.zen.ping.multicast.enabled", "false")
                .build();
        node = nodeBuilder().settings(settings).clusterName("monkeys.elasticsearch").client(false).node();
        node.start();
    }

    @AfterClass
    public static void stopElasticsearch() {
        node.close();
    }

    private static void removeOldDataDir(String datadir) throws Exception {
        File dataDir = new File(datadir);
        if (dataDir.exists()) {
            FileSystemUtils.deleteRecursively(dataDir);
        }
    }    
}

In the production code, I configured an Elasticsearch client as follows. The integration test extends the above defined abstract class and configures property elasticsearch.port as 9305 and elasticsearch.host as localhost.

@Configuration
public class ElasticsearchConfiguration {    
    @Bean(destroyMethod = "close")
    public Client elasticsearchClient(@Value("${elasticsearch.clusterName}") String clusterName,
                                      @Value("${elasticsearch.host}") String elasticsearchClusterHost,
                                      @Value("${elasticsearch.port}") Integer elasticsearchClusterPort) throws UnknownHostException {
        Settings settings = Settings.settingsBuilder().put("cluster.name", clusterName).build();
        InetSocketTransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName(elasticsearchClusterHost), elasticsearchClusterPort);
        return TransportClient.builder().settings(settings).build().addTransportAddress(transportAddress);
    }
}

That's it. The integration test will run the production code which is configured to connect to the node started in the AbstractElasticsearchTest.startElasticsearch().

In case you want to use the elasticsearch REST api, use port 9205. E.g. with Apache HttpComponents:

HttpClient httpClient = HttpClients.createDefault();
HttpPut httpPut = new HttpPut("http://localhost:9205/_template/" + templateName);
httpPut.setEntity(new FileEntity(new File("template.json")));
httpClient.execute(httpPut);
like image 179
Tim Van Laer Avatar answered Sep 18 '22 11:09

Tim Van Laer