VIVO-742 a first stab at Solr integration tests
To replace SolrQueryTest unit test.
This commit is contained in:
parent
4405d76683
commit
afa0c0a15e
4 changed files with 363 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -8,3 +8,4 @@
|
||||||
/webapp/config/runtime.properties
|
/webapp/config/runtime.properties
|
||||||
/webapp/config/debug.log4j.properties
|
/webapp/config/debug.log4j.properties
|
||||||
.build
|
.build
|
||||||
|
utilities/solrtester/.work
|
||||||
|
|
9
utilities/solrtester/log4j.properties
Normal file
9
utilities/solrtester/log4j.properties
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
log4j.appender.AllAppender=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.AllAppender.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.AllAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] %m%n
|
||||||
|
# log4j.appender.AllAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{1}] %m%n
|
||||||
|
|
||||||
|
log4j.rootLogger=INFO, AllAppender
|
||||||
|
|
||||||
|
# Make all of the Solr classes quieter...
|
||||||
|
log4j.logger.org.apache.solr=WARN
|
110
utilities/solrtester/solrtester-build.xml
Normal file
110
utilities/solrtester/solrtester-build.xml
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||||
|
|
||||||
|
<!-- ======================================================================
|
||||||
|
Integration tests to be sure that the Solr configuration does what we
|
||||||
|
want.
|
||||||
|
====================================================================== -->
|
||||||
|
|
||||||
|
<project name="solr-tester" default="describe">
|
||||||
|
<property name="src.dir" location="src" />
|
||||||
|
<property name="vitro.libs.dir" location="../../webapp/lib" />
|
||||||
|
<property name="solr.home.template"
|
||||||
|
location="../../solr/homeDirectoryTemplate" />
|
||||||
|
<property name="solr.war.file" location="../../solr/solr-4.7.2.war" />
|
||||||
|
|
||||||
|
<property name="working.dir" location=".work" />
|
||||||
|
<property name="classes.dir" location="${working.dir}/classes" />
|
||||||
|
<property name="solr.working.dir" location="${working.dir}/solrHome" />
|
||||||
|
<property name="solr.libs.dir" location="${working.dir}/solrLibs" />
|
||||||
|
|
||||||
|
<path id="main.compile.classpath">
|
||||||
|
<fileset dir="${vitro.libs.dir}" includes="*.jar" />
|
||||||
|
<fileset dir="${solr.libs.dir}" includes="*.jar" />
|
||||||
|
</path>
|
||||||
|
|
||||||
|
<path id="test.run.classpath">
|
||||||
|
<pathelement location="${classes.dir}" />
|
||||||
|
<path refid="main.compile.classpath" />
|
||||||
|
</path>
|
||||||
|
|
||||||
|
<!-- =================================
|
||||||
|
target: describe
|
||||||
|
================================= -->
|
||||||
|
<target name="describe"
|
||||||
|
description="--> Describe the targets (this is the default).">
|
||||||
|
<echo>
|
||||||
|
all - Runs "clean", then "test".
|
||||||
|
clean - Delete all artifacts so the next build will be from scratch.
|
||||||
|
test - Set up the Solr configuration, compile, and run the JUnit tests.
|
||||||
|
</echo>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================
|
||||||
|
target: all
|
||||||
|
================================= -->
|
||||||
|
<target name="all"
|
||||||
|
depends="clean,test"
|
||||||
|
description="Build from scratch and run the tests.">
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================
|
||||||
|
target: clean
|
||||||
|
================================= -->
|
||||||
|
<target name="clean"
|
||||||
|
description="Delete the Solr configuration and the compiled clases.">
|
||||||
|
<delete dir="${working.dir}" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- =================================
|
||||||
|
target: test
|
||||||
|
================================= -->
|
||||||
|
<target name="test" depends="compile" description="Run the tests.">
|
||||||
|
<java classname="org.junit.runner.JUnitCore"
|
||||||
|
fork="yes"
|
||||||
|
failonerror="true">
|
||||||
|
<arg value="edu.cornell.mannlib.vitro.utilities.solrtest.SolrConfigTester" />
|
||||||
|
<classpath refid="test.run.classpath" />
|
||||||
|
<sysproperty key="test.solr.home" value="${solr.working.dir}" />
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- - - - - - - - - - - - - - - - - -
|
||||||
|
target: setup
|
||||||
|
- - - - - - - - - - - - - - - - - -->
|
||||||
|
<target name="setup">
|
||||||
|
<mkdir dir="${working.dir}" />
|
||||||
|
|
||||||
|
<mkdir dir="${solr.working.dir}" />
|
||||||
|
<sync todir="${solr.working.dir}" includeemptydirs="true">
|
||||||
|
<fileset dir="${solr.home.template}" />
|
||||||
|
</sync>
|
||||||
|
|
||||||
|
<mkdir dir="${solr.libs.dir}" />
|
||||||
|
<unwar src="${solr.war.file}" dest="${solr.libs.dir}">
|
||||||
|
<patternset includes="WEB-INF/lib/*" />
|
||||||
|
<mapper type="flatten" />
|
||||||
|
</unwar>
|
||||||
|
|
||||||
|
<mkdir dir="${classes.dir}" />
|
||||||
|
<copy file="log4j.properties" todir="${classes.dir}" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- - - - - - - - - - - - - - - - - -
|
||||||
|
target: compile
|
||||||
|
- - - - - - - - - - - - - - - - - -->
|
||||||
|
<target name="compile" depends="setup">
|
||||||
|
<javac srcdir="${src.dir}"
|
||||||
|
destdir="${classes.dir}"
|
||||||
|
debug="true"
|
||||||
|
deprecation="true"
|
||||||
|
encoding="UTF8"
|
||||||
|
includeantruntime="false"
|
||||||
|
optimize="true"
|
||||||
|
source="1.7">
|
||||||
|
<classpath refid="main.compile.classpath" />
|
||||||
|
</javac>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,243 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.utilities.solrtest;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.apache.solr.client.solrj.SolrServerException;
|
||||||
|
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
|
||||||
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
|
import org.apache.solr.common.SolrDocumentList;
|
||||||
|
import org.apache.solr.common.SolrException;
|
||||||
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
|
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||||
|
import org.apache.solr.core.CoreContainer;
|
||||||
|
import org.apache.solr.core.SolrCore;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@RunWith(JUnit4.class)
|
||||||
|
public class SolrConfigTester {
|
||||||
|
private static CoreContainer container;
|
||||||
|
private static EmbeddedSolrServer server;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
String solrHomeString = System.getProperty("test.solr.home");
|
||||||
|
container = new CoreContainer(solrHomeString);
|
||||||
|
|
||||||
|
try (LogLeveler l = new LogLeveler(SolrCore.class, Level.ERROR)) {
|
||||||
|
container.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
server = new EmbeddedSolrServer(container, "collection1");
|
||||||
|
server.deleteByQuery("*:*");
|
||||||
|
server.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
server.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// The tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serverResponds() throws Exception {
|
||||||
|
server.ping();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SolrException.class)
|
||||||
|
public void docIdIsRequred() throws Exception {
|
||||||
|
try (LogLeveler l = new LogLeveler(SolrCore.class, Level.OFF)) {
|
||||||
|
addDocuments(inputDoc(null, field("nameRaw", "No ID")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleName() throws Exception {
|
||||||
|
addDocuments(inputDoc("idSimple", field("nameRaw", "SimpleName")));
|
||||||
|
assertQueryResults("simple name", "SimpleName", "idSimple");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void upperLowerName() throws Exception {
|
||||||
|
addDocuments(inputDoc("idUpperLower", field("nameRaw", "Lower, Upper")));
|
||||||
|
assertQueryResults("upper lower name", "Lower", "idUpperLower");
|
||||||
|
assertQueryResults("upper lower name", "lower", "idUpperLower");
|
||||||
|
assertQueryResults("upper lower name", "UPPER", "idUpperLower");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nameIsNotStemmed() throws Exception {
|
||||||
|
addDocuments(inputDoc("nameStemming", field("nameRaw", "Swimming, Bills"),
|
||||||
|
field("nameLowercaseSingleValued", "Lower, Upper")));
|
||||||
|
assertQueryResults("name not stemmed", "Swimming", "nameStemming");
|
||||||
|
assertQueryResults("name not stemmed", "Bills", "nameStemming");
|
||||||
|
assertQueryResults("name not stemmed", "Swim");
|
||||||
|
assertQueryResults("name not stemmed", "Bill");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A name with an umlaut over an o is found exactly, or with the umlaut
|
||||||
|
* missing, upper case or lower case.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void nameWithUmlaut() throws Exception {
|
||||||
|
addDocuments(inputDoc("idUmlaut",
|
||||||
|
field("nameRaw", "P\u00F6ysen B\u00F6ysen")));
|
||||||
|
assertQueryResults("name with umlaut", "Boysen", "idUmlaut");
|
||||||
|
assertQueryResults("name with umlaut", "B\u00F6ysen", "idUmlaut");
|
||||||
|
assertQueryResults("name with umlaut", "BOYSEN", "idUmlaut");
|
||||||
|
assertQueryResults("name with umlaut", "B\u00D6YSEN", "idUmlaut");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ALLTEXT is searched, but to make the 3rd case work, we need
|
||||||
|
* ALLTEXTUNSTEMMED also. Why is that?
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void allTextIsSearched() throws Exception {
|
||||||
|
addDocuments(inputDoc("allTextSearch", field("ALLTEXT", "Wonderful"),
|
||||||
|
field("ALLTEXTUNSTEMMED", "Wonderful")));
|
||||||
|
assertQueryResults("all text", "Wonderful", "allTextSearch");
|
||||||
|
assertQueryResults("all text", "wonderful", "allTextSearch");
|
||||||
|
assertQueryResults("all text", "WoNdErFuL", "allTextSearch");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void allTextIsStemmed() throws Exception {
|
||||||
|
addDocuments(inputDoc("allTextStem", field("ALLTEXT", "Swimming"),
|
||||||
|
field("ALLTEXTUNSTEMMED", "Swimming")));
|
||||||
|
assertQueryResults("all text stem", "Swim", "allTextStem");
|
||||||
|
assertQueryResults("all text stem", "swim", "allTextStem");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Helper methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
public InputField field(String name, String... values) {
|
||||||
|
return new InputField(name, null, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputField field(String name, Float boost, String... values) {
|
||||||
|
return new InputField(name, boost, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SolrInputDocument inputDoc(String docId, InputField... fields) {
|
||||||
|
SolrInputDocument doc = new SolrInputDocument();
|
||||||
|
if (docId != null) {
|
||||||
|
doc.addField("DocId", docId);
|
||||||
|
}
|
||||||
|
for (InputField f : fields) {
|
||||||
|
for (String value : f.values) {
|
||||||
|
if (f.boost == null) {
|
||||||
|
doc.addField(f.name, value);
|
||||||
|
} else {
|
||||||
|
doc.addField(f.name, value, f.boost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDocuments(SolrInputDocument... documents)
|
||||||
|
throws SolrServerException, IOException {
|
||||||
|
for (SolrInputDocument doc : documents) {
|
||||||
|
server.add(doc);
|
||||||
|
}
|
||||||
|
server.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertQueryResults(String message, String query,
|
||||||
|
String... expectedDocIds) throws SolrServerException {
|
||||||
|
ModifiableSolrParams params = new ModifiableSolrParams();
|
||||||
|
params.set("q", query);
|
||||||
|
|
||||||
|
QueryResponse qResp = server.query(params);
|
||||||
|
|
||||||
|
SolrDocumentList docList = qResp.getResults();
|
||||||
|
List<String> expected = Arrays.asList(expectedDocIds);
|
||||||
|
List<String> actual = new ArrayList<>();
|
||||||
|
for (int i = 0; i < docList.getNumFound(); i++) {
|
||||||
|
actual.add(String.valueOf(docList.get(i).getFirstValue("DocId")));
|
||||||
|
}
|
||||||
|
assertEquals(message + " : '" + query + "'", expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Helper classes
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
public static class InputField {
|
||||||
|
final String name;
|
||||||
|
final Float boost;
|
||||||
|
final String[] values;
|
||||||
|
|
||||||
|
public InputField(String name, Float boost, String[] values) {
|
||||||
|
this.name = name;
|
||||||
|
this.boost = boost;
|
||||||
|
this.values = values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LogLeveler implements AutoCloseable {
|
||||||
|
private final Logger logger;
|
||||||
|
private final Level initialLevel;
|
||||||
|
|
||||||
|
public LogLeveler(Class<?> clazz, Level desiredLevel) {
|
||||||
|
this.logger = Logger.getLogger(clazz);
|
||||||
|
this.initialLevel = this.logger.getLevel();
|
||||||
|
this.logger.setLevel(desiredLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
this.logger.setLevel(this.initialLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* // ** Let's index a document into our embedded server
|
||||||
|
*
|
||||||
|
* SolrInputDocument newDoc = new SolrInputDocument();
|
||||||
|
* newDoc.addField("title", "Test Document 1");
|
||||||
|
* newDoc.addField("id", "doc-1");
|
||||||
|
* newDoc.addField("text", "Hello world!");
|
||||||
|
* server.add(newDoc);
|
||||||
|
* server.commit();
|
||||||
|
*
|
||||||
|
* // ** And now let's query for it
|
||||||
|
*
|
||||||
|
* params.set("q", "title:test");
|
||||||
|
* QueryResponse qResp = server.query(params);
|
||||||
|
*
|
||||||
|
* SolrDocumentList docList = qResp.getResults();
|
||||||
|
* System.out.println("Num docs: " + docList.getNumFound());
|
||||||
|
* SolrDocument doc = docList.get(0);
|
||||||
|
* System.out.println("Title: " + doc.getFirstValue("title").toString());
|
||||||
|
* </pre>
|
||||||
|
*/
|
Loading…
Add table
Reference in a new issue