提交 1262b2c8 编写于 作者: T Tim Lantz

Merge remote-tracking branch 'upstream/master'

......@@ -61,6 +61,9 @@ Upcoming changes</a>
<li class=bug>
“Build Now” link did not work for multijobs.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-16974">issue 16974</a>)
<li class=bug>
Edit views with non-ASCII names did not work since 1.500.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-18373">issue 18373</a>)
<li class='major bug'>
Fixed API incompatibility since 1.489.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-18356">issue 18356</a>)
......@@ -75,6 +78,8 @@ Upcoming changes</a>
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-15380">issue 15380</a>)
<li class=rfe>
Added a new extension point to monitor the flow of stuff in the queue.
<li class=rfe>
Possible to create a custom <code>AbstractDiskSpaceMonitor</code>.
<li class=rfe>
Executors running the builds can be now a subject of access control.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-18285">issue 18285</a>)
......
......@@ -214,7 +214,10 @@ public final class ComputerSet extends AbstractModelObject implements Describabl
for (NodeMonitor nodeMonitor : NodeMonitor.getAll()) {
Thread t = nodeMonitor.triggerUpdate();
t.setName(nodeMonitor.getColumnCaption());
String columnCaption = nodeMonitor.getColumnCaption();
if (columnCaption != null) {
t.setName(columnCaption);
}
}
rsp.forwardToPreviousPage(req);
}
......
......@@ -962,7 +962,7 @@ public abstract class View extends AbstractModelObject implements AccessControll
save();
FormApply.success("../"+name).generateResponse(req,rsp,this);
FormApply.success("../" + Util.rawEncode(name)).generateResponse(req,rsp,this);
}
/**
......
......@@ -9,6 +9,7 @@ import java.util.logging.Logger;
/**
* @author Kohsuke Kawaguchi
* @see DiskSpaceMonitorDescriptor
*/
public abstract class AbstractDiskSpaceMonitor extends NodeMonitor {
/**
......
......@@ -85,12 +85,12 @@ public abstract class AbstractNodeMonitorDescriptor<T> extends Descriptor<NodeMo
*
* Once set to non-null, never be null.
*/
private volatile Record record = null;
private transient volatile Record record = null;
/**
* Represents the update activity in progress.
*/
private volatile Record inProgress = null;
private transient volatile Record inProgress = null;
/**
* Performs monitoring of the given computer object.
......@@ -270,7 +270,7 @@ public abstract class AbstractNodeMonitorDescriptor<T> extends Descriptor<NodeMo
}
}
private final Logger LOGGER = Logger.getLogger(getClass().getName());
private static final Logger LOGGER = Logger.getLogger(AbstractNodeMonitorDescriptor.class.getName());
private static final long HOUR = 1000*60*60L;
}
......@@ -64,7 +64,7 @@ public class DiskSpaceMonitor extends AbstractDiskSpaceMonitor {
return Messages.DiskSpaceMonitor_DisplayName();
}
protected DiskSpace getFreeSpace(Computer c) throws IOException, InterruptedException {
@Override protected DiskSpace monitor(Computer c) throws IOException, InterruptedException {
FilePath p = c.getNode().getRootPath();
if(p==null) return null;
......
......@@ -45,8 +45,9 @@ import org.kohsuke.stapler.export.Exported;
* {@link AbstractNodeMonitorDescriptor} for {@link NodeMonitor} that checks a free disk space of some directory.
*
* @author Kohsuke Kawaguchi
* @since 1.520
*/
/*package*/ abstract class DiskSpaceMonitorDescriptor extends AbstractNodeMonitorDescriptor<DiskSpace> {
public abstract class DiskSpaceMonitorDescriptor extends AbstractNodeMonitorDescriptor<DiskSpace> {
/**
* Value object that represents the disk space.
*/
......@@ -59,13 +60,6 @@ import org.kohsuke.stapler.export.Exported;
private boolean triggered;
private Class<? extends AbstractDiskSpaceMonitor> trigger;
/**
* @deprecated as of 1.467
*/
public DiskSpace(long size) {
this(".",size);
}
/**
* @param path
* Specify the file path that was monitored.
......@@ -165,16 +159,8 @@ import org.kohsuke.stapler.export.Exported;
private static final long serialVersionUID = 2L;
}
protected DiskSpace monitor(Computer c) throws IOException, InterruptedException {
return getFreeSpace(c);
}
/**
* Computes the free size.
*/
protected abstract DiskSpace getFreeSpace(Computer c) throws IOException, InterruptedException;
protected static final class GetUsableSpace implements FileCallable<DiskSpace> {
public GetUsableSpace() {}
@IgnoreJRERequirement
public DiskSpace invoke(File f, VirtualChannel channel) throws IOException {
try {
......
......@@ -36,6 +36,7 @@ import hudson.model.Descriptor;
import hudson.util.DescriptorList;
import java.util.List;
import javax.annotation.CheckForNull;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
......@@ -75,7 +76,7 @@ public abstract class NodeMonitor implements ExtensionPoint, Describable<NodeMon
* null to not render a column. The convention is to use capitalization like "Foo Bar Zot".
*/
@Exported
public String getColumnCaption() {
public @CheckForNull String getColumnCaption() {
return getDescriptor().getDisplayName();
}
......
......@@ -66,7 +66,7 @@ public class TemporarySpaceMonitor extends AbstractDiskSpaceMonitor {
return Messages.TemporarySpaceMonitor_DisplayName();
}
protected DiskSpace getFreeSpace(Computer c) throws IOException, InterruptedException {
@Override protected DiskSpace monitor(Computer c) throws IOException, InterruptedException {
FilePath p = c.getNode().getRootPath();
if(p==null) return null;
......
......@@ -31,52 +31,56 @@ import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlRadioButtonInput;
import org.jvnet.hudson.test.Email;
import org.jvnet.hudson.test.HudsonTestCase;
import org.w3c.dom.Text;
import static hudson.model.Messages.Hudson_ViewName;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.fail;
import static org.junit.Assert.*;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.JenkinsRule.WebClient;
/**
* @author Kohsuke Kawaguchi
*/
public class ViewTest extends HudsonTestCase {
public class ViewTest {
@Rule public JenkinsRule j = new JenkinsRule();
@Bug(7100)
public void testXHudsonHeader() throws Exception {
assertNotNull(new WebClient().goTo("/").getWebResponse().getResponseHeaderValue("X-Hudson"));
@Test public void xHudsonHeader() throws Exception {
assertNotNull(j.createWebClient().goTo("").getWebResponse().getResponseHeaderValue("X-Hudson"));
}
/**
* Creating two views with the same name.
*/
@Email("http://d.hatena.ne.jp/ssogabe/20090101/1230744150")
public void testConflictingName() throws Exception {
assertNull(jenkins.getView("foo"));
@Test public void conflictingName() throws Exception {
assertNull(j.jenkins.getView("foo"));
HtmlForm form = new WebClient().goTo("newView").getFormByName("createItem");
HtmlForm form = j.createWebClient().goTo("newView").getFormByName("createItem");
form.getInputByName("name").setValueAttribute("foo");
form.getRadioButtonsByName("mode").get(0).setChecked(true);
submit(form);
assertNotNull(jenkins.getView("foo"));
j.submit(form);
assertNotNull(j.jenkins.getView("foo"));
// do it again and verify an error
try {
submit(form);
j.submit(form);
fail("shouldn't be allowed to create two views of the same name.");
} catch (FailingHttpStatusCodeException e) {
assertEquals(400, e.getStatusCode());
}
}
public void testPrivateView() throws Exception {
createFreeStyleProject("project1");
@Test public void privateView() throws Exception {
j.createFreeStyleProject("project1");
User user = User.get("me", true); // create user
WebClient wc = new WebClient();
HtmlPage userPage = wc.goTo("/user/me");
WebClient wc = j.createWebClient();
HtmlPage userPage = wc.goTo("user/me");
HtmlAnchor privateViewsLink = userPage.getFirstAnchorByText("My Views");
assertNotNull("My Views link not available", privateViewsLink);
......@@ -85,48 +89,48 @@ public class ViewTest extends HudsonTestCase {
Text viewLabel = (Text) privateViewsPage.getFirstByXPath("//table[@id='viewList']//td[@class='active']/text()");
assertTrue("'All' view should be selected", viewLabel.getTextContent().contains(Hudson_ViewName()));
View listView = new ListView("listView", jenkins);
jenkins.addView(listView);
View listView = new ListView("listView", j.jenkins);
j.jenkins.addView(listView);
HtmlPage newViewPage = wc.goTo("/user/me/my-views/newView");
HtmlPage newViewPage = wc.goTo("user/me/my-views/newView");
HtmlForm form = newViewPage.getFormByName("createItem");
form.getInputByName("name").setValueAttribute("proxy-view");
((HtmlRadioButtonInput) form.getInputByValue("hudson.model.ProxyView")).setChecked(true);
HtmlPage proxyViewConfigurePage = submit(form);
HtmlPage proxyViewConfigurePage = j.submit(form);
View proxyView = user.getProperty(MyViewsProperty.class).getView("proxy-view");
assertNotNull(proxyView);
form = proxyViewConfigurePage.getFormByName("viewConfig");
form.getSelectByName("proxiedViewName").setSelectedAttribute("listView", true);
submit(form);
j.submit(form);
assertTrue(proxyView instanceof ProxyView);
assertEquals(((ProxyView) proxyView).getProxiedViewName(), "listView");
assertEquals(((ProxyView) proxyView).getProxiedView(), listView);
}
public void testDeleteView() throws Exception {
WebClient wc = new WebClient();
@Test public void deleteView() throws Exception {
WebClient wc = j.createWebClient();
ListView v = new ListView("list", jenkins);
jenkins.addView(v);
ListView v = new ListView("list", j.jenkins);
j.jenkins.addView(v);
HtmlPage delete = wc.getPage(v, "delete");
submit(delete.getFormByName("delete"));
assertNull(jenkins.getView("list"));
j.submit(delete.getFormByName("delete"));
assertNull(j.jenkins.getView("list"));
User user = User.get("user", true);
MyViewsProperty p = user.getProperty(MyViewsProperty.class);
v = new ListView("list", p);
p.addView(v);
delete = wc.getPage(v, "delete");
submit(delete.getFormByName("delete"));
j.submit(delete.getFormByName("delete"));
assertNull(p.getView("list"));
}
@Bug(9367)
public void testPersistence() throws Exception {
ListView view = new ListView("foo", jenkins);
jenkins.addView(view);
@Test public void persistence() throws Exception {
ListView view = new ListView("foo", j.jenkins);
j.jenkins.addView(view);
ListView v = (ListView) Jenkins.XSTREAM.fromXML(Jenkins.XSTREAM.toXML(view));
System.out.println(v.getProperties());
......@@ -134,24 +138,38 @@ public class ViewTest extends HudsonTestCase {
}
@Bug(9367)
public void testAllImagesCanBeLoaded() throws Exception {
@Test public void allImagesCanBeLoaded() throws Exception {
User.get("user", true);
WebClient webClient = new WebClient();
WebClient webClient = j.createWebClient();
webClient.setJavaScriptEnabled(false);
assertAllImageLoadSuccessfully(webClient.goTo("asynchPeople"));
j.assertAllImageLoadSuccessfully(webClient.goTo("asynchPeople"));
}
@Bug(16608)
public void testNotAlloedName() throws Exception {
HtmlForm form = new WebClient().goTo("newView").getFormByName("createItem");
@Test public void notAllowedName() throws Exception {
HtmlForm form = j.createWebClient().goTo("newView").getFormByName("createItem");
form.getInputByName("name").setValueAttribute("..");
form.getRadioButtonsByName("mode").get(0).setChecked(true);
try {
submit(form);
j.submit(form);
fail("\"..\" should not be allowed.");
} catch (FailingHttpStatusCodeException e) {
assertEquals(400, e.getStatusCode());
}
}
@Ignore("verified manually in Winstone but org.mortbay.JettyResponse.sendRedirect (6.1.26) seems to mangle the location")
@Bug(18373)
@Test public void unicodeName() throws Exception {
HtmlForm form = j.createWebClient().goTo("newView").getFormByName("createItem");
String name = "I ♥ NY";
form.getInputByName("name").setValueAttribute(name);
form.getRadioButtonsByName("mode").get(0).setChecked(true);
j.submit(form);
View view = j.jenkins.getView(name);
assertNotNull(view);
j.submit(j.createWebClient().getPage(view, "configure").getFormByName("viewConfig"));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册