private void collectLogs(String container, DockerCompose dockerCompose) { executor.submit(() -> { File outputFile = new File(logDirectory, container + ".log"); log.info("Writing logs for container '{}' to '{}'", container, outputFile.getAbsolutePath()); try (FileOutputStream outputStream = new FileOutputStream(outputFile)) { dockerCompose.writeLogs(container, outputStream); } catch (IOException e) { throw new RuntimeException("Error reading log", e); } }); }
@Override public boolean writeLogs(String container, OutputStream output) throws IOException { return dockerCompose.writeLogs(container, output); }
@Override public boolean writeLogs(String container, OutputStream output) throws IOException { return dockerCompose.writeLogs(container, output); }
@Override public boolean writeLogs(String container, OutputStream output) throws IOException { return dockerCompose.writeLogs(container, output); }
private void collectLogs(String container, DockerCompose dockerCompose) { executor.submit(() -> { File outputFile = new File(logDirectory, container + ".log"); log.info("Writing logs for container '{}' to '{}'", container, outputFile.getAbsolutePath()); try (FileOutputStream outputStream = new FileOutputStream(outputFile)) { dockerCompose.writeLogs(container, outputStream); } catch (IOException e) { throw new RuntimeException("Error reading log", e); } }); }
private void collectLogs(String container, DockerCompose dockerCompose) { executor.submit(() -> { File outputFile = new File(logDirectory, container + ".log"); log.info("Writing logs for container '{}' to '{}'", container, outputFile.getAbsolutePath()); try (FileOutputStream outputStream = new FileOutputStream(outputFile)) { dockerCompose.writeLogs(container, outputStream); } catch (IOException e) { throw new RuntimeException("Error reading log", e); } }); }
private void collectLogs(String container, DockerCompose dockerCompose) { executor.submit(() -> { File outputFile = new File(logDirectory, container + ".log"); try { Files.createFile(outputFile.toPath()); } catch (final FileAlreadyExistsException e) { // ignore } catch (final IOException e) { throw new RuntimeException("Error creating log file", e); } log.info("Writing logs for container '{}' to '{}'", container, outputFile.getAbsolutePath()); try (FileOutputStream outputStream = new FileOutputStream(outputFile)) { dockerCompose.writeLogs(container, outputStream); } catch (IOException e) { throw new RuntimeException("Error reading log", e); } }); }
@Test public void call_docker_compose_with_the_follow_flag_when_the_version_is_at_least_1_7_0_on_logs() throws IOException { when(executedProcess.getInputStream()).thenReturn( toInputStream("id"), toInputStream("docker-compose version 1.7.0, build 1ad8866"), toInputStream("logs")); ByteArrayOutputStream output = new ByteArrayOutputStream(); compose.writeLogs("db", output); verify(executor).execute("logs", "--no-color", "--follow", "db"); assertThat(new String(output.toByteArray(), StandardCharsets.UTF_8), is("logs")); }
@Test public void call_docker_compose_with_no_colour_flag_on_logs() throws IOException { when(executedProcess.getInputStream()).thenReturn( toInputStream("id"), toInputStream("docker-compose version 1.5.6, build 1ad8866"), toInputStream("logs")); ByteArrayOutputStream output = new ByteArrayOutputStream(); compose.writeLogs("db", output); verify(executor).execute("logs", "--no-color", "db"); assertThat(new String(output.toByteArray(), StandardCharsets.UTF_8), is("logs")); }
@Test public void call_docker_compose_with_no_container_on_logs() throws IOException { reset(executor); final Process mockIdProcess = mock(Process.class); when(mockIdProcess.exitValue()).thenReturn(0); final InputStream emptyStream = toInputStream(""); when(mockIdProcess.getInputStream()).thenReturn(emptyStream, emptyStream, emptyStream, toInputStream("id")); final Process mockVersionProcess = mock(Process.class); when(mockVersionProcess.exitValue()).thenReturn(0); when(mockVersionProcess.getInputStream()).thenReturn(toInputStream("docker-compose version 1.5.6, build 1ad8866")); when(executor.execute("ps", "-q", "db")).thenReturn(mockIdProcess); when(executor.execute("-v")).thenReturn(mockVersionProcess); when(executor.execute("logs", "--no-color", "db")).thenReturn(executedProcess); when(executedProcess.getInputStream()).thenReturn(toInputStream("logs")); ByteArrayOutputStream output = new ByteArrayOutputStream(); compose.writeLogs("db", output); verify(executor, times(4)).execute("ps", "-q", "db"); verify(executor).execute("logs", "--no-color", "db"); assertThat(new String(output.toByteArray(), StandardCharsets.UTF_8), is("logs")); }
@Test public void collect_logs_when_one_container_is_running_and_terminates_before_start_collecting_is_run() throws Exception { when(compose.services()).thenReturn(ImmutableList.of("db")); when(compose.writeLogs(eq("db"), any(OutputStream.class))).thenAnswer(args -> { OutputStream outputStream = (OutputStream) args.getArguments()[1]; IOUtils.write("log", outputStream); return false; }); logCollector.startCollecting(compose); logCollector.stopCollecting(); assertThat(logDirectory.listFiles(), arrayContaining(fileWithName("db.log"))); assertThat(new File(logDirectory, "db.log"), is(fileContainingString("log"))); }
@Test public void collect_logs_in_parallel_for_two_containers() throws IOException, InterruptedException { when(compose.services()).thenReturn(ImmutableList.of("db", "db2")); CountDownLatch dbLatch = new CountDownLatch(1); when(compose.writeLogs(eq("db"), any(OutputStream.class))).thenAnswer(args -> { OutputStream outputStream = (OutputStream) args.getArguments()[1]; IOUtils.write("log", outputStream); dbLatch.countDown(); return true; }); CountDownLatch db2Latch = new CountDownLatch(1); when(compose.writeLogs(eq("db2"), any(OutputStream.class))).thenAnswer(args -> { OutputStream outputStream = (OutputStream) args.getArguments()[1]; IOUtils.write("other", outputStream); db2Latch.countDown(); return true; }); logCollector.startCollecting(compose); assertThat(dbLatch.await(1, TimeUnit.SECONDS), is(true)); assertThat(db2Latch.await(1, TimeUnit.SECONDS), is(true)); assertThat(logDirectory.listFiles(), arrayContainingInAnyOrder(fileWithName("db.log"), fileWithName("db2.log"))); assertThat(new File(logDirectory, "db.log"), is(fileContainingString("log"))); assertThat(new File(logDirectory, "db2.log"), is(fileContainingString("other"))); logCollector.stopCollecting(); }
@Test public void collect_logs_when_one_container_is_running_and_does_not_terminate_until_after_start_collecting_is_run() throws Exception { when(compose.services()).thenReturn(ImmutableList.of("db")); CountDownLatch latch = new CountDownLatch(1); when(compose.writeLogs(eq("db"), any(OutputStream.class))).thenAnswer(args -> { if (!latch.await(1, TimeUnit.SECONDS)) { throw new RuntimeException("Latch was not triggered"); } OutputStream outputStream = (OutputStream) args.getArguments()[1]; IOUtils.write("log", outputStream); return false; }); logCollector.startCollecting(compose); latch.countDown(); logCollector.stopCollecting(); assertThat(logDirectory.listFiles(), arrayContaining(fileWithName("db.log"))); assertThat(new File(logDirectory, "db.log"), is(fileContainingString("log"))); }
@Test public void collect_logs_when_one_container_is_running_and_does_not_terminate() throws IOException, InterruptedException { when(compose.services()).thenReturn(ImmutableList.of("db")); CountDownLatch latch = new CountDownLatch(1); when(compose.writeLogs(eq("db"), any(OutputStream.class))).thenAnswer(args -> { OutputStream outputStream = (OutputStream) args.getArguments()[1]; IOUtils.write("log", outputStream); try { latch.await(1, TimeUnit.SECONDS); fail("Latch was not triggered"); } catch (InterruptedException e) { // Success return true; } fail("Latch was not triggered"); return false; }); logCollector.startCollecting(compose); logCollector.stopCollecting(); assertThat(logDirectory.listFiles(), arrayContaining(fileWithName("db.log"))); assertThat(new File(logDirectory, "db.log"), is(fileContainingString("log"))); latch.countDown(); }
@SuppressWarnings("unchecked") @Test public void be_able_to_save_logs_to_a_directory_while_containers_are_running() throws IOException, InterruptedException { File logLocation = logFolder.newFolder(); DockerComposeRule loggingComposition = DockerComposeRule.builder() .docker(mockDocker) .dockerCompose(dockerCompose) .files(mockFiles) .machine(machine) .saveLogsTo(logLocation.getAbsolutePath()) .build(); when(dockerCompose.services()).thenReturn(ImmutableList.of("db")); when(dockerCompose.id(any())).thenReturn(Optional.of("abcde")); when(mockDocker.state("abcde")).thenReturn(State.HEALTHY); CountDownLatch latch = new CountDownLatch(1); when(dockerCompose.writeLogs(eq("db"), any(OutputStream.class))).thenAnswer(args -> { OutputStream outputStream = (OutputStream) args.getArguments()[1]; IOUtils.write("db log", outputStream); latch.countDown(); return true; }); loggingComposition.before(); assertThat(latch.await(1, TimeUnit.SECONDS), is(true)); loggingComposition.after(); assertThat(logLocation.listFiles(), arrayContaining(fileWithName("db.log"))); assertThat(new File(logLocation, "db.log"), is(fileContainingString("db log"))); }