/*
* The MIT License
*
* Copyright (c) 2013 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.model;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.startsWith;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import hudson.security.ACL;
import hudson.security.AccessDeniedException2;
import hudson.security.GlobalMatrixAuthorizationStrategy;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* @author ogondza
*/
public class ComputerConfigDotXmlTest {
@Rule public final JenkinsRule rule = new JenkinsRule();
@Mock private StaplerRequest req;
@Mock private StaplerResponse rsp;
private Computer computer;
private SecurityContext oldSecurityContext;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
computer = spy(rule.createSlave().toComputer());
rule.jenkins.setSecurityRealm(rule.createDummySecurityRealm());
oldSecurityContext = ACL.impersonate(User.get("user").impersonate());
}
@After
public void tearDown() {
SecurityContextHolder.setContext(oldSecurityContext);
}
@Test(expected = AccessDeniedException2.class)
public void configXmlGetShouldFailForUnauthorized() throws Exception {
when(req.getMethod()).thenReturn("GET");
rule.jenkins.setAuthorizationStrategy(new GlobalMatrixAuthorizationStrategy());
computer.doConfigDotXml(req, rsp);
}
@Test(expected = AccessDeniedException2.class)
public void configXmlPostShouldFailForUnauthorized() throws Exception {
when(req.getMethod()).thenReturn("POST");
rule.jenkins.setAuthorizationStrategy(new GlobalMatrixAuthorizationStrategy());
computer.doConfigDotXml(req, rsp);
}
@Test
public void configXmlGetShouldYieldNodeConfiguration() throws Exception {
when(req.getMethod()).thenReturn("GET");
GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy();
rule.jenkins.setAuthorizationStrategy(auth);
Computer.EXTENDED_READ.setEnabled(true);
auth.add(Computer.EXTENDED_READ, "user");
final OutputStream outputStream = captureOutput();
computer.doConfigDotXml(req, rsp);
final String out = outputStream.toString();
assertThat(out, startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
assertThat(out, containsString("<name>slave0</name>"));
assertThat(out, containsString("<description>dummy</description>"));
}
@Test
public void configXmlPostShouldUpdateNodeConfiguration() throws Exception {
when(req.getMethod()).thenReturn("POST");
GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy();
rule.jenkins.setAuthorizationStrategy(auth);
auth.add(Computer.CONFIGURE, "user");
when(req.getInputStream()).thenReturn(xmlNode("node.xml"));
computer.doConfigDotXml(req, rsp);
final Node updatedSlave = rule.jenkins.getNode("SlaveFromXML");
assertThat(updatedSlave.getNodeName(), equalTo("SlaveFromXML"));
assertThat(updatedSlave.getNumExecutors(), equalTo(42));
}
private OutputStream captureOutput() throws IOException {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
when(rsp.getOutputStream()).thenReturn(new ServletOutputStream() {
@Override
public void write(int b) throws IOException {
baos.write(b);
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
throw new UnsupportedOperationException();
}
});
return baos;
}
private ServletInputStream xmlNode(final String name) {
class Stream extends ServletInputStream {
private final InputStream inner;
public Stream(final InputStream inner) {
this.inner = inner;
}
@Override
public int read() throws IOException {
return inner.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
throw new UnsupportedOperationException();
}
}
return new Stream(Computer.class.getResourceAsStream(name));
}
}