1 /* 2 * Copyright (C) 2016 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 17 package com.android.server.wifi; 18 19 import static org.hamcrest.MatcherAssert.assertThat; 20 import static org.hamcrest.Matchers.instanceOf; 21 import static org.junit.Assert.assertEquals; 22 23 import android.support.test.filters.SmallTest; 24 25 import org.junit.Before; 26 import org.junit.Test; 27 28 /** 29 * Unit tests for {@link LogcatLog}. 30 */ 31 @SmallTest 32 public class LogcatLogTest { 33 private static final String TAG = "LogcatLogTest"; 34 private LogcatLog mLogger; 35 36 /** Initializes test fixture. */ 37 @Before 38 public void setUp() { 39 mLogger = new LogcatLog(TAG); 40 } 41 42 /** 43 * Verifies that LogcatLog's LogMessage implementation correctly 44 * handles a format with no parameters. 45 * 46 * Note: In practice, we expect clients to use eC() and friends 47 * when the message is a literal. But we still want to make sure 48 * this functionality works. 49 */ 50 @Test 51 public void logMessageWorksWithParameterlessFormat() { 52 WifiLog.LogMessage logMessage = mLogger.err("hello world"); 53 logMessage.flush(); 54 assertEquals("hello world", logMessage.toString()); 55 } 56 57 /** Verifies that LogMessage works with an empty format. */ 58 @Test 59 public void logMessageWorksWithEmptyFormat() { 60 WifiLog.LogMessage logMessage = mLogger.err(""); 61 logMessage.flush(); 62 assertEquals("", logMessage.toString()); 63 } 64 65 /** Verifies that LogMessage works with a value-only format. */ 66 @Test 67 public void logMessageWorksWithValueOnly() { 68 WifiLog.LogMessage logMessage = mLogger.err("%"); 69 logMessage.c(1).flush(); 70 assertEquals("1", logMessage.toString()); 71 } 72 73 /** 74 * Verifies that LogMessage works when the placeholder is replaced 75 * by the placeholder character. 76 */ 77 @Test 78 public void logMessageIsNotConfusedByPlaceholderInValue() { 79 WifiLog.LogMessage logMessage = mLogger.err("%"); 80 logMessage.c('%').flush(); 81 assertEquals("%", logMessage.toString()); 82 } 83 84 /** Verifies that LogMessage works when a value is at the start of the format. */ 85 @Test 86 public void logMessageWorksWithValueAtBegin() { 87 WifiLog.LogMessage logMessage = mLogger.err("%stuff"); 88 logMessage.c(1).flush(); 89 assertEquals("1stuff", logMessage.toString()); 90 } 91 92 /** Verifies that LogMessage works when a value is in the middle of the format. */ 93 @Test 94 public void logMessageWorksWithValueInMiddle() { 95 WifiLog.LogMessage logMessage = mLogger.err("s%uff"); 96 logMessage.c(1).flush(); 97 assertEquals("s1uff", logMessage.toString()); 98 } 99 100 /** Verifies that LogMessage works when a value is at the end of the format. */ 101 @Test 102 public void logMessageWorksWithValueAtEnd() { 103 WifiLog.LogMessage logMessage = mLogger.err("stuff%"); 104 logMessage.c(1).flush(); 105 assertEquals("stuff1", logMessage.toString()); 106 } 107 108 /** Verifies that LogMessage works when a format has multiple values. */ 109 @Test 110 public void logMessageWorksWithMultipleValues() { 111 WifiLog.LogMessage logMessage = mLogger.err("% %"); 112 logMessage.c("hello").c("world").flush(); 113 assertEquals("hello world", logMessage.toString()); 114 } 115 116 /** Verifies that LogMessage works when a format has multiple values and literals. */ 117 @Test 118 public void logMessageWorksWithMultipleValuesAndLiterals() { 119 WifiLog.LogMessage logMessage = mLogger.err("first:% second:%"); 120 logMessage.c("hello").c("world").flush(); 121 assertEquals("first:hello second:world", logMessage.toString()); 122 } 123 124 /** Verifies that LogMessage works when a format has multiple adjacent values. */ 125 @Test 126 public void logMessageWorksWithAdjacentValues() { 127 WifiLog.LogMessage logMessage = mLogger.err("%%"); 128 logMessage.c("hello").c("world").flush(); 129 assertEquals("helloworld", logMessage.toString()); 130 } 131 132 /** Verifies that LogMessage silently ignores extraneous values. */ 133 @Test 134 public void logMessageSilentlyIgnoresExtraneousValues() { 135 WifiLog.LogMessage logMessage = mLogger.err("%"); 136 logMessage.c("hello world").c("more stuff").flush(); 137 assertEquals("hello world", logMessage.toString()); 138 } 139 140 /** 141 * Verifies that LogMessage silently ignores extraneous values, 142 * even with an empty format string. 143 */ 144 @Test 145 public void logMessageSilentlyIgnoresExtraneousValuesEvenForEmptyFormat() { 146 WifiLog.LogMessage logMessage = mLogger.err(""); 147 logMessage.c("hello world").c("more stuff").flush(); 148 assertEquals("", logMessage.toString()); 149 } 150 151 /** 152 * Verifies that LogMessage silently ignores extraneous values, 153 * even if the format string is all literals. 154 */ 155 @Test 156 public void logMessageSilentlyIgnoresExtraneousValuesEvenForFormatWithoutPlaceholders() { 157 WifiLog.LogMessage logMessage = mLogger.err("literal format"); 158 logMessage.c("hello world").c("more stuff").flush(); 159 assertEquals("literal format", logMessage.toString()); 160 } 161 162 /** Verifies that LogMessage copies an unused placeholder to output. */ 163 @Test 164 public void logMessageCopiesUnusedPlaceholderToOutput() { 165 WifiLog.LogMessage logMessage = mLogger.err("%"); 166 logMessage.flush(); 167 assertEquals("%", logMessage.toString()); 168 } 169 170 /** Verifies that LogMessage copies multiple unused placeholders to output. */ 171 @Test 172 public void logMessageCopiesMultipleUnusedPlaceholdersToOutput() { 173 WifiLog.LogMessage logMessage = mLogger.err("%%%%%"); 174 logMessage.flush(); 175 assertEquals("%%%%%", logMessage.toString()); 176 } 177 178 /** 179 * Verifies that LogMessage copies an unused placeholder to output, 180 * even if preceded by non-placeholders. 181 */ 182 @Test 183 public void logMessageCopiesUnusedPlaceholderAtEndToOutput() { 184 WifiLog.LogMessage logMessage = mLogger.err("foo%"); 185 logMessage.flush(); 186 assertEquals("foo%", logMessage.toString()); 187 } 188 189 /** 190 * Verifies that LogMessage copies an unused placeholder to output, 191 * even if followed by non-placeholders. 192 */ 193 @Test 194 public void logMessageCopiesUnusedPlaceholderAtBeginToOutput() { 195 WifiLog.LogMessage logMessage = mLogger.err("%foo"); 196 logMessage.flush(); 197 assertEquals("%foo", logMessage.toString()); 198 } 199 200 /** 201 * Verifies that LogMessage copies an unused placeholder to output, 202 * even if it is in the middle of non-placeholders. 203 */ 204 @Test 205 public void logMessageCopiesUnusedPlaceholderInMiddleToOutput() { 206 WifiLog.LogMessage logMessage = mLogger.err("f%o"); 207 logMessage.flush(); 208 assertEquals("f%o", logMessage.toString()); 209 } 210 211 /** 212 * Verifies that LogMessage copies multiple unused placeholders to output, 213 * even if they are embedded amongst non-placeholders. 214 */ 215 @Test 216 public void logMessageCopiesUnusedPlaceholdersInMiddleToOutput() { 217 WifiLog.LogMessage logMessage = mLogger.err("f%o%o%d"); 218 logMessage.flush(); 219 assertEquals("f%o%o%d", logMessage.toString()); 220 } 221 222 /** 223 * Verifies that LogMessage preserves meta-characters in format string. 224 * 225 * Note that we deliberately test only the meta-characters that we 226 * expect to find in log messages. (Newline might also be 227 * preserved, but clients shouldn't depend on that, as messages 228 * that have newlines make logs hard to read.) 229 */ 230 @Test 231 public void logMessagePreservesMetaCharactersInFormat() { 232 WifiLog.LogMessage logMessage = mLogger.err("\\hello\tworld\\"); 233 logMessage.flush(); 234 assertEquals("\\hello\tworld\\", logMessage.toString()); 235 } 236 237 /** Verifies that LogMessage propagates meta-characters in char values. */ 238 @Test 239 public void logMessagePropagatesMetaCharactersInCharValues() { 240 WifiLog.LogMessage logMessage = mLogger.err("hello%big%world"); 241 logMessage.c('\t').c('\\').flush(); 242 assertEquals("hello\tbig\\world", logMessage.toString()); 243 } 244 245 /** Verifies that LogMessage propagates meta-characters in String values. */ 246 @Test 247 public void logMessagePropagatesMetaCharactersInStringValues() { 248 WifiLog.LogMessage logMessage = mLogger.err("%%world"); 249 logMessage.c("hello\t").c("big\\").flush(); 250 assertEquals("hello\tbig\\world", logMessage.toString()); 251 } 252 253 @Test 254 public void traceLogMessageIncludesCallerName() { 255 try { 256 LogcatLog.enableVerboseLogging(1); 257 WifiLog.LogMessage logMessage = mLogger.trace("%"); 258 logMessage.c("says hello").flush(); 259 assertEquals("traceLogMessageIncludesCallerName says hello", 260 logMessage.toString()); 261 } finally { 262 LogcatLog.enableVerboseLogging(0); 263 } 264 } 265 266 @Test 267 public void traceLogMessageRespectsNumFramesToIgnore() { 268 try { 269 LogcatLog.enableVerboseLogging(1); 270 WifiLog.LogMessage logMessage = traceHelper("%"); 271 logMessage.c("says hello").flush(); 272 assertEquals("traceLogMessageRespectsNumFramesToIgnore says hello", 273 logMessage.toString()); 274 } finally { 275 LogcatLog.enableVerboseLogging(0); 276 } 277 } 278 279 @Test 280 public void traceLogMessageDoesNotCrashOnOversizedNumFramesToIgnore() { 281 try { 282 LogcatLog.enableVerboseLogging(1); 283 WifiLog.LogMessage logMessage = mLogger.trace("%", 284 (new Throwable()).getStackTrace().length); 285 logMessage.c("says hello").flush(); 286 assertEquals("<unknown> says hello", logMessage.toString()); 287 } finally { 288 LogcatLog.enableVerboseLogging(0); 289 } 290 } 291 292 @Test 293 public void traceLogMessageDoesNotCrashOnOverflowingNumFramesToIgnore() { 294 try { 295 LogcatLog.enableVerboseLogging(1); 296 WifiLog.LogMessage logMessage = mLogger.trace("%", Integer.MAX_VALUE); 297 logMessage.c("says hello").flush(); 298 assertEquals("<unknown> says hello", logMessage.toString()); 299 } finally { 300 LogcatLog.enableVerboseLogging(0); 301 } 302 } 303 304 @Test 305 public void traceLogMessageDoesNotCrashOnUndersizedNumFramesToIgnore() { 306 try { 307 LogcatLog.enableVerboseLogging(1); 308 WifiLog.LogMessage logMessage = mLogger.trace("%", Integer.MIN_VALUE); 309 logMessage.c("says hello").flush(); 310 assertEquals("<unknown> says hello", logMessage.toString()); 311 } finally { 312 LogcatLog.enableVerboseLogging(0); 313 } 314 } 315 316 @Test 317 public void traceLogMessageReturnsDummyLogMessageByDefault() { 318 assertThat(mLogger.trace("%"), instanceOf(DummyLogMessage.class)); 319 } 320 321 @Test 322 public void dumpLogMessageReturnsDummyLogMessageByDefault() { 323 assertThat(mLogger.dump("%"), instanceOf(DummyLogMessage.class)); 324 } 325 326 private WifiLog.LogMessage traceHelper(String format) { 327 return mLogger.trace(format, 1); 328 } 329 } 330