use of org.jboss.pnc.spi.builddriver.DebugData in project pnc by project-ncl.
the class LivenessProbeTest method shouldFailTheBuildWhenAgentIsNotResponding.
@Test
public void shouldFailTheBuildWhenAgentIsNotResponding() throws InterruptedException, BuildDriverException {
TermdBuildDriverModuleConfig buildDriverModuleConfig = mock(TermdBuildDriverModuleConfig.class);
doReturn(200L).when(buildDriverModuleConfig).getLivenessProbeFrequencyMillis();
doReturn(500L).when(buildDriverModuleConfig).getLivenessFailTimeoutMillis();
ClientMockFactory buildAgentClientMockFactory = new ClientMockFactory();
TermdBuildDriver driver = new TermdBuildDriver(systemConfig, buildDriverModuleConfig, buildAgentClientMockFactory);
BuildExecutionSession buildExecution = mock(BuildExecutionSession.class);
BuildExecutionConfiguration buildExecutionConfiguration = mock(BuildExecutionConfiguration.class);
doReturn(buildExecutionConfiguration).when(buildExecution).getBuildExecutionConfiguration();
RunningEnvironment runningEnvironment = mock(RunningEnvironment.class);
doReturn(Paths.get("")).when(runningEnvironment).getWorkingDirectory();
doReturn(new DebugData(false)).when(runningEnvironment).getDebugData();
doReturn("http://localhost/").when(runningEnvironment).getInternalBuildAgentUrl();
doReturn(runningEnvironment).when(buildExecution).getRunningEnvironment();
BlockingQueue<Throwable> result = new ArrayBlockingQueue(1);
Consumer<CompletedBuild> onComplete = (completedBuild) -> Assert.fail("Build should complete with error.");
Consumer<Throwable> onError = (throwable) -> {
try {
result.put(throwable);
} catch (InterruptedException e) {
Assert.fail("Error in the test. Unable to add the result to queue.");
}
};
// when
RunningBuild runningBuild = driver.startProjectBuild(buildExecution, runningEnvironment, onComplete, onError);
// then
Throwable throwable = result.poll(1, TimeUnit.SECONDS);
Assert.assertNotNull("It should complete with an exception.", throwable);
Assert.assertEquals("Build Agent has gone away.", throwable.getMessage());
}
use of org.jboss.pnc.spi.builddriver.DebugData in project pnc by project-ncl.
the class TermdBuildDriver method startProjectBuild.
public RunningBuild startProjectBuild(BuildExecutionSession buildExecutionSession, RunningEnvironment runningEnvironment, Consumer<CompletedBuild> onComplete, Consumer<Throwable> onError, Optional<Consumer<Status>> onStatusUpdate) throws BuildDriverException {
logger.info("[{}] Starting build for Build Execution Session {}", runningEnvironment.getId(), buildExecutionSession.getId());
TermdRunningBuild termdRunningBuild = new TermdRunningBuild(runningEnvironment, buildExecutionSession.getBuildExecutionConfiguration(), onComplete, onError);
DebugData debugData = runningEnvironment.getDebugData();
String buildScript = prepareBuildScript(termdRunningBuild, debugData);
if (!termdRunningBuild.isCanceled()) {
String terminalUrl = getBuildAgentUrl(runningEnvironment);
final RemoteInvocation remoteInvocation = new RemoteInvocation(clientFactory, terminalUrl, onStatusUpdate, httpCallbackMode, buildExecutionSession.getId(), buildExecutionSession.getAccessToken());
buildExecutionSession.setBuildStatusUpdateConsumer(remoteInvocation.getClientStatusUpdateConsumer());
FileTransfer fileTransfer = new ClientFileTransfer(remoteInvocation.getBuildAgentClient(), MAX_LOG_SIZE);
fileTransferReadTimeout.ifPresent(fileTransfer::setReadTimeout);
CompletableFuture<Void> prepareBuildFuture = CompletableFuture.supplyAsync(() -> {
logger.debug("Uploading build script to build environment ...");
return uploadTask(termdRunningBuild.getRunningEnvironment(), buildScript, fileTransfer);
}, executor).thenApplyAsync(scriptPath -> {
logger.debug("Setting the script path ...");
remoteInvocation.setScriptPath(scriptPath);
return null;
}, executor).thenRunAsync(() -> {
logger.debug("Invoking remote script ...");
invokeRemoteScript(remoteInvocation);
}, executor);
CompletableFuture<RemoteInvocationCompletion> buildLivenessFuture = prepareBuildFuture.thenComposeAsync(nul -> {
logger.debug("Starting liveness monitor ...");
return monitorBuildLiveness(remoteInvocation);
}, executor);
CompletableFuture<RemoteInvocationCompletion> buildCompletionFuture = prepareBuildFuture.thenComposeAsync(nul -> {
logger.debug("Waiting fo remote script to complete...");
return remoteInvocation.getCompletionNotifier();
}, executor);
CompletableFuture<RemoteInvocationCompletion> optionallyEnableDebug = buildCompletionFuture.thenApplyAsync(remoteInvocationCompletion -> {
Status status = remoteInvocationCompletion.getStatus();
if (status.isFinal()) {
logger.debug("Script completionNotifier completed with status {}.", status);
if ((status == FAILED || status == SYSTEM_ERROR) && debugData.isEnableDebugOnFailure()) {
debugData.setDebugEnabled(true);
remoteInvocation.enableSsh();
}
}
return remoteInvocationCompletion;
}, executor);
CompletableFuture<Object> buildFuture = CompletableFuture.anyOf(buildLivenessFuture, optionallyEnableDebug);
buildFuture.handle((result, exception) -> {
RemoteInvocationCompletion completion;
if (result != null) {
// both of combined futures return the same type
RemoteInvocationCompletion remoteInvocationCompletion = (RemoteInvocationCompletion) result;
if (remoteInvocationCompletion.getException() != null) {
logger.warn("Completing build execution.", remoteInvocationCompletion.getException());
} else {
logger.debug("Completing build execution. Status: {};", remoteInvocationCompletion.getStatus());
}
completion = remoteInvocationCompletion;
} else if (exception != null && exception.getCause() instanceof java.util.concurrent.CancellationException) {
// canceled in non build operation (completableFuture cancel), non graceful completion
logger.warn("Completing build execution. Cancelled;");
completion = new RemoteInvocationCompletion(INTERRUPTED, Optional.empty());
} else {
logger.warn("Completing build execution. System error.", exception);
completion = new RemoteInvocationCompletion(new BuildDriverException("System error.", exception));
}
termdRunningBuild.setCancelHook(null);
remoteInvocation.close();
complete(termdRunningBuild, completion, fileTransfer);
return null;
});
termdRunningBuild.setCancelHook(() -> {
// try to cancel remote execution
remoteInvocation.cancel();
ScheduledFuture<?> forceCancel_ = scheduledExecutorService.schedule(() -> {
logger.debug("Force cancelling build ...");
prepareBuildFuture.cancel(true);
}, internalCancelTimeoutMillis, TimeUnit.MILLISECONDS);
remoteInvocation.addPreClose(() -> forceCancel_.cancel(false));
});
} else {
logger.debug("Skipping script uploading (cancel flag) ...");
}
return termdRunningBuild;
}
use of org.jboss.pnc.spi.builddriver.DebugData in project pnc by project-ncl.
the class BuildExecutionSessionMock method getBuildResult.
private BuildResult getBuildResult() {
EnvironmentDriverResult environmentDriverResult = null;
DebugData debugData = getRunningEnvironment() != null ? getRunningEnvironment().getDebugData() : null;
if (debugData != null && debugData.isDebugEnabled()) {
environmentDriverResult = new EnvironmentDriverResult(CompletionStatus.SUCCESS, "", Optional.of(debugData.getSshCredentials()));
}
CompletionStatus completionStatus = CompletionStatus.SUCCESS;
if (executorException == null) {
if (failedReasonStatus != null) {
switch(failedReasonStatus) {
case BUILD_ENV_SETUP_COMPLETE_WITH_ERROR:
case COLLECTING_RESULTS_FROM_REPOSITORY_MANAGER_COMPLETED_WITH_ERROR:
case SYSTEM_ERROR:
completionStatus = CompletionStatus.SYSTEM_ERROR;
break;
case BUILD_COMPLETED_WITH_ERROR:
completionStatus = CompletionStatus.FAILED;
break;
case CANCELLED:
completionStatus = CompletionStatus.CANCELLED;
break;
case DONE_WITH_ERRORS:
executorException = new ExecutorException("DONE_WITH_ERRORS cannot be set as failed reason.");
break;
}
}
}
ProcessException processException = null;
if (executorException != null) {
processException = new ProcessException(executorException);
completionStatus = CompletionStatus.SYSTEM_ERROR;
}
log.debug("Returning result of task {}.", getId());
return new BuildResult(completionStatus, Optional.ofNullable(processException), "", Optional.ofNullable(buildExecutionConfiguration), Optional.ofNullable(buildDriverResult), Optional.ofNullable(repositoryManagerResult), Optional.ofNullable(environmentDriverResult), Optional.empty());
}
use of org.jboss.pnc.spi.builddriver.DebugData in project pnc by project-ncl.
the class DebugInContainerTest method shouldEnableSshWhenBuildFails.
@Test
public void shouldEnableSshWhenBuildFails() throws InterruptedException, BuildDriverException {
TermdBuildDriverModuleConfig buildDriverModuleConfig = mock(TermdBuildDriverModuleConfig.class);
doReturn(1000L).when(buildDriverModuleConfig).getLivenessProbeFrequencyMillis();
doReturn(5000L).when(buildDriverModuleConfig).getLivenessFailTimeoutMillis();
doReturn(5000).when(buildDriverModuleConfig).getFileTransferReadTimeout();
ClientMockFactory buildAgentClientFactory = new ClientMockFactory();
TermdBuildDriver driver = new TermdBuildDriver(systemConfig, buildDriverModuleConfig, buildAgentClientFactory);
BuildExecutionSession buildExecution = mock(BuildExecutionSession.class);
BuildExecutionConfiguration buildExecutionConfiguration = mock(BuildExecutionConfiguration.class);
doReturn(buildExecutionConfiguration).when(buildExecution).getBuildExecutionConfiguration();
RunningEnvironment runningEnvironment = mock(RunningEnvironment.class);
doReturn(Paths.get("")).when(runningEnvironment).getWorkingDirectory();
doReturn(new DebugData(true)).when(runningEnvironment).getDebugData();
doReturn("http://localhost/").when(runningEnvironment).getInternalBuildAgentUrl();
doReturn(runningEnvironment).when(buildExecution).getRunningEnvironment();
BlockingQueue<CompletedBuild> result = new ArrayBlockingQueue(1);
Consumer<CompletedBuild> onComplete = (completedBuild) -> {
try {
result.put(completedBuild);
} catch (InterruptedException e) {
Assert.fail("Unable to consume build result.");
}
};
Consumer<Throwable> onError = (throwable) -> Assert.fail("Build should fail without system error.");
// when
RunningBuild runningBuild = driver.startProjectBuild(buildExecution, runningEnvironment, onComplete, onError);
// wait to start waiting for completion and start liveness probe
Thread.sleep(500);
buildAgentClientFactory.getOnStatusUpdate().accept(TaskStatusUpdateEvent.newBuilder().newStatus(Status.FAILED).build());
// then
CompletedBuild completedBuild = result.poll(3, TimeUnit.SECONDS);
Assert.assertNotNull("Missing build result.", completedBuild);
Assert.assertEquals("The build should fail.", BuildStatus.FAILED, completedBuild.getBuildResult().getBuildStatus());
List<Object> executedCommands = buildAgentClientFactory.getBuildAgentClient().getExecutedCommands();
logger.info("Executed commands {}.", executedCommands);
Assert.assertEquals(2, executedCommands.size());
Assertions.assertThat(executedCommands).anySatisfy(c -> ((String) c).contains("startSshd.sh"));
}
Aggregations