提交 28bf5d80 编写于 作者: K Kohsuke Kawaguchi

[FIXED JENKINS-15587]

The actual fix was in the pull request #675.
......@@ -55,6 +55,9 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=bug>
Fixed a bad interaction between Windows symlinks and build record lazy loading.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-15587">issue 15587</a>)
<li class=rfe>
Remember the lastStable/Failed/Successful/etc builds to avoid eager loading builds.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-16089">issue 16089</a>)
......
......@@ -1140,6 +1140,21 @@ public class Util {
return resolveSymlink(link);
}
/**
* Resolves a symlink to the {@link File} that points to.
*
* @return null
* if the specified file is not a symlink.
*/
public static File resolveSymlinkToFile(File link) throws InterruptedException, IOException {
String target = resolveSymlink(link);
if (target==null) return null;
File f = new File(target);
if (f.isAbsolute()) return f; // absolute symlink
return new File(link.getParentFile(),target); // relative symlink
}
/**
* Resolves symlink, if the given file is a symlink. Otherwise return null.
* <p>
......
......@@ -341,6 +341,12 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
/*package*/ static long parseTimestampFromBuildDir(File buildDir) throws IOException {
try {
if(Util.isSymlink(buildDir)) {
// "Util.resolveSymlink(file)" resolves NTFS symlinks.
File target = Util.resolveSymlinkToFile(buildDir);
if(target != null)
buildDir = target;
}
// canonicalization to ensure we are looking at the ID in the directory name
// as opposed to build numbers which are used in symlinks
return ID_FORMATTER.get().parse(buildDir.getCanonicalFile().getName()).getTime();
......@@ -348,6 +354,8 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
throw new IOException2("Invalid directory name "+buildDir,e);
} catch (NumberFormatException e) {
throw new IOException2("Invalid directory name "+buildDir,e);
} catch (InterruptedException e) {
throw new IOException2("Interrupted while resolving symlink directory "+buildDir,e);
}
}
......
......@@ -24,10 +24,20 @@
package hudson.model;
import hudson.Util;
import hudson.util.StreamTaskListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.TimeZone;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.xml.stream.events.Characters;
import static org.junit.Assert.*;
import org.junit.Test;
import org.jvnet.hudson.test.Bug;
......@@ -77,4 +87,31 @@ public class RunTest {
}
}
@Bug(15587)
@Test
public void testParseTimestampFromBuildDir() throws Exception {
//Assume.assumeTrue(!Functions.isWindows() || (NTFS && JAVA7) || ...);
String buildDateTime = "2012-12-21_04-02-28";
int buildNumber = 155;
StreamTaskListener l = StreamTaskListener.fromStdout();
File tempDir = Util.createTempDir();
File buildDir = new File(tempDir, buildDateTime);
assertEquals(true, buildDir.mkdir());
File buildDirSymLink = new File(tempDir, Integer.toString(buildNumber));
try {
buildDir.mkdir();
Util.createSymlink(tempDir, buildDir.getAbsolutePath(), buildDirSymLink.getName(), l);
long time = Run.parseTimestampFromBuildDir(buildDirSymLink);
assertEquals(buildDateTime, Run.ID_FORMATTER.get().format(new Date(time)));
} finally {
Util.deleteRecursive(tempDir);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册