blob: 9ee7e253a345bee404f061f0ee8f06c5ebe15674 [file] [log] [blame]
/*
* Copyright 2014-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.log;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import com.facebook.buck.testutil.FakeOutputStream;
import org.junit.Test;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
/**
* Unit tests for {@link ConsoleHandler}.
*/
public class ConsoleHandlerTest {
// We use a custom formatter so the test doesn't depend on locale, clock, or timezone.
private static class MessageOnlyFormatter extends Formatter {
@Override
public String format(LogRecord record) {
return record.getMessage();
}
}
@Test
public void consoleHandlerDoesNotWriteBelowLevelToStream() {
FakeOutputStream outputStream = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
publishAndFlush(handler, new LogRecord(Level.FINE, "Shh.."));
assertThat(outputStream.size(), equalTo(0));
}
@Test
public void consoleHandlerWritesAtLevelToStream() throws IOException {
FakeOutputStream outputStream = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
publishAndFlush(handler, new LogRecord(Level.INFO, "Hello"));
assertThat(outputStream.toString("UTF-8"), equalTo("Hello"));
}
@Test
public void consoleHandlerDoesNotFlushBelowSevere() {
FakeOutputStream outputStream = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
handler.publish(new LogRecord(Level.INFO, "Info"));
assertThat(outputStream.getLastFlushSize(), equalTo(0));
}
@Test
public void consoleHandlerFlushesSevere() {
FakeOutputStream outputStream = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
handler.publish(new LogRecord(Level.SEVERE, "Severe"));
assertThat(outputStream.getLastFlushSize(), equalTo(6));
}
@Test
public void consoleHandlerCanChangeOutputStreamWithoutClosing() throws IOException {
FakeOutputStream outputStream1 = new FakeOutputStream();
FakeOutputStream outputStream2 = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream1),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
publishAndFlush(handler, new LogRecord(Level.INFO, "Stream 1"));
assertThat(outputStream1.toString("UTF-8"), equalTo("Stream 1"));
threadIdToCommandId.put(49152L, "commandIdForOutputStream2");
handler.registerOutputStream("commandIdForOutputStream2", outputStream2);
assertThat(outputStream1.isClosed(), equalTo(false));
publishAndFlush(handler, newLogRecordWithThreadId(Level.INFO, "Stream 2", 49152));
assertThat(outputStream1.toString("UTF-8"), equalTo("Stream 1"));
assertThat(outputStream2.toString("UTF-8"), equalTo("Stream 2"));
handler.unregisterOutputStream("commandIdForOutputStream2");
assertThat(outputStream2.isClosed(), equalTo(false));
publishAndFlush(handler, new LogRecord(Level.INFO, " - DONE"));
assertThat(outputStream1.toString("UTF-8"), equalTo("Stream 1 - DONE"));
assertThat(outputStream2.toString("UTF-8"), equalTo("Stream 2"));
}
@Test
public void logRecordsOnlyGoToRegisteredOutputStream() throws IOException {
FakeOutputStream outputStream1 = new FakeOutputStream();
FakeOutputStream outputStream2 = new FakeOutputStream();
FakeOutputStream outputStream3 = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream1),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
threadIdToCommandId.put(49152L, "commandIdForOutputStream2");
threadIdToCommandId.put(64738L, "commandIdForOutputStream3");
handler.registerOutputStream("commandIdForOutputStream2", outputStream2);
handler.registerOutputStream("commandIdForOutputStream3", outputStream3);
publishAndFlush(handler, newLogRecordWithThreadId(Level.INFO, "Stream 2", 49152));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo("Stream 2"));
assertThat(outputStream3.toString("UTF-8"), equalTo(""));
publishAndFlush(handler, newLogRecordWithThreadId(Level.INFO, "Stream 3", 64738));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo("Stream 2"));
assertThat(outputStream3.toString("UTF-8"), equalTo("Stream 3"));
}
@Test
public void logRecordPublishedWithMultipleThreadIdsForSingleCommandId() throws IOException {
FakeOutputStream outputStream1 = new FakeOutputStream();
FakeOutputStream outputStream2 = new FakeOutputStream();
FakeOutputStream outputStream3 = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream1),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
threadIdToCommandId.put(49152L, "commandIdForOutputStream2");
threadIdToCommandId.put(49153L, "commandIdForOutputStream2");
threadIdToCommandId.put(64738L, "commandIdForOutputStream3");
handler.registerOutputStream("commandIdForOutputStream2", outputStream2);
handler.registerOutputStream("commandIdForOutputStream3", outputStream3);
publishAndFlush(handler, newLogRecordWithThreadId(Level.INFO, "Stream 2", 49152));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo("Stream 2"));
assertThat(outputStream3.toString("UTF-8"), equalTo(""));
publishAndFlush(handler, newLogRecordWithThreadId(Level.INFO, " - Another Stream 2", 49153));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo("Stream 2 - Another Stream 2"));
assertThat(outputStream3.toString("UTF-8"), equalTo(""));
}
@Test
public void previouslyRegisteredOutputStreamCanBeOverridden() throws IOException {
FakeOutputStream outputStream1 = new FakeOutputStream();
FakeOutputStream outputStream2 = new FakeOutputStream();
FakeOutputStream outputStream3 = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream1),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
threadIdToCommandId.put(49152L, "commandIdForOutputStream2");
handler.registerOutputStream("commandIdForOutputStream2", outputStream2);
publishAndFlush(handler, newLogRecordWithThreadId(Level.INFO, "Stream 2", 49152));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo("Stream 2"));
handler.registerOutputStream("commandIdForOutputStream2", outputStream3);
publishAndFlush(handler, newLogRecordWithThreadId(Level.INFO, "Stream 3", 49152));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo("Stream 2"));
assertThat(outputStream3.toString("UTF-8"), equalTo("Stream 3"));
}
@Test
public void levelOverrideAppliesOnlyToRegisteredStream() throws IOException {
FakeOutputStream outputStream1 = new FakeOutputStream();
FakeOutputStream outputStream2 = new FakeOutputStream();
FakeOutputStream outputStream3 = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream1),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
threadIdToCommandId.put(49152L, "commandIdForOutputStream2");
threadIdToCommandId.put(64738L, "commandIdForOutputStream3");
handler.registerOutputStream("commandIdForOutputStream2", outputStream2);
handler.registerOutputStream("commandIdForOutputStream3", outputStream3);
publishAndFlush(handler, newLogRecordWithThreadId(Level.FINE, "Shh..", 49152));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo(""));
assertThat(outputStream3.toString("UTF-8"), equalTo(""));
publishAndFlush(handler, newLogRecordWithThreadId(Level.FINE, "Shh..", 64738));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo(""));
assertThat(outputStream3.toString("UTF-8"), equalTo(""));
commandIdToLevel.put("commandIdForOutputStream3", Level.ALL);
publishAndFlush(handler, newLogRecordWithThreadId(Level.FINE, "Stream 3", 64738));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo(""));
assertThat(outputStream3.toString("UTF-8"), equalTo("Stream 3"));
}
@Test
public void levelOverrideCanBeRemoved() throws IOException {
FakeOutputStream outputStream1 = new FakeOutputStream();
FakeOutputStream outputStream2 = new FakeOutputStream();
FakeOutputStream outputStream3 = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream1),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
threadIdToCommandId.put(49152L, "commandIdForOutputStream2");
threadIdToCommandId.put(64738L, "commandIdForOutputStream3");
handler.registerOutputStream("commandIdForOutputStream2", outputStream2);
handler.registerOutputStream("commandIdForOutputStream3", outputStream3);
commandIdToLevel.put("commandIdForOutputStream3", Level.FINE);
publishAndFlush(handler, newLogRecordWithThreadId(Level.FINE, "Stream 3", 64738));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo(""));
assertThat(outputStream3.toString("UTF-8"), equalTo("Stream 3"));
commandIdToLevel.remove("commandIdForOutputStream3");
publishAndFlush(handler, newLogRecordWithThreadId(Level.FINE, "Shh...", 64738));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo(""));
assertThat(outputStream3.toString("UTF-8"), equalTo("Stream 3"));
}
@Test
public void logMessageWithUnregisteredThreadIdGoesToAllConsoles() throws IOException {
FakeOutputStream outputStream1 = new FakeOutputStream();
FakeOutputStream outputStream2 = new FakeOutputStream();
FakeOutputStream outputStream3 = new FakeOutputStream();
ConcurrentHashMap<Long, String> threadIdToCommandId = new ConcurrentHashMap<>();
ConcurrentHashMap<String, OutputStreamWriter> commandIdToConsoleWriter =
new ConcurrentHashMap<>();
ConcurrentHashMap<String, Level> commandIdToLevel = new ConcurrentHashMap<>();
ConsoleHandler handler = new ConsoleHandler(
ConsoleHandler.utf8OutputStreamWriter(outputStream1),
new MessageOnlyFormatter(),
Level.INFO,
threadIdToCommandId,
commandIdToConsoleWriter,
commandIdToLevel);
threadIdToCommandId.put(49152L, "commandIdForOutputStream2");
threadIdToCommandId.put(64738L, "commandIdForOutputStream3");
handler.registerOutputStream("commandIdForOutputStream2", outputStream2);
handler.registerOutputStream("commandIdForOutputStream3", outputStream3);
publishAndFlush(handler, newLogRecordWithThreadId(Level.INFO, "What thread is this?", 999999));
assertThat(outputStream1.toString("UTF-8"), equalTo(""));
assertThat(outputStream2.toString("UTF-8"), equalTo("What thread is this?"));
assertThat(outputStream3.toString("UTF-8"), equalTo("What thread is this?"));
}
private static void publishAndFlush(Handler handler, LogRecord logRecord) {
handler.publish(logRecord);
handler.flush();
}
private static LogRecord newLogRecordWithThreadId(Level level, String contents, int threadId) {
LogRecord result = new LogRecord(level, contents);
result.setThreadID(threadId);
return result;
}
}