Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the way unit tests modify the timestamp of a file #77

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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