Skip to content

Commit

Permalink
Fix the way unit tests modify the timestamp of a file
Browse files Browse the repository at this point in the history
The current approach is to copy the file until it gets a timestamp
newer than a given reference value.

Java 7 provides a better method to modify a file timestamp -
`Files.setLastModifiedTime`. Use it instead the current approach.
Not only it is better suited for the task, but Plexus Utils 3.1.0
no longer updates the timestamp of copied files and the current
approach is no longer working one - the tests are running
in endless loop.

This closes #77
  • Loading branch information
plamentotev committed Jan 13, 2018
1 parent c1bb12c commit 293b1d4
Showing 1 changed file with 42 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
package org.codehaus.plexus.archiver;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.FileTime;

import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.util.FileUtils;

Expand All @@ -35,31 +39,54 @@ public abstract class BasePlexusArchiverTest extends PlexusTestCase
{

/**
* Ensure that when a new file is created at the specified location that the timestamp of
* that file will be greater than the one specified as a reference.
*
* Warning: Runs in a busy loop creating a file until the output file is newer than the reference timestamp.
* This should be better than sleeping for a race condition time out value.
* Ensure that the last modified timestamp of a file will be greater
* than the one specified as a reference.
*
* @param outputFile the file to be created
* @param timestampReference the created file will have a newer timestamp than this reference timestamp.
* @param outputFile the file
* @param timestampReference the file will have a newer timestamp
* than this reference timestamp.
*
* @throws Exception failures
* @throws IOException if the timestamp could not be modified
*/
protected void waitUntilNewTimestamp( File outputFile, long timestampReference ) throws Exception
protected void waitUntilNewTimestamp( File outputFile, long timestampReference )
throws IOException
{
File tmpFile = File.createTempFile( "ZipArchiverTest.waitUntilNewTimestamp", null );
// slurp the file into a temp file and then copy the temp back over the top until it is newer.
FileUtils.copyFile( outputFile, tmpFile );
long startTime = System.currentTimeMillis();
File tmpFile = File.createTempFile(
"BasePlexusArchiverTest.waitUntilNewTimestamp", null );
long newTimestamp;

FileUtils.copyFile( tmpFile, outputFile );
while ( timestampReference >= outputFile.lastModified() )
// We could easily just set the last modified time using
// Files.setLastModifiedTime and System.currentTimeMillis(),
// but the problem is that tests are using this method to verify that
// the force flag is working. To ensure that modified or
// newly created files will have timestamp newer than
// `timestampReference`, we need to modify a file ourself.
// Otherwise the build may fail because when the test overrides
// `outputFile` it will have timestamp that is equal
// to `timestampReference`.
do
{
FileUtils.copyFile( tmpFile, outputFile );
FileUtils.fileWrite( tmpFile, "waitUntilNewTimestamp" );
newTimestamp = tmpFile.lastModified();
Thread.yield();
}
while ( timestampReference >= newTimestamp
// A simple guard to ensure that we'll not do this forever.
// If the last modified timestamp is not changed to
// a newer value after 10 seconds, probably it never will.
&& System.currentTimeMillis() - startTime < 10_000 );

tmpFile.delete();

if ( timestampReference >= newTimestamp )
{
throw new IOException("Could not modify the last modified timestamp "
+ "to newer than the refence value." );
}

FileTime newTimestampTime = FileTime.fromMillis( newTimestamp );
Files.setLastModifiedTime( outputFile.toPath(), newTimestampTime );
}

/**
Expand Down

0 comments on commit 293b1d4

Please sign in to comment.