blob: e991618d32f24a07f782bfcc43b14143d9f9155b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.solr.core;
import java.io.IOException;
import java.util.Map;
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.codecs.lucene50.Lucene50StoredFieldsFormat;
import org.apache.lucene.codecs.lucene50.Lucene50StoredFieldsFormat.Mode;
import org.apache.lucene.codecs.perfield.PerFieldDocValuesFormat;
import org.apache.lucene.codecs.perfield.PerFieldPostingsFormat;
import org.apache.lucene.index.SegmentInfo;
import org.apache.lucene.index.SegmentInfos;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.IndexSchemaFactory;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.util.TestHarness;
import org.junit.After;
import org.junit.Before;
import javax.xml.xpath.XPathExpressionException;
public class TestCodecSupport extends SolrTestCaseJ4 {
@Before
public void beforeTestCodecSupportTest() throws Exception {
initCore("solrconfig_codec.xml", "schema_codec.xml");
}
@After
public void afterTestCodecSupportTest() {
deleteCore();
}
public void testPostingsFormats() {
try (SolrCore core = h.getCore()) {
Codec codec = core.getCodec();
Map<String,SchemaField> fields = core.getLatestSchema().getFields();
SchemaField schemaField = fields.get("string_direct_f");
PerFieldPostingsFormat format = (PerFieldPostingsFormat) codec.postingsFormat();
assertEquals("Direct", format.getPostingsFormatForField(schemaField.getName()).getName());
schemaField = fields.get("string_standard_f");
assertEquals(TestUtil.getDefaultPostingsFormat().getName(), format.getPostingsFormatForField(schemaField.getName()).getName());
schemaField = fields.get("string_f");
assertEquals(TestUtil.getDefaultPostingsFormat().getName(), format.getPostingsFormatForField(schemaField.getName()).getName());
}
}
public void testDocValuesFormats() {
try (SolrCore core = h.getCore()) {
// NOTE: Direct (and Disk) DocValues formats were removed, so we use "Asserting"
// as a way to vet that the configuration actually matters.
Codec codec = core.getCodec();
Map<String,SchemaField> fields = core.getLatestSchema().getFields();
SchemaField schemaField = fields.get("string_disk_f");
PerFieldDocValuesFormat format = (PerFieldDocValuesFormat) codec.docValuesFormat();
assertEquals(TestUtil.getDefaultDocValuesFormat().getName(), format.getDocValuesFormatForField(schemaField.getName()).getName());
schemaField = fields.get("string_direct_f");
assertEquals("Asserting", format.getDocValuesFormatForField(schemaField.getName()).getName());
schemaField = fields.get("string_f");
assertEquals(TestUtil.getDefaultDocValuesFormat().getName(), format.getDocValuesFormatForField(schemaField.getName()).getName());
}
}
public void testDynamicFieldsPostingsFormats() {
try (SolrCore core = h.getCore()) {
Codec codec = core.getCodec();
PerFieldPostingsFormat format = (PerFieldPostingsFormat) codec.postingsFormat();
assertEquals("Direct", format.getPostingsFormatForField("foo_direct").getName());
assertEquals("Direct", format.getPostingsFormatForField("bar_direct").getName());
assertEquals(TestUtil.getDefaultPostingsFormat().getName(), format.getPostingsFormatForField("foo_standard").getName());
assertEquals(TestUtil.getDefaultPostingsFormat().getName(), format.getPostingsFormatForField("bar_standard").getName());
}
}
public void testDynamicFieldsDocValuesFormats() {
// NOTE: Direct (and Disk) DocValues formats were removed, so we use "Asserting"
// as a way to vet that the configuration actually matters.
try (SolrCore core = h.getCore()) {
Codec codec = core.getCodec();
PerFieldDocValuesFormat format = (PerFieldDocValuesFormat) codec.docValuesFormat();
assertEquals(TestUtil.getDefaultDocValuesFormat().getName(), format.getDocValuesFormatForField("foo_disk").getName());
assertEquals(TestUtil.getDefaultDocValuesFormat().getName(), format.getDocValuesFormatForField("bar_disk").getName());
assertEquals("Asserting", format.getDocValuesFormatForField("foo_direct").getName());
assertEquals("Asserting", format.getDocValuesFormatForField("bar_direct").getName());
}
}
private void reloadCoreAndRecreateIndex() {
h.getCoreContainer().reload(h.coreName);
assertU(delQ("*:*"));
assertU(add(doc("string_f", "foo")));
assertU(commit());
}
private void doTestCompressionMode(String propertyValue, String expectedModeString) throws IOException {
if (propertyValue != null) {
System.setProperty("tests.COMPRESSION_MODE", propertyValue);
}
try {
reloadCoreAndRecreateIndex();
try (SolrCore core = h.getCore()) {
assertCompressionMode(expectedModeString, core);
}
} finally {
System.clearProperty("tests.COMPRESSION_MODE");
}
}
protected void assertCompressionMode(String expectedModeString, SolrCore core) throws IOException {
core.withSearcher(searcher -> {
SegmentInfos infos = SegmentInfos.readLatestCommit(searcher.getIndexReader().directory());
SegmentInfo info = infos.info(infos.size() - 1).info;
assertEquals(
"Expecting compression mode string to be " + expectedModeString + " but got: " + info.getAttribute(Lucene50StoredFieldsFormat.MODE_KEY) + "\n SegmentInfo: " + info + "\n SegmentInfos: "
+ infos + "\n Codec: " + core.getCodec(), expectedModeString, info.getAttribute(Lucene50StoredFieldsFormat.MODE_KEY));
return null;
});
}
public void testCompressionMode1() throws Exception {
assertEquals("incompatible change in compressionMode property",
"compressionMode", SchemaCodecFactory.COMPRESSION_MODE);
doTestCompressionMode("BEST_SPEED", "BEST_SPEED");
}
public void testCompressionMode2() throws Exception {
assertEquals("incompatible change in compressionMode property",
"compressionMode", SchemaCodecFactory.COMPRESSION_MODE);
doTestCompressionMode("BEST_COMPRESSION", "BEST_COMPRESSION");
}
public void testCompressionMode3() throws Exception {
assertEquals("incompatible change in compressionMode property",
"compressionMode", SchemaCodecFactory.COMPRESSION_MODE);
doTestCompressionMode("best_speed", "BEST_SPEED");
}
public void testCompressionMode4() throws Exception {
assertEquals("incompatible change in compressionMode property",
"compressionMode", SchemaCodecFactory.COMPRESSION_MODE);;
doTestCompressionMode("best_compression", "BEST_COMPRESSION");
}
public void testMixedCompressionMode() throws Exception {
System.setProperty("tests.COMPRESSION_MODE", "BEST_SPEED");
h.getCoreContainer().reload(h.coreName);
assertU(add(doc("string_f", "1", "text", "foo bar")));
assertU(commit());
try (SolrCore core = h.getCore()) {
assertCompressionMode("BEST_SPEED", core);
}
System.setProperty("tests.COMPRESSION_MODE", "BEST_COMPRESSION");
h.getCoreContainer().reload(h.coreName);
assertU(add(doc("string_f", "2", "text", "foo zar")));
assertU(commit());
try (SolrCore core = h.getCore()) {
assertCompressionMode("BEST_COMPRESSION", core);
}
System.setProperty("tests.COMPRESSION_MODE", "BEST_SPEED");
h.getCoreContainer().reload(h.coreName);
assertU(add(doc("string_f", "3", "text", "foo zoo")));
assertU(commit());
try (SolrCore core = h.getCore()) {
assertCompressionMode("BEST_SPEED", core);
}
assertQ(req("q", "*:*"),
"//*[@numFound='3']");
assertQ(req("q", "text:foo"),
"//*[@numFound='3']");
assertU(optimize("maxSegments", "1"));
try (SolrCore core = h.getCore()) {
assertCompressionMode("BEST_SPEED", core);
}
System.clearProperty("tests.COMPRESSION_MODE");
}
public void testBadCompressionMode() throws Exception {
SolrException thrown = LuceneTestCase.expectThrows(SolrException.class, () -> {
doTestCompressionMode("something_that_doesnt_exist", "something_that_doesnt_exist");
});
assertEquals(SolrException.ErrorCode.SERVER_ERROR.code, thrown.code());
assertTrue("Unexpected Exception message: " + thrown.getMessage(),
thrown.getMessage().contains("Unable to reload core"));
final SchemaCodecFactory factory1 = new SchemaCodecFactory();
final NamedList<String> nl = new NamedList<>();
nl.add(SchemaCodecFactory.COMPRESSION_MODE, "something_that_doesnt_exist");
thrown = LuceneTestCase.expectThrows(SolrException.class, () -> {
factory1.init(nl);
});
assertEquals(SolrException.ErrorCode.SERVER_ERROR.code, thrown.code());
assertTrue("Unexpected Exception message: " + thrown.getMessage(),
thrown.getMessage().contains("Invalid compressionMode: 'something_that_doesnt_exist'"));
final SchemaCodecFactory factory2 = new SchemaCodecFactory();
final NamedList<String> nl2 = new NamedList<>();
nl2.add(SchemaCodecFactory.COMPRESSION_MODE, "");
thrown = LuceneTestCase.expectThrows(SolrException.class, () -> {
factory2.init(nl2);
});
assertEquals(SolrException.ErrorCode.SERVER_ERROR.code, thrown.code());
assertTrue("Unexpected Exception message: " + thrown.getMessage(),
thrown.getMessage().contains("Invalid compressionMode: ''"));
}
@LuceneTestCase.Nightly // non nightly changes this
public void testCompressionModeDefault()
throws IOException, XPathExpressionException {
assertEquals("Default Solr compression mode changed. Is this expected?", SchemaCodecFactory.SOLR_DEFAULT_COMPRESSION_MODE, Mode.valueOf("BEST_SPEED"));
String previousCoreName = h.coreName;
String newCoreName = "core_with_default_compression";
SolrCore c = null;
SolrConfig config = TestHarness.createConfig(testSolrHome, previousCoreName, "solrconfig_codec2.xml", loader);
assertEquals("Unexpected codec factory for this test.", "solr.SchemaCodecFactory", config.get("codecFactory/@class"));
String path = IndexSchema.normalize("codecFactory", config.getPrefix());
LuceneTestCase.expectThrows(SolrException.class, () -> config.getNode(h.getXpath().compile(path), path, false).children().iterator().next());
IndexSchema schema = IndexSchemaFactory.buildIndexSchema("schema_codec.xml", config);
CoreContainer coreContainer = h.getCoreContainer();
CoreDescriptor cd = new CoreDescriptor(newCoreName, testSolrHome.resolve(newCoreName), coreContainer);
c = new SolrCore(coreContainer, cd, new ConfigSet("fakeConfigset", config, schema, null, true));
c.start();
assertNull(coreContainer.registerCore(cd, c, false));
h.coreName = newCoreName;
try {
assertEquals("We are not using the correct core", "solrconfig_codec2.xml", c.getConfigResource());
assertU(add(doc("string_f", "foo")));
assertU(commit());
assertCompressionMode(SchemaCodecFactory.SOLR_DEFAULT_COMPRESSION_MODE.name(), c);
} finally {
h.coreName = previousCoreName;
coreContainer.unload(newCoreName);
}
}
}