]> source.dussan.org Git - archiva.git/blob
adb5cb0ca294c18f4a855b3e956719703022703e
[archiva.git] /
1 package org.apache.archiva.repository.scanner;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import junit.framework.TestCase;
23 import org.apache.archiva.configuration.ArchivaConfiguration;
24 import org.apache.archiva.consumers.InvalidRepositoryContentConsumer;
25 import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
26 import org.apache.archiva.repository.base.BasicManagedRepository;
27 import org.apache.archiva.repository.base.BasicRemoteRepository;
28 import org.apache.archiva.repository.ManagedRepository;
29 import org.apache.archiva.repository.RemoteRepository;
30 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
31 import org.apache.commons.lang3.SystemUtils;
32 import org.easymock.IMocksControl;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 import org.springframework.beans.BeansException;
36 import org.springframework.beans.factory.BeanFactory;
37 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
38 import org.springframework.beans.factory.ObjectProvider;
39 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
40 import org.springframework.context.ApplicationContext;
41 import org.springframework.context.ApplicationEvent;
42 import org.springframework.context.MessageSourceResolvable;
43 import org.springframework.context.NoSuchMessageException;
44 import org.springframework.core.ResolvableType;
45 import org.springframework.core.env.Environment;
46 import org.springframework.core.io.Resource;
47 import org.springframework.test.context.ContextConfiguration;
48
49 import javax.inject.Inject;
50 import java.io.IOException;
51 import java.lang.annotation.Annotation;
52 import java.net.URI;
53 import java.net.URISyntaxException;
54 import java.nio.file.Path;
55 import java.nio.file.Paths;
56 import java.util.Arrays;
57 import java.util.Collections;
58 import java.util.Date;
59 import java.util.HashMap;
60 import java.util.List;
61 import java.util.Locale;
62 import java.util.Map;
63 import java.util.function.Function;
64
65 import static org.easymock.EasyMock.*;
66
67 /**
68  * RepositoryContentConsumersTest
69  */
70 @RunWith( ArchivaSpringJUnit4ClassRunner.class )
71 @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } )
72 public class RepositoryContentConsumersTest
73     extends TestCase
74 {
75
76     @Inject
77     ApplicationContext applicationContext;
78
79     protected ManagedRepository createRepository( String id, String name, Path location ) throws IOException {
80         BasicManagedRepository repo = BasicManagedRepository.newFilesystemInstance(id, name, location.getParent().resolve(id));
81         repo.setLocation( location.toAbsolutePath().toUri() );
82         return repo;
83     }
84
85     protected RemoteRepository createRemoteRepository( String id, String name, String url ) throws URISyntaxException, IOException {
86         BasicRemoteRepository repo = BasicRemoteRepository.newFilesystemInstance(id, name, Paths.get("remotes"));
87         repo.setLocation( new URI( url ) );
88         return repo;
89     }
90
91     private RepositoryContentConsumers lookupRepositoryConsumers()
92         throws Exception
93     {
94
95         ArchivaConfiguration configuration =
96             applicationContext.getBean( "archivaConfiguration#test-conf", ArchivaConfiguration.class );
97
98         ArchivaAdministrationStub administrationStub = new ArchivaAdministrationStub( configuration );
99
100         RepositoryContentConsumers consumerUtilStub = new RepositoryContentConsumersStub( administrationStub );
101
102         RepositoryContentConsumers consumerUtil =
103             applicationContext.getBean( "repositoryContentConsumers#test", RepositoryContentConsumers.class );
104         ApplicationContext context = new MockApplicationContext( consumerUtil.getAvailableKnownConsumers(), //
105                                                                  consumerUtil.getAvailableInvalidConsumers() );
106
107         consumerUtilStub.setApplicationContext( context );
108         consumerUtilStub.setSelectedInvalidConsumers( consumerUtil.getSelectedInvalidConsumers() );
109         consumerUtilStub.setSelectedKnownConsumers( consumerUtil.getSelectedKnownConsumers() );
110         consumerUtilStub.setArchivaAdministration( administrationStub );
111
112         assertNotNull( "RepositoryContentConsumers should not be null.", consumerUtilStub );
113
114         return consumerUtilStub;
115     }
116
117     @Test
118     public void testGetSelectedKnownIds()
119         throws Exception
120     {
121         RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
122
123         String expectedKnownIds[] =
124             new String[]{ "create-missing-checksums", "validate-checksum", "validate-signature", "index-content",
125                 "auto-remove", "auto-rename", "create-archiva-metadata", "duplicate-artifacts" };
126 //update-db-artifact, create-missing-checksums, update-db-repository-metadata,
127 //validate-checksum, validate-signature, index-content, auto-remove, auto-rename,
128 //metadata-updater
129         List<String> knownConsumers = consumerutil.getSelectedKnownConsumerIds();
130         assertNotNull( "Known Consumer IDs should not be null", knownConsumers );
131         assertEquals( "Known Consumer IDs.size " + knownConsumers, expectedKnownIds.length, knownConsumers.size() );
132
133         for ( String expectedId : expectedKnownIds )
134         {
135             assertTrue( "Known id [" + expectedId + "] exists.", knownConsumers.contains( expectedId ) );
136         }
137     }
138
139     @Test
140     public void testGetSelectedInvalidIds()
141         throws Exception
142     {
143         RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
144
145         String expectedInvalidIds[] = new String[]{ "update-db-bad-content" };
146
147         List<String> invalidConsumers = consumerutil.getSelectedInvalidConsumerIds();
148         assertNotNull( "Invalid Consumer IDs should not be null", invalidConsumers );
149         assertEquals( "Invalid Consumer IDs.size", expectedInvalidIds.length, invalidConsumers.size() );
150
151         for ( String expectedId : expectedInvalidIds )
152         {
153             assertTrue( "Invalid id [" + expectedId + "] exists.", invalidConsumers.contains( expectedId ) );
154         }
155     }
156
157     @Test
158     public void testGetSelectedKnownConsumerMap()
159         throws Exception
160     {
161         RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
162
163         String expectedSelectedKnownIds[] =
164             new String[]{ "create-missing-checksums", "validate-checksum", "index-content", "auto-remove",
165                 "auto-rename" };
166
167         Map<String, KnownRepositoryContentConsumer> knownConsumerMap = consumerutil.getSelectedKnownConsumersMap();
168         assertNotNull( "Known Consumer Map should not be null", knownConsumerMap );
169         assertEquals( "Known Consumer Map.size but " + knownConsumerMap, expectedSelectedKnownIds.length,
170                       knownConsumerMap.size() );
171
172         for ( String expectedId : expectedSelectedKnownIds )
173         {
174             KnownRepositoryContentConsumer consumer = knownConsumerMap.get( expectedId );
175             assertNotNull( "Known[" + expectedId + "] should not be null.", consumer );
176             assertEquals( "Known[" + expectedId + "].id", expectedId, consumer.getId() );
177         }
178     }
179
180     @Test
181     public void testGetSelectedInvalidConsumerMap()
182         throws Exception
183     {
184         RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
185
186         String expectedSelectedInvalidIds[] = new String[]{ "update-db-bad-content" };
187
188         Map<String, InvalidRepositoryContentConsumer> invalidConsumerMap =
189             consumerutil.getSelectedInvalidConsumersMap();
190         assertNotNull( "Invalid Consumer Map should not be null", invalidConsumerMap );
191         assertEquals( "Invalid Consumer Map.size", expectedSelectedInvalidIds.length, invalidConsumerMap.size() );
192
193         for ( String expectedId : expectedSelectedInvalidIds )
194         {
195             InvalidRepositoryContentConsumer consumer = invalidConsumerMap.get( expectedId );
196             assertNotNull( "Known[" + expectedId + "] should not be null.", consumer );
197             assertEquals( "Known[" + expectedId + "].id", expectedId, consumer.getId() );
198         }
199     }
200
201     @Test
202     public void testGetAvailableKnownList()
203         throws Exception
204     {
205         RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
206
207         String expectedKnownIds[] =
208             new String[]{ "update-db-artifact", "create-missing-checksums", "update-db-repository-metadata",
209                 "validate-checksum", "index-content", "auto-remove", "auto-rename", "available-but-unselected" };
210
211         List<KnownRepositoryContentConsumer> knownConsumers = consumerutil.getAvailableKnownConsumers();
212         assertNotNull( "known consumers should not be null.", knownConsumers );
213         assertEquals( "known consumers", expectedKnownIds.length, knownConsumers.size() );
214
215         List<String> expectedIds = Arrays.asList( expectedKnownIds );
216         for ( KnownRepositoryContentConsumer consumer : knownConsumers )
217         {
218             assertTrue( "Consumer [" + consumer.getId() + "] returned by .getAvailableKnownConsumers() is unexpected.",
219                         expectedIds.contains( consumer.getId() ) );
220         }
221     }
222
223     @Test
224     public void testGetAvailableInvalidList()
225         throws Exception
226     {
227         RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
228
229         String expectedInvalidIds[] = new String[]{ "update-db-bad-content", "move-to-trash-then-notify" };
230
231         List<InvalidRepositoryContentConsumer> invalidConsumers = consumerutil.getAvailableInvalidConsumers();
232         assertNotNull( "invalid consumers should not be null.", invalidConsumers );
233         assertEquals( "invalid consumers", expectedInvalidIds.length, invalidConsumers.size() );
234
235         List<String> expectedIds = Arrays.asList( expectedInvalidIds );
236         for ( InvalidRepositoryContentConsumer consumer : invalidConsumers )
237         {
238             assertTrue(
239                 "Consumer [" + consumer.getId() + "] returned by .getAvailableInvalidConsumers() is unexpected.",
240                 expectedIds.contains( consumer.getId() ) );
241         }
242     }
243
244     @Test
245     public void testExecution()
246         throws Exception
247     {
248         IMocksControl knownControl = createNiceControl();
249
250         RepositoryContentConsumers consumers = lookupRepositoryConsumers();
251         KnownRepositoryContentConsumer selectedKnownConsumer =
252             knownControl.createMock( KnownRepositoryContentConsumer.class );
253
254         KnownRepositoryContentConsumer unselectedKnownConsumer =
255             createNiceControl().createMock( KnownRepositoryContentConsumer.class );
256
257         consumers.setApplicationContext(
258             new MockApplicationContext( Arrays.asList( selectedKnownConsumer, unselectedKnownConsumer ), null ) );
259
260         consumers.setSelectedKnownConsumers( Collections.singletonList( selectedKnownConsumer ) );
261
262         IMocksControl invalidControl = createControl();
263
264         InvalidRepositoryContentConsumer selectedInvalidConsumer =
265             invalidControl.createMock( InvalidRepositoryContentConsumer.class );
266
267         InvalidRepositoryContentConsumer unselectedInvalidConsumer =
268             createControl().createMock( InvalidRepositoryContentConsumer.class );
269
270         consumers.setApplicationContext(
271             new MockApplicationContext( null, Arrays.asList( selectedInvalidConsumer, unselectedInvalidConsumer ) ) );
272
273         consumers.setSelectedInvalidConsumers( Collections.singletonList( selectedInvalidConsumer ) );
274
275         ManagedRepository repo = createRepository( "id", "name", Paths.get( "target/test-repo" ) );
276         Path testFile = Paths.get( "target/test-repo/path/to/test-file.txt" );
277
278         Date startTime = new Date( System.currentTimeMillis() );
279         startTime.setTime( 12345678 );
280
281         selectedKnownConsumer.beginScan( repo, startTime, false );
282         expect( selectedKnownConsumer.getIncludes() ).andReturn( Collections.singletonList( "**/*.txt" ) );
283         selectedKnownConsumer.processFile( _OS( "path/to/test-file.txt" ), false );
284
285         knownControl.replay();
286
287         selectedInvalidConsumer.beginScan( repo, startTime, false );
288         invalidControl.replay();
289
290         consumers.executeConsumers( repo, testFile, true );
291
292         knownControl.verify();
293         invalidControl.verify();
294
295         knownControl.reset();
296         invalidControl.reset();
297
298         Path notIncludedTestFile = Paths.get( "target/test-repo/path/to/test-file.xml" );
299
300         selectedKnownConsumer.beginScan( repo, startTime, false );
301         expect( selectedKnownConsumer.getExcludes() ).andReturn( Collections.<String>emptyList() );
302
303         expect( selectedKnownConsumer.getIncludes() ).andReturn( Collections.singletonList( "**/*.txt" ) );
304
305         knownControl.replay();
306
307         selectedInvalidConsumer.beginScan( repo, startTime, false );
308         selectedInvalidConsumer.processFile( _OS( "path/to/test-file.xml" ), false );
309         expect( selectedInvalidConsumer.getId() ).andReturn( "invalid" );
310         invalidControl.replay();
311
312         consumers.executeConsumers( repo, notIncludedTestFile, true );
313
314         knownControl.verify();
315         invalidControl.verify();
316
317         knownControl.reset();
318         invalidControl.reset();
319
320         Path excludedTestFile = Paths.get( "target/test-repo/path/to/test-file.txt" );
321
322         selectedKnownConsumer.beginScan( repo, startTime, false );
323         expect( selectedKnownConsumer.getExcludes() ).andReturn( Collections.singletonList( "**/test-file.txt" ) );
324         knownControl.replay();
325
326         selectedInvalidConsumer.beginScan( repo, startTime, false );
327         selectedInvalidConsumer.processFile( _OS( "path/to/test-file.txt" ), false );
328         expect( selectedInvalidConsumer.getId() ).andReturn( "invalid" );
329         invalidControl.replay();
330
331         consumers.executeConsumers( repo, excludedTestFile, true );
332
333         knownControl.verify();
334         invalidControl.verify();
335     }
336
337     /**
338      * Create an OS specific version of the filepath.
339      * Provide path in unix "/" format.
340      */
341     private String _OS( String path )
342     {
343         if ( SystemUtils.IS_OS_WINDOWS )
344         {
345             return path.replace( '/', '\\' );
346         }
347         return path;
348     }
349
350     private static <T> Map<String, T> convertToMap( List<T> objects)
351     {
352         HashMap<String,T> map = new HashMap<>();
353         for ( T o : objects )
354         {
355             map.put( o.toString(), o );
356         }
357         return map;
358     }
359
360     private static <T> Function<List<T>,Map<String,T>> getConversionFunction(Class<T> type) {
361         return ts -> convertToMap( ts );
362     }
363
364     public class MockApplicationContext
365         implements ApplicationContext
366     {
367         private List<KnownRepositoryContentConsumer> knownRepositoryContentConsumer;
368
369         private List<InvalidRepositoryContentConsumer> invalidRepositoryContentConsumers;
370
371         public MockApplicationContext( List<KnownRepositoryContentConsumer> knownRepositoryContentConsumer,
372                                        List<InvalidRepositoryContentConsumer> invalidRepositoryContentConsumers )
373         {
374             this.knownRepositoryContentConsumer = knownRepositoryContentConsumer;
375             this.invalidRepositoryContentConsumers = invalidRepositoryContentConsumers;
376         }
377
378         @Override
379         public String getApplicationName()
380         {
381             return "foo";
382         }
383
384         @Override
385         public AutowireCapableBeanFactory getAutowireCapableBeanFactory()
386             throws IllegalStateException
387         {
388             throw new UnsupportedOperationException( "Not supported yet." );
389         }
390
391         @Override
392         public String getDisplayName()
393         {
394             throw new UnsupportedOperationException( "Not supported yet." );
395         }
396
397         @Override
398         public String getId()
399         {
400             throw new UnsupportedOperationException( "Not supported yet." );
401         }
402
403         @Override
404         public ApplicationContext getParent()
405         {
406             throw new UnsupportedOperationException( "Not supported yet." );
407         }
408
409         @Override
410         public long getStartupDate()
411         {
412             throw new UnsupportedOperationException( "Not supported yet." );
413         }
414
415         @Override
416         public boolean containsBeanDefinition( String beanName )
417         {
418             throw new UnsupportedOperationException( "Not supported yet." );
419         }
420
421         @Override
422         public int getBeanDefinitionCount()
423         {
424             throw new UnsupportedOperationException( "Not supported yet." );
425         }
426
427         @Override
428         public String[] getBeanDefinitionNames()
429         {
430             throw new UnsupportedOperationException( "Not supported yet." );
431         }
432
433         @Override
434         public <T> ObjectProvider<T> getBeanProvider( Class<T> aClass, boolean b )
435         {
436             return null;
437         }
438
439         @Override
440         public <T> ObjectProvider<T> getBeanProvider( ResolvableType resolvableType, boolean b )
441         {
442             return null;
443         }
444
445         @Override
446         public String[] getBeanNamesForType( Class type )
447         {
448             throw new UnsupportedOperationException( "Not supported yet." );
449         }
450
451         @Override
452         public String[] getBeanNamesForType( Class type, boolean includeNonSingletons, boolean allowEagerInit )
453         {
454             throw new UnsupportedOperationException( "Not supported yet." );
455         }
456
457         @Override
458         public <T> T getBean( Class<T> aClass, Object... objects )
459             throws BeansException
460         {
461             throw new UnsupportedOperationException( "Not supported yet." );
462         }
463
464         @Override
465         public <T> ObjectProvider<T> getBeanProvider( Class<T> aClass )
466         {
467             return null;
468         }
469
470         @Override
471         public <T> ObjectProvider<T> getBeanProvider( ResolvableType resolvableType )
472         {
473             return null;
474         }
475
476         @SuppressWarnings( "unchecked" )
477         @Override
478         public <T> Map<String, T> getBeansOfType( Class<T> type )
479             throws BeansException
480         {
481             List<T> list = null;
482             if (type == KnownRepositoryContentConsumer.class) {
483                 list = (List<T>) knownRepositoryContentConsumer;
484             } else if (type == InvalidRepositoryContentConsumer.class) {
485                 list = (List<T>) invalidRepositoryContentConsumers;
486             }
487             if (list!=null) {
488                 return getConversionFunction( type ).apply( list );
489             }
490             throw new UnsupportedOperationException( "Should not have been called" );
491         }
492
493         @Override
494         public <T> Map<String, T> getBeansOfType( Class<T> type, boolean includeNonSingletons, boolean allowEagerInit )
495             throws BeansException
496         {
497             throw new UnsupportedOperationException( "Not supported yet." );
498         }
499
500         @Override
501         public boolean containsBean( String name )
502         {
503             throw new UnsupportedOperationException( "Not supported yet." );
504         }
505
506         @Override
507         public String[] getAliases( String name )
508         {
509             throw new UnsupportedOperationException( "Not supported yet." );
510         }
511
512         @Override
513         public Object getBean( String name )
514             throws BeansException
515         {
516             throw new UnsupportedOperationException( "Not supported yet." );
517         }
518
519         @Override
520         public <T> T getBean( String name, Class<T> requiredType )
521             throws BeansException
522         {
523             throw new UnsupportedOperationException( "Not supported yet." );
524         }
525
526         @Override
527         public Object getBean( String name, Object[] args )
528             throws BeansException
529         {
530             throw new UnsupportedOperationException( "Not supported yet." );
531         }
532
533         @Override
534         public Class getType( String name )
535             throws NoSuchBeanDefinitionException
536         {
537             throw new UnsupportedOperationException( "Not supported yet." );
538         }
539
540         @Override
541         public Class<?> getType( String s, boolean b ) throws NoSuchBeanDefinitionException
542         {
543             return null;
544         }
545
546         @Override
547         public boolean isPrototype( String name )
548             throws NoSuchBeanDefinitionException
549         {
550             throw new UnsupportedOperationException( "Not supported yet." );
551         }
552
553         @Override
554         public boolean isSingleton( String name )
555             throws NoSuchBeanDefinitionException
556         {
557             throw new UnsupportedOperationException( "Not supported yet." );
558         }
559
560         @Override
561         public boolean isTypeMatch( String name, Class targetType )
562             throws NoSuchBeanDefinitionException
563         {
564             throw new UnsupportedOperationException( "Not supported yet." );
565         }
566
567         @Override
568         public boolean containsLocalBean( String name )
569         {
570             throw new UnsupportedOperationException( "Not supported yet." );
571         }
572
573         @Override
574         public BeanFactory getParentBeanFactory()
575         {
576             throw new UnsupportedOperationException( "Not supported yet." );
577         }
578
579         @Override
580         public String getMessage( String code, Object[] args, String defaultMessage, Locale locale )
581         {
582             throw new UnsupportedOperationException( "Not supported yet." );
583         }
584
585         @Override
586         public String getMessage( String code, Object[] args, Locale locale )
587             throws NoSuchMessageException
588         {
589             throw new UnsupportedOperationException( "Not supported yet." );
590         }
591
592         @Override
593         public String getMessage( MessageSourceResolvable resolvable, Locale locale )
594             throws NoSuchMessageException
595         {
596             throw new UnsupportedOperationException( "Not supported yet." );
597         }
598
599         @Override
600         public void publishEvent( ApplicationEvent event )
601         {
602             throw new UnsupportedOperationException( "Not supported yet." );
603         }
604
605         @Override
606         public Resource[] getResources( String locationPattern )
607             throws IOException
608         {
609             throw new UnsupportedOperationException( "Not supported yet." );
610         }
611
612         @Override
613         public ClassLoader getClassLoader()
614         {
615             throw new UnsupportedOperationException( "Not supported yet." );
616         }
617
618         @Override
619         public Resource getResource( String location )
620         {
621             throw new UnsupportedOperationException( "Not supported yet." );
622         }
623
624         @Override
625         public <T> T getBean( Class<T> tClass )
626             throws BeansException
627         {
628             throw new UnsupportedOperationException( "Not supported yet." );
629         }
630
631         @Override
632         public Map<String, Object> getBeansWithAnnotation( Class<? extends Annotation> aClass )
633             throws BeansException
634         {
635             throw new UnsupportedOperationException( "Not supported yet." );
636         }
637
638         @Override
639         public <A extends Annotation> A findAnnotationOnBean( String s, Class<A> aClass )
640         {
641             throw new UnsupportedOperationException( "Not supported yet." );
642         }
643
644         @Override
645         public Environment getEnvironment()
646         {
647             return null;
648         }
649
650         @Override
651         public String[] getBeanNamesForAnnotation( Class<? extends Annotation> aClass )
652         {
653             return new String[0];
654         }
655
656         @Override
657         public void publishEvent( Object o )
658         {
659             // no op
660         }
661
662         @Override
663         public String[] getBeanNamesForType( ResolvableType resolvableType )
664         {
665             return new String[0];
666         }
667
668         @Override
669         public String[] getBeanNamesForType( ResolvableType resolvableType, boolean b, boolean b1 )
670         {
671             return new String[0];
672         }
673
674         @Override
675         public boolean isTypeMatch( String s, ResolvableType resolvableType )
676             throws NoSuchBeanDefinitionException
677         {
678             return false;
679         }
680     }
681 }