提交 7c568178 编写于 作者: J Jesse Glick

[FIXED JENKINS-21958] FilePath.copyRecursiveTo given a scanner including a...

[FIXED JENKINS-21958] FilePath.copyRecursiveTo given a scanner including a symlink but not any regular file in the same directory would neglect to create the parent directory on the destination and thus not copy the link.
(Util.createSymlink is partly to blame for not throwing a descriptive IOException when it fails to create a link,
but this is its historical behavior needed for compatibility.
copyRecursiveTo also continues to suppress error text from this method because there is nowhere for it to go.
Perhaps need a new variant of createSymlink that is guaranteed to either have created the link or throw an exception.)
上级 7b420175
......@@ -55,7 +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=>
<li class=bug>
Archiving of symlinks as artifacts did not work in some cases.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-21958">issue 21958</a>)
</ul>
</div><!--=TRUNK-END=-->
......
......@@ -1933,7 +1933,7 @@ public final class FilePath implements Serializable {
@Override public void visit(File f, String relativePath) throws IOException {
if (f.isFile()) {
File target = new File(dest, relativePath);
target.getParentFile().mkdirs();
IOUtils.mkdirs(target.getParentFile());
Util.copyFile(f, target);
count.incrementAndGet();
}
......@@ -1943,6 +1943,7 @@ public final class FilePath implements Serializable {
}
@Override public void visitSymlink(File link, String target, String relativePath) throws IOException {
try {
IOUtils.mkdirs(new File(dest, relativePath).getParentFile());
Util.createSymlink(dest, target, relativePath, TaskListener.NULL);
} catch (InterruptedException x) {
throw (IOException) new IOException(x.toString()).initCause(x);
......
......@@ -24,28 +24,32 @@
package hudson.tasks;
import hudson.model.AbstractProject;
import org.junit.Test;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Result;
import hudson.model.StreamBuildListener;
import hudson.tasks.LogRotatorTest.TestsFail;
import java.io.File;
import static hudson.tasks.LogRotatorTest.build;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import jenkins.util.VirtualFile;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.FailureBuilder;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestBuilder;
import static org.junit.Assert.*;
/**
* Verifies that artifacts from the last successful and stable builds of a job will be kept if requested.
......@@ -167,6 +171,37 @@ public class ArtifactArchiverTest {
assertEquals("(no artifacts)", Result.SUCCESS, build(project));
assertFalse(project.getBuildByNumber(1).getHasArtifacts());
}
@Bug(21958)
@Test public void symlinks() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
p.getBuildersList().add(new TestBuilder() {
@Override public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
FilePath ws = build.getWorkspace();
if (ws == null) {
return false;
}
FilePath dir = ws.child("dir");
dir.mkdirs();
dir.child("fizz").write("contents", null);
dir.child("lodge").symlinkTo("fizz", listener);
return true;
}
});
p.getPublishersList().add(new ArtifactArchiver("dir/lodge", "", false, true));
FreeStyleBuild b = j.assertBuildStatusSuccess(p.scheduleBuild2(0));
FilePath ws = b.getWorkspace();
assertNotNull(ws);
assumeTrue("May not be testable on Windows:\n" + JenkinsRule.getLog(b), ws.child("dir/lodge").exists());
List<FreeStyleBuild.Artifact> artifacts = b.getArtifacts();
assertEquals(1, artifacts.size());
FreeStyleBuild.Artifact artifact = artifacts.get(0);
assertEquals("dir/lodge", artifact.relativePath);
VirtualFile[] kids = b.getArtifactManager().root().child("dir").list();
assertEquals(1, kids.length);
assertEquals("lodge", kids[0].getName());
// do not check that it .exists() since its target has not been archived
}
private void runNewBuildAndStartUnitlIsCreated(AbstractProject project) throws InterruptedException{
int buildNumber = project.getNextBuildNumber();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册