More add field tests; json escaped double quotes -> single + json() wrapper

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1537399 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Steven Rowe 2013-10-31 08:30:37 +00:00
parent 6bca1a44e9
commit 6a51e5b963
2 changed files with 213 additions and 49 deletions

View File

@ -132,6 +132,39 @@
</fieldType>
<!-- A text field with defaults appropriate for English: it
tokenizes with StandardTokenizer, removes English stop words
(lang/stopwords_en.txt), down cases, protects words from protwords.txt, and
finally applies Porter's stemming. The query time analyzer
also applies synonyms from synonyms.txt. -->
<fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<!-- in this example, we will only use synonyms at query time
<filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
-->
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPossessiveFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
<filter class="solr.EnglishMinimalStemFilterFactory"/>
-->
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPossessiveFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
<filter class="solr.EnglishMinimalStemFilterFactory"/>
-->
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
</fieldType>
<!-- field type that doesn't generate phrases from unquoted multiple tokens per analysis unit -->
<fieldType name="text_np" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">

View File

@ -17,7 +17,6 @@ package org.apache.solr.rest.schema;
*/
import org.apache.commons.io.FileUtils;
import org.apache.solr.AnalysisAfterCoreReloadTest;
import org.apache.solr.util.RestTestBase;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.After;
@ -28,14 +27,24 @@ import org.restlet.ext.servlet.ServerServlet;
import java.io.File;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.regex.Pattern;
public class TestManagedSchemaFieldResource extends RestTestBase {
private static File tmpSolrHome;
private static File tmpConfDir;
private static final String collection = "collection1";
private static final String confDir = collection + "/conf";
@Before
public void before() throws Exception {
createTempDir();
String tmpSolrHome = TEMP_DIR + File.separator + AnalysisAfterCoreReloadTest.class.getSimpleName() + System.currentTimeMillis();
FileUtils.copyDirectory(new File(TEST_HOME()), new File(tmpSolrHome).getAbsoluteFile());
tmpSolrHome = new File( TEMP_DIR + File.separator + TestManagedSchemaFieldResource.class.getSimpleName()
+ System.currentTimeMillis());
tmpConfDir = new File(tmpSolrHome, confDir);
FileUtils.copyDirectory(new File(TEST_HOME()), tmpSolrHome.getAbsoluteFile());
final SortedMap<ServletHolder,String> extraServlets = new TreeMap<ServletHolder,String>();
final ServletHolder solrRestApi = new ServletHolder("SolrRestApi", ServerServlet.class);
@ -45,7 +54,8 @@ public class TestManagedSchemaFieldResource extends RestTestBase {
System.setProperty("managed.schema.mutable", "true");
System.setProperty("enable.update.log", "false");
createJettyAndHarness(tmpSolrHome, "solrconfig-managed-schema.xml", "schema-rest.xml", "/solr", true, extraServlets);
createJettyAndHarness(tmpSolrHome.getAbsolutePath(), "solrconfig-managed-schema.xml", "schema-rest.xml",
"/solr", true, extraServlets);
}
@After
@ -61,21 +71,21 @@ public class TestManagedSchemaFieldResource extends RestTestBase {
@Test
public void testAddFieldBadFieldType() throws Exception {
assertJPut("/schema/fields/newfield",
json( "{'type':'not_in_there_at_all','stored':'false'}" ),
json( "{'type':'not_in_there_at_all','stored':false}" ),
"/error/msg==\"Field \\'newfield\\': Field type \\'not_in_there_at_all\\' not found.\"");
}
@Test
public void testAddFieldMismatchedName() throws Exception {
assertJPut("/schema/fields/newfield",
json( "{'name':'something_else','type':'text','stored':'false'}" ),
json( "{'name':'something_else','type':'text','stored':false}" ),
"/error/msg=='///regex:newfield///'");
}
@Test
public void testAddFieldBadProperty() throws Exception {
assertJPut("/schema/fields/newfield",
json( "{'type':'text','no_property_with_this_name':'false'}" ),
json( "{'type':'text','no_property_with_this_name':false}" ),
"/error/msg==\"java.lang.IllegalArgumentException: Invalid field property: no_property_with_this_name\"");
}
@ -87,7 +97,7 @@ public class TestManagedSchemaFieldResource extends RestTestBase {
"/response/lst[@name='error']/int[@name='code'] = '404'");
assertJPut("/schema/fields/newfield",
json( "{'type':'text','stored':'false'}" ),
json("{'type':'text','stored':false}"),
"/responseHeader/status==0");
assertQ("/schema/fields/newfield?indent=on&wt=xml",
@ -104,6 +114,122 @@ public class TestManagedSchemaFieldResource extends RestTestBase {
"/response/result[@name='response']/doc/str[@name='id'][.='123']");
}
@Test
public void testAddFieldWithMulipleOptions() throws Exception {
assertQ("/schema/fields/newfield?indent=on&wt=xml",
"count(/response/lst[@name='field']) = 0",
"/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
"/response/lst[@name='error']/int[@name='code'] = '404'");
assertJPut("/schema/fields/newfield",
json("{'type':'text_en','stored':true,'indexed':false}"),
"/responseHeader/status==0");
File managedSchemaFile = new File(tmpConfDir, "managed-schema");
assertTrue(managedSchemaFile.exists());
String managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
Pattern newfieldStoredTrueIndexedFalsePattern
= Pattern.compile( "<field name=\"newfield\" type=\"text_en\" "
+ "(?=.*stored=\"true\")(?=.*indexed=\"false\").*/>");
assertTrue(newfieldStoredTrueIndexedFalsePattern.matcher(managedSchemaContents).find());
assertQ("/schema/fields/newfield?indent=on&wt=xml",
"count(/response/lst[@name='field']) = 1",
"/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
"/response/lst[@name='field']/str[@name='name'] = 'newfield'",
"/response/lst[@name='field']/str[@name='type'] = 'text_en'",
"/response/lst[@name='field']/bool[@name='indexed'] = 'false'",
"/response/lst[@name='field']/bool[@name='stored'] = 'true'");
assertU(adoc("newfield", "value1 value2", "id", "1234"));
assertU(commit());
assertQ("/schema/fields/newfield2?indent=on&wt=xml",
"count(/response/lst[@name='field']) = 0",
"/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
"/response/lst[@name='error']/int[@name='code'] = '404'");
assertJPut("/schema/fields/newfield2",
json("{'type':'text_en','stored':true,'indexed':true,'multiValued':true}"),
"/responseHeader/status==0");
managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
Pattern newfield2StoredTrueIndexedTrueMultiValuedTruePattern
= Pattern.compile( "<field name=\"newfield2\" type=\"text_en\" "
+ "(?=.*stored=\"true\")(?=.*indexed=\"true\")(?=multiValued=\"true\").*/>");
assertTrue(newfield2StoredTrueIndexedTrueMultiValuedTruePattern.matcher(managedSchemaContents).find());
assertQ("/schema/fields/newfield2?indent=on&wt=xml",
"count(/response/lst[@name='field']) = 1",
"/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
"/response/lst[@name='field']/str[@name='name'] = 'newfield2'",
"/response/lst[@name='field']/str[@name='type'] = 'text_en'",
"/response/lst[@name='field']/bool[@name='indexed'] = 'true'",
"/response/lst[@name='field']/bool[@name='stored'] = 'true'",
"/response/lst[@name='field']/bool[@name='multiValued'] = 'true'");
assertU(adoc("newfield2", "value1 value2", "newfield2", "value3 value4", "id", "5678"));
assertU(commit());
assertQ("/select?q=newfield2:value3",
"/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
"/response/result[@name='response'][@numFound='1']",
"count(/response/result[@name='response']/doc) = 1",
"/response/result[@name='response']/doc/str[@name='id'][.='5678']");
}
@Test
public void testAddFieldCollectionWithMultipleOptions() throws Exception {
assertQ("/schema/fields?indent=on&wt=xml",
"count(/response/arr[@name='fields']/lst/str[@name]) > 0", // there are fields
"count(/response/arr[@name='fields']/lst/str[starts-with(@name,'newfield')]) = 0"); // but none named newfield*
assertJPost("/schema/fields",
json("[{'name':'newfield','type':'text_en','stored':true,'indexed':false}]"),
"/responseHeader/status==0");
File managedSchemaFile = new File(tmpConfDir, "managed-schema");
assertTrue(managedSchemaFile.exists());
String managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
Pattern newfieldStoredTrueIndexedFalsePattern
= Pattern.compile( "<field name=\"newfield\" type=\"text_en\" "
+ "(?=.*stored=\"true\")(?=.*indexed=\"false\").*/>");
assertTrue(newfieldStoredTrueIndexedFalsePattern.matcher(managedSchemaContents).find());
assertQ("/schema/fields?indent=on&wt=xml",
"/response/arr[@name='fields']/lst"
+ "[str[@name='name']='newfield' and str[@name='type']='text_en'"
+ " and bool[@name='stored']='true' and bool[@name='indexed']='false']");
assertU(adoc("newfield", "value1 value2", "id", "789"));
assertU(commit());
assertJPost("/schema/fields",
json("[{'name':'newfield2','type':'text_en','stored':true,'indexed':true,'multiValued':true}]"),
"/responseHeader/status==0");
managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
Pattern newfield2StoredTrueIndexedTrueMultiValuedTruePattern
= Pattern.compile( "<field name=\"newfield2\" type=\"text_en\" "
+ "(?=.*stored=\"true\")(?=.*indexed=\"true\")(?=multiValued=\"true\").*/>");
assertTrue(newfield2StoredTrueIndexedTrueMultiValuedTruePattern.matcher(managedSchemaContents).find());
assertQ("/schema/fields?indent=on&wt=xml",
"/response/arr[@name='fields']/lst"
+ "[str[@name='name']='newfield2' and str[@name='type']='text_en'"
+ " and bool[@name='stored']='true' and bool[@name='indexed']='true' and bool[@name='multiValued']='true']");
assertU(adoc("newfield2", "value1 value2", "newfield2", "value3 value4", "id", "790"));
assertU(commit());
assertQ("/select?q=newfield2:value3",
"/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
"/response/result[@name='response'][@numFound='1']",
"count(/response/result[@name='response']/doc) = 1",
"/response/result[@name='response']/doc/str[@name='id'][.='790']");
}
@Test
public void testAddCopyField() throws Exception {
assertQ("/schema/fields/newfield2?indent=on&wt=xml",
@ -112,13 +238,13 @@ public class TestManagedSchemaFieldResource extends RestTestBase {
"/response/lst[@name='error']/int[@name='code'] = '404'");
assertJPut("/schema/fields/fieldA",
"{\"type\":\"text\",\"stored\":\"false\"}",
json("{'type':'text','stored':false}"),
"/responseHeader/status==0");
assertJPut("/schema/fields/fieldB",
"{\"type\":\"text\",\"stored\":\"false\", \"copyFields\":[\"fieldA\"]}",
json("{'type':'text','stored':false, 'copyFields':['fieldA']}"),
"/responseHeader/status==0");
assertJPut("/schema/fields/fieldC",
"{\"type\":\"text\",\"stored\":\"false\", \"copyFields\":\"fieldA\"}",
json("{'type':'text','stored':false, 'copyFields':'fieldA'}"),
"/responseHeader/status==0");
assertQ("/schema/fields/fieldB?indent=on&wt=xml",
@ -132,11 +258,11 @@ public class TestManagedSchemaFieldResource extends RestTestBase {
);
//fine to pass in empty list, just won't do anything
assertJPut("/schema/fields/fieldD",
"{\"type\":\"text\",\"stored\":\"false\", \"copyFields\":[]}",
json("{'type':'text','stored':false, 'copyFields':[]}"),
"/responseHeader/status==0");
//some bad usages
assertJPut("/schema/fields/fieldF",
"{\"type\":\"text\",\"stored\":\"false\", \"copyFields\":[\"some_nonexistent_field_ignore_exception\"]}",
json("{'type':'text','stored':false, 'copyFields':['some_nonexistent_field_ignore_exception']}"),
"/error/msg==\"copyField dest :\\'some_nonexistent_field_ignore_exception\\' is not an explicit field and doesn\\'t match a dynamicField.\"");
}
@ -153,8 +279,8 @@ public class TestManagedSchemaFieldResource extends RestTestBase {
"/response/lst[@name='error']/int[@name='code'] = '404'");
assertJPost("/schema/fields",
"[{\"name\":\"newfield1\",\"type\":\"text\",\"stored\":\"false\"},"
+" {\"name\":\"newfield2\",\"type\":\"text\",\"stored\":\"false\"}]",
json( "[{'name':'newfield1','type':'text','stored':false},"
+ " {'name':'newfield2','type':'text','stored':false}]"),
"/responseHeader/status==0");
assertQ("/schema/fields/newfield1?indent=on&wt=xml",
@ -184,55 +310,60 @@ public class TestManagedSchemaFieldResource extends RestTestBase {
@Test
public void testPostCopy() throws Exception {
assertJPost("/schema/fields",
json( "[{'name':'fieldA','type':'text','stored':'false'},"
+ " {'name':'fieldB','type':'text','stored':'false'},"
+ " {'name':'fieldC','type':'text','stored':'false', 'copyFields':['fieldB']}]" ),
json( "[{'name':'fieldA','type':'text','stored':false},"
+ " {'name':'fieldB','type':'text','stored':false},"
+ " {'name':'fieldC','type':'text','stored':false, 'copyFields':['fieldB']}]"),
"/responseHeader/status==0");
assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=fieldC",
"count(/response/arr[@name='copyFields']/lst) = 1"
);
assertJPost("/schema/fields",
"[{\"name\":\"fieldD\",\"type\":\"text\",\"stored\":\"false\"},"
+ "{\"name\":\"fieldE\",\"type\":\"text\",\"stored\":\"false\"},"
+ " {\"name\":\"fieldF\",\"type\":\"text\",\"stored\":\"false\", \"copyFields\":[\"fieldD\",\"fieldE\"]},"
+ " {\"name\":\"fieldG\",\"type\":\"text\",\"stored\":\"false\", \"copyFields\":\"fieldD\"}"//single
+ "]",
json( "[{'name':'fieldD','type':'text','stored':false},"
+ " {'name':'fieldE','type':'text','stored':false},"
+ " {'name':'fieldF','type':'text','stored':false, 'copyFields':['fieldD','fieldE']},"
+ " {'name':'fieldG','type':'text','stored':false, 'copyFields':'fieldD'}]"),//single
"/responseHeader/status==0");
assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=fieldF",
"count(/response/arr[@name='copyFields']/lst) = 2"
);
//passing in an empty list is perfectly acceptable, it just won't do anything
assertJPost("/schema/fields",
"[{\"name\":\"fieldX\",\"type\":\"text\",\"stored\":\"false\"},"
+ "{\"name\":\"fieldY\",\"type\":\"text\",\"stored\":\"false\"},"
+ " {\"name\":\"fieldZ\",\"type\":\"text\",\"stored\":\"false\", \"copyFields\":[]}]",
json( "[{'name':'fieldX','type':'text','stored':false},"
+ " {'name':'fieldY','type':'text','stored':false},"
+ " {'name':'fieldZ','type':'text','stored':false, 'copyFields':[]}]"),
"/responseHeader/status==0");
//some bad usages
assertJPost("/schema/fields",
"[{\"name\":\"fieldH\",\"type\":\"text\",\"stored\":\"false\"},"
+ "{\"name\":\"fieldI\",\"type\":\"text\",\"stored\":\"false\"},"
+ " {\"name\":\"fieldJ\",\"type\":\"text\",\"stored\":\"false\", \"copyFields\":[\"some_nonexistent_field_ignore_exception\"]}]",
"/error/msg==\"copyField dest :\\'some_nonexistent_field_ignore_exception\\' is not an explicit field and doesn\\'t match a dynamicField.\"");
json( "[{'name':'fieldH','type':'text','stored':false},"
+ " {'name':'fieldI','type':'text','stored':false},"
+ " {'name':'fieldJ','type':'text','stored':false, 'copyFields':['some_nonexistent_field_ignore_exception']}]"),
"/error/msg=='copyField dest :\\'some_nonexistent_field_ignore_exception\\' is not an explicit field and doesn\\'t match a dynamicField.'");
}
@Test
public void testPostCopyFields() throws Exception {
assertJPost("/schema/fields",
"[{\"name\":\"fieldA\",\"type\":\"text\",\"stored\":\"false\"},"
+ "{\"name\":\"fieldB\",\"type\":\"text\",\"stored\":\"false\"},"
+ "{\"name\":\"fieldC\",\"type\":\"text\",\"stored\":\"false\"},"
+ "{\"name\":\"fieldD\",\"type\":\"text\",\"stored\":\"false\"},"
+ " {\"name\":\"fieldE\",\"type\":\"text\",\"stored\":\"false\"}]",
json( "[{'name':'fieldA','type':'text','stored':false},"
+ " {'name':'fieldB','type':'text','stored':false},"
+ " {'name':'fieldC','type':'text','stored':false},"
+ " {'name':'fieldD','type':'text','stored':false},"
+ " {'name':'fieldE','type':'text','stored':false}]"),
"/responseHeader/status==0");
assertJPost("/schema/copyfields",
json( "[{'source':'fieldA', 'dest':'fieldB'},"
+ " {'source':'fieldD', 'dest':['fieldC', 'fieldE']}]"),
"/responseHeader/status==0");
assertJPost("/schema/copyfields", "[{\"source\":\"fieldA\", \"dest\":\"fieldB\"},{\"source\":\"fieldD\", \"dest\":[\"fieldC\", \"fieldE\"]}]", "/responseHeader/status==0");
assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=fieldA",
"count(/response/arr[@name='copyFields']/lst) = 1");
assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=fieldD",
"count(/response/arr[@name='copyFields']/lst) = 2");
assertJPost("/schema/copyfields", "[{\"source\":\"some_nonexistent_field_ignore_exception\", \"dest\":[\"fieldA\"]}]", "/error/msg==\"copyField source :\\'some_nonexistent_field_ignore_exception\\' is not a glob and doesn\\'t match any explicit field or dynamicField.\"");
assertJPost("/schema/copyfields", "[{\"source\":\"fieldD\", \"dest\":[\"some_nonexistent_field_ignore_exception\"]}]", "/error/msg==\"copyField dest :\\'some_nonexistent_field_ignore_exception\\' is not an explicit field and doesn\\'t match a dynamicField.\"");
}
assertJPost("/schema/copyfields",
json("[{'source':'some_nonexistent_field_ignore_exception', 'dest':['fieldA']}]"),
"/error/msg=='copyField source :\\'some_nonexistent_field_ignore_exception\\' is not a glob and doesn\\'t match any explicit field or dynamicField.'");
assertJPost("/schema/copyfields",
json("[{'source':'fieldD', 'dest':['some_nonexistent_field_ignore_exception']}]"),
"/error/msg=='copyField dest :\\'some_nonexistent_field_ignore_exception\\' is not an explicit field and doesn\\'t match a dynamicField.'");
}
}