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>
...
<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>
코드는 다음과 같이 작성한다. 클러스터로 실행할 수 있다. (클러스터없이는 ElasticsearchTestCase로 할 수 있긴 하나, 대부분의 테스트를 실제 환경과 비슷하게 할 수 있는 ElasticIntegrationTest를 사용하는 것이 나에게는 편한듯하다.)
@ClusterScope(scope = Scope.TEST, numDataNodes = 1)
public class ElasticsearchSimpleTest extends ElasticsearchIntegrationTest {
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 클래스이다.
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에서 에러가 발생한다.
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>
...
<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>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
이슈는 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가 나오지 않음)
'Elasticsearch' 카테고리의 다른 글
ElasticsearchIntegrationTest 상속하여 @SuiteScopeTest - setupSuiteScopeCluster() 사용 (0) | 2015.05.06 |
---|---|
elasticsearch intergration test 시 ClusterScope 주의사항 (0) | 2015.05.06 |
위도 / 경도 (latitude, longitude) 찾기 (0) | 2015.04.09 |
[elasticsearch] 실행시 초기화 실패 해결하기 (0) | 2015.04.02 |
[elasticsearch] java api의 Settings관련 프로퍼티 설정 (0) | 2015.04.02 |