1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.index.updater;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.text.SimpleDateFormat;
29 import java.util.Collection;
30 import java.util.Date;
31 import java.util.Properties;
32 import java.util.Set;
33
34 import org.apache.lucene.index.Term;
35 import org.apache.lucene.search.Query;
36 import org.apache.lucene.search.TermQuery;
37 import org.apache.lucene.store.ByteBuffersDirectory;
38 import org.apache.lucene.store.Directory;
39 import org.apache.lucene.store.IOContext;
40 import org.apache.maven.index.ArtifactInfo;
41 import org.apache.maven.index.FlatSearchRequest;
42 import org.apache.maven.index.FlatSearchResponse;
43 import org.apache.maven.index.MAVEN;
44 import org.apache.maven.index.SearchType;
45 import org.apache.maven.index.context.DocumentFilter;
46 import org.apache.maven.index.context.IndexUtils;
47 import org.apache.maven.index.context.IndexingContext;
48 import org.jmock.Expectations;
49 import org.jmock.Mockery;
50 import org.jmock.api.Invocation;
51 import org.jmock.lib.action.ReturnValueAction;
52 import org.jmock.lib.action.VoidAction;
53 import org.junit.Ignore;
54 import org.junit.Test;
55
56 import static org.junit.Assert.assertEquals;
57 import static org.junit.Assert.assertFalse;
58 import static org.junit.Assert.assertTrue;
59
60
61
62
63 public class DefaultIndexUpdaterTest extends AbstractIndexUpdaterTest {
64
65 SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
66
67 @Test
68 public void testReplaceIndex() throws Exception {
69 indexer.addArtifactToIndex(
70 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.2", null), context);
71
72 Query q = indexer.constructQuery(MAVEN.ARTIFACT_ID, "commons-lang", SearchType.SCORED);
73
74 FlatSearchResponse response1 = indexer.searchFlat(new FlatSearchRequest(q));
75 Collection<ArtifactInfo> content1 = response1.getResults();
76
77 assertEquals(content1.toString(), 1, content1.size());
78
79
80
81 Directory tempIndexDirectory = new ByteBuffersDirectory();
82
83 IndexingContext tempContext = indexer.addIndexingContext(
84 repositoryId + "temp", repositoryId, null, tempIndexDirectory, repositoryUrl, null, MIN_CREATORS);
85
86 indexer.addArtifactToIndex(
87 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.3", null), tempContext);
88
89 indexer.addArtifactToIndex(
90 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.4", null), tempContext);
91
92 FlatSearchResponse response2 = indexer.searchFlat(new FlatSearchRequest(q, tempContext));
93 Collection<ArtifactInfo> tempContent = response2.getResults();
94 assertEquals(tempContent.toString(), 2, tempContent.size());
95
96
97 tempContext.updateTimestamp(true);
98
99
100
101 ByteBuffersDirectory tempDir2 = new ByteBuffersDirectory();
102 IndexUtils.copyDirectory(tempContext.getIndexDirectory(), tempDir2);
103
104 Date newIndexTimestamp = tempContext.getTimestamp();
105
106 indexer.removeIndexingContext(tempContext, false);
107
108 context.replace(tempDir2);
109
110 assertEquals(newIndexTimestamp, context.getTimestamp());
111
112 FlatSearchResponse response3 = indexer.searchFlat(new FlatSearchRequest(q));
113 Collection<ArtifactInfo> content2 = response3.getResults();
114 assertEquals(content2.toString(), 2, content2.size());
115 }
116
117 @Test
118 public void testMergeIndex() throws Exception {
119 indexer.addArtifactToIndex(
120 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.2", null), context);
121
122 Query q = indexer.constructQuery(MAVEN.ARTIFACT_ID, "commons-lang", SearchType.SCORED);
123
124 {
125 FlatSearchResponse response1 = indexer.searchFlat(new FlatSearchRequest(q));
126 Collection<ArtifactInfo> content1 = response1.getResults();
127
128 assertEquals(content1.toString(), 1, content1.size());
129 }
130
131
132
133 {
134 Directory tempIndexDirectory = new ByteBuffersDirectory();
135
136 IndexingContext tempContext = indexer.addIndexingContext(
137 repositoryId + "temp", repositoryId, null, tempIndexDirectory, repositoryUrl, null, MIN_CREATORS);
138
139
140
141
142
143 indexer.addArtifactToIndex(
144 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.3", null), tempContext);
145
146 indexer.addArtifactToIndex(
147 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.4", null), tempContext);
148
149 FlatSearchResponse tempResponse = indexer.searchFlat(new FlatSearchRequest(q));
150 Collection<ArtifactInfo> tempContent = tempResponse.getResults();
151 assertEquals(tempContent.toString(), 3, tempContent.size());
152
153 ByteBuffersDirectory tempDir2 = new ByteBuffersDirectory();
154 for (String file : tempContext.getIndexDirectory().listAll()) {
155 tempDir2.copyFrom(tempContext.getIndexDirectory(), file, file, IOContext.DEFAULT);
156 }
157
158 indexer.removeIndexingContext(tempContext, false);
159
160 context.merge(tempDir2);
161
162 FlatSearchResponse response2 = indexer.searchFlat(new FlatSearchRequest(q));
163 Collection<ArtifactInfo> content2 = response2.getResults();
164 assertEquals(content2.toString(), 3, content2.size());
165 }
166 }
167
168 @Test
169 public void testMergeIndexDeletes() throws Exception {
170 indexer.addArtifactToIndex(
171 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.2", null), context);
172
173 indexer.addArtifactToIndex(
174 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.3", null), context);
175
176 indexer.addArtifactToIndex(
177 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.4", null), context);
178
179 {
180 Directory tempIndexDirectory = new ByteBuffersDirectory();
181
182 IndexingContext tempContext = indexer.addIndexingContext(
183 repositoryId + "temp", repositoryId, null, tempIndexDirectory, repositoryUrl, null, MIN_CREATORS);
184
185 indexer.addArtifactToIndex(
186 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.4", null), tempContext);
187
188 indexer.addArtifactToIndex(
189 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.2", null), tempContext);
190
191 indexer.deleteArtifactFromIndex(
192 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.2", null), tempContext);
193
194 indexer.deleteArtifactFromIndex(
195 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.4", null), tempContext);
196
197 ByteBuffersDirectory tempDir2 = new ByteBuffersDirectory();
198 for (String file : tempContext.getIndexDirectory().listAll()) {
199 tempDir2.copyFrom(tempContext.getIndexDirectory(), file, file, IOContext.DEFAULT);
200 }
201
202 indexer.removeIndexingContext(tempContext, false);
203
204 context.merge(tempDir2);
205 }
206
207 Query q = indexer.constructQuery(MAVEN.ARTIFACT_ID, "commons-lang", SearchType.SCORED);
208
209 FlatSearchResponse response = indexer.searchFlat(new FlatSearchRequest(q));
210 Collection<ArtifactInfo> content2 = response.getResults();
211
212 assertEquals(content2.toString(), 1, content2.size());
213 }
214
215 @Test
216 public void testMergeSearch() throws Exception {
217 File repo1 = new File(getBasedir(), "src/test/nexus-658");
218 Directory indexDir1 = new ByteBuffersDirectory();
219
220 IndexingContext context1 =
221 indexer.addIndexingContext("nexus-658", "nexus-658", repo1, indexDir1, null, null, DEFAULT_CREATORS);
222 indexer.scan(context1);
223
224 File repo2 = new File(getBasedir(), "src/test/nexus-13");
225 Directory indexDir2 = new ByteBuffersDirectory();
226
227 IndexingContext context2 =
228 indexer.addIndexingContext("nexus-13", "nexus-13", repo2, indexDir2, null, null, DEFAULT_CREATORS);
229 indexer.scan(context2);
230
231 context1.merge(indexDir2);
232
233 Query q = new TermQuery(new Term(ArtifactInfo.SHA1, "b5e9d009320d11b9859c15d3ad3603b455fa1c85"));
234 FlatSearchRequest request = new FlatSearchRequest(q, context1);
235 FlatSearchResponse response = indexer.searchFlat(request);
236
237 Set<ArtifactInfo> results = response.getResults();
238 ArtifactInfo artifactInfo = results.iterator().next();
239 assertEquals(artifactInfo.getArtifactId(), "dma.integration.tests");
240 }
241
242 @Test
243 public void testMergeGroups() throws Exception {
244 indexer.addArtifactToIndex(
245 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.2", null), context);
246
247 indexer.addArtifactToIndex(
248 createArtifactContext(repositoryId, "commons-collections", "commons-collections", "1.0", null),
249 context);
250
251 indexer.addArtifactToIndex(
252 createArtifactContext(repositoryId, "org.slf4j", "slf4j-api", "1.4.2", null), context);
253
254 indexer.addArtifactToIndex(
255 createArtifactContext(repositoryId, "org.slf4j", "slf4j-log4j12", "1.4.2", null), context);
256
257 {
258 Directory tempIndexDirectory = new ByteBuffersDirectory();
259
260 IndexingContext tempContext = indexer.addIndexingContext(
261 repositoryId + "temp", repositoryId, null, tempIndexDirectory, repositoryUrl, null, MIN_CREATORS);
262
263 indexer.addArtifactToIndex(
264 createArtifactContext(repositoryId, "commons-lang", "commons-lang", "2.4", null), tempContext);
265
266 indexer.addArtifactToIndex(createArtifactContext(repositoryId, "junit", "junit", "3.8", null), tempContext);
267
268 indexer.addArtifactToIndex(
269 createArtifactContext(repositoryId, "org.slf4j.foo", "jcl104-over-slf4j", "1.4.2", null), context);
270
271 ByteBuffersDirectory tempDir2 = new ByteBuffersDirectory();
272 for (String file : tempContext.getIndexDirectory().listAll()) {
273 tempDir2.copyFrom(tempContext.getIndexDirectory(), file, file, IOContext.DEFAULT);
274 }
275
276 indexer.removeIndexingContext(tempContext, false);
277
278 context.merge(tempDir2);
279 }
280
281 Set<String> rootGroups = context.getRootGroups();
282
283 assertEquals(rootGroups.toString(), 4, rootGroups.size());
284
285 Set<String> allGroups = context.getAllGroups();
286
287 assertEquals(allGroups.toString(), 5, allGroups.size());
288 }
289
290 @Test
291 public void testNoIndexUpdate() throws Exception {
292 Mockery mockery = new Mockery();
293
294 final String indexUrl = repositoryUrl + ".index";
295 final Date contextTimestamp = df.parse("20081125010000.000 -0600");
296
297 final ResourceFetcher mockFetcher = mockery.mock(ResourceFetcher.class);
298
299 final IndexingContext tempContext = mockery.mock(IndexingContext.class);
300
301 final Properties localProps = new Properties();
302 localProps.setProperty(IndexingContext.INDEX_CHUNK_COUNTER, "1");
303 localProps.setProperty(IndexingContext.INDEX_CHAIN_ID, "someid");
304 localProps.setProperty(IndexingContext.INDEX_TIMESTAMP, "20081125010000.000 -0600");
305
306 mockery.checking(new Expectations() {
307 {
308 allowing(tempContext).getIndexDirectoryFile();
309 will(new IndexDirectoryFileAction(localProps, testBasedir));
310
311 allowing(tempContext).getTimestamp();
312 will(returnValue(contextTimestamp));
313
314 allowing(tempContext).getId();
315 will(returnValue(repositoryId));
316
317 allowing(tempContext).commit();
318
319 allowing(tempContext).getIndexUpdateUrl();
320 will(returnValue(indexUrl));
321
322 allowing(tempContext).getIndexCreators();
323 will(returnValue(DEFAULT_CREATORS));
324
325 oneOf(mockFetcher).connect(repositoryId, indexUrl);
326
327 oneOf(mockFetcher)
328 .retrieve(
329 with(IndexingContext.INDEX_REMOTE_PROPERTIES_FILE));
330 will(new PropertiesAction() {
331 @Override
332 Properties getProperties() {
333 Properties properties = new Properties();
334 properties.setProperty(IndexingContext.INDEX_ID, "central");
335 properties.setProperty(IndexingContext.INDEX_TIMESTAMP, "20081125010000.000 -0600");
336 return properties;
337 }
338 });
339
340 allowing(tempContext).getIndexDirectoryFile();
341
342 oneOf(mockFetcher).disconnect();
343 }
344 });
345
346
347
348 IndexUpdateRequest updateRequest = new IndexUpdateRequest(tempContext, mockFetcher);
349
350 IndexUpdateResult updateResult = updater.fetchAndUpdateIndex(updateRequest);
351
352 mockery.assertIsSatisfied();
353 assertIndexUpdateSucceeded(updateResult);
354 }
355
356 @Test
357 public void testFullIndexUpdate() throws Exception {
358 Mockery mockery = new Mockery();
359
360 final String indexUrl = repositoryUrl + ".index";
361 final Date contextTimestamp = df.parse("20081125010000.000 -0600");
362
363 final ResourceFetcher mockFetcher = mockery.mock(ResourceFetcher.class);
364
365 final IndexingContext tempContext = mockery.mock(IndexingContext.class);
366
367 mockery.checking(new Expectations() {
368 {
369 allowing(tempContext).getIndexDirectoryFile();
370 will(new ReturnValueAction(testBasedir));
371
372 allowing(tempContext).getTimestamp();
373 will(returnValue(contextTimestamp));
374
375 allowing(tempContext).getId();
376 will(returnValue(repositoryId));
377
378 allowing(tempContext).getIndexUpdateUrl();
379 will(returnValue(indexUrl));
380
381 allowing(tempContext).commit();
382
383 allowing(tempContext).getIndexCreators();
384 will(returnValue(DEFAULT_CREATORS));
385
386 allowing(tempContext).commit();
387
388 oneOf(mockFetcher).connect(repositoryId, indexUrl);
389
390 oneOf(mockFetcher)
391 .retrieve(
392 with(IndexingContext.INDEX_REMOTE_PROPERTIES_FILE));
393 will(new PropertiesAction() {
394 @Override
395 Properties getProperties() {
396 Properties properties = new Properties();
397 properties.setProperty(IndexingContext.INDEX_ID, "central");
398 properties.setProperty(IndexingContext.INDEX_TIMESTAMP, "20081126010000.000 -0600");
399 return properties;
400 }
401 });
402
403 allowing(tempContext).getIndexDirectoryFile();
404
405 oneOf(mockFetcher)
406 .retrieve(
407 with(IndexingContext.INDEX_FILE_PREFIX + ".gz"));
408 will(returnValue(newInputStream("index-updater/server-root/nexus-maven-repository-index.gz")));
409
410 oneOf(tempContext).replace(with(any(Directory.class)), with(any(Set.class)), with(any(Set.class)));
411
412 oneOf(mockFetcher).disconnect();
413 }
414 });
415
416
417
418 IndexUpdateRequest updateRequest = new IndexUpdateRequest(tempContext, mockFetcher);
419
420 IndexUpdateResult updateResult = updater.fetchAndUpdateIndex(updateRequest);
421
422 mockery.assertIsSatisfied();
423 assertIndexUpdateSucceeded(updateResult);
424 }
425
426 @Test
427 public void testIncrementalIndexUpdate() throws Exception {
428 Mockery mockery = new Mockery();
429
430 final String indexUrl = repositoryUrl + ".index";
431 final Date contextTimestamp = df.parse("20081128000000.000 -0600");
432
433 final ResourceFetcher mockFetcher = mockery.mock(ResourceFetcher.class);
434
435 final IndexingContext tempContext = mockery.mock(IndexingContext.class);
436
437 final Properties localProps = new Properties();
438 localProps.setProperty(IndexingContext.INDEX_CHUNK_COUNTER, "1");
439 localProps.setProperty(IndexingContext.INDEX_CHAIN_ID, "someid");
440
441 mockery.checking(new Expectations() {
442 {
443 allowing(tempContext).getTimestamp();
444 will(returnValue(contextTimestamp));
445
446 allowing(tempContext).getId();
447 will(returnValue(repositoryId));
448
449 allowing(tempContext).getIndexUpdateUrl();
450 will(returnValue(indexUrl));
451
452 allowing(tempContext).commit();
453
454 allowing(tempContext).getIndexCreators();
455 will(returnValue(DEFAULT_CREATORS));
456
457 oneOf(mockFetcher).connect(repositoryId, indexUrl);
458
459 oneOf(mockFetcher)
460 .retrieve(
461 with(IndexingContext.INDEX_REMOTE_PROPERTIES_FILE));
462 will(new PropertiesAction() {
463 @Override
464 Properties getProperties() {
465 Properties properties = new Properties();
466 properties.setProperty(IndexingContext.INDEX_ID, "central");
467 properties.setProperty(IndexingContext.INDEX_TIMESTAMP, "20081129174241.859 -0600");
468 properties.setProperty(IndexingContext.INDEX_CHUNK_COUNTER, "3");
469 properties.setProperty(IndexingContext.INDEX_CHAIN_ID, "someid");
470 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "0", "3");
471 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "1", "2");
472 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "2", "1");
473 return properties;
474 }
475 });
476
477 allowing(tempContext).getIndexDirectoryFile();
478 will(new IndexDirectoryFileAction(localProps, testBasedir));
479
480 oneOf(mockFetcher)
481 .retrieve(
482 with(IndexingContext.INDEX_FILE_PREFIX + ".2.gz"));
483 will(returnValue(newInputStream("index-updater/server-root/nexus-maven-repository-index.gz")));
484 oneOf(mockFetcher)
485 .retrieve(
486 with(IndexingContext.INDEX_FILE_PREFIX + ".3.gz"));
487 will(returnValue(newInputStream("index-updater/server-root/nexus-maven-repository-index.gz")));
488
489
490 oneOf(tempContext)
491 .merge(
492 with(any(Directory.class)),
493 with(aNull(DocumentFilter.class)),
494 with(any(Set.class)),
495 with(any(Set.class)));
496
497 oneOf(tempContext)
498 .merge(
499 with(any(Directory.class)),
500 with(aNull(DocumentFilter.class)),
501 with(any(Set.class)),
502 with(any(Set.class)));
503
504 oneOf(mockFetcher).disconnect();
505 }
506 });
507
508
509
510 IndexUpdateRequest updateRequest = new IndexUpdateRequest(tempContext, mockFetcher);
511 updateRequest.setIncrementalOnly(true);
512
513 IndexUpdateResult updateResult = updater.fetchAndUpdateIndex(updateRequest);
514
515 mockery.assertIsSatisfied();
516 assertIndexUpdateSucceeded(updateResult);
517 }
518
519 @Test
520 public void testIncrementalIndexUpdateNoCounter() throws Exception {
521 Mockery mockery = new Mockery();
522
523 final String indexUrl = repositoryUrl + ".index";
524 final Date contextTimestamp = df.parse("20081128000000.000 -0600");
525
526 final ResourceFetcher mockFetcher = mockery.mock(ResourceFetcher.class);
527
528 final IndexingContext tempContext = mockery.mock(IndexingContext.class);
529
530 mockery.checking(new Expectations() {
531 {
532 allowing(tempContext).getIndexDirectoryFile();
533 will(new ReturnValueAction(testBasedir));
534
535 allowing(tempContext).getTimestamp();
536 will(returnValue(contextTimestamp));
537
538 allowing(tempContext).getId();
539 will(returnValue(repositoryId));
540
541 allowing(tempContext).getIndexUpdateUrl();
542 will(returnValue(indexUrl));
543
544 allowing(tempContext).commit();
545
546 allowing(tempContext).getIndexCreators();
547 will(returnValue(DEFAULT_CREATORS));
548
549 oneOf(mockFetcher).connect(repositoryId, indexUrl);
550
551 oneOf(mockFetcher)
552 .retrieve(
553 with(IndexingContext.INDEX_REMOTE_PROPERTIES_FILE));
554 will(new PropertiesAction() {
555 @Override
556 Properties getProperties() {
557 Properties properties = new Properties();
558 properties.setProperty(IndexingContext.INDEX_ID, "central");
559 properties.setProperty(IndexingContext.INDEX_TIMESTAMP, "20081129174241.859 -0600");
560 properties.setProperty(IndexingContext.INDEX_CHUNK_COUNTER, "3");
561 properties.setProperty(IndexingContext.INDEX_CHAIN_ID, "someid");
562 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "0", "3");
563 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "1", "2");
564 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "2", "1");
565 return properties;
566 }
567 });
568
569 oneOf(mockFetcher)
570 .retrieve(
571 with(IndexingContext.INDEX_FILE_PREFIX + ".gz"));
572 will(returnValue(newInputStream("index-updater/server-root/nexus-maven-repository-index.gz")));
573
574
575 oneOf(tempContext).replace(with(any(Directory.class)), with(any(Set.class)), with(any(Set.class)));
576
577 never(mockFetcher)
578 .retrieve(
579 with(IndexingContext.INDEX_FILE_PREFIX + ".2.gz"));
580
581 never(tempContext).merge(with(any(Directory.class)));
582
583 oneOf(mockFetcher).disconnect();
584 }
585 });
586
587
588
589 IndexUpdateRequest updateRequest = new IndexUpdateRequest(tempContext, mockFetcher);
590
591 IndexUpdateResult updateResult = updater.fetchAndUpdateIndex(updateRequest);
592
593 mockery.assertIsSatisfied();
594 assertIndexUpdateSucceeded(updateResult);
595 }
596
597 @Test
598 public void testIncrementalOnlyIndexUpdateNoCounter() throws Exception {
599 Mockery mockery = new Mockery();
600
601 final String indexUrl = repositoryUrl + ".index";
602 final Date contextTimestamp = df.parse("20081128000000.000 -0600");
603
604 final ResourceFetcher mockFetcher = mockery.mock(ResourceFetcher.class);
605
606 final IndexingContext tempContext = mockery.mock(IndexingContext.class);
607
608 mockery.checking(new Expectations() {
609 {
610 allowing(tempContext).getIndexDirectoryFile();
611 will(new ReturnValueAction(testBasedir));
612
613 allowing(tempContext).getTimestamp();
614 will(returnValue(contextTimestamp));
615
616 allowing(tempContext).getId();
617 will(returnValue(repositoryId));
618
619 allowing(tempContext).getIndexUpdateUrl();
620 will(returnValue(indexUrl));
621
622 allowing(tempContext).getIndexCreators();
623 will(returnValue(DEFAULT_CREATORS));
624
625 oneOf(mockFetcher).connect(repositoryId, indexUrl);
626
627 oneOf(mockFetcher)
628 .retrieve(
629 with(IndexingContext.INDEX_REMOTE_PROPERTIES_FILE));
630 will(new PropertiesAction() {
631 @Override
632 Properties getProperties() {
633 Properties properties = new Properties();
634 properties.setProperty(IndexingContext.INDEX_ID, "central");
635 properties.setProperty(IndexingContext.INDEX_TIMESTAMP, "20081129174241.859 -0600");
636 properties.setProperty(IndexingContext.INDEX_CHUNK_COUNTER, "3");
637 properties.setProperty(IndexingContext.INDEX_CHAIN_ID, "someid");
638 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "0", "3");
639 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "1", "2");
640 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "2", "1");
641 return properties;
642 }
643 });
644
645 oneOf(mockFetcher).disconnect();
646 }
647 });
648
649 IndexUpdateRequest updateRequest = new IndexUpdateRequest(tempContext, mockFetcher);
650 updateRequest.setIncrementalOnly(true);
651
652 IndexUpdateResult updateResult = updater.fetchAndUpdateIndex(updateRequest);
653
654 mockery.assertIsSatisfied();
655 assertIndexUpdateFailed(updateResult);
656 }
657
658 @Test
659 public void testIncrementalIndexUpdateNoUpdateNecessary() throws Exception {
660 Mockery mockery = new Mockery();
661
662 final String indexUrl = repositoryUrl + ".index";
663 final Date contextTimestamp = df.parse("20081128000000.000 -0600");
664
665 final ResourceFetcher mockFetcher = mockery.mock(ResourceFetcher.class);
666
667 final IndexingContext tempContext = mockery.mock(IndexingContext.class);
668
669 final Properties localProps = new Properties();
670 localProps.setProperty(IndexingContext.INDEX_CHUNK_COUNTER, "3");
671 localProps.setProperty(IndexingContext.INDEX_CHAIN_ID, "someid");
672
673 mockery.checking(new Expectations() {
674 {
675 allowing(tempContext).getTimestamp();
676 will(returnValue(contextTimestamp));
677
678 allowing(tempContext).getId();
679 will(returnValue(repositoryId));
680
681 allowing(tempContext).getIndexUpdateUrl();
682 will(returnValue(indexUrl));
683
684 allowing(tempContext).getIndexCreators();
685 will(returnValue(DEFAULT_CREATORS));
686
687 allowing(tempContext).commit();
688
689 oneOf(mockFetcher).connect(repositoryId, indexUrl);
690
691 oneOf(mockFetcher)
692 .retrieve(
693 with(IndexingContext.INDEX_REMOTE_PROPERTIES_FILE));
694 will(new PropertiesAction() {
695 @Override
696 Properties getProperties() {
697 Properties properties = new Properties();
698 properties.setProperty(IndexingContext.INDEX_ID, "central");
699 properties.setProperty(IndexingContext.INDEX_TIMESTAMP, "20081129174241.859 -0600");
700 properties.setProperty(IndexingContext.INDEX_CHUNK_COUNTER, "3");
701 properties.setProperty(IndexingContext.INDEX_CHAIN_ID, "someid");
702 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "0", "3");
703 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "1", "2");
704 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "2", "1");
705 return properties;
706 }
707 });
708
709 allowing(tempContext).getIndexDirectoryFile();
710 will(new IndexDirectoryFileAction(localProps, testBasedir));
711
712 never(mockFetcher)
713 .retrieve(
714 with(IndexingContext.INDEX_FILE_PREFIX + ".gz"));
715
716
717 never(mockFetcher)
718 .retrieve(
719 with(IndexingContext.INDEX_FILE_PREFIX + ".1.gz"));
720
721 never(mockFetcher)
722 .retrieve(
723 with(IndexingContext.INDEX_FILE_PREFIX + ".2.gz"));
724
725 never(mockFetcher)
726 .retrieve(
727 with(IndexingContext.INDEX_FILE_PREFIX + ".3.gz"));
728
729 never(tempContext).merge(with(any(Directory.class)));
730
731 never(tempContext).replace(with(any(Directory.class)));
732
733 oneOf(mockFetcher).disconnect();
734 }
735 });
736
737
738
739 IndexUpdateRequest updateRequest = new IndexUpdateRequest(tempContext, mockFetcher);
740
741 IndexUpdateResult updateResult = updater.fetchAndUpdateIndex(updateRequest);
742
743 mockery.assertIsSatisfied();
744 assertIndexUpdateSucceeded(updateResult);
745 }
746
747 @Test
748 public void testUpdateForceFullUpdate() throws Exception {
749 Mockery mockery = new Mockery();
750
751 final String indexUrl = repositoryUrl + ".index";
752 final Date contextTimestamp = df.parse("20081128000000.000 -0600");
753
754 final ResourceFetcher mockFetcher = mockery.mock(ResourceFetcher.class);
755
756 final IndexingContext tempContext = mockery.mock(IndexingContext.class);
757
758 mockery.checking(new Expectations() {
759 {
760 allowing(tempContext).getIndexDirectoryFile();
761 will(new ReturnValueAction(testBasedir));
762
763 allowing(tempContext).getTimestamp();
764 will(returnValue(contextTimestamp));
765
766 allowing(tempContext).getId();
767 will(returnValue(repositoryId));
768
769 allowing(tempContext).getIndexUpdateUrl();
770 will(returnValue(indexUrl));
771
772 allowing(tempContext).commit();
773
774 allowing(tempContext).getIndexCreators();
775 will(returnValue(DEFAULT_CREATORS));
776
777 oneOf(mockFetcher).connect(repositoryId, indexUrl);
778
779 oneOf(mockFetcher)
780 .retrieve(
781 with(IndexingContext.INDEX_REMOTE_PROPERTIES_FILE));
782 will(new PropertiesAction() {
783 @Override
784 Properties getProperties() {
785 Properties properties = new Properties();
786 properties.setProperty(IndexingContext.INDEX_ID, "central");
787 properties.setProperty(IndexingContext.INDEX_TIMESTAMP, "20081129174241.859 -0600");
788 properties.setProperty(IndexingContext.INDEX_CHUNK_COUNTER, "3");
789 properties.setProperty(IndexingContext.INDEX_CHAIN_ID, "someid");
790 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "0", "3");
791 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "1", "2");
792 properties.setProperty(IndexingContext.INDEX_CHUNK_PREFIX + "2", "1");
793 return properties;
794 }
795 });
796
797 never(tempContext).getIndexDirectoryFile();
798
799 never(mockFetcher)
800 .retrieve(
801 with(IndexingContext.INDEX_FILE_PREFIX + ".1.gz"));
802
803 never(mockFetcher)
804 .retrieve(
805 with(IndexingContext.INDEX_FILE_PREFIX + ".2.gz"));
806
807 never(mockFetcher)
808 .retrieve(
809 with(IndexingContext.INDEX_FILE_PREFIX + ".3.gz"));
810
811 oneOf(mockFetcher).retrieve(with(IndexingContext.INDEX_FILE_PREFIX + ".gz"));
812 will(returnValue(newInputStream("index-updater/server-root/nexus-maven-repository-index.gz")));
813
814 never(tempContext).merge(with(any(Directory.class)));
815
816 never(tempContext).merge(with(any(Directory.class)));
817
818 oneOf(tempContext).replace(with(any(Directory.class)), with(any(Set.class)), with(any(Set.class)));
819
820 oneOf(mockFetcher).disconnect();
821 }
822 });
823
824
825
826 IndexUpdateRequest updateRequest = new IndexUpdateRequest(tempContext, mockFetcher);
827
828 updateRequest.setForceFullUpdate(true);
829
830 IndexUpdateResult updateResult = updater.fetchAndUpdateIndex(updateRequest);
831
832 mockery.assertIsSatisfied();
833 assertIndexUpdateSucceeded(updateResult);
834 }
835
836 @Test
837 @Ignore("Legacy format no longer supported with Lucene 4")
838 public void ignoreTestUpdateForceFullUpdateNoGZ() throws Exception {
839 Mockery mockery = new Mockery();
840
841 final String indexUrl = repositoryUrl + ".index";
842 final Date contextTimestamp = df.parse("20081128000000.000 -0600");
843
844 final ResourceFetcher mockFetcher = mockery.mock(ResourceFetcher.class);
845
846 final IndexingContext tempContext = mockery.mock(IndexingContext.class);
847
848 mockery.checking(new Expectations() {
849 {
850 allowing(tempContext).getIndexDirectoryFile();
851 will(new ReturnValueAction(testBasedir));
852
853 allowing(tempContext).getTimestamp();
854 will(returnValue(contextTimestamp));
855
856 allowing(tempContext).commit();
857
858 allowing(tempContext).getId();
859 will(returnValue(repositoryId));
860
861 allowing(tempContext).getIndexUpdateUrl();
862 will(returnValue(indexUrl));
863
864 allowing(tempContext).getIndexCreators();
865 will(returnValue(DEFAULT_CREATORS));
866
867 oneOf(mockFetcher).connect(repositoryId, indexUrl);
868
869 oneOf(mockFetcher)
870 .retrieve(
871 with(IndexingContext.INDEX_REMOTE_PROPERTIES_FILE));
872 will(new PropertiesAction() {
873 @Override
874 Properties getProperties() {
875 Properties properties = new Properties();
876 properties.setProperty(IndexingContext.INDEX_ID, "central");
877 properties.setProperty(IndexingContext.INDEX_LEGACY_TIMESTAMP, "20081129174241.859 -0600");
878 return properties;
879 }
880 });
881
882 never(tempContext).getIndexDirectoryFile();
883
884 oneOf(mockFetcher).retrieve(with(IndexingContext.INDEX_FILE_PREFIX + ".gz"));
885
886 will(throwException(new IOException()));
887
888 oneOf(mockFetcher).retrieve(with(IndexingContext.INDEX_FILE_PREFIX + ".zip"));
889
890 will(returnValue(newInputStream("index-updater/server-root/legacy/nexus-maven-repository-index.zip")));
891
892 never(tempContext).merge(with(any(Directory.class)));
893
894 never(tempContext).merge(with(any(Directory.class)));
895
896 oneOf(tempContext).replace(with(any(Directory.class)));
897
898 oneOf(mockFetcher).disconnect();
899 }
900 });
901
902
903
904 IndexUpdateRequest updateRequest = new IndexUpdateRequest(tempContext, mockFetcher);
905
906 updateRequest.setForceFullUpdate(true);
907
908 IndexUpdateResult updateResult = updater.fetchAndUpdateIndex(updateRequest);
909
910 mockery.assertIsSatisfied();
911 assertIndexUpdateSucceeded(updateResult);
912 }
913
914 protected InputStream newInputStream(String path) throws IOException {
915 File file = getTestFile("src/test/resources/" + path);
916 if (file.isFile()) {
917 return new FileInputStream(file);
918 }
919 return null;
920 }
921
922 abstract static class PropertiesAction extends VoidAction {
923 @Override
924 public Object invoke(Invocation invocation) throws Throwable {
925 Properties properties = getProperties();
926
927 try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) {
928 properties.store(buf, null);
929 buf.flush();
930 return new ByteArrayInputStream(buf.toByteArray());
931 }
932 }
933
934 abstract Properties getProperties();
935 }
936
937 private static class IndexDirectoryFileAction extends VoidAction {
938 File file;
939
940 public IndexDirectoryFileAction(Properties properties, File basedir) throws Exception {
941 basedir.mkdirs();
942
943 this.file = new File(basedir, IndexingContext.INDEX_UPDATER_PROPERTIES_FILE);
944
945 try (FileOutputStream fos = new FileOutputStream(this.file)) {
946 properties.store(fos, "");
947 }
948 }
949
950 @Override
951 public Object invoke(Invocation invocation) throws Throwable {
952 return this.file.getParentFile();
953 }
954 }
955
956 private void assertIndexUpdateSucceeded(IndexUpdateResult updateResult) {
957 assertTrue("Index update should have succeeded, but says it failed", updateResult.isSuccessful());
958 }
959
960 private void assertIndexUpdateFailed(IndexUpdateResult updateResult) {
961 assertFalse("Index update should have failed, but says it succeeded", updateResult.isSuccessful());
962 }
963 }