]> source.dussan.org Git - archiva.git/blob
da72e9eaa50dc0ec9d9397282b1a3796ca60c0ed
[archiva.git] /
1 package org.apache.archiva.maven.proxy;
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  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  */
20
21 import net.sf.ehcache.CacheManager;
22 import org.apache.archiva.configuration.ArchivaConfiguration;
23 import org.apache.archiva.configuration.ArchivaRuntimeConfiguration;
24 import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
25 import org.apache.archiva.configuration.ProxyConnectorConfiguration;
26 import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
27 import org.apache.archiva.policies.CachedFailuresPolicy;
28 import org.apache.archiva.policies.ChecksumPolicy;
29 import org.apache.archiva.policies.PolicyOption;
30 import org.apache.archiva.policies.PropagateErrorsDownloadPolicy;
31 import org.apache.archiva.policies.PropagateErrorsOnUpdateDownloadPolicy;
32 import org.apache.archiva.policies.ReleasesPolicy;
33 import org.apache.archiva.policies.SnapshotsPolicy;
34 import org.apache.archiva.proxy.ProxyRegistry;
35 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
36 import org.apache.archiva.repository.ManagedRepository;
37 import org.apache.archiva.repository.ManagedRepositoryContent;
38 import org.apache.archiva.repository.RepositoryRegistry;
39 import org.apache.archiva.repository.RepositoryType;
40 import org.apache.archiva.repository.base.RepositoryHandlerDependencies;
41 import org.apache.archiva.repository.base.managed.BasicManagedRepository;
42 import org.apache.archiva.repository.storage.StorageAsset;
43 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
44 import org.apache.maven.wagon.Wagon;
45 import org.easymock.EasyMock;
46 import org.easymock.IMocksControl;
47 import org.junit.Before;
48 import org.junit.runner.RunWith;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.springframework.context.ApplicationContext;
52 import org.springframework.test.context.ContextConfiguration;
53
54 import javax.inject.Inject;
55 import java.io.BufferedReader;
56 import java.io.FileReader;
57 import java.io.IOException;
58 import java.nio.charset.Charset;
59 import java.nio.file.Files;
60 import java.nio.file.Path;
61 import java.nio.file.Paths;
62 import java.nio.file.attribute.FileTime;
63 import java.text.ParseException;
64 import java.text.SimpleDateFormat;
65 import java.util.ArrayList;
66 import java.util.Calendar;
67 import java.util.Collection;
68 import java.util.Date;
69 import java.util.List;
70 import java.util.Locale;
71 import java.util.concurrent.TimeUnit;
72 import java.util.stream.Collectors;
73
74 import static org.junit.Assert.*;
75
76 /**
77  * AbstractProxyTestCase
78  */
79 @RunWith( ArchivaSpringJUnit4ClassRunner.class )
80 @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } )
81 public abstract class AbstractProxyTestCase
82 {
83     @Inject
84     protected ApplicationContext applicationContext;
85
86     @Inject
87     private ProxyRegistry proxyRegistry;
88
89     @Inject
90     RepositoryRegistry repositoryRegistry;
91
92     @SuppressWarnings( "unused" )
93     @Inject
94     RepositoryHandlerDependencies repositoryHandlerDependencies;
95
96     protected static final String ID_PROXIED1 = "proxied1";
97
98     protected static final String ID_PROXIED1_TARGET = "proxied1-target";
99
100     protected static final String ID_PROXIED2 = "proxied2";
101
102     protected static final String ID_PROXIED2_TARGET = "proxied2-target";
103
104     protected static final String ID_DEFAULT_MANAGED = "default-managed-repository";
105
106     protected static final String REPOPATH_PROXIED1 = "src/test/repositories/proxied1";
107
108     protected static final String REPOPATH_PROXIED1_TARGET = "target/test-repository/proxied1";
109
110     protected static final String REPOPATH_PROXIED2 = "src/test/repositories/proxied2";
111
112     protected static final String REPOPATH_PROXIED2_TARGET = "target/test-repository/proxied2";
113
114     protected static final String REPOPATH_DEFAULT_MANAGED = "src/test/repositories/managed";
115
116     // protected static final String REPOPATH_DEFAULT_MANAGED_TARGET = "target/test-repository/managed";
117
118     protected IMocksControl wagonMockControl;
119
120     protected Wagon wagonMock;
121
122
123     protected RepositoryProxyHandler proxyHandler;
124
125     protected ManagedRepositoryContent managedDefaultRepository;
126
127     protected Path managedDefaultDir;
128
129     protected MockConfiguration config;
130
131     protected Logger log = LoggerFactory.getLogger( getClass() );
132
133     WagonDelegate delegate;
134
135     @Before
136     public void setUp()
137         throws Exception
138     {
139         config =
140             (MockConfiguration) applicationContext.getBean( "archivaConfiguration#mock", ArchivaConfiguration.class );
141
142         config.getConfiguration().setManagedRepositories( new ArrayList<ManagedRepositoryConfiguration>() );
143         config.getConfiguration().setRemoteRepositories( new ArrayList<RemoteRepositoryConfiguration>() );
144         config.getConfiguration().setProxyConnectors( new ArrayList<ProxyConnectorConfiguration>() );
145         ArchivaRuntimeConfiguration runtimeConfiguration = new ArchivaRuntimeConfiguration();
146         List<String> checksumTypes = new ArrayList<>();
147         checksumTypes.add("md5");
148         checksumTypes.add("sha256");
149         checksumTypes.add("sha1");
150         checksumTypes.add("asc");
151         runtimeConfiguration.setChecksumTypes(checksumTypes);
152         config.getConfiguration().setArchivaRuntimeConfiguration(runtimeConfiguration);
153         repositoryRegistry.setArchivaConfiguration( config );
154
155         // Setup source repository (using default layout)
156         String name = getClass().getSimpleName();
157         Path repoPath = Paths.get("target/test-repository/managed/" + name);
158
159         managedDefaultRepository =
160             createRepository( ID_DEFAULT_MANAGED, "Default Managed Repository", repoPath.toString(), "default" );
161
162         managedDefaultDir = repoPath.resolve(ID_DEFAULT_MANAGED) ;
163
164         org.apache.archiva.repository.ManagedRepository repoConfig = repositoryRegistry.getManagedRepository(ID_DEFAULT_MANAGED);
165
166         // Setup target (proxied to) repository.
167         saveRemoteRepositoryConfig( ID_PROXIED1, "Proxied Repository 1",
168             Paths.get( REPOPATH_PROXIED1 ).toUri().toURL().toExternalForm(), "default" );
169
170         // Setup target (proxied to) repository.
171         saveRemoteRepositoryConfig( ID_PROXIED2, "Proxied Repository 2",
172             Paths.get( REPOPATH_PROXIED2 ).toUri().toURL().toExternalForm(), "default" );
173
174
175         repositoryRegistry.reload();
176         repositoryRegistry.putRepository(repoConfig);
177
178
179         // Setup the proxy handler.
180         //proxyHandler = applicationContext.getBean (RepositoryProxyHandler) lookup( RepositoryProxyHandler.class.getName() );
181
182         proxyHandler = applicationContext.getBean( "repositoryProxyHandler#test", RepositoryProxyHandler.class );
183         assertNotNull( proxyRegistry );
184         assertTrue(proxyRegistry.getAllHandler( ).get( RepositoryType.MAVEN).contains( proxyHandler ));
185
186
187         // Setup the wagon mock.
188         wagonMockControl = EasyMock.createNiceControl();
189         wagonMock = wagonMockControl.createMock( Wagon.class );
190
191         delegate = (WagonDelegate) applicationContext.getBean( "wagon#http", Wagon.class );
192
193         delegate.setDelegate( wagonMock );
194
195         CacheManager.getInstance().clearAll();
196
197         log.info( "\n.\\ {}() \\._________________________________________\n", name );
198     }
199
200     protected void assertChecksums( Path expectedFile, String expectedSha1Contents, String expectedMd5Contents )
201         throws Exception
202     {
203         Path sha1File = expectedFile.toAbsolutePath().resolveSibling( expectedFile.getFileName().toString()+ ".sha1" );
204         Path md5File = expectedFile.toAbsolutePath().resolveSibling( expectedFile.getFileName().toString() + ".md5" );
205
206         if ( expectedSha1Contents == null )
207         {
208             assertFalse( "SHA1 File should NOT exist: " + sha1File.toAbsolutePath(), Files.exists(sha1File) );
209         }
210         else
211         {
212             assertTrue( "SHA1 File should exist: " + sha1File.toAbsolutePath(), Files.exists(sha1File) );
213             String actualSha1Contents = readChecksumFile( sha1File );
214             assertEquals( "SHA1 File contents: " + sha1File.toAbsolutePath(), expectedSha1Contents, actualSha1Contents );
215         }
216
217         if ( expectedMd5Contents == null )
218         {
219             assertFalse( "MD5 File should NOT exist: " + md5File.toAbsolutePath(), Files.exists(md5File) );
220         }
221         else
222         {
223             assertTrue( "MD5 File should exist: " + md5File.toAbsolutePath(), Files.exists(md5File) );
224             String actualMd5Contents = readChecksumFile( md5File );
225             assertEquals( "MD5 File contents: " + md5File.toAbsolutePath(), expectedMd5Contents, actualMd5Contents );
226         }
227     }
228
229     protected void assertFileEquals( Path expectedFile, Path actualFile, Path sourceFile )
230         throws Exception
231     {
232         assertNotNull( "Expected File should not be null.", expectedFile );
233         assertNotNull( "Actual File should not be null.", actualFile );
234
235         assertTrue( "Check actual file exists.", Files.exists(actualFile) );
236         assertTrue("Check expected file exists", Files.exists(expectedFile));
237         assertTrue( "Check file is the same.", Files.isSameFile( expectedFile,
238             actualFile));
239         String expectedContents =
240             org.apache.commons.io.FileUtils.readFileToString( sourceFile.toFile(), Charset.defaultCharset() );
241         String actualContents =
242             org.apache.commons.io.FileUtils.readFileToString( actualFile.toFile(), Charset.defaultCharset() );
243         assertEquals( "Check file contents.", expectedContents, actualContents );
244     }
245
246     protected void assertNotDownloaded(  StorageAsset downloadedFile )
247     {
248         assertNull( "Found file: " + downloadedFile + "; but was expecting a failure", downloadedFile );
249     }
250
251     @SuppressWarnings( "unchecked" )
252     protected void assertNoTempFiles( Path expectedFile )
253     {
254         Path workingDir = expectedFile.getParent();
255         if ( ( workingDir == null ) || !Files.isDirectory( workingDir) )
256         {
257             return;
258         }
259
260         Collection<Path> tmpFiles = null;
261         try {
262             tmpFiles = Files.list(workingDir).filter(path -> Files.isRegularFile(path) && path.getFileName().toString().endsWith(".tmp")).collect(Collectors.toList());
263         } catch (IOException e) {
264             log.error("Could not retrieve tmpFiles {}", workingDir);
265         }
266         if ( tmpFiles!=null && !tmpFiles.isEmpty() )
267         {
268             StringBuilder emsg = new StringBuilder();
269             emsg.append( "Found Temp Files in dir: " ).append( workingDir.toString() );
270             for ( Path tfile : tmpFiles )
271             {
272                 emsg.append( "\n   " ).append( tfile.getFileName().toString());
273             }
274             fail( emsg.toString() );
275         }
276     }
277
278     /**
279      * A faster recursive copy that omits .svn directories.
280      *
281      * @param sourceDirectory the source directory to copy
282      * @param destDirectory   the target location
283      * @throws java.io.IOException if there is a copying problem
284      * @todo get back into plexus-utils, share with converter module
285      */
286     protected void copyDirectoryStructure( Path sourceDirectory, Path destDirectory )
287         throws IOException
288     {
289         if ( !Files.exists(sourceDirectory) )
290         {
291             throw new IOException( "Source directory doesn't exists (" + sourceDirectory.toAbsolutePath() + ")." );
292         }
293
294         Path[] files = Files.list(sourceDirectory).filter(path -> Files.isRegularFile(path)).toArray(Path[]::new);
295
296         String sourcePath = sourceDirectory.toAbsolutePath().toString();
297
298         for ( int i = 0; i < files.length; i++ )
299         {
300             Path file = files[i];
301
302             String dest = file.toAbsolutePath().toString();
303
304             dest = dest.substring( sourcePath.length() + 1 );
305
306             Path destination = destDirectory.resolve( dest );
307
308             if ( Files.isRegularFile(file) )
309             {
310                 destination = destination.getParent();
311
312                 org.apache.commons.io.FileUtils.copyFile( file.toFile(), destination.resolve( file.getFileName() ).toFile(), false );
313                 // TODO: Change when there is a FileUtils.copyFileToDirectory(file, destination, boolean) option
314                 //FileUtils.copyFileToDirectory( file, destination );
315             }
316             else if ( Files.isDirectory(file) )
317             {
318                 if ( !".svn".equals( file.getFileName().toString() ) )
319                 {
320                     if ( !Files.exists(destination))
321                     {
322                         Files.createDirectories(destination);
323                     }
324
325                     copyDirectoryStructure( file, destination );
326                 }
327             }
328             else
329             {
330                 throw new IOException( "Unknown file type: " + file.toAbsolutePath() );
331             }
332         }
333     }
334
335
336     protected ManagedRepositoryContent createRepository( String id, String name, String path, String layout )
337         throws Exception
338     {
339         ManagedRepository repo = BasicManagedRepository.newFilesystemInstance(id, name, Paths.get(path).resolve(id));
340         repositoryRegistry.putRepository(repo);
341         return repositoryRegistry.getManagedRepository(id).getContent();
342     }
343
344     /**
345      * Read the first line from the checksum file, and return it (trimmed).
346      */
347     protected String readChecksumFile( Path checksumFile )
348         throws Exception
349     {
350         FileReader freader = null;
351         BufferedReader buf = null;
352
353         try
354         {
355             freader = new FileReader( checksumFile.toFile() );
356             buf = new BufferedReader( freader );
357             return buf.readLine();
358         }
359         finally
360         {
361             if ( buf != null )
362             {
363                 buf.close();
364             }
365
366             if ( freader != null )
367             {
368                 freader.close();
369             }
370         }
371     }
372
373     protected void saveConnector( String sourceRepoId, String targetRepoId, boolean disabled )
374     {
375         saveConnector( sourceRepoId, targetRepoId, ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS, SnapshotsPolicy.ALWAYS,
376                        CachedFailuresPolicy.NO, disabled );
377     }
378
379     protected void saveConnector( String sourceRepoId, String targetRepoId, PolicyOption checksumPolicy, PolicyOption releasePolicy,
380                                   PolicyOption snapshotPolicy, PolicyOption cacheFailuresPolicy, boolean disabled )
381     {
382         saveConnector( sourceRepoId, targetRepoId, checksumPolicy, releasePolicy, snapshotPolicy, cacheFailuresPolicy,
383                        PropagateErrorsDownloadPolicy.QUEUE, disabled );
384     }
385
386     protected void saveConnector( String sourceRepoId, String targetRepoId, PolicyOption checksumPolicy, PolicyOption releasePolicy,
387                                   PolicyOption snapshotPolicy, PolicyOption cacheFailuresPolicy, PolicyOption errorPolicy,
388                                   boolean disabled )
389     {
390         saveConnector( sourceRepoId, targetRepoId, checksumPolicy, releasePolicy, snapshotPolicy, cacheFailuresPolicy,
391                        errorPolicy, PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT, disabled );
392     }
393
394     protected void saveConnector(String sourceRepoId, String targetRepoId, PolicyOption checksumPolicy, PolicyOption releasePolicy,
395                                  PolicyOption snapshotPolicy, PolicyOption cacheFailuresPolicy, PolicyOption errorPolicy,
396                                  PolicyOption errorOnUpdatePolicy, boolean disabled )
397     {
398         ProxyConnectorConfiguration connectorConfig = new ProxyConnectorConfiguration();
399         connectorConfig.setSourceRepoId( sourceRepoId );
400         connectorConfig.setTargetRepoId( targetRepoId );
401         connectorConfig.setProxyId(sourceRepoId);
402         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CHECKSUM, checksumPolicy.getId() );
403         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_RELEASES, releasePolicy.getId() );
404         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_SNAPSHOTS, snapshotPolicy.getId() );
405         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CACHE_FAILURES, cacheFailuresPolicy.getId());
406         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_PROPAGATE_ERRORS, errorPolicy.getId() );
407         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_PROPAGATE_ERRORS_ON_UPDATE, errorOnUpdatePolicy.getId() );
408         connectorConfig.setDisabled( disabled );
409
410         int count = config.getConfiguration().getProxyConnectors().size();
411         config.getConfiguration().addProxyConnector( connectorConfig );
412
413         // Proper Triggering ...
414         String prefix = "proxyConnectors.proxyConnector(" + count + ")";
415         config.triggerChange( prefix + ".sourceRepoId", connectorConfig.getSourceRepoId() );
416         config.triggerChange( prefix + ".targetRepoId", connectorConfig.getTargetRepoId() );
417         config.triggerChange( prefix + ".proxyId", connectorConfig.getProxyId() );
418         config.triggerChange( prefix + ".policies.releases", connectorConfig.getPolicy( "releases", "" ) );
419         config.triggerChange( prefix + ".policies.checksum", connectorConfig.getPolicy( "checksum", "" ) );
420         config.triggerChange( prefix + ".policies.snapshots", connectorConfig.getPolicy( "snapshots", "" ) );
421         config.triggerChange( prefix + ".policies.cache-failures", connectorConfig.getPolicy( "cache-failures", "" ) );
422         config.triggerChange( prefix + ".policies.propagate-errors",
423                               connectorConfig.getPolicy( "propagate-errors", "" ) );
424         config.triggerChange( prefix + ".policies.propagate-errors-on-update",
425                               connectorConfig.getPolicy( "propagate-errors-on-update", "" ) );
426     }
427
428     protected void saveManagedRepositoryConfig( String id, String name, String path, String layout )
429     {
430         ManagedRepositoryConfiguration repoConfig = new ManagedRepositoryConfiguration();
431
432         repoConfig.setId( id );
433         repoConfig.setName( name );
434         repoConfig.setLayout( layout );
435
436         repoConfig.setLocation( path );
437
438         int count = config.getConfiguration().getManagedRepositories().size();
439         config.getConfiguration().addManagedRepository( repoConfig );
440
441         String prefix = "managedRepositories.managedRepository(" + count + ")";
442         config.triggerChange( prefix + ".id", repoConfig.getId() );
443         config.triggerChange( prefix + ".name", repoConfig.getName() );
444         config.triggerChange( prefix + ".location", repoConfig.getLocation() );
445         config.triggerChange( prefix + ".layout", repoConfig.getLayout() );
446     }
447
448     protected void saveRemoteRepositoryConfig( String id, String name, String url, String layout )
449     {
450         RemoteRepositoryConfiguration repoConfig = new RemoteRepositoryConfiguration();
451
452         repoConfig.setId( id );
453         repoConfig.setName( name );
454         repoConfig.setLayout( layout );
455         repoConfig.setUrl( url );
456
457         int count = config.getConfiguration().getRemoteRepositories().size();
458         config.getConfiguration().addRemoteRepository( repoConfig );
459
460         String prefix = "remoteRepositories.remoteRepository(" + count + ")";
461         config.triggerChange( prefix + ".id", repoConfig.getId() );
462         config.triggerChange( prefix + ".name", repoConfig.getName() );
463         config.triggerChange( prefix + ".url", repoConfig.getUrl() );
464         config.triggerChange( prefix + ".layout", repoConfig.getLayout() );
465         repositoryRegistry.reload();
466     }
467
468     protected Path saveTargetedRepositoryConfig( String id, String originalPath, String targetPath, String layout )
469         throws IOException
470     {
471         Path repoLocation = Paths.get( targetPath );
472         org.apache.archiva.common.utils.FileUtils.deleteDirectory( repoLocation );
473         copyDirectoryStructure( Paths.get(originalPath) , repoLocation );
474
475         saveRemoteRepositoryConfig( id, "Target Repo-" + id, targetPath, layout );
476
477         return repoLocation;
478     }
479
480
481     /**
482      * Copy the specified resource directory from the src/test/repository/managed/ to
483      * the testable directory under target/test-repository/managed/${testName}/
484      *
485      * @param resourcePath
486      * @throws IOException
487      */
488     protected void setupTestableManagedRepository( String resourcePath )
489         throws IOException
490     {
491         String resourceDir = resourcePath;
492
493         if ( !resourcePath.endsWith( "/" ) )
494         {
495             int idx = resourcePath.lastIndexOf( '/' );
496             resourceDir = resourcePath.substring( 0, idx );
497         }
498
499         Path sourceRepoDir = Paths.get( REPOPATH_DEFAULT_MANAGED );
500         Path sourceDir = sourceRepoDir.resolve(resourceDir );
501
502         Path destRepoDir = managedDefaultDir;
503         Path destDir = destRepoDir.resolve(resourceDir );
504
505         // Cleanout destination dirs.
506         if ( Files.exists(destDir))
507         {
508             org.apache.archiva.common.utils.FileUtils.deleteDirectory( destDir );
509         }
510
511         // Make the destination dir.
512         Files.createDirectories(destDir);
513
514         // Test the source dir.
515         if ( !Files.exists(sourceDir) )
516         {
517             // This is just a warning.
518             log.error( "[WARN] Skipping setup of testable managed repository, source dir does not exist: {}", //
519                        sourceDir );
520         }
521         else
522         {
523
524             // Test that the source is a dir.
525             if ( !Files.isDirectory( sourceDir) )
526             {
527                 fail( "Unable to setup testable managed repository, source is not a directory: " + sourceDir );
528             }
529
530             // Copy directory structure.
531             copyDirectoryStructure( sourceDir, destDir );
532         }
533     }
534
535     protected void setManagedNewerThanRemote( Path managedFile, Path remoteFile )
536     {
537         setManagedNewerThanRemote( managedFile, remoteFile, 55000 );
538     }
539
540     protected void setManagedNewerThanRemote( Path managedFile, Path remoteFile, long time )
541     {
542         assertTrue( "Managed File should exist: ", Files.exists(managedFile) );
543         assertTrue( "Remote File should exist: ", Files.exists(remoteFile) );
544
545         try
546         {
547             Files.setLastModifiedTime( managedFile,
548                 FileTime.from(Files.getLastModifiedTime( remoteFile ).toMillis() + time, TimeUnit.MILLISECONDS ));
549         }
550         catch ( IOException e )
551         {
552             e.printStackTrace( );
553         }
554
555         try
556         {
557             assertTrue( Files.getLastModifiedTime( managedFile).compareTo( Files.getLastModifiedTime( remoteFile )) > 0);
558         }
559         catch ( IOException e )
560         {
561             e.printStackTrace( );
562         }
563     }
564
565     protected void setManagedOlderThanRemote( Path managedFile, Path remoteFile )
566     {
567         setManagedOlderThanRemote( managedFile, remoteFile, 55000 );
568     }
569
570     protected void setManagedOlderThanRemote( Path  managedFile, Path remoteFile, long time )
571     {
572         assertTrue( "Managed File should exist: ", Files.exists(managedFile) );
573         assertTrue( "Remote File should exist: ", Files.exists(remoteFile) );
574
575         try
576         {
577             Files.setLastModifiedTime( managedFile,
578                 FileTime.from(Files.getLastModifiedTime( remoteFile ).toMillis() - time, TimeUnit.MILLISECONDS ));
579         }
580         catch ( IOException e )
581         {
582             e.printStackTrace( );
583         }
584
585         try
586         {
587             assertTrue( Files.getLastModifiedTime( managedFile ).compareTo(Files.getLastModifiedTime( remoteFile  )) < 0 );
588         }
589         catch ( IOException e )
590         {
591             e.printStackTrace( );
592         }
593
594     }
595
596     protected void assertNotModified( Path file, long expectedModificationTime )
597     {
598         try
599         {
600             assertEquals( "File <" + file.toAbsolutePath() + "> not have been modified.", expectedModificationTime,
601                           Files.getLastModifiedTime( file ).toMillis());
602         }
603         catch ( IOException e )
604         {
605             e.printStackTrace( );
606         }
607     }
608
609
610     protected void assertNotExistsInManagedDefaultRepo( Path testFile )
611         throws Exception
612     {
613         Path managedDefaultPath = managedDefaultDir;
614
615         assertTrue( "Unit Test Failure: File <" + testFile
616                         + "> should be have been defined within the managed default path of <" + managedDefaultPath
617                         + ">", testFile.startsWith( managedDefaultPath ) );
618
619         assertFalse( "File < " + testFile + "> should not exist in managed default repository.", Files.exists(testFile) );
620     }
621
622     protected static Date getFutureDate()
623         throws ParseException
624     {
625         Calendar cal = Calendar.getInstance();
626         cal.add( Calendar.YEAR, 1 );
627         return cal.getTime();
628     }
629
630     protected static Date getPastDate()
631         throws ParseException
632     {
633         return new SimpleDateFormat( "yyyy-MM-dd", Locale.US ).parse( "2000-01-01" );
634     }
635 }