1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.tradefed.log; 17 18 import com.android.ddmlib.Log; 19 import com.android.ddmlib.Log.LogLevel; 20 21 import junit.framework.TestCase; 22 23 import org.easymock.EasyMock; 24 25 /** 26 * Unit tests for {@link LogRegistry}. 27 */ 28 public class LogRegistryTest extends TestCase { 29 30 private static final String LOG_TAG = "LogRegistryTest"; 31 32 private LogRegistry mLogRegistry; 33 private ThreadGroup mStubThreadGroup; 34 35 @Override 36 protected void setUp() throws Exception { 37 super.setUp(); 38 mStubThreadGroup = new ThreadGroup("LogRegistryTest"); 39 mLogRegistry = 40 new LogRegistry() { 41 // override thread group to avoid conflict with the "real" LogRegistry and the 42 // logger in use for this test run 43 @Override 44 ThreadGroup getCurrentThreadGroup() { 45 return mStubThreadGroup; 46 } 47 48 @Override 49 public void saveGlobalLog() { 50 // empty on purpose, avoid leaving logs that we can't clean. 51 } 52 }; 53 } 54 55 @Override 56 protected void tearDown() throws Exception { 57 super.tearDown(); 58 mLogRegistry.closeAndRemoveAllLogs(); 59 } 60 61 /** 62 * Tests that {@link LogRegistry#getLogger} returns the logger that was previously registered. 63 */ 64 public void testGetLogger() { 65 StdoutLogger stdoutLogger = new StdoutLogger(); 66 mLogRegistry.registerLogger(stdoutLogger); 67 68 ILeveledLogOutput returnedLogger = mLogRegistry.getLogger(); 69 assertEquals(stdoutLogger, returnedLogger); 70 mLogRegistry.unregisterLogger(); 71 } 72 73 /** 74 * Tests that {@link LogRegistry#printLog} calls into the underlying logger's printLog method 75 * when the logging level is appropriate for printing. 76 */ 77 public void testPrintLog_sameLogLevel() { 78 String testMessage = "This is a test message."; 79 ILeveledLogOutput mockLogger = EasyMock.createMock(ILeveledLogOutput.class); 80 mLogRegistry.registerLogger(mockLogger); 81 82 EasyMock.expect(mockLogger.getLogLevel()).andReturn(LogLevel.VERBOSE); 83 mockLogger.printLog(LogLevel.VERBOSE, LOG_TAG, testMessage); 84 85 EasyMock.replay(mockLogger); 86 mLogRegistry.printLog(LogLevel.VERBOSE, LOG_TAG, testMessage); 87 mLogRegistry.unregisterLogger(); 88 } 89 90 /** 91 * Tests that {@link LogRegistry#printLog} does not call into the underlying logger's printLog 92 * method when the logging level is lower than necessary to log. 93 */ 94 public void testPrintLog_lowerLogLevel() { 95 String testMessage = "This is a test message."; 96 ILeveledLogOutput mockLogger = EasyMock.createMock(ILeveledLogOutput.class); 97 mLogRegistry.registerLogger(mockLogger); 98 99 // Setting LogLevel == ERROR will let everything print 100 EasyMock.expect(mockLogger.getLogLevel()).andReturn(LogLevel.ERROR); 101 102 EasyMock.replay(mockLogger); 103 mLogRegistry.printLog(LogLevel.VERBOSE, LOG_TAG, testMessage); 104 mLogRegistry.unregisterLogger(); 105 } 106 107 /** 108 * Tests for ensuring new threads spawned without an explicit ThreadGroup will inherit the 109 * same logger as the parent's logger. 110 */ 111 public void testThreadedLogging() { 112 final String testMessage = "Another test message!"; 113 final ILeveledLogOutput mockLogger = EasyMock.createMock(ILeveledLogOutput.class); 114 115 // Simple class that will run in a thread, simulating a new thread spawed inside an Invocation 116 class SecondThread implements Runnable { 117 @Override 118 public void run() { 119 Log.e(LOG_TAG, testMessage); 120 } 121 } 122 // Simple class that will run in a thread, simulating a new Invocation 123 class FirstThread implements Runnable { 124 @Override 125 public void run() { 126 mLogRegistry.registerLogger(mockLogger); 127 Log.v(LOG_TAG, testMessage); 128 Thread secondThread = new Thread(new SecondThread()); // no explicit ThreadGroup 129 secondThread.start(); 130 try { 131 secondThread.join(); // threaded, but force serialization for testing 132 } 133 catch (InterruptedException ie) { 134 fail("Thread was unexpectedly interrupted."); 135 } 136 finally { 137 mLogRegistry.unregisterLogger(); 138 } 139 } 140 } 141 142 // first thread calls 143 EasyMock.expect(mockLogger.getLogLevel()).andReturn(LogLevel.VERBOSE); 144 mockLogger.printLog(LogLevel.VERBOSE, LOG_TAG, testMessage); 145 // second thread should inherit same logger 146 EasyMock.expect(mockLogger.getLogLevel()).andReturn(LogLevel.ERROR); 147 mockLogger.printLog(LogLevel.ERROR, LOG_TAG, testMessage); 148 149 EasyMock.replay(mockLogger); 150 151 ThreadGroup tg = new ThreadGroup("TestThreadGroup"); 152 Thread firstThread = new Thread(tg, new FirstThread()); 153 firstThread.start(); 154 155 try { 156 firstThread.join(); // threaded, but force serialization for testing 157 } 158 catch (InterruptedException ie) { 159 fail("Thread was unexpectedly interrupted."); 160 } 161 } 162 } 163