You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sa...@apache.org on 2013/10/31 09:33:24 UTC

svn commit: r1537400 - in /lucene/dev/branches/branch_4x: ./ solr/ solr/core/ solr/core/src/test-files/solr/collection1/conf/schema-rest.xml solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldResource.java

Author: sarowe
Date: Thu Oct 31 08:33:23 2013
New Revision: 1537400

URL: http://svn.apache.org/r1537400
Log:
More add field tests; json escaped double quotes -> single + json() wrapper (merged trunk r1537399)

Modified:
    lucene/dev/branches/branch_4x/   (props changed)
    lucene/dev/branches/branch_4x/solr/   (props changed)
    lucene/dev/branches/branch_4x/solr/core/   (props changed)
    lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema-rest.xml
    lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldResource.java

Modified: lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema-rest.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema-rest.xml?rev=1537400&r1=1537399&r2=1537400&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema-rest.xml (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema-rest.xml Thu Oct 31 08:33:23 2013
@@ -134,6 +134,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">

Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldResource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldResource.java?rev=1537400&r1=1537399&r2=1537400&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldResource.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldResource.java Thu Oct 31 08:33:23 2013
@@ -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.ServerSer
 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 TestManagedSchemaFieldResou
     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,22 +71,22 @@ public class TestManagedSchemaFieldResou
   @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'}" ),
-        "/error/msg==\"java.lang.IllegalArgumentException: Invalid field property: no_property_with_this_name\"");
+               json( "{'type':'text','no_property_with_this_name':false}" ),
+               "/error/msg==\"java.lang.IllegalArgumentException: Invalid field property: no_property_with_this_name\"");
   }
   
   @Test
@@ -87,8 +97,8 @@ public class TestManagedSchemaFieldResou
             "/response/lst[@name='error']/int[@name='code'] = '404'");
     
     assertJPut("/schema/fields/newfield",
-        json( "{'type':'text','stored':'false'}" ),
-        "/responseHeader/status==0");
+               json("{'type':'text','stored':false}"),
+               "/responseHeader/status==0");
     
     assertQ("/schema/fields/newfield?indent=on&wt=xml",
             "count(/response/lst[@name='field']) = 1",
@@ -105,21 +115,137 @@ public class TestManagedSchemaFieldResou
   }
 
   @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",
             "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/fieldA",
-        "{\"type\":\"text\",\"stored\":\"false\"}",
-        "/responseHeader/status==0");
+    assertJPut("/schema/fields/fieldA", 
+               json("{'type':'text','stored':false}"),
+               "/responseHeader/status==0");
     assertJPut("/schema/fields/fieldB",
-        "{\"type\":\"text\",\"stored\":\"false\", \"copyFields\":[\"fieldA\"]}",
-        "/responseHeader/status==0");
+               json("{'type':'text','stored':false, 'copyFields':['fieldA']}"),
+               "/responseHeader/status==0");
     assertJPut("/schema/fields/fieldC",
-        "{\"type\":\"text\",\"stored\":\"false\", \"copyFields\":\"fieldA\"}",
-        "/responseHeader/status==0");
+               json("{'type':'text','stored':false, 'copyFields':'fieldA'}"),
+               "/responseHeader/status==0");
 
     assertQ("/schema/fields/fieldB?indent=on&wt=xml",
             "count(/response/lst[@name='field']) = 1",
@@ -132,12 +258,12 @@ public class TestManagedSchemaFieldResou
     );
     //fine to pass in empty list, just won't do anything
     assertJPut("/schema/fields/fieldD",
-        "{\"type\":\"text\",\"stored\":\"false\", \"copyFields\":[]}",
-        "/responseHeader/status==0");
+               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\"]}",
-        "/error/msg==\"copyField dest :\\'some_nonexistent_field_ignore_exception\\' is not an explicit field and doesn\\'t match a dynamicField.\"");
+               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.\"");
   }
 
   @Test
@@ -153,8 +279,8 @@ public class TestManagedSchemaFieldResou
             "/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 TestManagedSchemaFieldResou
   @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\":[]}]",
-        "/responseHeader/status==0");
+                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.'");
   }
-
 }