提交 b7a6c5d5 编写于 作者: O Olivier Lamy

fix changelog

......@@ -30,4 +30,5 @@ debian/configure-stamp
*.debhelper.log
jenkins_*.build
jenkins_*.changes
*.deb
push-build.sh
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head id="head">
<!--
We record noteworthy changes in this file, which then become http://jenkins-ci.org/changelog
Some tips:
- record your changes between "TRUNK-BEGIN" and "TRUNK-END".
(unless you are making changes in the RC branch, in which case it goes
to the rc section.
- there are four CSS classes to denote the kind of changes. "rfe" for enhancement and "bug" for bug fixes,
plus 'major' to indicate major RFE/bugfix.
- link to bugs in the issue tracker, e-mail thread in the archive, and so on if you can.
-->
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Changelog</title>
<link rel="alternate" title="Hudson announcements" href="https://hudson.dev.java.net/servlets/ProjectNewsRSS" type="application/rss+xml">
<link rel="stylesheet" TYPE="text/css" href="changelog.css">
......@@ -22,14 +40,14 @@
<div id="ratings" style="display:none; font-size:120%;
border:1px solid black; background-color:#eee; padding:0.5em; margin-bottom:1em">
Help other Hudson users by letting the community know which releases you've used,
and whether they had any significant issues. <br/>
Legend: <br/>
and whether they had any significant issues. <br>
Legend: <br>
<img src="http://ci.jenkins-ci.org/images/16x16/health-80plus.gif" width="16" height="16"
alt="Sunny"/> = I use it on my production site without major issues. <br/>
alt="Sunny"> = I use it on my production site without major issues. <br>
<img src="http://ci.jenkins-ci.org/images/16x16/health-40to59.gif" width="16" height="16"
alt="Cloudy"/> = I don't recommend it. <br/>
alt="Cloudy"> = I don't recommend it. <br>
<img src="http://ci.jenkins-ci.org/images/16x16/health-00to19.gif" width="16" height="16"
alt="Lightning"/> = I tried it but rolled back to a previous version. <br/>
alt="Lightning"> = I tried it but rolled back to a previous version. <br>
View ratings below, and click one of the icons next to your version to provide your input.
</div>
......@@ -39,6 +57,22 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=bug>
MavenBuild does not respect the "alternate settings" value of its parent MavenModuleSetBuild
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-8670">issue 8670</a>)
<li class=bug>
Jenkins wasn't telling build wrappers that builds were aborted when they were aborted.
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-8054">issue 8054</a>)
<li class=bug>
Maven deployment with uniqueVersion == true creating "new" versions for attached artifacts
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-8651">issue 8651</a>)
</ul>
</div><!--=TRUNK-END=-->
<!-- these changes are controlled by the release process. DO NOT MODIFY -->
<div id="rc" style="display:none;"><!--=BEGIN=-->
<h3><a name=v1.397>What's new in 1.397</a> <!--=DATE=--></h3>
<ul class=image>
<li class='major bug'>
Fixed a master/slave communication problem since 1.378 that often manifests as "Not in GZIP format"
......@@ -59,17 +93,26 @@ Upcoming changes</a>
Windows XP slave stopped working in 1.396 (related to name change)
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-8676">issue 8676</a>)
<li class=bug>
Maven deployment with uniqueVersion == true creating "new" versions for attached artifacts
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-8651">issue 8651</a>)
Unnecessary log messages if a remote pipe is not read until EOF
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-8592">issue 8592</a>)
<li class=bug>
Fixed a bug in the calendar computation.
(<a href="http://issues.hudson-ci.org/browse/HUDSON-8656">issue 8656 in Hudson</a>)
<li class=bug>
Fixed an NPE when loading full build history.
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-8660">issue 8660</a>)
<li class=bug>
EXECUTOR_NUMBER uniqueness can degrate over time
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-4756">issue 4756</a>)
<li class=rfe>
build RSS feeds now contain description of builds.
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-3935">issue 3935</a>)
<li class=rfe>
Debian package will force-terminate Jenkins if it fails to shut down in 5 seconds.
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-5415">issue 5415</a>)
</ul>
</div><!--=TRUNK-END=-->
<!-- these changes are controlled by the release process. DO NOT MODIFY -->
<div id="rc" style="display:none;"><!--=BEGIN=-->
<h3><a name=v1.396>What's new in 1.396</a> <!--=DATE=--></h3>
</div><!--=END=-->
<h3><a name=v1.396>What's new in 1.396</a> (2011/02/02)</h3>
<ul class=image>
<li class=bug>
Fixed a bug in crontab "day of week" handling in locales where a week starts from Monday.
......@@ -83,10 +126,9 @@ Upcoming changes</a>
If the JNLP-connected slave drops out without the master not noticing, allow the reconnection
without rejecting it.
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-5055">issue 5055</a>)
<li class'major rfe'>
<li class='major rfe'>
Fixed a trademark bug that caused a considerable fiasco by renaming to Jenkins
</ul>
</div><!--=END=-->
<h3><a name=v1.395>What's new in 1.395</a> (2011/01/21)</h3>
<ul class=image>
<li class=bug>
......@@ -294,7 +336,7 @@ Upcoming changes</a>
<li class=rfe>
Update bundled subversion plugin to version 1.20 and ssh-slaves to version 0.14.
</ul>
<s><h4><a name=v1.385>What's new in 1.385</a> (2010/11/15)</h4></s>
<h4><s><a name=v1.385>What's new in 1.385</a> (2010/11/15)</s></h4>
<ul class=image>
<li class=rfe> Oops, same as 1.384
</ul>
......@@ -355,7 +397,7 @@ Upcoming changes</a>
<li class=rfe>
Improved packet fragmentation in Winstone when writing out HTTP responses.
<li class=rfe><a href="http://wiki.jenkins-ci.org/display/JENKINS//Extension+Point+for+Project+Views+Navigation">Extension Point to provide alternate UI for Project Views implemented</a>
</l> (<a href="http://issues.jenkins-ci.org/browse/JENKINS-1467">issue 1467</a>)
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-1467">issue 1467</a>)
</ul>
<h3><a name=v1.380>What's new in 1.380</a> (2010/10/09)</h3>
<ul class=image>
......@@ -630,7 +672,7 @@ Upcoming changes</a>
Fix redirect after login when return URL has characters that need encoding.
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-6960">issue 6960</a>)
<li class=bug>
&lt;input type='hidden'> field shouldn't be getting the plain text password value.
&lt;input type='hidden'&gt; field shouldn't be getting the plain text password value.
<li class=rfe>
Added a mechanism to register CLI option handler as an extension point.
<li class=rfe>
......@@ -1583,7 +1625,7 @@ Upcoming changes</a>
(<a href="http://issues.jenkins-ci.org/browse/JENKINS-4752">issue 4752</a>)
<li class='major bug'>
Fixed <tt>NotExportableException</tt> when making a remote API call on a project.
(<a href="https://hudson.dev.java.net/servlets/BrowseList?list=users&by=thread&from=2222483">report</a>)
(<a href="https://hudson.dev.java.net/servlets/BrowseList?list=users&amp;by=thread&amp;from=2222483">report</a>)
<li class=bug>
Fixed <tt>IllegalArgumentException: name</tt>
(<a href="http://old.nabble.com/bug-1.331-to26145963.html">report</a>)
......
......@@ -4,7 +4,7 @@
<parent>
<artifactId>pom</artifactId>
<groupId>org.jenkins-ci.main</groupId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
</parent>
<artifactId>cli</artifactId>
<name>Jenkins CLI</name>
......
......@@ -28,7 +28,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -1819,7 +1819,7 @@ public final class FilePath implements Serializable {
value = fixEmpty(value);
// none entered yet, or something is seriously wrong
if(value==null || (AbstractProject<?,?>)subject ==null) return FormValidation.ok();
if(value==null) return FormValidation.ok();
// a common mistake is to use wildcard
if(value.contains("*")) return FormValidation.error(Messages.FilePath_validateRelativePath_wildcardNotAllowed());
......
......@@ -193,7 +193,7 @@ public class MarkupText extends AbstractMarkupText {
* Replaces the group tokens like "$0", "$1", and etc with their actual matches.
*/
public String replace(String s) {
StringBuffer buf = new StringBuffer();
StringBuilder buf = new StringBuilder(s.length() + 10);
for( int i=0; i<s.length(); i++) {
char ch = s.charAt(i);
......
......@@ -227,8 +227,9 @@ public abstract class Plugin implements Saveable {
*/
public void save() throws IOException {
if(BulkChange.contains(this)) return;
getConfigXml().write(this);
SaveableListener.fireOnChange(this, getConfigXml());
XmlFile config = getConfigXml();
config.write(this);
SaveableListener.fireOnChange(this, config);
}
/**
......
......@@ -485,9 +485,10 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
* or null if there's no back up.
*/
public String getBackupVersion() {
if (getBackupFile().exists()) {
File backup = getBackupFile();
if (backup.exists()) {
try {
JarFile backupPlugin = new JarFile(getBackupFile());
JarFile backupPlugin = new JarFile(backup);
return backupPlugin.getManifest().getMainAttributes().getValue("Plugin-Version");
} catch (IOException e) {
LOGGER.log(WARNING, "Failed to get backup version ", e);
......
......@@ -89,8 +89,9 @@ public final class ProxyConfiguration implements Saveable {
public void save() throws IOException {
if(BulkChange.contains(this)) return;
getXmlFile().write(this);
SaveableListener.fireOnChange(this, getXmlFile());
XmlFile config = getXmlFile();
config.write(this);
SaveableListener.fireOnChange(this, config);
}
public static XmlFile getXmlFile() {
......
......@@ -1033,7 +1033,7 @@ public class Util {
listener.getLogger().println(String.format("ln -s %s %s failed: %d %s",targetPath, symlinkFile, r, errmsg));
} catch (IOException e) {
PrintStream log = listener.getLogger();
log.printf("ln %s %s failed\n",targetPath, new File(baseDir, symlinkPath));
log.printf("ln %s %s failed%n",targetPath, new File(baseDir, symlinkPath));
Util.displayIOException(e,listener);
e.printStackTrace( log );
}
......
......@@ -116,7 +116,8 @@ public class InstallPluginCommand extends CLICommand {
Data dt = s.getData();
if (dt==null)
stdout.println(Messages.InstallPluginCommand_NoUpdateDataRetrieved(s.getUrl()));
candidates.addAll(dt.plugins.keySet());
else
candidates.addAll(dt.plugins.keySet());
}
stdout.println(Messages.InstallPluginCommand_DidYouMean(source,EditDistance.findNearest(source,candidates)));
}
......
......@@ -60,7 +60,7 @@ public class ListChangesCommand extends AbstractBuildRangeCommand {
for (AbstractBuild build : builds) {
ChangeLogSet<?> cs = build.getChangeSet();
for (Entry e : cs) {
stdout.printf("%s,%s\n",
stdout.printf("%s,%s%n",
QuotedStringTokenizer.quote(e.getAuthor().getId()),
QuotedStringTokenizer.quote(e.getMsg()));
}
......@@ -70,7 +70,7 @@ public class ListChangesCommand extends AbstractBuildRangeCommand {
for (AbstractBuild build : builds) {
ChangeLogSet<?> cs = build.getChangeSet();
for (Entry e : cs) {
stdout.printf("%s\t%s\n",e.getAuthor(),e.getMsg());
stdout.printf("%s\t%s%n",e.getAuthor(),e.getMsg());
for (String p : e.getAffectedPaths())
stdout.println(" "+p);
}
......
......@@ -220,7 +220,7 @@ public class MatrixBuild extends AbstractBuild<MatrixProject,MatrixBuild> {
}
if (p.getTouchStoneResultCondition() != null && r.isWorseThan(p.getTouchStoneResultCondition())) {
logger.printf("Touchstone configurations resulted in %s, so aborting...\n", r);
logger.printf("Touchstone configurations resulted in %s, so aborting...%n", r);
return r;
}
......
......@@ -425,14 +425,16 @@ public abstract class AbstractBuild<P extends AbstractProject<P,R>,R extends Abs
// error message doesn't point users to the slave. So let's do it here.
listener.hyperlink("/computer/"+builtOn+"/log","Looks like the node went offline during the build. Check the slave log for the details.");
// grab the end of the log file. This might not work very well if the slave already
// starts reconnecting. Fixing this requires a ring buffer in slave logs.
AnnotatedLargeText<Computer> log = c.getLogText();
StringWriter w = new StringWriter();
log.writeHtmlTo(Math.max(0,c.getLogFile().length()-10240),w);
listener.getLogger().print(ExpandableDetailsNote.encodeTo("details",w.toString()));
listener.getLogger().println();
if (c != null) {
// grab the end of the log file. This might not work very well if the slave already
// starts reconnecting. Fixing this requires a ring buffer in slave logs.
AnnotatedLargeText<Computer> log = c.getLogText();
StringWriter w = new StringWriter();
log.writeHtmlTo(Math.max(0,c.getLogFile().length()-10240),w);
listener.getLogger().print(ExpandableDetailsNote.encodeTo("details",w.toString()));
listener.getLogger().println();
}
}
// kill run-away processes that are left
......
......@@ -37,6 +37,7 @@ import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;
import static hudson.model.Result.ABORTED;
import static hudson.model.Result.FAILURE;
/**
......@@ -136,6 +137,9 @@ public abstract class Build <P extends Project<P,B>,B extends Build<P,B>>
if(!build(listener,project.getBuilders()))
r = FAILURE;
} catch (InterruptedException e) {
r = ABORTED;
throw e;
} finally {
if (r != null) setResult(r);
// tear down in reverse order
......
......@@ -25,12 +25,10 @@
package hudson.model;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Util;
import hudson.cli.declarative.CLIMethod;
import hudson.console.AnnotatedLargeText;
import hudson.model.Descriptor.FormException;
import hudson.model.Hudson.MasterComputer;
import hudson.model.queue.WorkUnit;
import hudson.node_monitors.NodeMonitor;
import hudson.remoting.Channel;
......@@ -59,7 +57,6 @@ import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.HttpResponses;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.HttpRedirect;
import org.kohsuke.stapler.WebMethod;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import org.kohsuke.args4j.Option;
......@@ -69,11 +66,7 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Enumeration;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
......@@ -596,11 +589,22 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
e.interrupt();
} else {
// if the number is increased, add new ones
while(executors.size()<numExecutors) {
Executor e = new Executor(this, executors.size());
e.start();
executors.add(e);
}
addNewExecutorIfNecessary();
}
}
private void addNewExecutorIfNecessary() {
Set<Integer> availableNumbers = new HashSet<Integer>();
for (int i = 0; i < numExecutors; i++)
availableNumbers.add(i);
for (Executor executor : executors)
availableNumbers.remove(executor.getNumber());
for (Integer number : availableNumbers) {
Executor e = new Executor(this, number);
e.start();
executors.add(e);
}
}
......@@ -700,6 +704,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
*/
/*package*/ synchronized void removeExecutor(Executor e) {
executors.remove(e);
addNewExecutorIfNecessary();
if(!isAlive())
Hudson.getInstance().removeComputer(this);
}
......
......@@ -798,8 +798,6 @@ public abstract class Descriptor<T extends Describable<T>> implements Saveable {
List<T> newInstancesFromHeteroList(StaplerRequest req, JSONObject formData, String key,
Collection<? extends Descriptor<T>> descriptors) throws FormException {
List<T> items = new ArrayList<T>();
return newInstancesFromHeteroList(req,formData.get(key),descriptors);
}
......
......@@ -1766,7 +1766,8 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
env = c.getEnvironment().overrideAll(env);
String rootUrl = Hudson.getInstance().getRootUrl();
if(rootUrl!=null) {
env.put("HUDSON_URL", rootUrl);
env.put("JENKINS_URL", rootUrl);
env.put("HUDSON_URL", rootUrl); // Legacy compatibility
env.put("BUILD_URL", rootUrl+getUrl());
env.put("JOB_URL", rootUrl+getParent().getUrl());
}
......@@ -1796,7 +1797,8 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
*/
public final EnvVars getCharacteristicEnvVars() {
EnvVars env = new EnvVars();
env.put("HUDSON_SERVER_COOKIE",Util.getDigestOf("ServerID:"+Hudson.getInstance().getSecretKey()));
env.put("JENKINS_SERVER_COOKIE",Util.getDigestOf("ServerID:"+Hudson.getInstance().getSecretKey()));
env.put("HUDSON_SERVER_COOKIE",Util.getDigestOf("ServerID:"+Hudson.getInstance().getSecretKey())); // Legacy compatibility
env.put("BUILD_NUMBER",String.valueOf(number));
env.put("BUILD_ID",getId());
env.put("BUILD_TAG","hudson-"+getParent().getName()+"-"+number);
......@@ -1926,8 +1928,7 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
}
public String getEntryDescription(Run entry) {
// TODO: this could provide some useful details
return null;
return entry.getDescription();
}
public Calendar getEntryTimestamp(Run entry) {
......
......@@ -218,18 +218,23 @@ public final class CronTab {
private static final CalendarField DAY_OF_WEEK = new CalendarField("dow", Calendar.DAY_OF_WEEK, 1,-1, true, HOUR) {
long bits(CronTab c) { return c.dayOfWeek; }
void rollUp(Calendar cal, int i) {
cal.add(Calendar.DAY_OF_WEEK,7);
cal.add(Calendar.DAY_OF_WEEK, 7 * i);
}
@Override
void setTo(Calendar c, int i) {
int v = i-offset;
int was = c.get(field);
c.set(field,v);
if (v<c.getFirstDayOfWeek()) {
final int firstDayOfWeek = c.getFirstDayOfWeek();
if (v < firstDayOfWeek && was >= firstDayOfWeek) {
// in crontab, the first DoW is always Sunday, but in Java, it can be Monday or in theory arbitrary other days.
// When first DoW is 1/2 Monday, calendar points to 1/2 Monday, setting the DoW to Sunday makes
// the calendar moves forward to 1/8 Sunday, instead of 1/1 Sunday. So we need to compensate that effect here.
addTo(c,-7);
} else if (was < firstDayOfWeek && firstDayOfWeek <= v) {
// If we wrap the other way around, we need to adjust in the opposite direction of above.
addTo(c, 7);
}
}
};
......
......@@ -37,6 +37,7 @@ import org.kohsuke.stapler.StaplerResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.Serializable;
/**
* Abstraction for a login mechanism through external authenticator/identity provider
......@@ -109,7 +110,7 @@ public abstract class FederatedLoginService implements ExtensionPoint {
/**
* Identity information as obtained from {@link FederatedLoginService}.
*/
public abstract class FederatedIdentity {
public abstract class FederatedIdentity implements Serializable {
/**
* Gets the string representation of the identity in the form that makes sense to the enclosing
* {@link FederatedLoginService}, such as full OpenID URL.
......
......@@ -580,7 +580,7 @@ public class SlaveComputer extends Computer {
// if this method is called from within the slave computation thread, this should work
Channel c = Channel.current();
if (c!=null && c.getProperty("slave")==Boolean.TRUE)
if (c!=null && Boolean.TRUE.equals(c.getProperty("slave")))
return c;
return null;
......
......@@ -170,8 +170,8 @@ public final class TestResult extends MetaTabulatedResult {
File f = new File(baseDir,includedFiles[0]);
throw new AbortException(
String.format(
"Test reports were found but none of them are new. Did tests run? \n"+
"For example, %s is %s old\n", f,
"Test reports were found but none of them are new. Did tests run? %n"+
"For example, %s is %s old%n", f,
Util.getTimeSpanString(buildTime-f.lastModified())));
}
}
......
......@@ -103,8 +103,8 @@ public abstract class DefaultTestResultParserImpl extends TestResultParser imple
// none of the files were new
throw new AbortException(
String.format(
"Test reports were found but none of them are new. Did tests run? \n"+
"For example, %s is %s old\n", paths[0].getRemote(),
"Test reports were found but none of them are new. Did tests run? %n"+
"For example, %s is %s old%n", paths[0].getRemote(),
Util.getTimeSpanString(localBuildTime-paths[0].lastModified())));
}
......
......@@ -148,11 +148,6 @@ public abstract class Graph {
public void doMap(StaplerRequest req, StaplerResponse rsp) throws IOException {
if (req.checkIfModified(timestamp, rsp)) return;
String w = req.getParameter("width");
if(w==null) w=String.valueOf(defaultW);
String h = req.getParameter("height");
if(h==null) h=String.valueOf(defaultH);
ChartRenderingInfo info = new ChartRenderingInfo();
render(req,info);
......
......@@ -441,58 +441,55 @@ public class QuotedStringTokenizer
if (first!=last || (first!='"' && first!='\''))
return s;
StringBuffer b=new StringBuffer(s.length()-2);
synchronized(b)
StringBuilder b=new StringBuilder(s.length()-2);
boolean escape=false;
for (int i=1;i<s.length()-1;i++)
{
boolean escape=false;
for (int i=1;i<s.length()-1;i++)
{
char c = s.charAt(i);
char c = s.charAt(i);
if (escape)
{
escape=false;
switch (c)
{
case 'n':
b.append('\n');
break;
case 'r':
b.append('\r');
break;
case 't':
b.append('\t');
break;
case 'f':
b.append('\f');
break;
case 'b':
b.append('\b');
break;
case 'u':
b.append((char)(
(convertHexDigit((byte)s.charAt(i++))<<24)+
(convertHexDigit((byte)s.charAt(i++))<<16)+
(convertHexDigit((byte)s.charAt(i++))<<8)+
(convertHexDigit((byte)s.charAt(i++)))
)
);
break;
default:
b.append(c);
}
}
else if (c=='\\')
if (escape)
{
escape=false;
switch (c)
{
escape=true;
continue;
case 'n':
b.append('\n');
break;
case 'r':
b.append('\r');
break;
case 't':
b.append('\t');
break;
case 'f':
b.append('\f');
break;
case 'b':
b.append('\b');
break;
case 'u':
b.append((char)(
(convertHexDigit((byte)s.charAt(i++))<<24)+
(convertHexDigit((byte)s.charAt(i++))<<16)+
(convertHexDigit((byte)s.charAt(i++))<<8)+
(convertHexDigit((byte)s.charAt(i++)))
)
);
break;
default:
b.append(c);
}
else
b.append(c);
}
return b.toString();
else if (c=='\\')
{
escape=true;
continue;
}
else
b.append(c);
}
return b.toString();
}
/* ------------------------------------------------------------ */
......
......@@ -105,7 +105,7 @@ public class VersionNumber implements Comparable<VersionNumber> {
@Override
public String toString() {
StringBuffer buf = new StringBuffer();
StringBuilder buf = new StringBuilder();
for( int i=0; i<digits.length; i++ ) {
if(i!=0) buf.append('.');
buf.append( Integer.toString(digits[i]) );
......
......@@ -391,9 +391,9 @@ public class BeanBuilder extends GroovyObjectSupport {
private void finalizeDeferredProperties() {
for (DeferredProperty dp : deferredProperties.values()) {
if (dp.value instanceof List) {
dp.value = manageListIfNecessary(dp.value);
dp.value = manageListIfNecessary((List)dp.value);
} else if (dp.value instanceof Map) {
dp.value = manageMapIfNecessary(dp.value);
dp.value = manageMapIfNecessary((Map)dp.value);
}
dp.setInBeanConfig();
}
......@@ -558,10 +558,9 @@ public class BeanBuilder extends GroovyObjectSupport {
* @param value The current map
* @return A ManagedMap or a normal map
*/
private Object manageMapIfNecessary(Object value) {
Map<Object,Object> map = (Map)value;
private Object manageMapIfNecessary(Map<Object, Object> value) {
boolean containsRuntimeRefs = false;
for (Entry<Object,Object> e : map.entrySet()) {
for (Entry<Object, Object> e : value.entrySet()) {
Object v = e.getValue();
if (v instanceof RuntimeBeanReference) {
containsRuntimeRefs = true;
......@@ -575,7 +574,7 @@ public class BeanBuilder extends GroovyObjectSupport {
if(containsRuntimeRefs) {
// return new ManagedMap(map);
ManagedMap m = new ManagedMap();
m.putAll(map);
m.putAll(value);
return m;
}
return value;
......@@ -588,10 +587,9 @@ public class BeanBuilder extends GroovyObjectSupport {
* @param value The object that represents the list
* @return Either a new list or a managed one
*/
private Object manageListIfNecessary(Object value) {
List list = (List)value;
private Object manageListIfNecessary(List<Object> value) {
boolean containsRuntimeRefs = false;
for (ListIterator i = list.listIterator(); i.hasNext();) {
for (ListIterator<Object> i = value.listIterator(); i.hasNext();) {
Object e = i.next();
if(e instanceof RuntimeBeanReference) {
containsRuntimeRefs = true;
......@@ -604,7 +602,7 @@ public class BeanBuilder extends GroovyObjectSupport {
}
if(containsRuntimeRefs) {
List tmp = new ManagedList();
tmp.addAll((List)value);
tmp.addAll(value);
value = tmp;
}
return value;
......@@ -660,4 +658,4 @@ public class BeanBuilder extends GroovyObjectSupport {
this.binding = b.getVariables();
}
}
\ No newline at end of file
}
......@@ -27,6 +27,7 @@ import hudson.Functions;
import hudson.model.ModelObject;
import hudson.model.Run;
import org.kohsuke.stapler.Header;
import org.kohsuke.stapler.HttpResponses;
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
......@@ -37,6 +38,8 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
/**
* Displays the history of records (normally {@link Run}s) on the side panel.
*
......@@ -151,6 +154,8 @@ public class HistoryWidget<O extends ModelObject,T> extends Widget {
public void doAjax( StaplerRequest req, StaplerResponse rsp,
@Header("n") String n ) throws IOException, ServletException {
if (n==null) throw HttpResponses.error(SC_BAD_REQUEST,new Exception("Missing the 'n' HTTP header"));
rsp.setContentType("text/html;charset=UTF-8");
// pick up builds to send back
......
......@@ -48,6 +48,13 @@ THE SOFTWARE.
<tr class="build-row">
<td colspan="3" align="right">
<script>
function replace(a, b) {
var p = a.parentNode;
var next = a.nextSibling;
p.removeChild(a);
p.insertBefore(b,next);
}
function loadAllBuildHistory() {
// first display the "loading..." icon
var box = $("loadAllBuildHistory");
......@@ -59,14 +66,12 @@ THE SOFTWARE.
onComplete: function(rsp,_) {
<!-- neither outerHTML nor responseXML works in Firefox 2.0 -->
var hist = $$("buildHistory");
var p = hist.parentNode;
var next = hist.nextSibling;
p.removeChild(hist);
var div = document.createElement('div');
div.innerHTML = rsp.responseText;
var newhist = document.createElement('div');
newhist.innerHTML = rsp.responseText;
newhist.headers = hist.headers
p.insertBefore(div,next);
replace(hist, newhist);
}
});
}
......
......@@ -51,7 +51,7 @@ public class UpdateCenterTest extends TestCase {
UpdateSite us = new UpdateSite("default", url.toExternalForm());
UpdateSite.Data data = us.new Data(JSONObject.fromObject(json));
assertTrue(data.core.url.startsWith("http://updates.hudson-labs.org/"));
assertTrue(data.core.url.startsWith("http://updates.jenkins-ci.org/"));
assertTrue(data.plugins.containsKey("rake"));
System.out.println(data.core.url);
}
......
package hudson.scheduler;
import static org.junit.Assert.assertEquals;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.Locale;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.jvnet.hudson.test.For;
import org.jvnet.hudson.test.Url;
/**
* A collection of unit tests focused around crontabs restricted to particular
* days of the week. This flexes across all the locales in the system to check
* the correctness of the {@link CronTab} class, more specifically the
* {@link CronTab#floor(Calendar)} and {@link CronTab#ceil(Calendar)} methods.
*/
@For(CronTab.class)
@RunWith(Parameterized.class)
public class CronTabDayOfWeekLocaleTest {
@Parameters
public static Collection<Object[]> parameters() {
final Locale[] locales = Locale.getAvailableLocales();
final Collection<Object[]> parameters = new ArrayList<Object[]>();
for (final Locale locale : locales) {
final Calendar cal = Calendar.getInstance(locale);
if (GregorianCalendar.class.equals(cal.getClass())) {
parameters.add(new Object[] { locale });
}
}
return parameters;
}
private final Locale locale;
public CronTabDayOfWeekLocaleTest(Locale locale) {
this.locale = locale;
}
/**
* This unit test is an slight adaptation of the unit test found in
* HUDSON-8656.
*/
@Test
@Url("http://issues.hudson-ci.org/browse/HUDSON-8656")
public void hudson8658() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 23 * * 1-5"; // execute on weekdays @23:00
final CronTab cron = new CronTab(cronStr);
final Calendar next = cron.ceil(cal);
final Calendar expectedDate = Calendar.getInstance();
// Expected next: Monday, Jan 17th 2011, 23:00
expectedDate.set(2011, 0, 17, 23, 0, 0);
compare(expectedDate, next);
}
@Test
public void isSundayAndNextRunIsMonday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 1"; // Mondays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.ceil(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Monday, Jan 17th 2011, 00:00
expected.set(2011, 0, 17, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndPreviousRunIsMonday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 1"; // Mondays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.floor(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Monday, Jan 10th 2011, 00:00
expected.set(2011, 0, 10, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndNextRunIsTuesday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 2"; // Tuesdays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.ceil(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Tuesday, Jan 18th 2011, 00:00
expected.set(2011, 0, 18, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndPreviousRunIsTuesday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 2"; // Tuesdays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.floor(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Tuesday, Jan 11th 2011, 00:00
expected.set(2011, 0, 11, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndNextRunIsWednesday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 3"; // Wednesdays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.ceil(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Wednesday, Jan 19th 2011, 00:00
expected.set(2011, 0, 19, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndPreviousRunIsWednesday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 3"; // Wednesdays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.floor(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Wednesday, Jan 12th 2011, 00:00
expected.set(2011, 0, 12, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndNextRunIsThursday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 4"; // Thursdays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.ceil(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Thursday, Jan 20th 2011, 00:00
expected.set(2011, 0, 20, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndPreviousRunIsThursday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 4"; // Thursdays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.floor(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Thursday, Jan 13th 2011, 00:00
expected.set(2011, 0, 13, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndNextRunIsFriday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 5"; // Fridays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.ceil(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Friday, Jan 21th 2011, 00:00
expected.set(2011, 0, 21, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndPreviousRunIsFriday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 5"; // Fridays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.floor(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Friday, Jan 14th 2011, 00:00
expected.set(2011, 0, 14, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndNextRunIsSaturday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 6"; // Saturdays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.ceil(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Saturday, Jan 22th 2011, 00:00
expected.set(2011, 0, 22, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndPreviousRunIsSaturday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 0 * * 6"; // Saturdays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.floor(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Saturday, Jan 15th 2011, 00:00
expected.set(2011, 0, 15, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndNextRunIsNextSunday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 1, 0, 0); // Sunday, Jan 16th 2011, 01:00
final String cronStr = "0 0 * * 0"; // Sundays @00:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.ceil(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Sunday, Jan 22th 2011, 00:00
expected.set(2011, 0, 23, 0, 0, 0);
compare(expected, actual);
}
@Test
public void isSundayAndNextRunIsPreviousSunday() throws Exception {
final Calendar cal = Calendar.getInstance(locale);
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 1 * * 0"; // Sundays @01:00
final CronTab cron = new CronTab(cronStr);
final Calendar actual = cron.floor(cal);
final Calendar expected = Calendar.getInstance();
// Expected next: Sunday, Jan 9th 2011, 01:00
expected.set(2011, 0, 9, 1, 0, 0);
compare(expected, actual);
}
private void compare(final Calendar expected, final Calendar actual) {
final DateFormat f = DateFormat.getDateTimeInstance();
final String msg = "Locale: " + locale + " FirstDayOfWeek: " + actual.getFirstDayOfWeek() + " Expected: "
+ f.format(expected.getTime()) + " Actual: " + f.format(actual.getTime());
assertEquals(msg, expected.get(Calendar.YEAR), actual.get(Calendar.YEAR));
assertEquals(msg, expected.get(Calendar.MONTH), actual.get(Calendar.MONTH));
assertEquals(msg, expected.get(Calendar.DAY_OF_MONTH), actual.get(Calendar.DAY_OF_MONTH));
assertEquals(msg, expected.get(Calendar.HOUR), actual.get(Calendar.HOUR));
assertEquals(msg, expected.get(Calendar.MINUTE), actual.get(Calendar.MINUTE));
}
}
......@@ -27,8 +27,11 @@ import antlr.ANTLRException;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
import junit.framework.TestCase;
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.Url;
import static java.util.Calendar.MONDAY;
......@@ -69,6 +72,48 @@ public class CronTabTest extends TestCase {
compare(new GregorianCalendar(2010,7,1,0,0),x.ceil(c));
}
/**
* Verifies that HUDSON-8656 never crops up again.
*/
@Url("http://issues.hudson-ci.org/browse/HUDSON-8656")
public void testCeil4() throws ANTLRException {
final Calendar cal = Calendar.getInstance(new Locale("de", "de"));
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 23 * * 1-5"; // execute on weekdays @23:00
final CronTab cron = new CronTab(cronStr);
final Calendar next = cron.ceil(cal);
final Calendar expectedDate = Calendar.getInstance();
expectedDate.set(2011, 0, 17, 23, 0, 0); // Expected next: Monday, Jan 17th 2011, 23:00
assertEquals(expectedDate.get(Calendar.HOUR), next.get(Calendar.HOUR));
assertEquals(expectedDate.get(Calendar.MINUTE), next.get(Calendar.MINUTE));
assertEquals(expectedDate.get(Calendar.YEAR), next.get(Calendar.YEAR));
assertEquals(expectedDate.get(Calendar.MONTH), next.get(Calendar.MONTH));
assertEquals(expectedDate.get(Calendar.DAY_OF_MONTH), next.get(Calendar.DAY_OF_MONTH)); // FAILS: is Monday, Jan 10th, 23:00
}
/**
* Verifies that HUDSON-8656 never crops up again.
*/
@Url("http://issues.hudson-ci.org/browse/HUDSON-8656")
public void testCeil5() throws ANTLRException {
final Calendar cal = Calendar.getInstance(new Locale("de", "at"));
cal.set(2011, 0, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00
final String cronStr = "0 23 * * 1-5"; // execute on weekdays @23:00
final CronTab cron = new CronTab(cronStr);
final Calendar next = cron.ceil(cal);
final Calendar expectedDate = Calendar.getInstance();
expectedDate.set(2011, 0, 17, 23, 0, 0); // Expected next: Monday, Jan 17th 2011, 23:00
assertEquals(expectedDate.get(Calendar.HOUR), next.get(Calendar.HOUR));
assertEquals(expectedDate.get(Calendar.MINUTE), next.get(Calendar.MINUTE));
assertEquals(expectedDate.get(Calendar.YEAR), next.get(Calendar.YEAR));
assertEquals(expectedDate.get(Calendar.MONTH), next.get(Calendar.MONTH));
assertEquals(expectedDate.get(Calendar.DAY_OF_MONTH), next.get(Calendar.DAY_OF_MONTH)); // FAILS: is Monday, Jan 10th, 23:00
}
public void testFloor1() throws Exception {
CronTab x = new CronTab("30 * * * *");
Calendar c = new GregorianCalendar(2000,2,1,1,40);
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
</parent>
<artifactId>maven-plugin</artifactId>
......
......@@ -44,6 +44,7 @@ import hudson.scm.ChangeLogSet.Entry;
import hudson.tasks.BuildWrapper;
import hudson.tasks.Maven.MavenInstallation;
import hudson.util.ArgumentListBuilder;
import hudson.util.IOUtils;
import org.apache.maven.BuildFailureException;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.apache.maven.execution.MavenSession;
......@@ -601,6 +602,21 @@ public class MavenBuild extends AbstractMavenBuild<MavenModule,MavenBuild> {
// use the per-project repository. should it be per-module? But that would cost too much in terms of disk
// the workspace must be on this node, so getRemote() is safe.
margs.add("-Dmaven.repo.local="+getWorkspace().child(".repository").getRemote());
if (mms.getAlternateSettings() != null) {
if (IOUtils.isAbsolute(mms.getAlternateSettings())) {
margs.add("-s").add(mms.getAlternateSettings());
} else {
FilePath mrSettings = getModuleRoot().child(mms.getAlternateSettings());
FilePath wsSettings = getWorkspace().child(mms.getAlternateSettings());
if (!wsSettings.exists() && mrSettings.exists())
wsSettings = mrSettings;
margs.add("-s").add(wsSettings.getRemote());
}
}
margs.add("-f",getModuleRoot().child("pom.xml").getRemote());
margs.addTokenized(getProject().getGoals());
......
......@@ -24,6 +24,7 @@
*/
package hudson.maven;
import static hudson.model.Result.ABORTED;
import static hudson.model.Result.FAILURE;
import hudson.AbortException;
import hudson.EnvVars;
......@@ -651,6 +652,9 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
process.discard();
}
}
} catch (InterruptedException e) {
r = ABORTED;
throw e;
} finally {
if (r != null) {
setResult(r);
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
</parent>
<artifactId>maven3-agent</artifactId>
<name>Jenkins Maven3 CLI Agent</name>
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
</parent>
<artifactId>maven3-interceptor</artifactId>
<name>Jenkins Maven3 Interceptor</name>
......
......@@ -10,7 +10,7 @@
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<name>Jenkins plugin POM</name>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
......@@ -38,7 +38,7 @@
<dependency><!-- if a plugin wants to depend on the maven plugin, choose the right version automatically -->
<groupId>org.jenkins-ci.main</groupId>
<artifactId>maven-plugin</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
......@@ -48,25 +48,25 @@
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-war</artifactId>
<type>war</type>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-core</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-test-harness</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>ui-samples-plugin</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
......
......@@ -32,7 +32,7 @@ THE SOFTWARE.
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Jenkins main module</name>
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -23,6 +23,7 @@
*/
package hudson.remoting;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
......@@ -92,7 +93,19 @@ public final class Pipe implements Serializable {
* Gets the reading end of the pipe.
*/
public InputStream getIn() {
return in;
return new FilterInputStream(in) {
@Override
public void close() throws IOException {
try {
// Since closing the reading side does not stop the writing side. We read till the stream is done.
final byte[] buffer = new byte[4096];
while(read(buffer) != -1) {
}
} finally {
super.close();
}
}
};
}
/**
......
......@@ -39,7 +39,7 @@ public class MainDialog extends JFrame {
private final JLabel statusLabel;
public MainDialog() throws HeadlessException {
super("Hudson slave agent");
super("Jenkins slave agent");
ImageIcon background = new ImageIcon(getClass().getResource("title.png"));
......
......@@ -24,9 +24,13 @@
package hudson.remoting;
import hudson.remoting.ChannelRunner.InProcessCompatibilityMode;
import hudson.remoting.FastPipedInputStream.ClosedBy;
import junit.framework.Test;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullOutputStream;
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.For;
import org.jvnet.hudson.test.Url;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
......@@ -35,6 +39,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
/**
* Test {@link Pipe}.
......@@ -55,6 +62,60 @@ public class PipeTest extends RmiTestBase implements Serializable {
System.out.println("result=" + r);
assertEquals(5,r);
}
/**
* Helper class for testPartialReadQuietlyConsumesPipeOnClose.
*/
private static class EventCounterHandler extends Handler {
int count = 0;
@Override
public void publish(final LogRecord record) {
if (ProxyOutputStream.class.getName().equals(record.getLoggerName())) {
Throwable thrown = record.getThrown();
while (thrown != null) {
if (thrown instanceof ClosedBy) {
count += 1;
break;
}
thrown = thrown.getCause();
}
}
}
@Override
public void flush() {
}
@Override
public void close() throws SecurityException {
}
public int getCount() {
return count;
}
}
/**
* This test should be reproducing the initial bug as reported in JENKINS-8592. The assert in this test is not the
* best and is fragile, but it is the best I can come up with.
*/
@Bug(8592)
@For(Pipe.class)
@Url("http://issues.jenkins-ci.org/browse/JENKINS-8592")
public void testPartialReadQuietlyConsumesPipeOnClose() throws Exception {
final EventCounterHandler handler = new EventCounterHandler();
final Logger logger = Logger.getLogger(ProxyOutputStream.class.getName());
logger.addHandler(handler);
final Pipe p = Pipe.createRemoteToLocal();
final Future<Integer> f = channel.callAsync(new WritingCallable(p));
final InputStream in = p.getIn();
assertEquals(in.read(), 0);
in.close();
f.get();
logger.removeHandler(handler);
assertEquals(0, handler.getCount());
}
private static class WritingCallable implements Callable<Integer, IOException> {
private final Pipe pipe;
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<artifactId>pom</artifactId>
<groupId>org.jenkins-ci.main</groupId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jenkins-ci.main</groupId>
......
package hudson.model;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.HudsonTestCase;
/**
......@@ -12,9 +13,7 @@ public class ExecutorTest extends HudsonTestCase {
Executor e = c.getExecutors().get(0);
// kill an executor
e.killHard();
while (e.isAlive())
Thread.sleep(10);
kill(e);
// make sure it's dead
assertTrue(c.getExecutors().contains(e));
......@@ -27,6 +26,44 @@ public class ExecutorTest extends HudsonTestCase {
submit(p.getFormByName("yank"));
assertFalse(c.getExecutors().contains(e));
waitUntilExecutorSizeIs(c, 2);
}
@Bug(4756)
public void testWhenAnExecuterIsYankedANewExecuterTakesItsPlace() throws Exception {
Computer c = hudson.toComputer();
Executor e = getExecutorByNumber(c, 0);
kill(e);
e.doYank();
waitUntilExecutorSizeIs(c, 2);
assertNotNull(getExecutorByNumber(c, 0));
assertNotNull(getExecutorByNumber(c, 1));
}
private void waitUntilExecutorSizeIs(Computer c, int executorCollectionSize) throws InterruptedException {
int timeOut = 10;
while (c.getExecutors().size() != executorCollectionSize) {
Thread.sleep(10);
if (timeOut-- == 0) fail("executor collection size was not " + executorCollectionSize);
}
}
private void kill(Executor e) throws InterruptedException {
e.killHard();
while (e.isAlive())
Thread.sleep(10);
}
private Executor getExecutorByNumber(Computer c, int executorNumber) {
for (Executor executor : c.getExecutors()) {
if (executor.getNumber() == executorNumber) {
return executor;
}
}
return null;
}
}
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
</parent>
<artifactId>ui-samples-plugin</artifactId>
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>1.397-SNAPSHOT</version>
<version>1.398-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -1472,6 +1472,9 @@ function updateBuildHistory(ajaxUrl,nBuild) {
function updateBuilds() {
var bh = $('buildHistory');
if (bh.headers == null) {
// Yahoo.log("Missing headers in buildHistory element");
}
new Ajax.Request(ajaxUrl, {
requestHeaders: bh.headers,
onSuccess: function(rsp) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册