Skip to content

Commit

Permalink
Merge pull request #29 from yandex-qatools/jpi_its
Browse files Browse the repository at this point in the history
Jpi serve + integration tests for serve
  • Loading branch information
lanwen committed Jun 3, 2016
2 parents baf08d5 + 48ca2ef commit ee8bb71
Show file tree
Hide file tree
Showing 12 changed files with 214 additions and 13 deletions.
12 changes: 12 additions & 0 deletions juseppe-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@
<groupId>io.airlift</groupId>
<artifactId>airline</artifactId>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,17 @@
@Command(name = "serve", description = "starts the jetty server with Juseppe to serve generated json and plugins")
public class ServeCommand extends JuseppeCommand {

private static final String JENKINS_PLUGIN_WILDCARD = "*.hpi";
private static final String HPI_EXT = "*.hpi";
private static final String JPI_EXT = "*.jpi";

private static final Logger LOG = LoggerFactory.getLogger(ServeCommand.class);

@Arguments(title = "port", description = "Port to bind jetty on")
private int port = Props.populated().getPort();
private int port = -1;

@Override
public void unsafeRun(Props props) throws Exception {
Server server = new Server(port);
Server server = new Server(port == -1 ? props.getPort() : port);
server.addLifeCycleListener(new GenStarter(props));

if (isWatch()) {
Expand All @@ -46,10 +48,16 @@ public void unsafeRun(Props props) throws Exception {
Resource.newResource(props.getPluginsDir())
));

context.addServlet(new ServletHolder("update-site", new DefaultServlet()), "/" + props.getUcJsonName());
context.addServlet(new ServletHolder("release-history",
new DefaultServlet()), "/" + props.getReleaseHistoryJsonName());
context.addServlet(new ServletHolder("plugins", new DefaultServlet()), JENKINS_PLUGIN_WILDCARD);
context.addServlet(
new ServletHolder("update-site", new DefaultServlet()),
"/" + props.getUcJsonName()
);
context.addServlet(
new ServletHolder("release-history",
new DefaultServlet()), "/" + props.getReleaseHistoryJsonName()
);
context.addServlet(new ServletHolder("plugins-hpi", new DefaultServlet()), HPI_EXT);
context.addServlet(new ServletHolder("plugins-jpi", new DefaultServlet()), JPI_EXT);

Slf4jRequestLog requestLog = new Slf4jRequestLog();
requestLog.setLogDateFormat(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ru.lanwen.jenkins.juseppe.cli;


import org.junit.ClassRule;
import org.junit.Test;

import static com.jayway.restassured.RestAssured.given;

/**
* @author lanwen (Merkushev Kirill)
*/
public class ServeCommandTest {

@ClassRule
public static ServeRule srv = new ServeRule();

@Test(timeout = 10000)
public void shouldFetchUpdateCenter() throws Exception {
given()
.baseUri(srv.uri().toString())
.log().all()
.expect()
.log().status()
.get("update-center.json").then().assertThat().statusCode(200);
}

@Test(timeout = 10000)
public void shouldFetchHpi() throws Exception {
given()
.baseUri(srv.uri().toString())
.log().all()
.expect()
.log().status()
.get("clang-scanbuild-plugin.hpi").then().assertThat().statusCode(200);
}

@Test(timeout = 10000)
public void shouldFetchJpi() throws Exception {
given()
.baseUri(srv.uri().toString())
.log().all()
.expect()
.log().status()
.get("sample-pipeline-dsl-ext-plugin-0.1.0.jpi").then().assertThat().statusCode(200);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package ru.lanwen.jenkins.juseppe.cli;

import org.junit.rules.ExternalResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.lanwen.jenkins.juseppe.props.Props;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.URI;
import java.util.concurrent.CompletableFuture;

import static com.google.common.io.Resources.getResource;
import static java.lang.String.format;

/**
* @author lanwen (Merkushev Kirill)
*/
public class ServeRule extends ExternalResource {
private static final Logger LOG = LoggerFactory.getLogger(ServeRule.class);

private CompletableFuture<Void> future;
private int port;

@Override
protected void before() throws Throwable {
port = findRandomOpenPortOnAllLocalInterfaces();
future = CompletableFuture.runAsync(() -> {
try {
new ServeCommand().unsafeRun(Props.populated()
.withBaseurl(uri())
.withPluginsDir(getResource("serve/plugins").getFile())
.withCert(getResource("serve/cert/uc.crt").getFile())
.withKey(getResource("serve/cert/uc.key").getFile())
.withPort(port));
} catch (Exception e) {
LOG.error("Can't start juseppe", e);
}
});
}

@Override
protected void after() {
future.cancel(true);
}

public URI uri() {
return URI.create(format("http://localhost:%s", port));
}

private Integer findRandomOpenPortOnAllLocalInterfaces() throws IOException {
try (ServerSocket socket = new ServerSocket(0)) {
return socket.getLocalPort();
}
}
}
21 changes: 21 additions & 0 deletions juseppe-cli/src/test/resources/serve/cert/uc.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDZTCCAk2gAwIBAgIJAMWW8t2gQwMPMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
BAYTAkVOMRYwFAYDVQQIDA1VcGRhdGUtQ2VudGVyMRAwDgYDVQQHDAdKdXNlcHBl
MRAwDgYDVQQKDAdKdXNlcHBlMB4XDTE1MDYyOTE0NTY0N1oXDTE4MDUyMDE0NTY0
N1owSTELMAkGA1UEBhMCRU4xFjAUBgNVBAgMDVVwZGF0ZS1DZW50ZXIxEDAOBgNV
BAcMB0p1c2VwcGUxEDAOBgNVBAoMB0p1c2VwcGUwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQCfX3nPkfyk+979zMhmfrlKa8K6t+USOcqcxcZ06ZbxRc/s
RdXEvjMXL751zgjFrpUvSc5qpozvKo5Uqta/4Se96kagzQv7DEcJVCtY6F9R96Hs
KpT/vl+Hjv6fuhap0JuOjtfClWQAe/i2goD16LUHS3LXKo1orDDUPtaKLHIRQIkO
D+xhPpr0iEjKELjjbWs2wOYNMh9FASHZiGLsf63thXy8lL5t2bfF+j2XNqyy33Si
8xs3+MLH5nhyrFGdLjd9V3QgbY1lqCbdkUoXCQjfIGom97gQnbw8/61gcAroNaAL
CIhJ/cu0DdV+/ddmVI9bJNiQTT7Lu90YujL2b7YrAgMBAAGjUDBOMB0GA1UdDgQW
BBRbIQ5EOViBEA0fGnsa4jNhznfbsDAfBgNVHSMEGDAWgBRbIQ5EOViBEA0fGnsa
4jNhznfbsDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQADOO0+SojP
Vvp80VG+dFe06JRdEt0SYFWUY/yEXzo5o2nKKloAnRWbcBJSokJi12xQaqBu8DDk
KQA6fvOpdIXaqgC5RYCmlG4/2ZXr9W7vlfBeggGYH8iRbmWAsA2QJct8NtbN2OwM
i3vTeQTK9qnz0tjdFeRhIiOq4ZEFXIYrHKUyrOrE/fLdWBKiL/bncIUZufBzOuT5
1l7H/eceb0nsP8JFHtWxAkaN/0mGgoY9g6Af2bEYNg94jjmQ2bugo4kVYq8REPSk
0gbKukRX6FPYdpiAa7Rdjw22dfNZLTXahlVMRFmohmIGSBPvGOEKwWD4KicdFgvH
9Qk/e5LNgzDH
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions juseppe-cli/src/test/resources/serve/cert/uc.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAn195z5H8pPve/czIZn65SmvCurflEjnKnMXGdOmW8UXP7EXV
xL4zFy++dc4Ixa6VL0nOaqaM7yqOVKrWv+EnvepGoM0L+wxHCVQrWOhfUfeh7CqU
/75fh47+n7oWqdCbjo7XwpVkAHv4toKA9ei1B0ty1yqNaKww1D7WiixyEUCJDg/s
YT6a9IhIyhC4421rNsDmDTIfRQEh2Yhi7H+t7YV8vJS+bdm3xfo9lzasst90ovMb
N/jCx+Z4cqxRnS43fVd0IG2NZagm3ZFKFwkI3yBqJve4EJ28PP+tYHAK6DWgCwiI
Sf3LtA3Vfv3XZlSPWyTYkE0+y7vdGLoy9m+2KwIDAQABAoIBAFFyxNj8/cX/Zs4E
WyJufxl2ixVLqAkxece3F55mRprVl9ZjNkWPAqNF5itkeX01pM5/BLvilEIiWI0S
ph933Qyk7yV8xTOu6Zrt5h1Q3G4ShTEh7fXpf/7SaHSO8MgmcWlgvQmXuXy53ri/
Z1LFc8bfmzg1agFlhqrh1ljVMBJ6PyxqSD+akGGfhFU/82R7HX4FaosyXR9PBOdc
3xMtHGfBh5VpUIY1X5J0YXru/w8M2OjykkMsH3ubw8tcCE2cthvQ6V4pEo2zgCso
Jy94xM/OU1AnprsRL+jlGNTmlCXXNkWKof0EjdCApZRFr0+AjXjren0Exb2W2nNb
bzzP1IkCgYEA0recN5CQ0IAfu+8jpGqJW1AFj8gy3eZcr9vDy5gZwz9VLDTzuUmg
eCAgtbqCv3zr61F6+Q6F2GPoKEeIIkn4ZwjF0Up05blhpQT2Mq1Skpcw5U+QkxVZ
sVsH/hVDDb4UZwZVXSqwFp0LoI9QCSIdI/z1/9nUbPY7cf3AWVh6y70CgYEAwZ82
qzVSH7E+Lul+Akzz6iozX0DiulBDmhfdOuXXvNQpXTfg70EloTWZayDTIIFSz8Dt
2vVDuGWyLJ5AiWmooqjnK/z8yNrI9y6w23Ie7gCs3h7DCL3Icvg/eTluqw5bzQD+
WjdC7IEGysz/tTPOouqbkhORAVPGBM3+HkC09AcCgYBh0t3SKeog8apJ3D5GwTLd
UmwSkRWUULKs7bCbHxSuwQMwj7CqT1URD5E/7MNwVHVN/LjDUQuwJsmLkZHQoViR
tM/pVtCoKYT8UC5f3nkcFtabTnHG5r2KCcHPIl3Lzne4UIdmxj+Tb/sK4h187/pp
T7GAwsbMgw+b3vriP6JaXQKBgFbLSjRhSJkQWPGqlWPunwB/PlwauAgQ5tzyiadX
VOg+qvQwklJt/7JOVqGhK0NM9ZRPxc/7VgoY/E/n+MIgbQnNcSNU2vQmryOu+HTG
qXrDLrq7S25ltK9k/P8YcbWYUCqLoXlLgGKITEUotA/EU4LQbECFKOFRbljFBn8F
PpiNAoGBAMX9iZkaBeL8VJeNxxSSHSTQyxZG+GLQQnba39W5aoaXiAsRy9CHUrP5
CzehEOfpt18MS6QpujOuI9bDgfrFbJOnk5QeiD9WJXUa8FtAER2WnsQnky7W+3cU
sHQ1gC4gBBpH9ZDqP2wqK4L5WPzgreM3MzICMjwTzCsKUsg6kxKB
-----END RSA PRIVATE KEY-----
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.security.Security.addProvider;
Expand All @@ -40,24 +41,30 @@
* @author Kohsuke Kawaguchi
*/
public class Signer {

public Signer(String privateKeyPath, List<String> certificatePaths, List<String> rootCAPaths) {
this.privateKey = new File(privateKeyPath);
this.certificates = new ArrayList<>(certificatePaths.stream().map(File::new).collect(Collectors.toList()));
this.rootCA = new ArrayList<>(rootCAPaths.stream().map(File::new).collect(Collectors.toList()));
}

private static final Logger LOG = LoggerFactory.getLogger(Signer.class);

/**
* Private key to sign the update center. Must be used in conjunction with certificates
*/
private File privateKey = new File(populated().getKeyPath());
private File privateKey;

/**
* X509 certificate for the private key given by the privateKey option.
* Specify additional certificate options to pass in intermediate certificates, if any
*/
private List<File> certificates = new ArrayList<>(Collections.singleton(new File(populated().getCertPath())));
private List<File> certificates;

/**
* Additional root certificates. Should contain your certificate if it self-signed
*/
private List<File> rootCA = new ArrayList<>(Collections.singleton(new File(populated().getCertPath())));
private List<File> rootCA;


/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import java.util.stream.Stream;

import static java.lang.String.format;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
import static ru.lanwen.jenkins.juseppe.props.Props.populated;

/**
* @author Merkushev Kirill (github: lanwen)
Expand Down Expand Up @@ -60,7 +62,11 @@ public UpdateSiteGen withDefaults() {
).register(
site -> {
try {
site.setSignature(new Signer().sign(site));
site.setSignature(new Signer(
props.getKeyPath(),
singletonList(props.getCertPath()),
singletonList(props.getCertPath())
).sign(site));
} catch (GeneralSecurityException | IOException e) {
throw new RuntimeException("Can't generate signature", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import java.io.File;

import static com.google.common.io.Resources.getResource;
import static java.util.Collections.singletonList;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static ru.lanwen.jenkins.juseppe.props.Props.populated;

/**
* @author lanwen (Merkushev Kirill)
Expand All @@ -29,7 +31,11 @@ public void setUp() throws Exception {

@Test
public void shouldIgnoreSignIfNoCertIsConfigured() throws Exception {
Signature sign = new Signer().sign(new UpdateSite());
Signature sign = new Signer(
populated().getKeyPath(),
singletonList(populated().getCertPath()),
singletonList(populated().getCertPath())
).sign(new UpdateSite());

assertThat(sign.getSignature(), nullValue());
}
Expand All @@ -42,7 +48,11 @@ public void shouldSignWithSelfSignedCert() throws Exception {
System.setProperty(JuseppeEnvVars.JuseppeEnvEnum.JUSEPPE_PRIVATE_KEY_PATH.mapping(), key.getAbsolutePath());
System.setProperty(JuseppeEnvVars.JuseppeEnvEnum.JUSEPPE_CERT_PATH.mapping(), cert.getAbsolutePath());

Signature sign = new Signer().sign(new UpdateSite());
Signature sign = new Signer(
populated().getKeyPath(),
singletonList(populated().getCertPath()),
singletonList(populated().getCertPath())
).sign(new UpdateSite());

assertThat("sign", sign.getCorrectSignature(), notNullValue());
assertThat("digest", sign.getCorrectDigest(), notNullValue());
Expand Down
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@
<version>4.12</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>rest-assured</artifactId>
<version>2.8.0</version>
<scope>test</scope>
</dependency>

</dependencies>
</dependencyManagement>

Expand Down

0 comments on commit ee8bb71

Please sign in to comment.