/* * 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.search; import org.apache.lucene.util.TestUtil; import org.apache.solr.schema.SchemaField; import org.apache.solr.schema.TrieIntField; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.SolrTestCaseJ4; import org.junit.BeforeClass; public class TestTrieFacet extends SolrTestCaseJ4 { final static int MIN_VALUE = 20; final static int MAX_VALUE = 60; final static String TRIE_INT_P8_S_VALUED = "foo_ti1"; final static String TRIE_INT_P8_M_VALUED = "foo_ti"; final static String TRIE_INT_P0_S_VALUED = "foo_i1"; final static String TRIE_INT_P0_M_VALUED = "foo_i"; final static String[] M_VALUED = new String[] { TRIE_INT_P0_M_VALUED, TRIE_INT_P8_M_VALUED }; final static String[] S_VALUED = new String[] { TRIE_INT_P0_S_VALUED, TRIE_INT_P8_S_VALUED }; final static String[] P0 = new String[] { TRIE_INT_P0_M_VALUED, TRIE_INT_P0_S_VALUED }; final static String[] P8 = new String[] { TRIE_INT_P8_M_VALUED, TRIE_INT_P8_S_VALUED }; static int NUM_DOCS; private static TrieIntField assertCastFieldType(SchemaField f) { assertTrue("who changed the schema? test isn't valid: " + f.getName(), f.getType() instanceof TrieIntField); return (TrieIntField) f.getType(); } @BeforeClass public static void beforeClass() throws Exception { initCore("solrconfig-tlog.xml","schema.xml"); // don't break the test assertTrue("min value must be less then max value", MIN_VALUE < MAX_VALUE); assertTrue("min value must be greater then zero", 0 < MIN_VALUE); // sanity check no one breaks the schema out from under us... for (String f : M_VALUED) { SchemaField sf = h.getCore().getLatestSchema().getField(f); assertTrue("who changed the schema? test isn't valid: " + f, sf.multiValued()); } for (String f : S_VALUED) { SchemaField sf = h.getCore().getLatestSchema().getField(f); assertFalse("who changed the schema? test isn't valid: " + f, sf.multiValued()); } for (String f : P0) { SchemaField sf = h.getCore().getLatestSchema().getField(f); assertEquals("who changed the schema? test isn't valid: " + f, 0, assertCastFieldType(sf).getPrecisionStep()); } for (String f : P8) { SchemaField sf = h.getCore().getLatestSchema().getField(f); assertEquals("who changed the schema? test isn't valid: " + f, 8, assertCastFieldType(sf).getPrecisionStep()); } // we don't need a lot of docs -- at least one failure only had ~1000 NUM_DOCS = TestUtil.nextInt(random(), 200, 1500); { // ensure at least one doc has every valid value in the multivalued fields SolrInputDocument doc = sdoc("id", "0"); for (int val = MIN_VALUE; val <= MAX_VALUE; val++) { for (String f : M_VALUED) { doc.addField(f, val); } } assertU(adoc(doc)); } // randomized docs (note: starting at i=1) for (int i=1; i < NUM_DOCS; i++) { SolrInputDocument doc = sdoc("id", i+""); if (useField()) { int val = TestUtil.nextInt(random(), MIN_VALUE, MAX_VALUE); for (String f : S_VALUED) { doc.addField(f, val); } } if (useField()) { int numMulti = atLeast(1); while (0 < numMulti--) { int val = TestUtil.nextInt(random(), MIN_VALUE, MAX_VALUE); for (String f: M_VALUED) { doc.addField(f, val); } } } assertU(adoc(doc)); } assertU(commit()); } /** * Similar to usually() but we want it to happen just as often regardless * of test multiplier and nightly status */ private static boolean useField() { return 0 != TestUtil.nextInt(random(), 0, 9); } private static void doTestNoZeros(final String field, final String method) throws Exception { assertQ("sanity check # docs in index: " + NUM_DOCS, req("q", "*:*", "rows", "0") ,"//result[@numFound="+NUM_DOCS+"]"); assertQ("sanity check that no docs match 0 failed", req("q", field+":0", "rows", "0") ,"//result[@numFound=0]"); assertQ("sanity check that no docs match [0 TO 0] failed", req("q", field+":[0 TO 0]", "rows", "0") ,"//result[@numFound=0]"); assertQ("*:* facet with mincount 0 found unexpected 0 value", req("q", "*:*" ,"rows", "0" ,"indent","true" ,"facet", "true" ,"facet.field", field ,"facet.limit", "-1" ,"facet.mincount", "0" ,"facet.method", method ) // trivial sanity check we're at least getting facet counts in output ,"*[count(//lst[@name='facet_fields']/lst[@name='"+field+"']/int)!=0]" // main point of test ,"*[count(//lst[@name='facet_fields']/lst[@name='"+field+"']/int[@name='0'])=0]" ); } // enum public void testSingleValuedTrieP0_enum() throws Exception { doTestNoZeros(TRIE_INT_P0_S_VALUED, "enum"); } public void testMultiValuedTrieP0_enum() throws Exception { doTestNoZeros(TRIE_INT_P0_M_VALUED, "enum"); } public void testSingleValuedTrieP8_enum() throws Exception { doTestNoZeros(TRIE_INT_P8_S_VALUED, "enum"); } public void testMultiValuedTrieP8_enum() throws Exception { doTestNoZeros(TRIE_INT_P8_M_VALUED, "enum"); } // fc public void testSingleValuedTrieP0_fc() throws Exception { doTestNoZeros(TRIE_INT_P0_S_VALUED, "fc"); } public void testMultiValuedTrieP0_fc() throws Exception { doTestNoZeros(TRIE_INT_P0_M_VALUED, "fc"); } public void testSingleValuedTrieP8_fc() throws Exception { doTestNoZeros(TRIE_INT_P8_S_VALUED, "fc"); } public void testMultiValuedTrieP8_fc() throws Exception { doTestNoZeros(TRIE_INT_P8_M_VALUED, "fc"); } // fcs public void testSingleValuedTrieP0_fcs() throws Exception { doTestNoZeros(TRIE_INT_P0_S_VALUED, "fcs"); } public void testMultiValuedTrieP0_fcs() throws Exception { doTestNoZeros(TRIE_INT_P0_M_VALUED, "fcs"); } public void testSingleValuedTrieP8_fcs() throws Exception { doTestNoZeros(TRIE_INT_P8_S_VALUED, "fcs"); } public void testMultiValuedTrieP8_fcs() throws Exception { doTestNoZeros(TRIE_INT_P8_M_VALUED, "fcs"); } }