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