提交 a33e147a 编写于 作者: K Kohsuke Kawaguchi

[FIXED JENKINS-16979]

Added backward compatible data loader and a corresponding test case.
上级 3344dff2
......@@ -63,6 +63,9 @@ Upcoming changes</a>
<div id="rc" style="display:none;"><!--=BEGIN=-->
<h3><a name=v1.504>What's new in 1.504</a> <!--=DATE=--></h3>
<ul class=image>
<li class='major bug'>
Fixed a regression in the "discard old builds" in 1.503.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-16979">issue 16979</a>)
<li class='major bug'>
Maven 3.0.5 upgrade.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-16965">issue 16965</a>)
......
package jenkins.model;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.core.JVM;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.mapper.Mapper;
import hudson.ExtensionPoint;
import hudson.model.AbstractDescribableImpl;
import hudson.model.AbstractProject;
import hudson.model.Job;
import hudson.model.Run;
import hudson.tasks.LogRotator;
import hudson.util.RobustReflectionConverter;
import java.io.IOException;
......@@ -34,4 +44,38 @@ public abstract class BuildDiscarder extends AbstractDescribableImpl<BuildDiscar
public BuildDiscarderDescriptor getDescriptor() {
return (BuildDiscarderDescriptor)super.getDescriptor();
}
/**
* {@link AbstractProject#logRotator} used to be typed as {@link LogRotator},
* so such configuration file ends up trying to unmarshal {@link BuildDiscarder} and
* not its subtype.
*
* This converter makes this work by unmarshalling a {@link LogRotator}.
*/
public static class ConverterImpl implements Converter {
private RobustReflectionConverter ref;
public ConverterImpl(Mapper m) {
ref = new RobustReflectionConverter(m,new JVM().bestReflectionProvider()) {
@Override
protected Object instantiateNewInstance(HierarchicalStreamReader reader, UnmarshallingContext context) {
return reflectionProvider.newInstance(LogRotator.class);
}
};
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
// abstract class, so there shouldn't be any instance.
throw new UnsupportedOperationException();
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
// force unmarshal as LogRotator
return ref.unmarshal(reader,context);
}
public boolean canConvert(Class type) {
return type==BuildDiscarder.class;
}
}
}
package jenkins.model
import hudson.model.AbstractProject
import hudson.tasks.LogRotator
import org.jvnet.hudson.test.Bug
import org.jvnet.hudson.test.HudsonTestCase
import org.jvnet.hudson.test.recipes.LocalData
import javax.xml.transform.Source
import javax.xml.transform.stream.StreamSource
/**
*
*
* @author Kohsuke Kawaguchi
*/
public class BuildDiscarderTest extends HudsonTestCase {
@Bug(16979)
@LocalData
void testCompatibility() {
AbstractProject p = jenkins.getItem("foo")
verifyLogRotatorSanity(p)
// now persist in the new format
p.save()
def xml = p.configFile.asString()
// make sure this new format roundtrips by itself
p.buildDiscarder = null
p.updateByXml((Source)new StreamSource(new StringReader(xml)))
verifyLogRotatorSanity(p)
// another sanity check
assert xml.contains("<logRotator class=\"${LogRotator.class.name}\">")
}
private static void verifyLogRotatorSanity(AbstractProject p) {
LogRotator d = p.buildDiscarder
assert d.daysToKeep == 4;
assert d.numToKeep == 3;
assert d.artifactDaysToKeep == 2;
assert d.artifactNumToKeep == 1;
}
}
\ No newline at end of file
<?xml version='1.0' encoding='UTF-8'?>
<!--
Pre 1.503, LogRotator was a concrete class and saved like this
-->
<project>
<actions/>
<description></description>
<logRotator>
<daysToKeep>4</daysToKeep>
<numToKeep>3</numToKeep>
<artifactDaysToKeep>2</artifactDaysToKeep>
<artifactNumToKeep>1</artifactNumToKeep>
</logRotator>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers class="vector"/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册