/* * Copyright (C) 2009 Google 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 org.waveprotocol.wave.util.logging; import com.google.common.collect.Lists; import junit.framework.TestCase; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; /** * Tests basic Log functions. * * */ public class LogTest extends TestCase { /** Handler of LogRecords which just adds them to an internal list. */ private class LogRecordRecorder extends Handler { private final List<LogRecord> records = Lists.newArrayList(); /** {@inheritDoc} */ @Override public void close() throws SecurityException { } /** {@inheritDoc} */ @Override public void flush() { } /** {@inheritDoc} */ @Override public void publish(LogRecord record) { records.add(record); record.getSourceClassName(); // Force inference } } private static int logNumber = 0; /** * Asserts that some context appears in a message. A bit dodgy in that it * searches independently for the key and value strings. */ private void assertContext(LogRecord record, String detail, String key, String value) { assertTrue("actual message missing from log", record.getMessage().contains(detail)); assertTrue("context key '" + key + "' missing", record.getMessage().contains(key)); assertTrue("context value '" + value + "' missing", record.getMessage().contains(value)); } /** * Asserts that some context does not appear in a message. Allows neither the * key nor the value to appear. */ private void assertNoContext(LogRecord record, String detail, String key, String value) { assertTrue("actual message missing from log", record.getMessage().contains(detail)); assertFalse("context key '" + key + "' found", record.getMessage().contains(key)); assertFalse("context value '" + value + "' found", record.getMessage().contains(value)); } /** Gets a new Log that logs to the given handler. */ private Log getNewLog(Handler handler) { Logger logger = Logger.getLogger(LogTest.class.getName() + ".log" + logNumber++); logger.addHandler(handler); return new Log(logger); } /** Test that logging actually gives back a record. */ public void test01LogSomething() { LogRecordRecorder handler = new LogRecordRecorder(); Log log = getNewLog(handler); log.info("hi there"); Exception e = new RuntimeException("Akk"); log.warning("Warning", e); assertEquals(2, handler.records.size()); assertEquals(LogTest.class.getName(), handler.records.get(0).getSourceClassName()); assertEquals("test01LogSomething", handler.records.get(0).getSourceMethodName()); assertEquals(Level.INFO, handler.records.get(0).getLevel()); assertEquals("hi there", handler.records.get(0).getMessage()); assertNull(handler.records.get(0).getThrown()); assertEquals(LogTest.class.getName(), handler.records.get(1).getSourceClassName()); assertEquals("test01LogSomething", handler.records.get(1).getSourceMethodName()); assertEquals(Level.WARNING, handler.records.get(1).getLevel()); assertEquals("Warning", handler.records.get(1).getMessage()); assertEquals(e, handler.records.get(1).getThrown()); } /** Tests that context information is prepended to log messages. */ public void test02IncludesContext() { LogRecordRecorder handler = new LogRecordRecorder(); Log log = getNewLog(handler); log.severe("initial"); log.putContext("something", "interesting"); try { log.severe("added"); } finally { log.removeContext("something"); } log.severe("removed"); assertEquals(3, handler.records.size()); assertNoContext(handler.records.get(0), "initial", "something", "interesting"); assertContext(handler.records.get(1), "added", "something", "interesting"); assertNoContext(handler.records.get(2), "removed", "something", "interesting"); } /** Tests that independent log context is maintained for each thread. */ public void test03ContextIsPerThread() throws Exception { LogRecordRecorder handler = new LogRecordRecorder(); final Log log = getNewLog(handler); ExecutorService service = Executors.newSingleThreadExecutor(); try { log.putContext("something", "interesting"); log.severe("initial"); assertEquals(1, handler.records.size()); assertContext(handler.records.get(0), "initial", "something", "interesting"); service.submit(new Runnable() { /** {@inheritDoc} */ @Override public void run() { log.severe("other"); } }).get(); assertEquals(2, handler.records.size()); assertNoContext(handler.records.get(1), "other", "something", "interesting"); service.submit(new Runnable() { /** {@inheritDoc} */ @Override public void run() { log.putContext("something", "else"); log.severe("context"); } }).get(); assertEquals(3, handler.records.size()); assertContext(handler.records.get(2), "context", "something", "else"); log.severe("final"); assertEquals(4, handler.records.size()); assertContext(handler.records.get(3), "final", "something", "interesting"); } finally { log.removeContext("something"); service.shutdown(); } } }