-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add ProcessLaunchHealthCheck Closes #41
- Loading branch information
Showing
2 changed files
with
148 additions
and
0 deletions.
There are no files selected for viewing
48 changes: 48 additions & 0 deletions
48
src/main/java/org/kiwiproject/dropwizard/util/health/ProcessLaunchHealthCheck.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package org.kiwiproject.dropwizard.util.health; | ||
|
||
import static java.nio.charset.StandardCharsets.UTF_8; | ||
import static org.kiwiproject.metrics.health.HealthCheckResults.newHealthyResult; | ||
import static org.kiwiproject.metrics.health.HealthCheckResults.newUnhealthyResult; | ||
|
||
import com.codahale.metrics.health.HealthCheck; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.kiwiproject.base.process.ProcessHelper; | ||
import org.kiwiproject.io.KiwiIO; | ||
|
||
/** | ||
* Health check that checks if we are able to launch processes. This check attempts to launch a simple echo process | ||
* and verifies the output is as expected. | ||
* | ||
* @implNote Only works on *nix-like systems, or maybe in Windows if there is an echo command installed and on the PATH. | ||
*/ | ||
@Slf4j | ||
public class ProcessLaunchHealthCheck extends HealthCheck { | ||
|
||
static final String ECHO_MESSAGE = "Launch process health check"; | ||
|
||
private final ProcessHelper processes; | ||
|
||
public ProcessLaunchHealthCheck(ProcessHelper processes) { | ||
this.processes = processes; | ||
} | ||
|
||
@Override | ||
protected Result check() { | ||
try { | ||
var process = processes.launch("echo", ECHO_MESSAGE); | ||
var line = KiwiIO.readInputStreamOf(process, UTF_8); | ||
return resultBasedOnEchoOutput(line); | ||
} catch (Exception e) { | ||
LOG.trace("Process launch health check is not healthy", e); | ||
return newUnhealthyResult("Failed launching an 'echo' process: " + e.getMessage()); | ||
} | ||
} | ||
|
||
private static Result resultBasedOnEchoOutput(String line) { | ||
if (ECHO_MESSAGE.equals(line.stripTrailing())) { | ||
return newHealthyResult(); | ||
} | ||
|
||
return newUnhealthyResult("Output [%s] from 'echo' does not match expected [%s]", line, ECHO_MESSAGE); | ||
} | ||
} |
100 changes: 100 additions & 0 deletions
100
src/test/java/org/kiwiproject/dropwizard/util/health/ProcessLaunchHealthCheckTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package org.kiwiproject.dropwizard.util.health; | ||
|
||
import static org.kiwiproject.base.KiwiStrings.f; | ||
import static org.kiwiproject.dropwizard.util.health.ProcessLaunchHealthCheck.ECHO_MESSAGE; | ||
import static org.kiwiproject.test.assertj.dropwizard.metrics.HealthCheckResultAssertions.assertThatHealthCheck; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.when; | ||
|
||
import com.google.common.base.Charsets; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.condition.EnabledOnOs; | ||
import org.junit.jupiter.api.condition.OS; | ||
import org.kiwiproject.base.process.ProcessHelper; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.UncheckedIOException; | ||
|
||
@DisplayName("ProcessLaunchHealthCheck") | ||
class ProcessLaunchHealthCheckTest { | ||
|
||
private ProcessLaunchHealthCheck healthCheck; | ||
private ProcessHelper processes; | ||
private Process process; | ||
|
||
@BeforeEach | ||
void setup() { | ||
process = mock(Process.class); | ||
processes = mock(ProcessHelper.class); | ||
healthCheck = new ProcessLaunchHealthCheck(processes); | ||
} | ||
|
||
@Nested | ||
class IsHealthy { | ||
|
||
@Test | ||
void whenEchoProcessCanBeLaunched() { | ||
when(processes.launch("echo", ECHO_MESSAGE)).thenReturn(process); | ||
|
||
var inputStream = toInputStream(ECHO_MESSAGE); | ||
when(process.getInputStream()).thenReturn(inputStream); | ||
|
||
assertThatHealthCheck(healthCheck) | ||
.isHealthy(); | ||
} | ||
|
||
/** | ||
* Only running on Linux and MacOS since we know for a fact that 'echo' exists there. | ||
*/ | ||
@Test | ||
@EnabledOnOs({OS.LINUX, OS.MAC}) | ||
void whenEchoProcessCanBeLaunched_UsingActualProcess() { | ||
healthCheck = new ProcessLaunchHealthCheck(new ProcessHelper()); | ||
|
||
assertThatHealthCheck(healthCheck) | ||
.isHealthy(); | ||
} | ||
} | ||
|
||
@Nested | ||
class IsUnhealthy { | ||
|
||
@Test | ||
void whenEchoMessageDoesNotMatchExpectedOutput() { | ||
when(processes.launch("echo", ECHO_MESSAGE)).thenReturn(process); | ||
|
||
var droidsMessage = "These are not the droids you're looking for.. "; | ||
var inputStream = toInputStream(droidsMessage); | ||
when(process.getInputStream()).thenReturn(inputStream); | ||
|
||
assertThatHealthCheck(healthCheck) | ||
.isUnhealthy() | ||
.hasMessage(f("Output [{}] from 'echo' does not match expected [{}]", | ||
droidsMessage, ECHO_MESSAGE)); | ||
} | ||
|
||
@Test | ||
void whenExceptionIsThrown() { | ||
var message = "Process launch failure"; | ||
IOException ioException = new IOException(message); | ||
UncheckedIOException uncheckedIOException = new UncheckedIOException(ioException); | ||
|
||
when(processes.launch("echo", ECHO_MESSAGE)).thenThrow(uncheckedIOException); | ||
|
||
assertThatHealthCheck(healthCheck) | ||
.isUnhealthy() | ||
.hasMessageStartingWith("Failed launching an 'echo' process: ") | ||
.hasMessageEndingWith(uncheckedIOException.getMessage()); | ||
} | ||
} | ||
|
||
private InputStream toInputStream(String value) { | ||
return new ByteArrayInputStream(value.getBytes(Charsets.UTF_8)); | ||
} | ||
} | ||
|