java에서 elasticsearch 테스트를 하려면 두가지가 있다.

첫번째, elasticsearch 데몬(standalone)을 실행한 후, index/type 만들고 mapping 구조를 만든 후, 직접 코드에서 요청하는 것

두번째, integration test(local daemon)을 실행할 수 있다.



여기서는 두번째를 얘기하고자 한다. 

elasticsearch의 자바 페이지에서는 integration test를 설명하고 있다. 

아래 문서를 참조로 elasticsearch 1.4.1를 기준으로 작성한다.


http://www.elastic.co/guide/en/elasticsearch/reference/current/testing-framework.html

http://www.elastic.co/guide/en/elasticsearch/reference/current/using-elasticsearch-test-classes.html



pom.xml 파일은 다음과 같이 구성한다. 



<dependencies>
<properties>
<encoding>UTF-8</encoding>
<jdk.version>1.8</jdk.version>
<spring.groupId>org.springframework</spring.groupId>
<spring.version>3.2.6.RELEASE</spring.version>
<elasticsearch.version>1.4.1</elasticsearch.version>
<lucene.version>4.10.2</lucene.version>
<randomizedtesting-runner.version>2.1.11</randomizedtesting-runner.version>

</properties>

...

<dependencies>

...

<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-test-framework</artifactId>
<version>${lucene.version}</version>
<exclusions>
<exclusion>
<artifactId>randomizedtesting-runner</artifactId>
<groupId>com.carrotsearch.randomizedtesting</groupId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
<scope>test</scope>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>com.carrotsearch.randomizedtesting</groupId>
<artifactId>randomizedtesting-runner</artifactId>
<version>${randomizedtesting-runner.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>

</dependency>

</dependencies>




코드는 다음과 같이 작성한다. 클러스터로 실행할 수 있다. (클러스터없이는 ElasticsearchTestCase로 할 수 있긴 하나, 대부분의 테스트를 실제 환경과 비슷하게 할 수 있는 ElasticIntegrationTest를 사용하는 것이 나에게는 편한듯하다.)



@ClusterScope(scope = Scope.TEST, numDataNodes = 1)
public class ElasticsearchSimpleTest extends ElasticsearchIntegrationTest {

@Test
public void simpleTest() {
prepareCreate("test").setSettings("index.number_of_shards", 1).execute().actionGet();
client().prepareIndex(
"test", "type1", "1").setSource("field1", "value1", "field2", "value2").setRefresh(true).execute().actionGet();
refresh();

SearchResponse
searchResponse = client().prepareSearch().setQuery("{ \"term\" : { \"field1\" : \"value1\" }}").execute().actionGet();
Assert.assertEquals(1L,
searchResponse.getHits().totalHits());
}

}


(참고로, @ClusterScope를 따로 주지 않으면 여러 노드 4개가 실행된다. ClusterScope를 적절히 활용하는 것이 좋다.)

@ClusterScope(scope = Scope.TEST, numDataNodes = 1)



ElasticsearchIntegrationTest의 상속도는 다음과 같다. 조상은 LuceneTestCast 클래스이다. 

출처: http://thydoc.com/




console(터미널)에서 실행하는 mvn 은 잘 동작한다.

그러나, eclipse test 실행시 에러가 발생한다. 다음과 같이 assertion (-ea가 없다는) 에러가 발생한다.


Assertions mismatch: -ea was not specified but -Dtests.asserts=true
[2015-05-04 11:10:46] [ERROR] [o.e.c.l.l.Log4jESLogger] internalError (139): FAILURE  : com.google.elasticsearch.ElasticsearchSimpleTest
REPRODUCE WITH  : mvn clean test -Dtests.seed=BDAB67EEB7810B0E -Dtests.class=com.google.elasticsearch.ElasticsearchSimpleTest -Dtests.prefix=tests -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Seoul -Dtests.processors=8
Throwable:
java.lang.Exception: Assertions mismatch: -ea was not specified but -Dtests.asserts=true
    __randomizedtesting.SeedInfo.seed([BDAB67EEB7810B0E]:0)
    org.apache.lucene.util.TestRuleAssertionsRequired$1.evaluate(
TestRuleAssertionsRequired.java:48)
    org.apache.lucene.util.TestRuleMarkFailure$1.evaluate(
TestRuleMarkFailure.java:48)
    org.apache.lucene.util.TestRuleIgnoreAfterMaxFailures$1.evaluate(
TestRuleIgnoreAfterMaxFailures.java:65)
    org.apache.lucene.util.TestRuleIgnoreTestSuites$1.evaluate(
TestRuleIgnoreTestSuites.java:55)
    [...com.carrotsearch.randomizedtesting.*]
    java.lang.Thread.run(
Thread.java:745)



eclipse test에 vm argument에 -ea 를 추가하고 테스트를 실행한다. 




이렇게 실행해도, 랜덤하게 실행이 안될 때가 있다. lucene-core.jar 가 lucene-test-framwork.jar 보다 먼저 선언되면 다음과 같이 Eclipse에서 에러가 발생한다. 

java.lang.AssertionError: fix your classpath to have tests-framework.jar before lucene-core.jar
    __randomizedtesting.SeedInfo.seed([ABFDA059E4FE81D]:0)
    org.apache.lucene.util.TestRuleSetupAndRestoreClassEnv.before(
TestRuleSetupAndRestoreClassEnv.java:178)
    org.apache.lucene.util.AbstractBeforeAfterRule$1.evaluate(
AbstractBeforeAfterRule.java:45)
    org.apache.lucene.util.TestRuleStoreClassName$1.evaluate(
TestRuleStoreClassName.java:42)
    [...com.carrotsearch.randomizedtesting.*]
    org.apache.lucene.util.TestRuleAssertionsRequired$1.evaluate(
TestRuleAssertionsRequired.java:54)
    org.apache.lucene.util.TestRuleMarkFailure$1.evaluate(
TestRuleMarkFailure.java:48)
    org.apache.lucene.util.TestRuleIgnoreAfterMaxFailures$1.evaluate(
TestRuleIgnoreAfterMaxFailures.java:65)
    org.apache.lucene.util.TestRuleIgnoreTestSuites$1.evaluate(
TestRuleIgnoreTestSuites.java:55)
    [...com.carrotsearch.randomizedtesting.*]

    java.lang.Thread.run(Thread.java:745)



완성pom.xml은 다음과 같다. lucene-core.jar는 elasticsearch.jar 에서 depencency가 있는 라이브러리라서, lucene-test-framework 뒤에 elasticsearch.jar가 오도록 작성하고 실행하면 잘 동작된다.  




<dependencies>
<properties>
<encoding>UTF-8</encoding>
<jdk.version>1.8</jdk.version>
<spring.groupId>org.springframework</spring.groupId>
<spring.version>3.2.6.RELEASE</spring.version>
<elasticsearch.version>1.4.1</elasticsearch.version>
<lucene.version>4.10.2</lucene.version>
<randomizedtesting-runner.version>2.1.11</randomizedtesting-runner.version>

</properties>

...

<dependencies>

...

<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-test-framework</artifactId>
<version>${lucene.version}</version>
<exclusions>
<exclusion>
<artifactId>randomizedtesting-runner</artifactId>
<groupId>com.carrotsearch.randomizedtesting</groupId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
<scope>test</scope>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>com.carrotsearch.randomizedtesting</groupId>
<artifactId>randomizedtesting-runner</artifactId>
<version>${randomizedtesting-runner.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>

</dependency>

<dependency>

<groupId>org.elasticsearch</groupId>

<artifactId>elasticsearch</artifactId>

<version>${elasticsearch.version}</version>

</dependency>

</dependencies>







이슈는 parent-pom이 있는 경우이다.  parent-pom에서 elasticsearch를 정의했을 때는 다음과 같이 pom.xml을 정의한다.


parent-pom

..

<elasticsearch.version>1.4.1</elasticsearch.version>

<lucene.version>4.10.2</lucene.version>


..

<dependency>

<groupId>org.apache.lucene</groupId>

<artifactId>lucene-test-framework</artifactId>

<version>${lucene.version}</version>

<exclusions>

<exclusion>

<artifactId>randomizedtesting-runner</artifactId>

<groupId>com.carrotsearch.randomizedtesting</groupId>

</exclusion>

</exclusions>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.elasticsearch</groupId>

<artifactId>elasticsearch</artifactId>

<version>${elasticsearch.version}</version>

</dependency>


child-pom

<dependency>

<groupId>org.apache.lucene</groupId>

<artifactId>lucene-test-framework</artifactId>

<version>${lucene.version}</version>

<exclusions>

<exclusion>

<artifactId>randomizedtesting-runner</artifactId>

<groupId>com.carrotsearch.randomizedtesting</groupId>

</exclusion>

</exclusions>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.elasticsearch</groupId>

<artifactId>elasticsearch</artifactId>

<version>${elasticsearch.version}</version>

<scope>test</scope>

<type>test-jar</type>

</dependency>

<dependency>

<groupId>com.carrotsearch.randomizedtesting</groupId>

<artifactId>randomizedtesting-runner</artifactId>

<version>${randomizedtesting-runner.version}</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.hamcrest</groupId>

<artifactId>hamcrest-all</artifactId>

<version>1.3</version>

<scope>test</scope>

</dependency>


이렇세 저장해서 테스트를 진행할 수 있다.


로그는 다음과 같이 정상적으로 출력된다. 


[2015-05-06 11:01:12] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): Test simpleTest(com.google.elasticsearch.ElasticsearchSimpleTest) started

[2015-05-06 11:01:12] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): Setup InternalTestCluster [TEST-Samuelui-MacBook-Pro.local-CHILD_VM=[0]-CLUSTER_SEED=[6220750888563846882]-HASH=[13DB7FA960D9C6F0]] with seed [56548BF9650B2EE2] using [1] data nodes and [0] client nodes

[2015-05-06 11:01:12] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] version[1.4.1], pid[38504], build[89d3241/2014-11-26T15:49:29Z]

[2015-05-06 11:01:12] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] initializing ...

[2015-05-06 11:01:12] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] loaded [], sites []

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] initialized

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] starting ...

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] bound_address {local[1]}, publish_address {local[1]}

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] TEST-Samuelui-MacBook-Pro.local-CHILD_VM=[0]-CLUSTER_SEED=[6220750888563846882]-HASH=[13DB7FA960D9C6F0]/7RWQIcmMSbCDh12Tu1r8ag

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] new_master [node_t0][7RWQIcmMSbCDh12Tu1r8ag][Samuelui-MacBook-Pro.local][local[1]]{mode=local}, reason: local-disco-initial_connect(master)

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] started

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): Start Shared Node [node_t0] not shared

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [transport_client_node_t0] loaded [], sites []

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] recovered [0] indices into cluster_state

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [transport_client_node_t0] bound_address {local[2]}, publish_address {local[2]}

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [ElasticsearchSetupTest#mapAndGeopointTest]: before test

[2015-05-06 11:01:14] [INFO] [o.e.c.l.l.Log4jESLogger] internalInfo (119): [node_t0] [location_poi] creating index, cause [api], shards [1]/[0], mappings [location, _default_]












참조할만한 소스 보기

1. codatlas.com (github 소스 볼 때 tree가 나오지 않음)

http://www.codatlas.com/github.com/elasticsearch/elasticsearch/master/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java

http://www.codatlas.com/github.com/elasticsearch/elasticsearch/master/src/test/java/org/elasticsearch/search/geo/GeoDistanceTests.java





Posted by '김용환'
,