elasticsearch2.1.1統合テストで発生した問題のまとめ

5217 ワード

elasticsearch 1.6.2バージョンから、プロジェクトグループはelasticsearchベースのアプリケーション開発を開始したが、これらのアプリケーションに対するユニットテストは相対的に遅れている.構築されたesテストクラスタでテスト例を走っている.実際、es自体は使用しやすい基盤の統合テスト能力を提供しています.es機能の統合テストを開始する前に、esテストの公式ドキュメントプロジェクトで使用するバージョンは2.1であることをお勧めします.1、次の問題はすべてこのバージョンに対応しています.
1.elasticsearchでのjarHell問題
解決策は、テストソースディレクトリsrc/test/javaにorg.elasticsearch.bootstrap.JarHellクラスを追加することです.ソースコードは以下の通りです.
package org.elasticsearch.bootstrap;
import java.net.URL;
public class JarHell {
    private JarHell() {}
    public static void checkJarHell() throws Exception {}
    public static void checkJarHell(URL urls[]) throws Exception {}
    public static void checkVersionFormat(String targetVersion) {}
    public static void checkJavaVersion(String resource, String targetVersion) {}
    public static URL[] parseClassPath() {return new URL[]{};}
}

参照ディレクトリ:es 2を解決する.1.1におけるjarHell問題
2.EasyMockとの統合に関する問題
ユニットテストではmockオブジェクトをよく使用しますが、主にEasyMockとPowerMockが使用されます.テストクラスがESIntegTestCaseから継承して継承テストを行う場合、@Beforeまたは@After IDを使用する場合は、LuceneTestCaseクラスの説明を参照してください.
 * For instance-level setup, use {@link Before} and {@link After} annotated
 * methods. If you override either {@link #setUp()} or {@link #tearDown()} in
 * your subclass, make sure you call super.setUp() and
 * super.tearDown(). This is detected and enforced.

3.elasticsearchクラスタインスタンスのshardとreplica数を設定する
shard個数とバックアップ個数の設定では、メソッドを再ロードします.
@Override
protected int numberOfShards() {
return 1;
}

@Override
protected int numberOfReplicas() {
return 0;
}

参照number of shards
4.elasticsearch集積テストの小例を示す
public class Alias {

    private AliasType aliasType;
    private MGIndex current;

    public Alias(AliasType aliasType) {
        this.aliasType = aliasType;
        current = MGIndexFactory.get(aliasType.getPrefix());
    }

    //    shard     
    public boolean isNeedAdd(Client client) throws ClusterUnhealthException {
        // Check shard doc
        String index = current.getIndexName();
        IndicesStatsResponse stats = client.admin().indices().prepareStats(index).execute().actionGet();
        if (stats.getFailedShards() > 0) {
            throw new ClusterUnhealthException("Get shards stats failed");
        }

        int docThreshold = current.getDocThreshold();

        for (ShardStats st : stats.getShards()) {
            String info = String.format("%s contains %d files which's threshold is %d", index,
                            st.getStats().getDocs().getCount(), docThreshold);
            MGLogger.info(info);

            if (st.getStats().getDocs().getCount() > docThreshold)
                return true;
        }

        return false;
    }
}

テスト関数は次のとおりです.
public class AliasTest extends ESIntegTestCase{
    Alias alias = null;

    @Before
    public void setUp() throws Exception {
        super.setUp();
        alias = new Alias(AliasType.ATTACHMENT);
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Override
    protected int numberOfShards() {
        return 1;
    }

    @Override
    protected int numberOfReplicas() {
        return 0;
    }

    @Test
    public void testIsNeedAdd() throws Exception {
        indexRandom(true, false,
            client().prepareIndex("test", "type1", "1").setSource("field1", "  "),
            client().prepareIndex("test", "type1", "2").setSource("field1", "    "),
            client().prepareIndex("test", "type1", "3").setSource("field1", "12")
        );

        refresh();
        MGIndex mgIndexMock = EasyMock.createMock(MGIndex.class);
        EasyMock.expect(mgIndexMock.getIndexName()).andReturn("test").times(2);
        EasyMock.expect(mgIndexMock.getDocThreshold()).andReturn(5).times(2);
        EasyMock.replay(mgIndexMock);
        alias.setCurrent(mgIndexMock);

        assertFalse(alias.isNeedAdd(client()));

        indexRandom(true, false,
            client().prepareIndex("test", "type1", "4").setSource("field1", "  "),
            client().prepareIndex("test", "type1", "5").setSource("field1", "    "),
            client().prepareIndex("test", "type1", "6").setSource("field1", "12")
        );

        assertTrue(alias.isNeedAdd(client()));

        EasyMock.verify(mgIndexMock);
    }
}

テストケースAliasTestでは、EasyMockを使用してオブジェクトをmockし、ESIntegTestCaseを継承することによってes機能の統合テストを行います.shardのバックアップがないクラスタを1つだけ構築し、shardのドキュメントの個数が5より大きい場合、isNeedAddの戻り値が空になります.
5.PowerMockとESIntegTestCaseの組み合わせによる問題
ESIntegTestCaseの先祖であるLuceneTestCaseが@RunWith(RandomizedRunner.class)とPowerMockがmock static関数で使用する@RunWith(PowerMockRunner.class)の競合を使用しているため、この方法ではesの統合テストとPowerMock mock static関数の能力を組み合わせることはできません.Bootstrap using a Junit RuleとDelegate to another JUnit RunnerがESIntegTestCaseとPowerMockの融合の問題を解決していないことを試み、記録は解決を保留した.