SOLR-1835: add SolrTestCaseJ4

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/branches/newtrunk@925285 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2010-03-19 15:43:07 +00:00
parent 676a9ca51d
commit d56233ab6b
3 changed files with 449 additions and 7 deletions

View File

@ -341,6 +341,7 @@
<path refid="compile.classpath.solrj" />
<pathelement location="${dest}/solr"/>
<pathelement location="${dest}/solrj"/> <!-- include solrj -->
<pathelement location="${common-solr.dir}/../lucene/build/classes/test" /> <!-- include some lucene test code -->
</path>
<path id="test.run.classpath">

View File

@ -0,0 +1,431 @@
/**
* 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;
import org.apache.lucene.util.LuceneTestCaseJ4;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.SolrInputField;
import org.apache.solr.common.util.XML;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.util.TestHarness;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import javax.xml.xpath.XPathExpressionException;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
/**
* A junit4 Solr test harness that extends LuceneTestCaseJ4.
* Unlike AbstractSolrTestCase, a new core is not created for each test method.
*
*/
public class SolrTestCaseJ4 extends LuceneTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
}
@AfterClass
public static void afterClass() throws Exception {
deleteCore();
}
@Override
public void setUp() throws Exception {
super.setUp();
log.info("###Starting " + getName()); // returns <unknown>???
}
@Override
public void tearDown() throws Exception {
log.info("###Ending " + getName());
super.tearDown();
}
/** Call initCore in @BeforeClass to instantiate a solr core in your test class,
* then call deleteCore in @AfterClass */
public static void initCore(String config, String schema) throws Exception {
configString = config;
schemaString = schema;
initCore();
}
protected static String configString;
protected static String schemaString;
protected static SolrConfig solrConfig;
/**
* Harness initialized by initTestHarness.
*
* <p>
* For use in test methods as needed.
* </p>
*/
protected static TestHarness h;
/**
* LocalRequestFactory initialized by initTestHarness using sensible
* defaults.
*
* <p>
* For use in test methods as needed.
* </p>
*/
protected static TestHarness.LocalRequestFactory lrf;
/**
* Subclasses must define this method to return the name of the
* schema.xml they wish to use.
*/
public static String getSchemaFile() {
return schemaString;
};
/**
* Subclasses must define this method to return the name of the
* solrconfig.xml they wish to use.
*/
public static String getSolrConfigFile() {
return configString;
};
/**
* The directory used to story the index managed by the TestHarness h
*/
protected static File dataDir;
/**
* Initializes things your test might need
*
* <ul>
* <li>Creates a dataDir in the "java.io.tmpdir"</li>
* <li>initializes the TestHarness h using this data directory, and getSchemaPath()</li>
* <li>initializes the LocalRequestFactory lrf using sensible defaults.</li>
* </ul>
*
*/
public static Logger log = LoggerFactory.getLogger(SolrTestCaseJ4.class);
public static void initCore() throws Exception {
log.info("####initCore");
dataDir = new File(System.getProperty("java.io.tmpdir")
+ System.getProperty("file.separator")
// + getClass().getName() + "-" + System.currentTimeMillis());
+ System.currentTimeMillis());
dataDir.mkdirs();
String configFile = getSolrConfigFile();
if (configFile != null) {
solrConfig = h.createConfig(getSolrConfigFile());
h = new TestHarness( dataDir.getAbsolutePath(),
solrConfig,
getSchemaFile());
lrf = h.getRequestFactory
("standard",0,20,"version","2.2");
}
log.info("####initCore end");
}
/** Subclasses that override setUp can optionally call this method
* to log the fact that their setUp process has ended.
*/
public void postSetUp() {
log.info("####POSTSETUP " + getName());
}
/** Subclasses that override tearDown can optionally call this method
* to log the fact that the tearDown process has started. This is necessary
* since subclasses will want to call super.tearDown() at the *end* of their
* tearDown method.
*/
public void preTearDown() {
log.info("####PRETEARDOWN " + getName());
}
/**
* Shuts down the test harness, and makes the best attempt possible
* to delete dataDir, unless the system property "solr.test.leavedatadir"
* is set.
*/
public static void deleteCore() throws Exception {
log.info("###deleteCore" );
if (h != null) { h.close(); }
if (dataDir != null) {
String skip = System.getProperty("solr.test.leavedatadir");
if (null != skip && 0 != skip.trim().length()) {
System.err.println("NOTE: per solr.test.leavedatadir, dataDir will not be removed: " + dataDir.getAbsolutePath());
} else {
if (!recurseDelete(dataDir)) {
System.err.println("!!!! WARNING: best effort to remove " + dataDir.getAbsolutePath() + " FAILED !!!!!");
}
}
}
dataDir = null;
solrConfig = null;
h = null;
lrf = null;
configString = schemaString = null;
}
/** Validates an update XML String is successful
*/
public void assertU(String update) {
assertU(null, update);
}
/** Validates an update XML String is successful
*/
public void assertU(String message, String update) {
checkUpdateU(message, update, true);
}
/** Validates an update XML String failed
*/
public void assertFailedU(String update) {
assertFailedU(null, update);
}
/** Validates an update XML String failed
*/
public void assertFailedU(String message, String update) {
checkUpdateU(message, update, false);
}
/** Checks the success or failure of an update message
*/
private void checkUpdateU(String message, String update, boolean shouldSucceed) {
try {
String m = (null == message) ? "" : message + " ";
if (shouldSucceed) {
String res = h.validateUpdate(update);
if (res != null) fail(m + "update was not successful: " + res);
} else {
String res = h.validateErrorUpdate(update);
if (res != null) fail(m + "update succeeded, but should have failed: " + res);
}
} catch (SAXException e) {
throw new RuntimeException("Invalid XML", e);
}
}
/** Validates a query matches some XPath test expressions and closes the query */
public void assertQ(SolrQueryRequest req, String... tests) {
assertQ(null, req, tests);
}
/** Validates a query matches some XPath test expressions and closes the query */
public void assertQ(String message, SolrQueryRequest req, String... tests) {
try {
String m = (null == message) ? "" : message + " ";
String response = h.query(req);
String results = h.validateXPath(response, tests);
if (null != results) {
fail(m + "query failed XPath: " + results +
"\n xml response was: " + response +
"\n request was: " + req.getParamString());
}
} catch (XPathExpressionException e1) {
throw new RuntimeException("XPath is invalid", e1);
} catch (Exception e2) {
throw new RuntimeException("Exception during query", e2);
}
}
/** Makes sure a query throws a SolrException with the listed response code */
public static void assertQEx(String message, SolrQueryRequest req, int code ) {
try {
h.query(req);
fail( message );
} catch (SolrException sex) {
assertEquals( code, sex.code() );
} catch (Exception e2) {
throw new RuntimeException("Exception during query", e2);
}
}
public static void assertQEx(String message, SolrQueryRequest req, SolrException.ErrorCode code ) {
try {
h.query(req);
fail( message );
} catch (SolrException e) {
assertEquals( code.code, e.code() );
} catch (Exception e2) {
throw new RuntimeException("Exception during query", e2);
}
}
/**
* @see TestHarness#optimize
*/
public static String optimize(String... args) {
return h.optimize(args);
}
/**
* @see TestHarness#commit
*/
public static String commit(String... args) {
return h.commit(args);
}
/**
* Generates a simple &lt;add&gt;&lt;doc&gt;... XML String with no options
*
* @param fieldsAndValues 0th and Even numbered args are fields names odds are field values.
* @see #add
* @see #doc
*/
public static String adoc(String... fieldsAndValues) {
Doc d = doc(fieldsAndValues);
return add(d);
}
/**
* Generates a simple &lt;add&gt;&lt;doc&gt;... XML String with no options
*/
public static String adoc(SolrInputDocument sdoc) {
List<String> fields = new ArrayList<String>();
for (SolrInputField sf : sdoc) {
for (Object o : sf.getValues()) {
fields.add(sf.getName());
fields.add(o.toString());
}
}
return adoc(fields.toArray(new String[fields.size()]));
}
/**
* Generates an &lt;add&gt;&lt;doc&gt;... XML String with options
* on the add.
*
* @param doc the Document to add
* @param args 0th and Even numbered args are param names, Odds are param values.
* @see #add
* @see #doc
*/
public static String add(Doc doc, String... args) {
try {
StringWriter r = new StringWriter();
// this is anoying
if (null == args || 0 == args.length) {
r.write("<add>");
r.write(doc.xml);
r.write("</add>");
} else {
XML.writeUnescapedXML(r, "add", doc.xml, (Object[])args);
}
return r.getBuffer().toString();
} catch (IOException e) {
throw new RuntimeException
("this should never happen with a StringWriter", e);
}
}
/**
* Generates a &lt;delete&gt;... XML string for an ID
*
* @see TestHarness#deleteById
*/
public static String delI(String id) {
return h.deleteById(id);
}
/**
* Generates a &lt;delete&gt;... XML string for an query
*
* @see TestHarness#deleteByQuery
*/
public static String delQ(String q) {
return h.deleteByQuery(q);
}
/**
* Generates a simple &lt;doc&gt;... XML String with no options
*
* @param fieldsAndValues 0th and Even numbered args are fields names, Odds are field values.
* @see TestHarness#makeSimpleDoc
*/
public static Doc doc(String... fieldsAndValues) {
Doc d = new Doc();
d.xml = h.makeSimpleDoc(fieldsAndValues).toString();
return d;
}
/**
* Generates a SolrQueryRequest using the LocalRequestFactory
* @see #lrf
*/
public static SolrQueryRequest req(String... q) {
return lrf.makeRequest(q);
}
/**
* Generates a SolrQueryRequest using the LocalRequestFactory
* @see #lrf
*/
public static SolrQueryRequest req(String[] params, String... moreParams) {
String[] allParams = moreParams;
if (params.length!=0) {
int len = params.length + moreParams.length;
allParams = new String[len];
System.arraycopy(params,0,allParams,0,params.length);
System.arraycopy(moreParams,0,allParams,params.length,moreParams.length);
}
return lrf.makeRequest(allParams);
}
/** Neccessary to make method signatures un-ambiguous */
public static class Doc {
public String xml;
public String toString() { return xml; }
}
public static boolean recurseDelete(File f) {
if (f.isDirectory()) {
for (File sub : f.listFiles()) {
if (!recurseDelete(sub)) {
return false;
}
}
}
return f.delete();
}
}

View File

@ -17,14 +17,20 @@
package org.apache.solr.request;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.util.AbstractSolrTestCase;
import org.junit.BeforeClass;
import org.junit.Test;
public class SimpleFacetsTest extends AbstractSolrTestCase {
public String getSchemaFile() { return "schema.xml"; }
public String getSolrConfigFile() { return "solrconfig.xml"; }
public String getCoreName() { return "basic"; }
public class SimpleFacetsTest extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig.xml","schema.xml");
}
@Test
public void testSimpleFacetCounts() {
assertU(adoc("id", "42", "trait_s", "Tool", "trait_s", "Obnoxious",
"name", "Zapp Brannigan"));
@ -210,7 +216,8 @@ public class SimpleFacetsTest extends AbstractSolrTestCase {
);
}
@Test
public void testDateFacets() {
final String f = "bday";
final String pre = "//lst[@name='facet_dates']/lst[@name='"+f+"']";
@ -382,6 +389,7 @@ public class SimpleFacetsTest extends AbstractSolrTestCase {
}
@Test
public void testFacetMultiValued() {
doFacetPrefix("t_s", "facet.method","enum");
doFacetPrefix("t_s", "facet.method", "enum", "facet.enum.cache.minDf", "2");
@ -389,6 +397,7 @@ public class SimpleFacetsTest extends AbstractSolrTestCase {
doFacetPrefix("t_s", "facet.method", "fc");
}
@Test
public void testFacetSingleValued() {
doFacets("t_s1");
}
@ -557,7 +566,7 @@ public class SimpleFacetsTest extends AbstractSolrTestCase {
}
@Test
public void testFacetPrefixMultiValued() {
doFacetPrefix("t_s", "facet.method","enum");
doFacetPrefix("t_s", "facet.method", "enum", "facet.enum.cache.minDf", "3");
@ -565,6 +574,7 @@ public class SimpleFacetsTest extends AbstractSolrTestCase {
doFacetPrefix("t_s", "facet.method", "fc");
}
@Test
public void testFacetPrefixSingleValued() {
doFacetPrefix("t_s1");
}