/* * Copyright [2017] Wikimedia Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.o19s.es.ltr.feature.store.index; import com.o19s.es.ltr.LtrTestUtils; import com.o19s.es.ltr.feature.store.StorableElement; import com.o19s.es.ltr.feature.store.StoredFeature; import com.o19s.es.ltr.feature.store.StoredFeatureNormalizers; import com.o19s.es.ltr.feature.store.StoredFeatureSet; import com.o19s.es.ltr.feature.store.StoredLtrModel; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.TestUtil; import org.elasticsearch.client.Requests; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; import java.util.HashMap; import java.util.Map; import static com.o19s.es.ltr.feature.store.index.IndexFeatureStore.STORE_PREFIX; import static com.o19s.es.ltr.feature.store.index.IndexFeatureStore.indexName; import static com.o19s.es.ltr.feature.store.index.IndexFeatureStore.isIndexStore; import static com.o19s.es.ltr.feature.store.index.IndexFeatureStore.storeName; import static org.apache.lucene.util.TestUtil.randomRealisticUnicodeString; import static org.apache.lucene.util.TestUtil.randomSimpleString; import static org.hamcrest.CoreMatchers.equalTo; public class IndexFeatureStoreTests extends LuceneTestCase { public void testParse() throws Exception { parseAssertions(LtrTestUtils.randomFeature()); parseAssertions(LtrTestUtils.randomFeatureSet()); parseAssertions(new StoredLtrModel( randomSimpleString(random(), 5, 10), LtrTestUtils.randomFeatureSet(), randomSimpleString(random(), 5, 10), randomRealisticUnicodeString(random(), 5, 1000), true, new StoredFeatureNormalizers())); } public void testIsIndexName() { assertTrue(isIndexStore(IndexFeatureStore.DEFAULT_STORE)); assertFalse(isIndexStore("not_really")); assertFalse(isIndexStore(IndexFeatureStore.STORE_PREFIX)); int nPass = random().nextInt(10) + 10; for (int i = 0; i < nPass; i++) { assertTrue(isIndexStore(indexName(TestUtil.randomSimpleString(random(), 1, 10)))); assertFalse(isIndexStore(TestUtil.randomSimpleString(random(), 1, STORE_PREFIX.length()))); } } public void testIndexName() { int nPass = random().nextInt(10) + 10; for (int i = 0; i < nPass; i++) { String name = indexName(TestUtil.randomSimpleString(random(), 1, 10)); assertTrue(name.startsWith(STORE_PREFIX)); } } public void testStoreName() { assertEquals("_default_", storeName(IndexFeatureStore.DEFAULT_STORE)); assertEquals("test", storeName(STORE_PREFIX + "test")); expectThrows(IllegalArgumentException.class, () -> IndexFeatureStore.storeName("not really")); int nPass = random().nextInt(10) + 10; for (int i = 0; i < nPass; i++) { String storeName = TestUtil.randomSimpleString(random(), 1, 10); String indexName = indexName(storeName); assertEquals(storeName, storeName(indexName)); } } public void testBadValues() throws IOException { Map<String, Object> map = new HashMap<>(); XContentBuilder builder = XContentBuilder.builder(Requests.INDEX_CONTENT_TYPE.xContent()); BytesReference bytes = BytesReference.bytes(builder.map(map)); assertThat(expectThrows(IllegalArgumentException.class, () -> IndexFeatureStore.parse(StoredFeature.class, StoredFeature.TYPE, bytes)) .getMessage(), equalTo("No StorableElement found.")); builder = XContentBuilder.builder(Requests.INDEX_CONTENT_TYPE.xContent()); map.put("featureset", LtrTestUtils.randomFeatureSet()); BytesReference bytes2 = BytesReference.bytes(builder.map(map)); assertThat(expectThrows(IllegalArgumentException.class, () -> IndexFeatureStore.parse(StoredFeature.class, StoredFeature.TYPE, bytes2)) .getMessage(), equalTo("Expected an element of type [" + StoredFeature.TYPE + "] but" + " got [" + StoredFeatureSet.TYPE + "].")); } private void parseAssertions(StorableElement elt) throws IOException { XContentBuilder builder = IndexFeatureStore.toSource(elt); BytesReference first = BytesReference.bytes(builder); StorableElement reParsed = IndexFeatureStore.parse(elt.getClass(), elt.type(), first); assertEquals(elt, reParsed); BytesRef ref = first.toBytesRef(); reParsed = IndexFeatureStore.parse(elt.getClass(), elt.type(), ref.bytes, ref.offset, ref.length); assertEquals(elt, reParsed); BytesReference second = BytesReference.bytes(IndexFeatureStore.toSource(reParsed)); assertEquals(first, second); assertNameAndTypes(elt, first); assertNameAndTypes(elt, second); } private void assertNameAndTypes(StorableElement elt, BytesReference ref) throws IOException { XContentParser parser = XContentFactory.xContent(Requests.INDEX_CONTENT_TYPE).createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, ref.streamInput()); Map<String,Object> map = parser.map(); assertEquals(elt.name(), map.get("name")); assertEquals(elt.type(), map.get("type")); assertTrue(map.containsKey(elt.type())); } }