View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  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  package org.apache.maven.search.backend.remoterepository.internal;
20  
21  import java.io.IOException;
22  import java.time.Instant;
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.Collection;
26  import java.util.List;
27  import java.util.concurrent.atomic.AtomicInteger;
28  
29  import org.apache.maven.search.api.MAVEN;
30  import org.apache.maven.search.api.Record;
31  import org.apache.maven.search.api.SearchRequest;
32  import org.apache.maven.search.api.request.BooleanQuery;
33  import org.apache.maven.search.api.request.FieldQuery;
34  import org.apache.maven.search.api.request.Query;
35  import org.apache.maven.search.backend.remoterepository.RemoteRepositorySearchBackend;
36  import org.apache.maven.search.backend.remoterepository.RemoteRepositorySearchBackendFactory;
37  import org.apache.maven.search.backend.remoterepository.RemoteRepositorySearchResponse;
38  import org.junit.Test;
39  import org.junit.runner.RunWith;
40  import org.junit.runners.Parameterized;
41  
42  import static org.hamcrest.MatcherAssert.assertThat;
43  import static org.hamcrest.Matchers.equalTo;
44  import static org.hamcrest.Matchers.greaterThan;
45  import static org.hamcrest.Matchers.notNullValue;
46  
47  /**
48   * UT for 2 backends: Maven Central and RAO releases. This tests make use of the fact that RAO is used as "staging"
49   * area for Maven Central, hence RAO releases contains everything that was staged and synced to Maven Central.
50   */
51  @RunWith(Parameterized.class)
52  public class RemoteRepositorySearchBackendImplTest {
53  
54      @Parameterized.Parameters
55      public static Collection<Object> data() {
56          return Arrays.asList(
57                  RemoteRepositorySearchBackendFactory.createDefaultMavenCentral(),
58                  RemoteRepositorySearchBackendFactory.createDefaultRAOReleases());
59      }
60  
61      private final RemoteRepositorySearchBackend backend;
62  
63      public RemoteRepositorySearchBackendImplTest(RemoteRepositorySearchBackend backend) {
64          this.backend = backend;
65      }
66  
67      private void dumpSingle(AtomicInteger counter, List<Record> page) {
68          for (Record record : page) {
69              StringBuilder sb = new StringBuilder();
70              sb.append(record.getValue(MAVEN.GROUP_ID)).append(":").append(record.getValue(MAVEN.ARTIFACT_ID));
71              if (record.hasField(MAVEN.VERSION)) {
72                  sb.append(":").append(record.getValue(MAVEN.VERSION));
73              }
74              if (record.hasField(MAVEN.CLASSIFIER)) {
75                  sb.append(":").append(record.getValue(MAVEN.CLASSIFIER));
76              }
77              if (record.hasField(MAVEN.FILE_EXTENSION)) {
78                  sb.append(":").append(record.getValue(MAVEN.FILE_EXTENSION));
79              }
80  
81              List<String> remarks = new ArrayList<>();
82              if (record.getLastUpdated() != null) {
83                  remarks.add("lastUpdate=" + Instant.ofEpochMilli(record.getLastUpdated()));
84              }
85              if (record.hasField(MAVEN.VERSION_COUNT)) {
86                  remarks.add("versionCount=" + record.getValue(MAVEN.VERSION_COUNT));
87              }
88              if (record.hasField(MAVEN.HAS_SOURCE)) {
89                  remarks.add("hasSource=" + record.getValue(MAVEN.HAS_SOURCE));
90              }
91              if (record.hasField(MAVEN.HAS_JAVADOC)) {
92                  remarks.add("hasJavadoc=" + record.getValue(MAVEN.HAS_JAVADOC));
93              }
94  
95              System.out.print(counter.incrementAndGet() + ". " + sb);
96              if (!remarks.isEmpty()) {
97                  System.out.print(" " + remarks);
98              }
99              System.out.println();
100         }
101     }
102 
103     private void dumpPage(RemoteRepositorySearchResponse searchResponse) throws IOException {
104         AtomicInteger counter = new AtomicInteger(0);
105         System.out.println(
106                 "QUERY: " + searchResponse.getSearchRequest().getQuery().toString());
107         System.out.println("URL: " + searchResponse.getUri());
108         dumpSingle(counter, searchResponse.getPage());
109         while (searchResponse.getTotalHits() > searchResponse.getCurrentHits()) {
110             System.out.println("NEXT PAGE (size "
111                     + searchResponse.getSearchRequest().getPaging().getPageSize() + ")");
112             searchResponse = backend.search(searchResponse.getSearchRequest().nextPage());
113             dumpSingle(counter, searchResponse.getPage());
114             if (counter.get() > 50) {
115                 System.out.println("ABORTED TO NOT SPAM");
116                 break; // do not spam the SMO service
117             }
118         }
119         System.out.println();
120     }
121 
122     @Test(expected = IllegalArgumentException.class)
123     public void smoke() throws IOException {
124         SearchRequest searchRequest = new SearchRequest(Query.query("smoke"));
125         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
126         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
127         dumpPage(searchResponse);
128     }
129 
130     @Test
131     public void notFound404Response() throws IOException {
132         // LIST GAs
133         SearchRequest searchRequest =
134                 new SearchRequest(FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.cstamas.no-such-thing"));
135         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
136         assertThat(searchResponse.getTotalHits(), equalTo(0));
137         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
138     }
139 
140     @Test
141     public void g() throws IOException {
142         // LIST GAs
143         SearchRequest searchRequest =
144                 new SearchRequest(FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven.plugins"));
145         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
146         assertThat(searchResponse.getTotalHits(), greaterThan(0));
147         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
148         dumpPage(searchResponse);
149     }
150 
151     @Test
152     public void ga() throws IOException {
153         // LIST GAVs
154         SearchRequest searchRequest = new SearchRequest(BooleanQuery.and(
155                 FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven.plugins"),
156                 FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "maven-clean-plugin")));
157         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
158         assertThat(searchResponse.getTotalHits(), greaterThan(0));
159         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
160         dumpPage(searchResponse);
161     }
162 
163     @Test
164     public void gav() throws IOException {
165         // LIST GAVCEs
166         SearchRequest searchRequest = new SearchRequest(BooleanQuery.and(
167                 FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven.plugins"),
168                 FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "maven-clean-plugin"),
169                 FieldQuery.fieldQuery(MAVEN.VERSION, "3.1.0")));
170         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
171         assertThat(searchResponse.getTotalHits(), equalTo(5));
172         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
173         dumpPage(searchResponse);
174     }
175 
176     @Test
177     public void gave() throws IOException {
178         // LIST GAVCEs
179         SearchRequest searchRequest = new SearchRequest(BooleanQuery.and(
180                 FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven.plugins"),
181                 FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "maven-clean-plugin"),
182                 FieldQuery.fieldQuery(MAVEN.VERSION, "3.1.0"),
183                 FieldQuery.fieldQuery(MAVEN.FILE_EXTENSION, "jar")));
184         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
185         assertThat(searchResponse.getTotalHits(), equalTo(1));
186         assertThat(searchResponse.getPage().get(0).getLastUpdated(), notNullValue());
187         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
188         dumpPage(searchResponse);
189     }
190 
191     @Test
192     public void gavWithTarGz() throws IOException {
193         // LIST GAVCEs
194         SearchRequest searchRequest = new SearchRequest(BooleanQuery.and(
195                 FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven"),
196                 FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "apache-maven"),
197                 FieldQuery.fieldQuery(MAVEN.VERSION, "3.9.3")));
198         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
199         assertThat(searchResponse.getTotalHits(), equalTo(8));
200         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
201         dumpPage(searchResponse);
202     }
203 
204     @Test
205     public void gavce() throws IOException {
206         // EXISTENCE check: total hits != 0 => exists, total hits == 0 => not exists
207         SearchRequest searchRequest = new SearchRequest(BooleanQuery.and(
208                 FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven.plugins"),
209                 FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "maven-clean-plugin"),
210                 FieldQuery.fieldQuery(MAVEN.VERSION, "3.1.0"),
211                 FieldQuery.fieldQuery(MAVEN.FILE_EXTENSION, "jar")));
212         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
213         assertThat(searchResponse.getTotalHits(), equalTo(1));
214         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
215         dumpPage(searchResponse);
216     }
217 
218     @Test
219     public void gavcesha1RightChecksum() throws IOException {
220         // validity check: total hits != 0 => valid, total hits == 0 => invalid
221         SearchRequest searchRequest = new SearchRequest(BooleanQuery.and(
222                 FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven.plugins"),
223                 FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "maven-clean-plugin"),
224                 FieldQuery.fieldQuery(MAVEN.VERSION, "3.1.0"),
225                 FieldQuery.fieldQuery(MAVEN.FILE_EXTENSION, "jar"),
226                 FieldQuery.fieldQuery(MAVEN.SHA1, "2e030994e207ee572491927b198b139424133b2e")));
227         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
228         assertThat(searchResponse.getTotalHits(), equalTo(1));
229         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
230         dumpPage(searchResponse);
231     }
232 
233     @Test
234     public void gavcesha1WrongChecksum() throws IOException {
235         // validity check: total hits != 0 => valid, total hits == 0 => invalid
236         SearchRequest searchRequest = new SearchRequest(BooleanQuery.and(
237                 FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven.plugins"),
238                 FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "maven-clean-plugin"),
239                 FieldQuery.fieldQuery(MAVEN.VERSION, "3.1.0"),
240                 FieldQuery.fieldQuery(MAVEN.FILE_EXTENSION, "jar"),
241                 FieldQuery.fieldQuery(MAVEN.SHA1, "wrong")));
242         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
243         assertThat(searchResponse.getTotalHits(), equalTo(0));
244         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
245         dumpPage(searchResponse);
246     }
247 
248     @Test
249     public void gavcesha1WClassifierRightChecksum() throws IOException {
250         // validity check: total hits != 0 => valid, total hits == 0 => invalid
251         SearchRequest searchRequest = new SearchRequest(BooleanQuery.and(
252                 FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven"),
253                 FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "apache-maven"),
254                 FieldQuery.fieldQuery(MAVEN.VERSION, "3.9.3"),
255                 FieldQuery.fieldQuery(MAVEN.CLASSIFIER, "bin"),
256                 FieldQuery.fieldQuery(MAVEN.FILE_EXTENSION, "tar.gz"),
257                 FieldQuery.fieldQuery(MAVEN.SHA1, "f700d2bf6a11803c29a3240a26e91b2d1c530f79")));
258         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
259         assertThat(searchResponse.getTotalHits(), equalTo(1));
260         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
261         dumpPage(searchResponse);
262     }
263 
264     @Test
265     public void gavcesha1WClassifierWrongChecksum() throws IOException {
266         // validity check: total hits != 0 => valid, total hits == 0 => invalid
267         SearchRequest searchRequest = new SearchRequest(BooleanQuery.and(
268                 FieldQuery.fieldQuery(MAVEN.GROUP_ID, "org.apache.maven"),
269                 FieldQuery.fieldQuery(MAVEN.ARTIFACT_ID, "apache-maven"),
270                 FieldQuery.fieldQuery(MAVEN.VERSION, "3.9.3"),
271                 FieldQuery.fieldQuery(MAVEN.CLASSIFIER, "bin"),
272                 FieldQuery.fieldQuery(MAVEN.FILE_EXTENSION, "tar.gz"),
273                 FieldQuery.fieldQuery(MAVEN.SHA1, "wrong")));
274         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
275         assertThat(searchResponse.getTotalHits(), equalTo(0));
276         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
277         dumpPage(searchResponse);
278     }
279 
280     @Test(expected = IllegalArgumentException.class)
281     public void sha1() throws IOException {
282         SearchRequest searchRequest =
283                 new SearchRequest(FieldQuery.fieldQuery(MAVEN.SHA1, "8ac9e16d933b6fb43bc7f576336b8f4d7eb5ba12"));
284         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
285         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
286         dumpPage(searchResponse);
287     }
288 
289     @Test(expected = IllegalArgumentException.class)
290     public void cn() throws IOException {
291         SearchRequest searchRequest =
292                 new SearchRequest(FieldQuery.fieldQuery(MAVEN.CLASS_NAME, "MavenRepositorySystem"));
293         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
294         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
295         dumpPage(searchResponse);
296     }
297 
298     @Test(expected = IllegalArgumentException.class)
299     public void fqcn() throws IOException {
300         SearchRequest searchRequest = new SearchRequest(
301                 FieldQuery.fieldQuery(MAVEN.FQ_CLASS_NAME, "org.apache.maven.bridge.MavenRepositorySystem"));
302         RemoteRepositorySearchResponse searchResponse = backend.search(searchRequest);
303         System.out.println("TOTAL HITS: " + searchResponse.getTotalHits());
304         dumpPage(searchResponse);
305     }
306 }