From b4fe626f73acaa3d52453543752709261994635a Mon Sep 17 00:00:00 2001 From: Christoph Kutzinski Date: Fri, 30 Dec 2011 16:47:13 +0100 Subject: [PATCH] [JENKINS-11073] don't fail copyToWithPermissions if setting last-modified fails on Windows (more reliable detection of Windows platforms than before) --- core/src/main/java/hudson/FilePath.java | 34 ++++++++++++------ core/src/test/java/hudson/FilePathTest.java | 40 +++++++++++++++++++++ 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index 73646db2a2..fc2efecad2 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -1068,6 +1068,28 @@ public final class FilePath implements Serializable { } }); } + + private void setLastModifiedIfPossible(final long timestamp) throws IOException, InterruptedException { + String message = act(new FileCallable() { + private static final long serialVersionUID = -828220335793641630L; + public String invoke(File f, VirtualChannel channel) throws IOException { + if(!f.setLastModified(timestamp)) { + if (Functions.isWindows()) { + // On Windows this seems to fail often. See JENKINS-11073 + // Therefore don't fail, but just log a warning + return "Failed to set the timestamp of "+f+" to "+timestamp; + } else { + throw new IOException("Failed to set the timestamp of "+f+" to "+timestamp); + } + } + return null; + } + }); + + if (message!=null) { + LOGGER.warning(message); + } + } /** * Checks if the file is a directory. @@ -1424,17 +1446,7 @@ public final class FilePath implements Serializable { copyTo(target); // copy file permission target.chmod(mode()); - - try { - target.touch(lastModified()); - } catch (IOException e) { - // On Windows this seems to fail often. See JENKINS-11073 - if (!target.isUnix()) { - LOGGER.warning("Failed to set timestamp on " + target.getRemote()); - } else { // rethrow - throw new IOException2(e); - } - } + target.setLastModifiedIfPossible(lastModified()); } /** diff --git a/core/src/test/java/hudson/FilePathTest.java b/core/src/test/java/hudson/FilePathTest.java index dd385d8c92..477a08299e 100644 --- a/core/src/test/java/hudson/FilePathTest.java +++ b/core/src/test/java/hudson/FilePathTest.java @@ -43,6 +43,8 @@ import java.util.concurrent.Executors; import org.apache.commons.io.FileUtils; import org.apache.commons.io.output.NullOutputStream; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Chmod; import org.jvnet.hudson.test.Bug; /** @@ -315,5 +317,43 @@ public class FilePathTest extends ChannelTestCase { "/home/test"); assertTrue(unixPath.isUnix()); } + + /** + * Tests that permissions are kept when using {@link FilePath#copyToWithPermission(FilePath)}. + * Also tries to check that a problem with setting the last-modified date on Windows doesn't fail the whole copy + * - well at least when running this test on a Windows OS. See JENKINS-11073 + */ + public void testCopyToWithPermission() throws IOException, InterruptedException { + File tmp = Util.createTempDir(); + try { + File child = new File(tmp,"child"); + FilePath childP = new FilePath(child); + childP.touch(4711); + + Chmod chmodTask = new Chmod(); + chmodTask.setProject(new Project()); + chmodTask.setFile(child); + chmodTask.setPerm("0400"); + chmodTask.execute(); + + FilePath copy = new FilePath(british,tmp.getPath()).child("copy"); + childP.copyToWithPermission(copy); + + assertEquals(childP.mode(),copy.mode()); + if (!Functions.isWindows()) { + assertEquals(childP.lastModified(),copy.lastModified()); + } + + // JENKINS-11073: + // Windows seems to have random failures when setting the timestamp on newly generated + // files. So test that: + for (int i=0; i<100; i++) { + copy = new FilePath(british,tmp.getPath()).child("copy"+i); + childP.copyToWithPermission(copy); + } + } finally { + Util.deleteRecursive(tmp); + } + } }