1+ /*
2+ * Licensed to Elasticsearch under one or more contributor
3+ * license agreements. See the NOTICE file distributed with
4+ * this work for additional information regarding copyright
5+ * ownership. Elasticsearch licenses this file to you under
6+ * the Apache License, Version 2.0 (the "License"); you may
7+ * not use this file except in compliance with the License.
8+ * You may obtain a copy of the License at
9+ *
10+ * http://www.apache.org/licenses/LICENSE-2.0
11+ *
12+ * Unless required by applicable law or agreed to in writing,
13+ * software distributed under the License is distributed on an
14+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+ * KIND, either express or implied. See the License for the
16+ * specific language governing permissions and limitations
17+ * under the License.
18+ */
19+
20+ package org .elasticsearch .index .query ;
21+
22+ import org .apache .lucene .search .Query ;
23+ import org .elasticsearch .Version ;
24+ import org .elasticsearch .cluster .ClusterService ;
25+ import org .elasticsearch .cluster .metadata .IndexMetaData ;
26+ import org .elasticsearch .common .inject .AbstractModule ;
27+ import org .elasticsearch .common .inject .Injector ;
28+ import org .elasticsearch .common .inject .ModulesBuilder ;
29+ import org .elasticsearch .common .inject .util .Providers ;
30+ import org .elasticsearch .common .io .stream .BytesStreamInput ;
31+ import org .elasticsearch .common .io .stream .BytesStreamOutput ;
32+ import org .elasticsearch .common .io .stream .Streamable ;
33+ import org .elasticsearch .common .settings .ImmutableSettings ;
34+ import org .elasticsearch .common .settings .Settings ;
35+ import org .elasticsearch .common .settings .SettingsModule ;
36+ import org .elasticsearch .common .xcontent .XContentFactory ;
37+ import org .elasticsearch .env .Environment ;
38+ import org .elasticsearch .env .EnvironmentModule ;
39+ import org .elasticsearch .index .Index ;
40+ import org .elasticsearch .index .IndexNameModule ;
41+ import org .elasticsearch .index .analysis .AnalysisModule ;
42+ import org .elasticsearch .index .cache .IndexCacheModule ;
43+ import org .elasticsearch .index .query .functionscore .FunctionScoreModule ;
44+ import org .elasticsearch .index .settings .IndexSettingsModule ;
45+ import org .elasticsearch .index .similarity .SimilarityModule ;
46+ import org .elasticsearch .indices .breaker .CircuitBreakerService ;
47+ import org .elasticsearch .indices .breaker .NoneCircuitBreakerService ;
48+ import org .elasticsearch .indices .query .IndicesQueriesModule ;
49+ import org .elasticsearch .script .ScriptModule ;
50+ import org .elasticsearch .test .ElasticsearchTestCase ;
51+ import org .elasticsearch .threadpool .ThreadPool ;
52+ import org .elasticsearch .threadpool .ThreadPoolModule ;
53+ import org .junit .AfterClass ;
54+ import org .junit .BeforeClass ;
55+ import org .junit .Ignore ;
56+ import org .junit .Test ;
57+
58+ import java .io .IOException ;
59+
60+ @ Ignore
61+ public abstract class BaseQueryTestCase <QB extends BaseQueryBuilder & Streamable > extends ElasticsearchTestCase {
62+
63+ private static Injector injector ;
64+ private static IndexQueryParserService queryParserService ;
65+ private static Index index ;
66+
67+ protected QB testQuery = createTestQueryBuilder ();
68+
69+ /**
70+ * Setup for the whole base test class.
71+ */
72+ @ BeforeClass
73+ public static void init () throws IOException {
74+ Settings settings = ImmutableSettings .settingsBuilder ()
75+ .put ("name" , BaseQueryTestCase .class .toString ())
76+ .put (IndexMetaData .SETTING_VERSION_CREATED , Version .CURRENT )
77+ .build ();
78+
79+ index = new Index ("test" );
80+ injector = new ModulesBuilder ().add (
81+ new EnvironmentModule (new Environment (settings )),
82+ new SettingsModule (settings ),
83+ new ThreadPoolModule (settings ),
84+ new IndicesQueriesModule (),
85+ new ScriptModule (settings ),
86+ new IndexSettingsModule (index , settings ),
87+ new IndexCacheModule (settings ),
88+ new AnalysisModule (settings ),
89+ new SimilarityModule (settings ),
90+ new IndexNameModule (index ),
91+ new IndexQueryParserModule (settings ),
92+ new FunctionScoreModule (),
93+ new AbstractModule () {
94+ @ Override
95+ protected void configure () {
96+ bind (ClusterService .class ).toProvider (Providers .of ((ClusterService ) null ));
97+ bind (CircuitBreakerService .class ).to (NoneCircuitBreakerService .class );
98+ }
99+ }
100+ ).createInjector ();
101+ queryParserService = injector .getInstance (IndexQueryParserService .class );
102+ }
103+
104+ @ AfterClass
105+ public static void after () throws Exception {
106+ terminate (injector .getInstance (ThreadPool .class ));
107+ injector = null ;
108+ index = null ;
109+ queryParserService = null ;
110+ }
111+
112+ /**
113+ * Create the query that is being tested
114+ */
115+ protected abstract QB createTestQueryBuilder ();
116+
117+ /**
118+ * Subclass should handle assertions on the lucene query produced by the query builder under test here
119+ */
120+ protected abstract void assertLuceneQuery (QB queryBuilder , Query query ) throws IOException ;
121+
122+ /**
123+ * Creates an empty builder of the type of query under test
124+ */
125+ protected abstract QB createEmptyQueryBuilder ();
126+
127+ /**
128+ * Generic test that creates new query from the test query and checks both for equality
129+ * and asserts equality on the two queries.
130+ */
131+ @ Test
132+ public void testFromXContent () throws IOException {
133+ QueryParseContext context = new QueryParseContext (index , queryParserService );
134+ String contentString = testQuery .toString ();
135+ context .reset (XContentFactory .xContent (contentString ).createParser (contentString ));
136+
137+ QueryBuilder newQuery = queryParserService .queryParser (testQuery .parserName ()).fromXContent (context );
138+ assertNotSame (newQuery , testQuery );
139+ assertEquals (newQuery , testQuery );
140+ }
141+
142+ /**
143+ * Test creates the {@link Query} from the {@link QueryBuilder} under test and delegates the
144+ * assertions being made on the result to the implementing subclass.
145+ */
146+ @ Test
147+ public void testToQuery () throws IOException {
148+ QueryParseContext context = new QueryParseContext (index , queryParserService );
149+ assertLuceneQuery (this .testQuery , this .testQuery .toQuery (context ));
150+ }
151+
152+ /**
153+ * Test serialization and deserialization of the test query.
154+ * @throws IOException
155+ */
156+ @ Test
157+ public void testSerialization () throws IOException {
158+ BytesStreamOutput output = new BytesStreamOutput ();
159+ testQuery .writeTo (output );
160+
161+ BytesStreamInput in = new BytesStreamInput (output .bytes ());
162+ QB deserializedQuery = createEmptyQueryBuilder ();
163+ deserializedQuery .readFrom (in );
164+
165+ assertEquals (deserializedQuery , testQuery );
166+ assertNotSame (deserializedQuery , testQuery );
167+ }
168+ }
0 commit comments