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 2016/11/02 23:59:33 UTC
[36/50] [abbrv] lucene-solr:apiv2: SOLR-8542: Adds Solr Learning to
Rank (LTR) plugin for reranking results with machine learning models.
(Michael Nilsson, Diego Ceccarelli, Joshua Pantony, Jon Dorando,
Naveen Santhapuri, Alessandro Benedetti, David Groh
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestRankingFeature.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestRankingFeature.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestRankingFeature.java
new file mode 100644
index 0000000..437e10d
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestRankingFeature.java
@@ -0,0 +1,123 @@
+/*
+ * 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.ltr.feature;
+
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.ltr.TestRerankBase;
+import org.apache.solr.ltr.model.LinearModel;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+public class TestRankingFeature extends TestRerankBase {
+
+ @BeforeClass
+ public static void before() throws Exception {
+ setuptest("solrconfig-ltr.xml", "schema.xml");
+
+ assertU(adoc("id", "1", "title", "w1", "description", "w1", "popularity",
+ "1"));
+ assertU(adoc("id", "2", "title", "w2 2asd asdd didid", "description",
+ "w2 2asd asdd didid", "popularity", "2"));
+ assertU(adoc("id", "3", "title", "w3", "description", "w3", "popularity",
+ "3"));
+ assertU(adoc("id", "4", "title", "w4", "description", "w4", "popularity",
+ "4"));
+ assertU(adoc("id", "5", "title", "w5", "description", "w5", "popularity",
+ "5"));
+ assertU(adoc("id", "6", "title", "w1 w2", "description", "w1 w2",
+ "popularity", "6"));
+ assertU(adoc("id", "7", "title", "w1 w2 w3 w4 w5", "description",
+ "w1 w2 w3 w4 w5 w8", "popularity", "7"));
+ assertU(adoc("id", "8", "title", "w1 w1 w1 w2 w2 w8", "description",
+ "w1 w1 w1 w2 w2", "popularity", "8"));
+ assertU(commit());
+ }
+
+ @AfterClass
+ public static void after() throws Exception {
+ aftertest();
+ }
+
+ @Test
+ public void testRankingSolrFeature() throws Exception {
+ // before();
+ loadFeature("powpularityS", SolrFeature.class.getCanonicalName(),
+ "{\"q\":\"{!func}pow(popularity,2)\"}");
+ loadFeature("unpopularityS", SolrFeature.class.getCanonicalName(),
+ "{\"q\":\"{!func}div(1,popularity)\"}");
+
+ loadModel("powpularityS-model", LinearModel.class.getCanonicalName(),
+ new String[] {"powpularityS"}, "{\"weights\":{\"powpularityS\":1.0}}");
+ loadModel("unpopularityS-model", LinearModel.class.getCanonicalName(),
+ new String[] {"unpopularityS"}, "{\"weights\":{\"unpopularityS\":1.0}}");
+
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("title:w1");
+ query.add("fl", "*, score");
+ query.add("rows", "4");
+
+ assertJQ("/query" + query.toQueryString(), "/response/numFound/==4");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='1'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/id=='8'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/id=='6'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[3]/id=='7'");
+ // Normal term match
+
+ query.add("rq", "{!ltr model=powpularityS-model reRankDocs=4}");
+ query.set("debugQuery", "on");
+
+ assertJQ("/query" + query.toQueryString(), "/response/numFound/==4");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='8'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/score==64.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/id=='7'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/score==49.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/id=='6'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/score==36.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[3]/id=='1'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[3]/score==1.0");
+
+ query.remove("rq");
+ query.add("rq", "{!ltr model=unpopularityS-model reRankDocs=4}");
+
+ assertJQ("/query" + query.toQueryString(), "/response/numFound/==4");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='1'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/score==1.0");
+
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/id=='6'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/id=='7'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[3]/id=='8'");
+
+ //bad solr ranking feature
+ loadFeature("powdesS", SolrFeature.class.getCanonicalName(),
+ "{\"q\":\"{!func}pow(description,2)\"}");
+ loadModel("powdesS-model", LinearModel.class.getCanonicalName(),
+ new String[] {"powdesS"}, "{\"weights\":{\"powdesS\":1.0}}");
+
+ query.remove("rq");
+ query.add("rq", "{!ltr model=powdesS-model reRankDocs=4}");
+
+ assertJQ("/query" + query.toQueryString(),
+ "/error/msg/=='"+FeatureException.class.getCanonicalName()+": " +
+ "java.lang.UnsupportedOperationException: " +
+ "Unable to extract feature for powdesS'");
+ // aftertest();
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScoreWithQ.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScoreWithQ.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScoreWithQ.java
new file mode 100644
index 0000000..754409a
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScoreWithQ.java
@@ -0,0 +1,74 @@
+/*
+ * 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.ltr.feature;
+
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.ltr.TestRerankBase;
+import org.apache.solr.ltr.model.LinearModel;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestUserTermScoreWithQ extends TestRerankBase {
+
+ @BeforeClass
+ public static void before() throws Exception {
+ setuptest("solrconfig-ltr.xml", "schema.xml");
+
+ assertU(adoc("id", "1", "title", "w1", "description", "w1", "popularity",
+ "1"));
+ assertU(adoc("id", "2", "title", "w2 2asd asdd didid", "description",
+ "w2 2asd asdd didid", "popularity", "2"));
+ assertU(adoc("id", "3", "title", "w3", "description", "w3", "popularity",
+ "3"));
+ assertU(adoc("id", "4", "title", "w4", "description", "w4", "popularity",
+ "4"));
+ assertU(adoc("id", "5", "title", "w5", "description", "w5", "popularity",
+ "5"));
+ assertU(adoc("id", "6", "title", "w1 w2", "description", "w1 w2",
+ "popularity", "6"));
+ assertU(adoc("id", "7", "title", "w1 w2 w3 w4 w5", "description",
+ "w1 w2 w3 w4 w5 w8", "popularity", "7"));
+ assertU(adoc("id", "8", "title", "w1 w1 w1 w2 w2 w8", "description",
+ "w1 w1 w1 w2 w2", "popularity", "8"));
+ assertU(commit());
+ }
+
+ @AfterClass
+ public static void after() throws Exception {
+ aftertest();
+ }
+
+ @Test
+ public void testUserTermScoreWithQ() throws Exception {
+ // before();
+ loadFeature("SomeTermQ", SolrFeature.class.getCanonicalName(),
+ "{\"q\":\"{!terms f=popularity}88888\"}");
+ loadModel("Term-modelQ", LinearModel.class.getCanonicalName(),
+ new String[] {"SomeTermQ"}, "{\"weights\":{\"SomeTermQ\":1.0}}");
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("title:w1");
+ query.add("fl", "*, score");
+ query.add("rows", "4");
+ query.add("rq", "{!ltr model=Term-modelQ reRankDocs=4}");
+ query.set("debugQuery", "on");
+
+ assertJQ("/query" + query.toQueryString(), "/response/numFound/==4");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/score==0.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/score==0.0");
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScorerQuery.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScorerQuery.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScorerQuery.java
new file mode 100644
index 0000000..c79207c
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScorerQuery.java
@@ -0,0 +1,74 @@
+/*
+ * 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.ltr.feature;
+
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.ltr.TestRerankBase;
+import org.apache.solr.ltr.model.LinearModel;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestUserTermScorerQuery extends TestRerankBase {
+
+ @BeforeClass
+ public static void before() throws Exception {
+ setuptest("solrconfig-ltr.xml", "schema.xml");
+
+ assertU(adoc("id", "1", "title", "w1", "description", "w1", "popularity",
+ "1"));
+ assertU(adoc("id", "2", "title", "w2 2asd asdd didid", "description",
+ "w2 2asd asdd didid", "popularity", "2"));
+ assertU(adoc("id", "3", "title", "w3", "description", "w3", "popularity",
+ "3"));
+ assertU(adoc("id", "4", "title", "w4", "description", "w4", "popularity",
+ "4"));
+ assertU(adoc("id", "5", "title", "w5", "description", "w5", "popularity",
+ "5"));
+ assertU(adoc("id", "6", "title", "w1 w2", "description", "w1 w2",
+ "popularity", "6"));
+ assertU(adoc("id", "7", "title", "w1 w2 w3 w4 w5", "description",
+ "w1 w2 w3 w4 w5 w8", "popularity", "7"));
+ assertU(adoc("id", "8", "title", "w1 w1 w1 w2 w2 w8", "description",
+ "w1 w1 w1 w2 w2", "popularity", "8"));
+ assertU(commit());
+ }
+
+ @AfterClass
+ public static void after() throws Exception {
+ aftertest();
+ }
+
+ @Test
+ public void testUserTermScorerQuery() throws Exception {
+ // before();
+ loadFeature("matchedTitleDFExt", SolrFeature.class.getCanonicalName(),
+ "{\"q\":\"${user_query}\",\"df\":\"title\"}");
+ loadModel("Term-matchedTitleDFExt", LinearModel.class.getCanonicalName(),
+ new String[] {"matchedTitleDFExt"},
+ "{\"weights\":{\"matchedTitleDFExt\":1.1}}");
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("title:w1");
+ query.add("fl", "*, score");
+ query.add("rows", "4");
+ query.add("rq",
+ "{!ltr model=Term-matchedTitleDFExt reRankDocs=4 efi.user_query=w8}");
+
+ assertJQ("/query" + query.toQueryString(), "/response/numFound/==4");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='8'");
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScorereQDF.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScorereQDF.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScorereQDF.java
new file mode 100644
index 0000000..f47a883
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestUserTermScorereQDF.java
@@ -0,0 +1,75 @@
+/*
+ * 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.ltr.feature;
+
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.ltr.TestRerankBase;
+import org.apache.solr.ltr.model.LinearModel;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestUserTermScorereQDF extends TestRerankBase {
+
+ @BeforeClass
+ public static void before() throws Exception {
+ setuptest("solrconfig-ltr.xml", "schema.xml");
+
+ assertU(adoc("id", "1", "title", "w1", "description", "w1", "popularity",
+ "1"));
+ assertU(adoc("id", "2", "title", "w2 2asd asdd didid", "description",
+ "w2 2asd asdd didid", "popularity", "2"));
+ assertU(adoc("id", "3", "title", "w3", "description", "w3", "popularity",
+ "3"));
+ assertU(adoc("id", "4", "title", "w4", "description", "w4", "popularity",
+ "4"));
+ assertU(adoc("id", "5", "title", "w5", "description", "w5", "popularity",
+ "5"));
+ assertU(adoc("id", "6", "title", "w1 w2", "description", "w1 w2",
+ "popularity", "6"));
+ assertU(adoc("id", "7", "title", "w1 w2 w3 w4 w5", "description",
+ "w1 w2 w3 w4 w5 w8", "popularity", "7"));
+ assertU(adoc("id", "8", "title", "w1 w1 w1 w2 w2 w8", "description",
+ "w1 w1 w1 w2 w2", "popularity", "8"));
+ assertU(commit());
+ }
+
+ @AfterClass
+ public static void after() throws Exception {
+ aftertest();
+ }
+
+ @Test
+ public void testUserTermScorerQWithDF() throws Exception {
+ // before();
+ loadFeature("matchedTitleDF", SolrFeature.class.getCanonicalName(),
+ "{\"q\":\"w5\",\"df\":\"title\"}");
+ loadModel("Term-matchedTitleDF", LinearModel.class.getCanonicalName(),
+ new String[] {"matchedTitleDF"},
+ "{\"weights\":{\"matchedTitleDF\":1.0}}");
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("title:w1");
+ query.add("fl", "*, score");
+ query.add("rows", "2");
+ query.add("rq", "{!ltr model=Term-matchedTitleDF reRankDocs=4}");
+ query.set("debugQuery", "on");
+
+ assertJQ("/query" + query.toQueryString(), "/response/numFound/==4");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='7'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/score==0.0");
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestValueFeature.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestValueFeature.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestValueFeature.java
new file mode 100644
index 0000000..084da4a
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestValueFeature.java
@@ -0,0 +1,165 @@
+/*
+ * 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.ltr.feature;
+
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.ltr.TestRerankBase;
+import org.apache.solr.ltr.model.LinearModel;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestValueFeature extends TestRerankBase {
+
+ @BeforeClass
+ public static void before() throws Exception {
+ setuptest("solrconfig-ltr.xml", "schema.xml");
+
+ assertU(adoc("id", "1", "title", "w1"));
+ assertU(adoc("id", "2", "title", "w2"));
+ assertU(adoc("id", "3", "title", "w3"));
+ assertU(adoc("id", "4", "title", "w4"));
+ assertU(adoc("id", "5", "title", "w5"));
+ assertU(adoc("id", "6", "title", "w1 w2"));
+ assertU(adoc("id", "7", "title", "w1 w2 w3 w4 w5"));
+ assertU(adoc("id", "8", "title", "w1 w1 w1 w2 w2"));
+ assertU(commit());
+ }
+
+ @AfterClass
+ public static void after() throws Exception {
+ aftertest();
+ }
+
+ @Test
+ public void testValueFeatureWithEmptyValue() throws Exception {
+ final RuntimeException expectedException =
+ new RuntimeException("mismatch: '0'!='500' @ responseHeader/status");
+ try {
+ loadFeature("c2", ValueFeature.class.getCanonicalName(), "{\"value\":\"\"}");
+ fail("testValueFeatureWithEmptyValue failed to throw exception: "+expectedException);
+ } catch (RuntimeException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+ @Test
+ public void testValueFeatureWithWhitespaceValue() throws Exception {
+ final RuntimeException expectedException =
+ new RuntimeException("mismatch: '0'!='500' @ responseHeader/status");
+ try {
+ loadFeature("c2", ValueFeature.class.getCanonicalName(),
+ "{\"value\":\" \"}");
+ fail("testValueFeatureWithWhitespaceValue failed to throw exception: "+expectedException);
+ } catch (RuntimeException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+ @Test
+ public void testRerankingWithConstantValueFeatureReplacesDocScore() throws Exception {
+ loadFeature("c3", ValueFeature.class.getCanonicalName(), "c3",
+ "{\"value\":2}");
+ loadModel("m3", LinearModel.class.getCanonicalName(), new String[] {"c3"},
+ "c3", "{\"weights\":{\"c3\":1.0}}");
+
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("title:w1");
+ query.add("fl", "*, score");
+ query.add("rows", "4");
+ query.add("wt", "json");
+ query.add("rq", "{!ltr model=m3 reRankDocs=4}");
+
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/score==2.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/score==2.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/score==2.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[3]/score==2.0");
+ }
+
+ @Test
+ public void testRerankingWithEfiValueFeatureReplacesDocScore() throws Exception {
+ loadFeature("c6", ValueFeature.class.getCanonicalName(), "c6",
+ "{\"value\":\"${val6}\"}");
+ loadModel("m6", LinearModel.class.getCanonicalName(), new String[] {"c6"},
+ "c6", "{\"weights\":{\"c6\":1.0}}");
+
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("title:w1");
+ query.add("fl", "*, score");
+ query.add("rows", "4");
+ query.add("wt", "json");
+ query.add("rq", "{!ltr model=m6 reRankDocs=4 efi.val6='2'}");
+
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/score==2.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/score==2.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/score==2.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[3]/score==2.0");
+ }
+
+
+ @Test
+ public void testValueFeatureImplicitlyNotRequiredShouldReturnOkStatusCode() throws Exception {
+ loadFeature("c5", ValueFeature.class.getCanonicalName(), "c5",
+ "{\"value\":\"${val6}\"}");
+ loadModel("m5", LinearModel.class.getCanonicalName(), new String[] {"c5"},
+ "c5", "{\"weights\":{\"c5\":1.0}}");
+
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("title:w1");
+ query.add("fl", "*, score,fvonly:[fvonly]");
+ query.add("rows", "4");
+ query.add("wt", "json");
+ query.add("rq", "{!ltr model=m5 reRankDocs=4}");
+
+ assertJQ("/query" + query.toQueryString(), "/responseHeader/status==0");
+ }
+
+ @Test
+ public void testValueFeatureExplictlyNotRequiredShouldReturnOkStatusCode() throws Exception {
+ loadFeature("c7", ValueFeature.class.getCanonicalName(), "c7",
+ "{\"value\":\"${val7}\",\"required\":false}");
+ loadModel("m7", LinearModel.class.getCanonicalName(), new String[] {"c7"},
+ "c7", "{\"weights\":{\"c7\":1.0}}");
+
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("title:w1");
+ query.add("fl", "*, score,fvonly:[fvonly]");
+ query.add("rows", "4");
+ query.add("wt", "json");
+ query.add("rq", "{!ltr model=m7 reRankDocs=4}");
+
+ assertJQ("/query" + query.toQueryString(), "/responseHeader/status==0");
+ }
+
+ @Test
+ public void testValueFeatureRequiredShouldReturn400StatusCode() throws Exception {
+ loadFeature("c8", ValueFeature.class.getCanonicalName(), "c8",
+ "{\"value\":\"${val8}\",\"required\":true}");
+ loadModel("m8", LinearModel.class.getCanonicalName(), new String[] {"c8"},
+ "c8", "{\"weights\":{\"c8\":1.0}}");
+
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("title:w1");
+ query.add("fl", "*, score,fvonly:[fvonly]");
+ query.add("rows", "4");
+ query.add("wt", "json");
+ query.add("rq", "{!ltr model=m8 reRankDocs=4}");
+
+ assertJQ("/query" + query.toQueryString(), "/responseHeader/status==400");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java
new file mode 100644
index 0000000..e8ee224
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java
@@ -0,0 +1,207 @@
+/*
+ * 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.ltr.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.solr.common.SolrException;
+import org.apache.solr.ltr.TestRerankBase;
+import org.apache.solr.ltr.feature.Feature;
+import org.apache.solr.ltr.norm.IdentityNormalizer;
+import org.apache.solr.ltr.norm.Normalizer;
+import org.apache.solr.ltr.store.FeatureStore;
+import org.apache.solr.ltr.store.rest.ManagedModelStore;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestLinearModel extends TestRerankBase {
+
+ public static LTRScoringModel createLinearModel(String name, List<Feature> features,
+ List<Normalizer> norms,
+ String featureStoreName, List<Feature> allFeatures,
+ Map<String,Object> params) throws ModelException {
+ final LTRScoringModel model = LTRScoringModel.getInstance(solrResourceLoader,
+ LinearModel.class.getCanonicalName(),
+ name,
+ features, norms, featureStoreName, allFeatures, params);
+ return model;
+ }
+
+ static ManagedModelStore store = null;
+ static FeatureStore fstore = null;
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ setuptest();
+ // loadFeatures("features-store-test-model.json");
+ store = getManagedModelStore();
+ fstore = getManagedFeatureStore().getFeatureStore("test");
+
+ }
+
+ @Test
+ public void getInstanceTest() {
+ final Map<String,Object> weights = new HashMap<>();
+ weights.put("constant1", 1d);
+ weights.put("constant5", 1d);
+
+ Map<String,Object> params = new HashMap<String,Object>();
+ final List<Feature> features = getFeatures(new String[] {
+ "constant1", "constant5"});
+ final List<Normalizer> norms =
+ new ArrayList<Normalizer>(
+ Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+ params.put("weights", weights);
+ final LTRScoringModel ltrScoringModel = createLinearModel("test1",
+ features, norms, "test", fstore.getFeatures(),
+ params);
+
+ store.addModel(ltrScoringModel);
+ final LTRScoringModel m = store.getModel("test1");
+ assertEquals(ltrScoringModel, m);
+ }
+
+ @Test
+ public void nullFeatureWeightsTest() {
+ final ModelException expectedException =
+ new ModelException("Model test2 doesn't contain any weights");
+ try {
+ final List<Feature> features = getFeatures(new String[]
+ {"constant1", "constant5"});
+ final List<Normalizer> norms =
+ new ArrayList<Normalizer>(
+ Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+ createLinearModel("test2",
+ features, norms, "test", fstore.getFeatures(), null);
+ fail("unexpectedly got here instead of catching "+expectedException);
+ } catch (ModelException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+ @Test
+ public void existingNameTest() {
+ final SolrException expectedException =
+ new SolrException(SolrException.ErrorCode.BAD_REQUEST,
+ ModelException.class.getCanonicalName()+": model 'test3' already exists. Please use a different name");
+ try {
+ final List<Feature> features = getFeatures(new String[]
+ {"constant1", "constant5"});
+ final List<Normalizer> norms =
+ new ArrayList<Normalizer>(
+ Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+ final Map<String,Object> weights = new HashMap<>();
+ weights.put("constant1", 1d);
+ weights.put("constant5", 1d);
+
+ Map<String,Object> params = new HashMap<String,Object>();
+ params.put("weights", weights);
+ final LTRScoringModel ltrScoringModel = createLinearModel("test3",
+ features, norms, "test", fstore.getFeatures(),
+ params);
+ store.addModel(ltrScoringModel);
+ final LTRScoringModel m = store.getModel("test3");
+ assertEquals(ltrScoringModel, m);
+ store.addModel(ltrScoringModel);
+ fail("unexpectedly got here instead of catching "+expectedException);
+ } catch (SolrException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+ @Test
+ public void duplicateFeatureTest() {
+ final ModelException expectedException =
+ new ModelException("duplicated feature constant1 in model test4");
+ try {
+ final List<Feature> features = getFeatures(new String[]
+ {"constant1", "constant1"});
+ final List<Normalizer> norms =
+ new ArrayList<Normalizer>(
+ Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+ final Map<String,Object> weights = new HashMap<>();
+ weights.put("constant1", 1d);
+ weights.put("constant5", 1d);
+
+ Map<String,Object> params = new HashMap<String,Object>();
+ params.put("weights", weights);
+ final LTRScoringModel ltrScoringModel = createLinearModel("test4",
+ features, norms, "test", fstore.getFeatures(),
+ params);
+ store.addModel(ltrScoringModel);
+ fail("unexpectedly got here instead of catching "+expectedException);
+ } catch (ModelException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+
+ }
+
+ @Test
+ public void missingFeatureWeightTest() {
+ final ModelException expectedException =
+ new ModelException("Model test5 lacks weight(s) for [constant5]");
+ try {
+ final List<Feature> features = getFeatures(new String[]
+ {"constant1", "constant5"});
+ final List<Normalizer> norms =
+ new ArrayList<Normalizer>(
+ Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+ final Map<String,Object> weights = new HashMap<>();
+ weights.put("constant1", 1d);
+ weights.put("constant5missing", 1d);
+
+ Map<String,Object> params = new HashMap<String,Object>();
+ params.put("weights", weights);
+ createLinearModel("test5",
+ features, norms, "test", fstore.getFeatures(),
+ params);
+ fail("unexpectedly got here instead of catching "+expectedException);
+ } catch (ModelException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+ @Test
+ public void emptyFeaturesTest() {
+ final ModelException expectedException =
+ new ModelException("no features declared for model test6");
+ try {
+ final List<Feature> features = getFeatures(new String[] {});
+ final List<Normalizer> norms =
+ new ArrayList<Normalizer>(
+ Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+ final Map<String,Object> weights = new HashMap<>();
+ weights.put("constant1", 1d);
+ weights.put("constant5missing", 1d);
+
+ Map<String,Object> params = new HashMap<String,Object>();
+ params.put("weights", weights);
+ final LTRScoringModel ltrScoringModel = createLinearModel("test6",
+ features, norms, "test", fstore.getFeatures(),
+ params);
+ store.addModel(ltrScoringModel);
+ fail("unexpectedly got here instead of catching "+expectedException);
+ } catch (ModelException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java
new file mode 100644
index 0000000..3748331
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java
@@ -0,0 +1,246 @@
+/*
+ * 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.ltr.model;
+
+//import static org.junit.internal.matchers.StringContains.containsString;
+
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.ltr.TestRerankBase;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class TestMultipleAdditiveTreesModel extends TestRerankBase {
+
+
+ @BeforeClass
+ public static void before() throws Exception {
+ setuptest("solrconfig-ltr.xml", "schema.xml");
+
+ assertU(adoc("id", "1", "title", "w1", "description", "w1", "popularity","1"));
+ assertU(adoc("id", "2", "title", "w2", "description", "w2", "popularity","2"));
+ assertU(adoc("id", "3", "title", "w3", "description", "w3", "popularity","3"));
+ assertU(adoc("id", "4", "title", "w4", "description", "w4", "popularity","4"));
+ assertU(adoc("id", "5", "title", "w5", "description", "w5", "popularity","5"));
+ assertU(commit());
+
+ loadFeatures("multipleadditivetreesmodel_features.json"); // currently needed to force
+ // scoring on all docs
+ loadModels("multipleadditivetreesmodel.json");
+ }
+
+ @AfterClass
+ public static void after() throws Exception {
+ aftertest();
+ }
+
+
+ @Test
+ public void testMultipleAdditiveTreesScoringWithAndWithoutEfiFeatureMatches() throws Exception {
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("*:*");
+ query.add("rows", "3");
+ query.add("fl", "*,score");
+
+ // Regular scores
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/score==1.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/score==1.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/score==1.0");
+
+ // No match scores since user_query not passed in to external feature info
+ // and feature depended on it.
+ query.add("rq", "{!ltr reRankDocs=3 model=multipleadditivetreesmodel efi.user_query=dsjkafljjk}");
+
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/score==-120.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/score==-120.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/score==-120.0");
+
+ // Matched user query since it was passed in
+ query.remove("rq");
+ query.add("rq", "{!ltr reRankDocs=3 model=multipleadditivetreesmodel efi.user_query=w3}");
+
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='3'");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/score==-20.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/score==-120.0");
+ assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/score==-120.0");
+ }
+
+ @Ignore
+ @Test
+ public void multipleAdditiveTreesTestExplain() throws Exception {
+ final SolrQuery query = new SolrQuery();
+ query.setQuery("*:*");
+ query.add("fl", "*,score,[fv]");
+ query.add("rows", "3");
+
+ query.add("rq",
+ "{!ltr reRankDocs=3 model=multipleadditivetreesmodel efi.user_query=w3}");
+
+ // test out the explain feature, make sure it returns something
+ query.setParam("debugQuery", "on");
+ String qryResult = JQ("/query" + query.toQueryString());
+
+ qryResult = qryResult.replaceAll("\n", " ");
+ // FIXME containsString doesn't exist.
+ // assertThat(qryResult, containsString("\"debug\":{"));
+ // qryResult = qryResult.substring(qryResult.indexOf("debug"));
+ //
+ // assertThat(qryResult, containsString("\"explain\":{"));
+ // qryResult = qryResult.substring(qryResult.indexOf("explain"));
+ //
+ // assertThat(qryResult, containsString("multipleadditivetreesmodel"));
+ // assertThat(qryResult,
+ // containsString(MultipleAdditiveTreesModel.class.getCanonicalName()));
+ //
+ // assertThat(qryResult, containsString("-100.0 = tree 0"));
+ // assertThat(qryResult, containsString("50.0 = tree 0"));
+ // assertThat(qryResult, containsString("-20.0 = tree 1"));
+ // assertThat(qryResult, containsString("'matchedTitle':1.0 > 0.5"));
+ // assertThat(qryResult, containsString("'matchedTitle':0.0 <= 0.5"));
+ //
+ // assertThat(qryResult, containsString(" Go Right "));
+ // assertThat(qryResult, containsString(" Go Left "));
+ // assertThat(qryResult,
+ // containsString("'this_feature_doesnt_exist' does not exist in FV"));
+ }
+
+ @Test
+ public void multipleAdditiveTreesTestNoParams() throws Exception {
+ final ModelException expectedException =
+ new ModelException("no trees declared for model multipleadditivetreesmodel_no_params");
+ try {
+ createModelFromFiles("multipleadditivetreesmodel_no_params.json",
+ "multipleadditivetreesmodel_features.json");
+ fail("multipleAdditiveTreesTestNoParams failed to throw exception: "+expectedException);
+ } catch (Exception actualException) {
+ Throwable rootError = getRootCause(actualException);
+ assertEquals(expectedException.toString(), rootError.toString());
+ }
+
+ }
+
+ @Test
+ public void multipleAdditiveTreesTestEmptyParams() throws Exception {
+ final ModelException expectedException =
+ new ModelException("no trees declared for model multipleadditivetreesmodel_no_trees");
+ try {
+ createModelFromFiles("multipleadditivetreesmodel_no_trees.json",
+ "multipleadditivetreesmodel_features.json");
+ fail("multipleAdditiveTreesTestEmptyParams failed to throw exception: "+expectedException);
+ } catch (Exception actualException) {
+ Throwable rootError = getRootCause(actualException);
+ assertEquals(expectedException.toString(), rootError.toString());
+ }
+ }
+
+ @Test
+ public void multipleAdditiveTreesTestNoWeight() throws Exception {
+ final ModelException expectedException =
+ new ModelException("MultipleAdditiveTreesModel tree doesn't contain a weight");
+ try {
+ createModelFromFiles("multipleadditivetreesmodel_no_weight.json",
+ "multipleadditivetreesmodel_features.json");
+ fail("multipleAdditiveTreesTestNoWeight failed to throw exception: "+expectedException);
+ } catch (Exception actualException) {
+ Throwable rootError = getRootCause(actualException);
+ assertEquals(expectedException.toString(), rootError.toString());
+ }
+ }
+
+ @Test
+ public void multipleAdditiveTreesTestTreesParamDoesNotContatinTree() throws Exception {
+ final ModelException expectedException =
+ new ModelException("MultipleAdditiveTreesModel tree doesn't contain a tree");
+ try {
+ createModelFromFiles("multipleadditivetreesmodel_no_tree.json",
+ "multipleadditivetreesmodel_features.json");
+ fail("multipleAdditiveTreesTestTreesParamDoesNotContatinTree failed to throw exception: "+expectedException);
+ } catch (Exception actualException) {
+ Throwable rootError = getRootCause(actualException);
+ assertEquals(expectedException.toString(), rootError.toString());
+ }
+ }
+
+ @Test
+ public void multipleAdditiveTreesTestNoFeaturesSpecified() throws Exception {
+ final ModelException expectedException =
+ new ModelException("no features declared for model multipleadditivetreesmodel_no_features");
+ try {
+ createModelFromFiles("multipleadditivetreesmodel_no_features.json",
+ "multipleadditivetreesmodel_features.json");
+ fail("multipleAdditiveTreesTestNoFeaturesSpecified failed to throw exception: "+expectedException);
+ } catch (ModelException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+ @Test
+ public void multipleAdditiveTreesTestNoRight() throws Exception {
+ final ModelException expectedException =
+ new ModelException("MultipleAdditiveTreesModel tree node is missing right");
+ try {
+ createModelFromFiles("multipleadditivetreesmodel_no_right.json",
+ "multipleadditivetreesmodel_features.json");
+ fail("multipleAdditiveTreesTestNoRight failed to throw exception: "+expectedException);
+ } catch (Exception actualException) {
+ Throwable rootError = getRootCause(actualException);
+ assertEquals(expectedException.toString(), rootError.toString());
+ }
+ }
+
+ @Test
+ public void multipleAdditiveTreesTestNoLeft() throws Exception {
+ final ModelException expectedException =
+ new ModelException("MultipleAdditiveTreesModel tree node is missing left");
+ try {
+ createModelFromFiles("multipleadditivetreesmodel_no_left.json",
+ "multipleadditivetreesmodel_features.json");
+ fail("multipleAdditiveTreesTestNoLeft failed to throw exception: "+expectedException);
+ } catch (Exception actualException) {
+ Throwable rootError = getRootCause(actualException);
+ assertEquals(expectedException.toString(), rootError.toString());
+ }
+ }
+
+ @Test
+ public void multipleAdditiveTreesTestNoThreshold() throws Exception {
+ final ModelException expectedException =
+ new ModelException("MultipleAdditiveTreesModel tree node is missing threshold");
+ try {
+ createModelFromFiles("multipleadditivetreesmodel_no_threshold.json",
+ "multipleadditivetreesmodel_features.json");
+ fail("multipleAdditiveTreesTestNoThreshold failed to throw exception: "+expectedException);
+ } catch (Exception actualException) {
+ Throwable rootError = getRootCause(actualException);
+ assertEquals(expectedException.toString(), rootError.toString());
+ }
+ }
+
+ @Test
+ public void multipleAdditiveTreesTestMissingTreeFeature() throws Exception {
+ final ModelException expectedException =
+ new ModelException("MultipleAdditiveTreesModel tree node is leaf with left=-100.0 and right=75.0");
+ try {
+ createModelFromFiles("multipleadditivetreesmodel_no_feature.json",
+ "multipleadditivetreesmodel_features.json");
+ fail("multipleAdditiveTreesTestMissingTreeFeature failed to throw exception: "+expectedException);
+ } catch (ModelException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestMinMaxNormalizer.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestMinMaxNormalizer.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestMinMaxNormalizer.java
new file mode 100644
index 0000000..055b3bc
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestMinMaxNormalizer.java
@@ -0,0 +1,120 @@
+/*
+ * 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.ltr.norm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.core.SolrResourceLoader;
+import org.junit.Test;
+
+public class TestMinMaxNormalizer {
+
+ private final SolrResourceLoader solrResourceLoader = new SolrResourceLoader();
+
+ private Normalizer implTestMinMax(Map<String,Object> params,
+ float expectedMin, float expectedMax) {
+ final Normalizer n = Normalizer.getInstance(
+ solrResourceLoader,
+ MinMaxNormalizer.class.getCanonicalName(),
+ params);
+ assertTrue(n instanceof MinMaxNormalizer);
+ final MinMaxNormalizer mmn = (MinMaxNormalizer)n;
+ assertEquals(mmn.getMin(), expectedMin, 0.0);
+ assertEquals(mmn.getMax(), expectedMax, 0.0);
+ return n;
+ }
+
+ @Test
+ public void testInvalidMinMaxNoParams() {
+ implTestMinMax(new HashMap<String,Object>(),
+ Float.NEGATIVE_INFINITY,
+ Float.POSITIVE_INFINITY);
+ }
+
+ @Test
+ public void testInvalidMinMaxMissingMax() {
+ final Map<String,Object> params = new HashMap<String,Object>();
+ params.put("min", "0.0f");
+ implTestMinMax(params,
+ 0.0f,
+ Float.POSITIVE_INFINITY);
+ }
+
+ @Test
+ public void testInvalidMinMaxMissingMin() {
+ final Map<String,Object> params = new HashMap<String,Object>();
+ params.put("max", "0.0f");
+ implTestMinMax(params,
+ Float.NEGATIVE_INFINITY,
+ 0.0f);
+ }
+
+ @Test
+ public void testMinMaxNormalizerMinLargerThanMax() {
+ final Map<String,Object> params = new HashMap<String,Object>();
+ params.put("min", "10.0f");
+ params.put("max", "0.0f");
+ implTestMinMax(params,
+ 10.0f,
+ 0.0f);
+ }
+
+ @Test
+ public void testMinMaxNormalizerMinEqualToMax() {
+ final Map<String,Object> params = new HashMap<String,Object>();
+ params.put("min", "10.0f");
+ params.put("max", "10.0f");
+ final NormalizerException expectedException =
+ new NormalizerException("MinMax Normalizer delta must not be zero "
+ + "| min = 10.0,max = 10.0,delta = 0.0");
+ try {
+ implTestMinMax(params,
+ 10.0f,
+ 10.0f);
+ fail("testMinMaxNormalizerMinEqualToMax failed to throw exception: "+expectedException);
+ } catch(NormalizerException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+ @Test
+ public void testNormalizer() {
+ final Map<String,Object> params = new HashMap<String,Object>();
+ params.put("min", "5.0f");
+ params.put("max", "10.0f");
+ final Normalizer n =
+ implTestMinMax(params,
+ 5.0f,
+ 10.0f);
+
+ float value = 8;
+ assertEquals((value - 5f) / (10f - 5f), n.normalize(value), 0.0001);
+ value = 100;
+ assertEquals((value - 5f) / (10f - 5f), n.normalize(value), 0.0001);
+ value = 150;
+ assertEquals((value - 5f) / (10f - 5f), n.normalize(value), 0.0001);
+ value = -1;
+ assertEquals((value - 5f) / (10f - 5f), n.normalize(value), 0.0001);
+ value = 5;
+ assertEquals((value - 5f) / (10f - 5f), n.normalize(value), 0.0001);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestStandardNormalizer.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestStandardNormalizer.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestStandardNormalizer.java
new file mode 100644
index 0000000..10fa972
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestStandardNormalizer.java
@@ -0,0 +1,132 @@
+/*
+ * 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.ltr.norm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.core.SolrResourceLoader;
+import org.junit.Test;
+
+public class TestStandardNormalizer {
+
+ private final SolrResourceLoader solrResourceLoader = new SolrResourceLoader();
+
+ private Normalizer implTestStandard(Map<String,Object> params,
+ float expectedAvg, float expectedStd) {
+ final Normalizer n = Normalizer.getInstance(
+ solrResourceLoader,
+ StandardNormalizer.class.getCanonicalName(),
+ params);
+ assertTrue(n instanceof StandardNormalizer);
+ final StandardNormalizer sn = (StandardNormalizer)n;
+ assertEquals(sn.getAvg(), expectedAvg, 0.0);
+ assertEquals(sn.getStd(), expectedStd, 0.0);
+ return n;
+ }
+
+ @Test
+ public void testNormalizerNoParams() {
+ implTestStandard(new HashMap<String,Object>(),
+ 0.0f,
+ 1.0f);
+ }
+
+ @Test
+ public void testInvalidSTD() {
+ final Map<String,Object> params = new HashMap<String,Object>();
+ params.put("std", "0f");
+ final NormalizerException expectedException =
+ new NormalizerException("Standard Normalizer standard deviation must be positive "
+ + "| avg = 0.0,std = 0.0");
+ try {
+ implTestStandard(params,
+ 0.0f,
+ 0.0f);
+ fail("testInvalidSTD failed to throw exception: "+expectedException);
+ } catch(NormalizerException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+ @Test
+ public void testInvalidSTD2() {
+ final Map<String,Object> params = new HashMap<String,Object>();
+ params.put("std", "-1f");
+ final NormalizerException expectedException =
+ new NormalizerException("Standard Normalizer standard deviation must be positive "
+ + "| avg = 0.0,std = -1.0");
+ try {
+ implTestStandard(params,
+ 0.0f,
+ -1f);
+ fail("testInvalidSTD2 failed to throw exception: "+expectedException);
+ } catch(NormalizerException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+ @Test
+ public void testInvalidSTD3() {
+ final Map<String,Object> params = new HashMap<String,Object>();
+ params.put("avg", "1f");
+ params.put("std", "0f");
+ final NormalizerException expectedException =
+ new NormalizerException("Standard Normalizer standard deviation must be positive "
+ + "| avg = 1.0,std = 0.0");
+ try {
+ implTestStandard(params,
+ 1f,
+ 0f);
+ fail("testInvalidSTD3 failed to throw exception: "+expectedException);
+ } catch(NormalizerException actualException) {
+ assertEquals(expectedException.toString(), actualException.toString());
+ }
+ }
+
+ @Test
+ public void testNormalizer() {
+ Map<String,Object> params = new HashMap<String,Object>();
+ params.put("avg", "0f");
+ params.put("std", "1f");
+ final Normalizer identity =
+ implTestStandard(params,
+ 0f,
+ 1f);
+
+ float value = 8;
+ assertEquals(value, identity.normalize(value), 0.0001);
+ value = 150;
+ assertEquals(value, identity.normalize(value), 0.0001);
+ params = new HashMap<String,Object>();
+ params.put("avg", "10f");
+ params.put("std", "1.5f");
+ final Normalizer norm = Normalizer.getInstance(
+ solrResourceLoader,
+ StandardNormalizer.class.getCanonicalName(),
+ params);
+
+ for (final float v : new float[] {10f, 20f, 25f, 30f, 31f, 40f, 42f, 100f,
+ 10000000f}) {
+ assertEquals((v - 10f) / (1.5f), norm.normalize(v), 0.0001);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestManagedFeatureStore.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestManagedFeatureStore.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestManagedFeatureStore.java
new file mode 100644
index 0000000..14373fb
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestManagedFeatureStore.java
@@ -0,0 +1,36 @@
+/*
+ * 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.ltr.store.rest;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.lucene.util.LuceneTestCase;
+
+public class TestManagedFeatureStore extends LuceneTestCase {
+
+ public static Map<String,Object> createMap(String name, String className, Map<String,Object> params) {
+ final Map<String,Object> map = new HashMap<String,Object>();
+ map.put(ManagedFeatureStore.NAME_KEY, name);
+ map.put(ManagedFeatureStore.CLASS_KEY, className);
+ if (params != null) {
+ map.put(ManagedFeatureStore.PARAMS_KEY, params);
+ }
+ return map;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManager.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManager.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManager.java
new file mode 100644
index 0000000..855f053
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManager.java
@@ -0,0 +1,163 @@
+/*
+ * 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.ltr.store.rest;
+
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.core.SolrResourceLoader;
+import org.apache.solr.ltr.TestRerankBase;
+import org.apache.solr.ltr.feature.FieldValueFeature;
+import org.apache.solr.ltr.feature.ValueFeature;
+import org.apache.solr.ltr.model.LinearModel;
+import org.apache.solr.rest.ManagedResource;
+import org.apache.solr.rest.ManagedResourceStorage;
+import org.apache.solr.rest.RestManager;
+import org.apache.solr.search.LTRQParserPlugin;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestModelManager extends TestRerankBase {
+
+ @BeforeClass
+ public static void init() throws Exception {
+ setuptest();
+ }
+
+ @Before
+ public void restart() throws Exception {
+ restTestHarness.delete(ManagedFeatureStore.REST_END_POINT + "/*");
+ restTestHarness.delete(ManagedModelStore.REST_END_POINT + "/*");
+
+ }
+
+ @Test
+ public void test() throws Exception {
+ final SolrResourceLoader loader = new SolrResourceLoader(
+ tmpSolrHome.toPath());
+
+ final RestManager.Registry registry = loader.getManagedResourceRegistry();
+ assertNotNull(
+ "Expected a non-null RestManager.Registry from the SolrResourceLoader!",
+ registry);
+
+ final String resourceId = "/schema/fstore1";
+ registry.registerManagedResource(resourceId, ManagedFeatureStore.class,
+ new LTRQParserPlugin());
+
+ final String resourceId2 = "/schema/mstore1";
+ registry.registerManagedResource(resourceId2, ManagedModelStore.class,
+ new LTRQParserPlugin());
+
+ final NamedList<String> initArgs = new NamedList<>();
+
+ final RestManager restManager = new RestManager();
+ restManager.init(loader, initArgs,
+ new ManagedResourceStorage.InMemoryStorageIO());
+
+ final ManagedResource res = restManager.getManagedResource(resourceId);
+ assertTrue(res instanceof ManagedFeatureStore);
+ assertEquals(res.getResourceId(), resourceId);
+
+ }
+
+ @Test
+ public void testRestManagerEndpoints() throws Exception {
+ // relies on these ManagedResources being activated in the
+ // schema-rest.xml used by this test
+ assertJQ("/schema/managed", "/responseHeader/status==0");
+
+ final String valueFeatureClassName = ValueFeature.class.getCanonicalName();
+
+ // Add features
+ String feature = "{\"name\": \"test1\", \"class\": \""+valueFeatureClassName+"\", \"params\": {\"value\": 1} }";
+ assertJPut(ManagedFeatureStore.REST_END_POINT, feature,
+ "/responseHeader/status==0");
+
+ feature = "{\"name\": \"test2\", \"class\": \""+valueFeatureClassName+"\", \"params\": {\"value\": 1} }";
+ assertJPut(ManagedFeatureStore.REST_END_POINT, feature,
+ "/responseHeader/status==0");
+
+ feature = "{\"name\": \"test3\", \"class\": \""+valueFeatureClassName+"\", \"params\": {\"value\": 1} }";
+ assertJPut(ManagedFeatureStore.REST_END_POINT, feature,
+ "/responseHeader/status==0");
+
+ feature = "{\"name\": \"test33\", \"store\": \"TEST\", \"class\": \""+valueFeatureClassName+"\", \"params\": {\"value\": 1} }";
+ assertJPut(ManagedFeatureStore.REST_END_POINT, feature,
+ "/responseHeader/status==0");
+
+ final String multipleFeatures = "[{\"name\": \"test4\", \"class\": \""+valueFeatureClassName+"\", \"params\": {\"value\": 1} }"
+ + ",{\"name\": \"test5\", \"class\": \""+valueFeatureClassName+"\", \"params\": {\"value\": 1} } ]";
+ assertJPut(ManagedFeatureStore.REST_END_POINT, multipleFeatures,
+ "/responseHeader/status==0");
+
+ final String fieldValueFeatureClassName = FieldValueFeature.class.getCanonicalName();
+
+ // Add bad feature (wrong params)_
+ final String badfeature = "{\"name\": \"fvalue\", \"class\": \""+fieldValueFeatureClassName+"\", \"params\": {\"value\": 1} }";
+ assertJPut(ManagedFeatureStore.REST_END_POINT, badfeature,
+ "/error/msg/=='No setter corrresponding to \\'value\\' in "+fieldValueFeatureClassName+"'");
+
+ final String linearModelClassName = LinearModel.class.getCanonicalName();
+
+ // Add models
+ String model = "{ \"name\":\"testmodel1\", \"class\":\""+linearModelClassName+"\", \"features\":[] }";
+ // fails since it does not have features
+ assertJPut(ManagedModelStore.REST_END_POINT, model,
+ "/responseHeader/status==400");
+ // fails since it does not have weights
+ model = "{ \"name\":\"testmodel2\", \"class\":\""+linearModelClassName+"\", \"features\":[{\"name\":\"test1\"}, {\"name\":\"test2\"}] }";
+ assertJPut(ManagedModelStore.REST_END_POINT, model,
+ "/responseHeader/status==400");
+ // success
+ model = "{ \"name\":\"testmodel3\", \"class\":\""+linearModelClassName+"\", \"features\":[{\"name\":\"test1\"}, {\"name\":\"test2\"}],\"params\":{\"weights\":{\"test1\":1.5,\"test2\":2.0}}}";
+ assertJPut(ManagedModelStore.REST_END_POINT, model,
+ "/responseHeader/status==0");
+ // success
+ final String multipleModels = "[{ \"name\":\"testmodel4\", \"class\":\""+linearModelClassName+"\", \"features\":[{\"name\":\"test1\"}, {\"name\":\"test2\"}],\"params\":{\"weights\":{\"test1\":1.5,\"test2\":2.0}} }\n"
+ + ",{ \"name\":\"testmodel5\", \"class\":\""+linearModelClassName+"\", \"features\":[{\"name\":\"test1\"}, {\"name\":\"test2\"}],\"params\":{\"weights\":{\"test1\":1.5,\"test2\":2.0}} } ]";
+ assertJPut(ManagedModelStore.REST_END_POINT, multipleModels,
+ "/responseHeader/status==0");
+ final String qryResult = JQ(ManagedModelStore.REST_END_POINT);
+
+ assert (qryResult.contains("\"name\":\"testmodel3\"")
+ && qryResult.contains("\"name\":\"testmodel4\"") && qryResult
+ .contains("\"name\":\"testmodel5\""));
+ /*
+ * assertJQ(LTRParams.MSTORE_END_POINT, "/models/[0]/name=='testmodel3'");
+ * assertJQ(LTRParams.MSTORE_END_POINT, "/models/[1]/name=='testmodel4'");
+ * assertJQ(LTRParams.MSTORE_END_POINT, "/models/[2]/name=='testmodel5'");
+ */
+ assertJQ(ManagedFeatureStore.REST_END_POINT,
+ "/featureStores==['TEST','_DEFAULT_']");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/_DEFAULT_",
+ "/features/[0]/name=='test1'");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/TEST",
+ "/features/[0]/name=='test33'");
+ }
+
+ @Test
+ public void testEndpointsFromFile() throws Exception {
+ loadFeatures("features-linear.json");
+ loadModels("linear-model.json");
+
+ assertJQ(ManagedModelStore.REST_END_POINT,
+ "/models/[0]/name=='6029760550880411648'");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/_DEFAULT_",
+ "/features/[1]/name=='description'");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5a66b3bc/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManagerPersistence.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManagerPersistence.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManagerPersistence.java
new file mode 100644
index 0000000..66c26fd
--- /dev/null
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManagerPersistence.java
@@ -0,0 +1,121 @@
+/*
+ * 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.ltr.store.rest;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.solr.ltr.TestRerankBase;
+import org.apache.solr.ltr.feature.ValueFeature;
+import org.apache.solr.ltr.model.LinearModel;
+import org.junit.Before;
+import org.junit.Test;
+import org.noggit.ObjectBuilder;
+
+public class TestModelManagerPersistence extends TestRerankBase {
+
+ @Before
+ public void init() throws Exception {
+ setupPersistenttest();
+ }
+
+ // executed first
+ @Test
+ public void testFeaturePersistence() throws Exception {
+
+ loadFeature("feature", ValueFeature.class.getCanonicalName(), "test",
+ "{\"value\":2}");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test",
+ "/features/[0]/name=='feature'");
+ restTestHarness.reload();
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test",
+ "/features/[0]/name=='feature'");
+ loadFeature("feature1", ValueFeature.class.getCanonicalName(), "test1",
+ "{\"value\":2}");
+ loadFeature("feature2", ValueFeature.class.getCanonicalName(), "test",
+ "{\"value\":2}");
+ loadFeature("feature3", ValueFeature.class.getCanonicalName(), "test2",
+ "{\"value\":2}");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test",
+ "/features/[0]/name=='feature'");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test",
+ "/features/[1]/name=='feature2'");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test1",
+ "/features/[0]/name=='feature1'");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test2",
+ "/features/[0]/name=='feature3'");
+ restTestHarness.reload();
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test",
+ "/features/[0]/name=='feature'");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test",
+ "/features/[1]/name=='feature2'");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test1",
+ "/features/[0]/name=='feature1'");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test2",
+ "/features/[0]/name=='feature3'");
+ loadModel("test-model", LinearModel.class.getCanonicalName(),
+ new String[] {"feature"}, "test", "{\"weights\":{\"feature\":1.0}}");
+ loadModel("test-model2", LinearModel.class.getCanonicalName(),
+ new String[] {"feature1"}, "test1", "{\"weights\":{\"feature1\":1.0}}");
+ final String fstorecontent = FileUtils
+ .readFileToString(fstorefile, "UTF-8");
+ final String mstorecontent = FileUtils
+ .readFileToString(mstorefile, "UTF-8");
+
+ //check feature/model stores on deletion
+ final ArrayList<Object> fStore = (ArrayList<Object>) ((Map<String,Object>)
+ ObjectBuilder.fromJSON(fstorecontent)).get("managedList");
+ for (int idx = 0;idx < fStore.size(); ++ idx) {
+ String store = (String) ((Map<String,Object>)fStore.get(idx)).get("store");
+ assertTrue(store.equals("test") || store.equals("test2") || store.equals("test1"));
+ }
+
+ final ArrayList<Object> mStore = (ArrayList<Object>) ((Map<String,Object>)
+ ObjectBuilder.fromJSON(mstorecontent)).get("managedList");
+ for (int idx = 0;idx < mStore.size(); ++ idx) {
+ String store = (String) ((Map<String,Object>)mStore.get(idx)).get("store");
+ assertTrue(store.equals("test") || store.equals("test1"));
+ }
+
+ assertJDelete(ManagedFeatureStore.REST_END_POINT + "/test2",
+ "/responseHeader/status==0");
+ assertJDelete(ManagedModelStore.REST_END_POINT + "/test-model2",
+ "/responseHeader/status==0");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test2",
+ "/features/==[]");
+ assertJQ(ManagedModelStore.REST_END_POINT + "/test-model2",
+ "/models/[0]/name=='test-model'");
+ restTestHarness.reload();
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test2",
+ "/features/==[]");
+ assertJQ(ManagedModelStore.REST_END_POINT + "/test-model2",
+ "/models/[0]/name=='test-model'");
+
+ assertJDelete(ManagedModelStore.REST_END_POINT + "/*",
+ "/responseHeader/status==0");
+ assertJDelete(ManagedFeatureStore.REST_END_POINT + "/*",
+ "/responseHeader/status==0");
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test1",
+ "/features/==[]");
+ restTestHarness.reload();
+ assertJQ(ManagedFeatureStore.REST_END_POINT + "/test1",
+ "/features/==[]");
+
+ }
+
+}