refactored server for dependancy injection, combined tests to run correctly in a multithreaded build
This commit is contained in:
parent
c599902ad5
commit
ea3f84b830
3 changed files with 95 additions and 107 deletions
22
build.gradle
22
build.gradle
|
|
@ -20,6 +20,7 @@ plugins {
|
|||
id 'java'
|
||||
id 'com.google.protobuf' version '0.8.8'
|
||||
id 'application'
|
||||
id 'com.adarshr.test-logger' version '1.6.0'
|
||||
}
|
||||
|
||||
def grpcVersion = '1.20.0'
|
||||
|
|
@ -49,6 +50,25 @@ dependencies {
|
|||
compile 'io.netty:netty-tcnative-boringssl-static:2.0.22.Final'
|
||||
}
|
||||
|
||||
test {
|
||||
testLogging.showStandardStreams = true
|
||||
testLogging.exceptionFormat = 'full'
|
||||
}
|
||||
|
||||
testlogger {
|
||||
theme 'standard'
|
||||
showExceptions true
|
||||
slowThreshold 2000
|
||||
showSummary true
|
||||
showPassed true
|
||||
showSkipped true
|
||||
showFailed true
|
||||
showStandardStreams false
|
||||
showPassedStandardStreams true
|
||||
showSkippedStandardStreams true
|
||||
showFailedStandardStreams true
|
||||
}
|
||||
|
||||
// Define the main class for the application
|
||||
mainClassName = 'JobServ.JobServClient'
|
||||
|
||||
|
|
@ -88,4 +108,4 @@ applicationDistribution.into('bin') {
|
|||
from(Server)
|
||||
from(Client)
|
||||
fileMode = 0755
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,25 +32,17 @@ public class JobServServer {
|
|||
private static final Logger logger = Logger.getLogger(JobServServer.class.getName());
|
||||
|
||||
private Server server;
|
||||
private final int port;
|
||||
private final SslContext ssl;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
* Sets port and builds sslContext
|
||||
* builds server object
|
||||
*/
|
||||
public JobServServer(int port,
|
||||
String serverCert,
|
||||
String privateKey,
|
||||
String trustStore) throws SSLException {
|
||||
this.port = port;
|
||||
SslContextBuilder sslContextBuilder = SslContextBuilder.forServer(new File(serverCert), new File(privateKey));
|
||||
|
||||
// Mutual TLS trust store and require client auth
|
||||
sslContextBuilder.trustManager(new File(trustStore));
|
||||
sslContextBuilder.clientAuth(ClientAuth.REQUIRE);
|
||||
|
||||
this.ssl = GrpcSslContexts.configure(sslContextBuilder).build();
|
||||
public JobServServer(SslContext ssl, int port) throws IOException {
|
||||
this.server = NettyServerBuilder.forPort(port)
|
||||
.addService(new ShellServerService())
|
||||
.sslContext(ssl)
|
||||
.build()
|
||||
.start();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -59,11 +51,7 @@ public class JobServServer {
|
|||
*/
|
||||
private void start() throws IOException {
|
||||
// TODO: this should be passed in from a configuration manager
|
||||
server = NettyServerBuilder.forPort(port)
|
||||
.addService(new ShellServerService())
|
||||
.sslContext(this.ssl)
|
||||
.build()
|
||||
.start();
|
||||
server.start();
|
||||
logger.info("Server initialized!");
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
|
|
@ -112,7 +100,14 @@ public class JobServServer {
|
|||
JobServServer server;
|
||||
|
||||
try {
|
||||
server = new JobServServer(Integer.parseInt(args[0]), args[1], args[2], args[3]);
|
||||
SslContextBuilder sslContextBuilder = SslContextBuilder.forServer(new File(args[1]), new File(args[2]));
|
||||
|
||||
// Mutual TLS trust store and require client auth
|
||||
sslContextBuilder.trustManager(new File(args[3]));
|
||||
sslContextBuilder.clientAuth(ClientAuth.REQUIRE);
|
||||
|
||||
server = new JobServServer(GrpcSslContexts.configure(sslContextBuilder).build(),
|
||||
Integer.parseInt(args[0]));
|
||||
|
||||
} catch (InputMismatchException e) {
|
||||
System.out.println("Invalid port!");
|
||||
|
|
@ -121,9 +116,12 @@ public class JobServServer {
|
|||
} catch (SSLException e) {
|
||||
System.out.println(e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
server.start();
|
||||
server.blockUntilShutdown();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ package JobServ;
|
|||
|
||||
import java.io.File;
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.AdditionalAnswers.delegatesTo;
|
||||
|
|
@ -17,8 +18,9 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.inprocess.InProcessChannelBuilder;
|
||||
import io.grpc.inprocess.InProcessServerBuilder;
|
||||
import io.grpc.netty.NettyChannelBuilder;
|
||||
import io.grpc.StatusRuntimeException;
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
import io.grpc.stub.StreamObserver;
|
||||
import io.grpc.testing.GrpcCleanupRule;
|
||||
import io.grpc.netty.GrpcSslContexts;
|
||||
|
|
@ -28,7 +30,7 @@ import io.netty.handler.ssl.SslContext;
|
|||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.netty.handler.ssl.SslProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
|
@ -46,44 +48,40 @@ import org.mockito.ArgumentMatchers;
|
|||
@RunWith(JUnit4.class)
|
||||
public class JobServerAuthenticationTest {
|
||||
|
||||
private final String projectRoot = "";
|
||||
|
||||
// Authorized client key/cert/ca
|
||||
private final String clientCa = "resources/client/ca.crt";
|
||||
private final String clientKey = "resources/client/private.pem";
|
||||
private final String clientCert = "resources/client/client.crt";
|
||||
private final String clientCa = projectRoot + "resources/client/ca.crt";
|
||||
private final String clientKey = projectRoot + "resources/client/private.pem";
|
||||
private final String clientCert = projectRoot + "resources/client/client.crt";
|
||||
|
||||
// Authorized server key/cert/ca
|
||||
private final String serverCa = "resources/server/ca.crt";
|
||||
private final String serverKey = "resources/server/private.pem";
|
||||
private final String serverCert = "resources/server/server.crt";
|
||||
private final String serverCa = projectRoot + "resources/server/ca.crt";
|
||||
private final String serverKey = projectRoot + "resources/server/private.pem";
|
||||
private final String serverCert = projectRoot + "resources/server/server.crt";
|
||||
|
||||
// controlled failure key/cert/ca
|
||||
private final String badCa = "resources/test/ca.crt";
|
||||
private final String badKey = "resources/test/private.pem";
|
||||
private final String badCert = "resources/test/test.crt";
|
||||
|
||||
// Automates (graceful) shutdown at end of tests
|
||||
@Rule
|
||||
public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
|
||||
|
||||
private final ShellServerGrpc.ShellServerImplBase serviceImpl= mock(ShellServerGrpc.ShellServerImplBase.class,
|
||||
delegatesTo(new ShellServerGrpc.ShellServerImplBase() {}));
|
||||
private final String badCa = projectRoot + "resources/test/ca.crt";
|
||||
private final String badKey = projectRoot + "resources/test/private.pem";
|
||||
private final String badCert = projectRoot + "resources/test/test.crt";
|
||||
|
||||
// badClient uses unauthorized certs
|
||||
private JobServClient goodClient;
|
||||
private JobServClient badClient;
|
||||
private JobServServer server;
|
||||
|
||||
// was setUp able to use SSL Certs
|
||||
private Boolean serverSslInitialized;
|
||||
private Boolean clientSslInitialized;
|
||||
private Boolean serverSslInitialized = true;
|
||||
private Boolean clientSslInitialized = true;
|
||||
|
||||
/*
|
||||
* setUp()
|
||||
* test constructor
|
||||
* generates both clients and the server
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
String serverName = InProcessServerBuilder.generateName();
|
||||
public JobServerAuthenticationTest() throws Exception {
|
||||
|
||||
System.out.println("Ctrl print");
|
||||
|
||||
try {
|
||||
// generate SSL contexts
|
||||
SslContextBuilder serverContextBuilder = SslContextBuilder.forServer(new File(serverCert),
|
||||
|
|
@ -91,42 +89,38 @@ public class JobServerAuthenticationTest {
|
|||
serverContextBuilder.trustManager(new File(clientCa));
|
||||
serverContextBuilder.clientAuth(ClientAuth.REQUIRE);
|
||||
|
||||
grpcCleanup.register(InProcessServerBuilder.forName(serverName)
|
||||
.sslContext(serverContextBuilder.build())
|
||||
.directExecutor()
|
||||
.addService(this.serviceImpl)
|
||||
.build().start());
|
||||
|
||||
this.server = new JobServServer(GrpcSslContexts.configure(serverContextBuilder).build(), 8448);
|
||||
this.serverSslInitialized = true;
|
||||
|
||||
} catch (SSLException e) {
|
||||
// One of the certs or keys was bad, ssl cannot be used
|
||||
this.serverSslInitialized = false;
|
||||
grpcCleanup.register(InProcessServerBuilder.forName(serverName)
|
||||
.directExecutor()
|
||||
.addService(this.serviceImpl).build().start());
|
||||
System.err.println(e.getMessage());
|
||||
|
||||
} catch (IOException e) {
|
||||
this.serverSslInitialized = false;
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
|
||||
// generate ssl for clients
|
||||
if (this.serverSslInitialized) {
|
||||
try {
|
||||
SslContextBuilder goodClientBuilder = SslContextBuilder.forClient();
|
||||
SslContextBuilder goodClientBuilder = GrpcSslContexts.forClient();
|
||||
goodClientBuilder.trustManager(new File(serverCa));
|
||||
goodClientBuilder.keyManager(new File(clientCert), new File(clientKey));
|
||||
|
||||
SslContextBuilder badClientBuilder = SslContextBuilder.forClient();
|
||||
SslContextBuilder badClientBuilder = GrpcSslContexts.forClient();
|
||||
badClientBuilder.trustManager(new File(serverCa));
|
||||
badClientBuilder.keyManager(new File(badCert), new File(badKey));
|
||||
|
||||
ManagedChannel goodChannel = grpcCleanup.register(InProcessChannelBuilder.forName(serverName)
|
||||
.sslContext(goodClientBuilder.build())
|
||||
.directExecutor()
|
||||
.build());
|
||||
ManagedChannel goodChannel = NettyChannelBuilder.forAddress("localhost", 8448)
|
||||
.sslContext(goodClientBuilder.build())
|
||||
.directExecutor()
|
||||
.build();
|
||||
|
||||
ManagedChannel badChannel = grpcCleanup.register(InProcessChannelBuilder.forName(serverName)
|
||||
.sslContext(badClientBuilder.build())
|
||||
.directExecutor()
|
||||
.build());
|
||||
ManagedChannel badChannel = NettyChannelBuilder.forAddress("localhost", 8448)
|
||||
.sslContext(badClientBuilder.build())
|
||||
.directExecutor()
|
||||
.build();
|
||||
|
||||
goodClient = new JobServClient(goodChannel);
|
||||
badClient = new JobServClient(badChannel);
|
||||
|
|
@ -134,53 +128,29 @@ public class JobServerAuthenticationTest {
|
|||
|
||||
} catch (SSLException e) {
|
||||
this.clientSslInitialized = false;
|
||||
ManagedChannel nonSslChannel = grpcCleanup.register(InProcessChannelBuilder.forName(serverName)
|
||||
.directExecutor()
|
||||
.build());
|
||||
goodClient = new JobServClient(nonSslChannel);
|
||||
badClient = null; //
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
|
||||
} else {
|
||||
this.clientSslInitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Server TLS Test
|
||||
* fails if server SslContext generation threw an SSLException
|
||||
* TLS Cert Auth Test
|
||||
* this needed to be one test because running multiple tests at the same time
|
||||
* fails as the server tries to rebind to the same port.
|
||||
*/
|
||||
@Test
|
||||
public void serverTlsTest() {
|
||||
assertEquals(this.serverSslInitialized, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Client TLS Test
|
||||
* fails if client SslContext generation threw an SSL Exception
|
||||
*/
|
||||
@Test
|
||||
public void clientTlsTest() {
|
||||
assertEquals(this.clientSslInitialized, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* TLS Cert Auth Negative Test
|
||||
* fails if badClient can successfully make requests of the server
|
||||
*/
|
||||
@Test
|
||||
public void certAuthNegTest() {
|
||||
assertEquals(clientSslInitialized, true);
|
||||
public void certificateAuthenticationTest() {
|
||||
assertEquals(true, serverSslInitialized);
|
||||
assertEquals(true, clientSslInitialized);
|
||||
|
||||
int result = badClient.sendNewJobMessage("test command");
|
||||
assertEquals(result, -2);
|
||||
}
|
||||
assertEquals(-2, result);
|
||||
|
||||
/*
|
||||
* TLS Cert Auth Positive Test
|
||||
* fails if goodClient cannot make requests of the server
|
||||
*/
|
||||
@Test
|
||||
public void certAuthPosTest() {
|
||||
assertEquals(clientSslInitialized, true);
|
||||
int result = goodClient.sendNewJobMessage("test command");
|
||||
result = goodClient.sendNewJobMessage("test command");
|
||||
Boolean assertCondition = result == -2;
|
||||
assertEquals(result, false);
|
||||
assertEquals(assertCondition, false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue