Skip to content

Commit

Permalink
Merge pull request #117 from iamdanfox/small-helpers
Browse files Browse the repository at this point in the history
New `circleAwareLogDirectory` enables partial log capture on CI
  • Loading branch information
iamdanfox authored Oct 14, 2016
2 parents a580343 + 9ed4193 commit 34ee34a
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 0 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ public class DockerComposeRuleTest {

This will automatically record logs for all containers in real time to the specified directory. Collection will stop when the containers terminate.

The `LogDirectory` class contains utility methods to generate these paths. For example, you can write logs directly into the `$CIRCLE_ARTIFACTS` directory on CI (but fall back to `build/dockerLogs` locally) using:

```java
.saveLogsTo(circleAwareLogDirectory(MyTest.class))
```

Methods in `LogDirectory` are intended to be statically imported for readability.

Skipping shutdown
-----------------

Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ dependencies {
testCompile "org.mockito:mockito-core:$mockitoVersion"
testCompile "com.github.tomakehurst:wiremock:2.0.6-beta"
testCompile "com.google.code.findbugs:jsr305:3.0.0"
testCompile "com.github.stefanbirkner:system-rules:1.16.1"
}

// Instead of copying files out of `$buildDir/test-results/` on CircleCI, we can
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.palantir.docker.compose.logging.DoNothingLogCollector;
import com.palantir.docker.compose.logging.FileLogCollector;
import com.palantir.docker.compose.logging.LogCollector;
import com.palantir.docker.compose.logging.LogDirectory;
import java.io.IOException;
import java.util.List;
import org.immutables.value.Value;
Expand Down Expand Up @@ -169,6 +170,14 @@ public Builder file(String dockerComposeYmlFile) {
return files(DockerComposeFiles.from(dockerComposeYmlFile));
}

/**
* Save the output of docker logs to files, stored in the <code>path</code> directory.
*
* See {@link LogDirectory} for some useful utilities, for example:
* {@link LogDirectory#circleAwareLogDirectory}.
*
* @param path directory into which log files should be saved
*/
public Builder saveLogsTo(String path) {
return logCollector(FileLogCollector.fromPath(path));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2016 Palantir Technologies, Inc. All rights reserved.
*/

package com.palantir.docker.compose.logging;

import java.util.Optional;

public class LogDirectory {

private LogDirectory() {}

/**
* For tests running on CircleCI, save logs into <code>$CIRCLE_ARTIFACTS/dockerLogs/&lt;testClassName&gt;</code>.
* This ensures partial logs can be recovered if the build is cancelled or times out, and
* also avoids needless copying.
*
* Otherwise, save logs from local runs to a folder inside <code>$project/build/dockerLogs</code> named
* after the test class.
*
* @param testClass the JUnit test class whose name will appear on the log folder
*/
public static String circleAwareLogDirectory(Class<?> testClass) {
String artifactRoot = Optional.ofNullable(System.getenv("CIRCLE_ARTIFACTS")).orElse("build");
return artifactRoot + "/dockerLogs/" + testClass.getSimpleName();
}

/**
* Save logs into a new folder, $project/build/dockerLogs/&lt;testClassName&gt;.
*/
public static String gradleDockerLogsDirectory(Class<?> testClass) {
return "build/dockerLogs/" + testClass.getSimpleName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2016 Palantir Technologies, Inc. All rights reserved.
*/

package com.palantir.docker.compose.logging;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.EnvironmentVariables;

public class LogDirectoryTest {

@Rule
public final EnvironmentVariables variablesRule = new EnvironmentVariables();

@Test
public void gradleDockerLogsDirectory_should_use_class_simple_name() {
String directory = LogDirectory.gradleDockerLogsDirectory(SomeTestClass.class);
assertThat(directory, is("build/dockerLogs/SomeTestClass"));
}

@Test
public void circleAwareLogDirectory_should_match_gradleDockerLogsDirectory_by_default() {
variablesRule.set("CIRCLE_ARTIFACTS", null);
String directory = LogDirectory.circleAwareLogDirectory(SomeTestClass.class);
assertThat(directory, is("build/dockerLogs/SomeTestClass"));
}

@Test
public void circleAwareLogDirectory_should_use_circle_environment_variable_if_available() {
variablesRule.set("CIRCLE_ARTIFACTS", "/tmp/circle-artifacts.g4DjuuD");

String directory = LogDirectory.circleAwareLogDirectory(SomeTestClass.class);
assertThat(directory, is("/tmp/circle-artifacts.g4DjuuD/dockerLogs/SomeTestClass"));
}

private static class SomeTestClass {}
}

0 comments on commit 34ee34a

Please sign in to comment.