1/* 2 * Copyright (C) 2017 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 17package com.android.server.wifi; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertTrue; 21import static org.mockito.Matchers.anyString; 22import static org.mockito.Matchers.contains; 23import static org.mockito.Mockito.verify; 24import static org.mockito.Mockito.verifyZeroInteractions; 25import static org.mockito.Mockito.when; 26 27import android.os.FileUtils; 28import android.test.suitebuilder.annotation.SmallTest; 29 30import libcore.io.IoUtils; 31 32import org.junit.Before; 33import org.junit.Test; 34import org.mockito.Mock; 35import org.mockito.MockitoAnnotations; 36import org.mockito.Spy; 37 38import java.io.File; 39import java.io.PrintWriter; 40import java.io.StringWriter; 41 42/** 43 * Unit tests for {@link LastMileLogger}. 44 */ 45@SmallTest 46public class LastMileLoggerTest { 47 @Mock WifiInjector mWifiInjector; 48 @Spy FakeWifiLog mLog; 49 private static final long FAKE_CONNECTION_ID = 1; 50 51 @Before 52 public void setUp() throws Exception { 53 MockitoAnnotations.initMocks(this); 54 when(mWifiInjector.makeLog(anyString())).thenReturn(mLog); 55 mTraceDataFile = File.createTempFile(TRACE_DATA_PREFIX, null); 56 mTraceEnableFile = File.createTempFile(TRACE_ENABLE_PREFIX, null); 57 mTraceReleaseFile = File.createTempFile(TRACE_RELEASE_PREFIX, null); 58 mTraceDataFile.deleteOnExit(); 59 mTraceEnableFile.deleteOnExit(); 60 mTraceReleaseFile.deleteOnExit(); 61 FileUtils.stringToFile(mTraceEnableFile, "0"); 62 mLastMileLogger = new LastMileLogger(mWifiInjector, mTraceDataFile.getPath(), 63 mTraceEnableFile.getPath(), mTraceReleaseFile.getPath()); 64 } 65 66 @Test 67 public void ctorDoesNotCrash() throws Exception { 68 new LastMileLogger(mWifiInjector, mTraceDataFile.getPath(), mTraceEnableFile.getPath(), 69 mTraceReleaseFile.getPath()); 70 verifyZeroInteractions(mLog); 71 } 72 73 @Test 74 public void connectionEventStartedEnablesTracing() throws Exception { 75 mLastMileLogger.reportConnectionEvent( 76 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 77 assertEquals("1", IoUtils.readFileAsString(mTraceEnableFile.getPath())); 78 } 79 80 @Test 81 public void connectionEventStartedDoesNotCrashIfReleaseFileIsMissing() throws Exception { 82 mTraceReleaseFile.delete(); 83 mLastMileLogger.reportConnectionEvent( 84 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 85 verify(mLog).warn(contains("Failed to open free_buffer")); 86 } 87 88 @Test 89 public void connectionEventStartedDoesNotEnableTracingIfReleaseFileIsMissing() 90 throws Exception { 91 mTraceReleaseFile.delete(); 92 mLastMileLogger.reportConnectionEvent( 93 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 94 assertEquals("0", IoUtils.readFileAsString(mTraceEnableFile.getPath())); 95 } 96 97 @Test 98 public void connectionEventStartedDoesNotAttemptToReopenReleaseFile() throws Exception { 99 mLastMileLogger.reportConnectionEvent( 100 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 101 102 // This is a rather round-about way of verifying that we don't attempt to re-open 103 // the file. Namely: if we delete the |release| file, and CONNECTION_EVENT_STARTED 104 // _did_ re-open the file, then we'd log an error message. Since the test is deleting the 105 // |release| file, the absence of a warning message means that we didn't try to open the 106 // file again. 107 // 108 // A more direct test would require the use of a factory for the creation of the 109 // FileInputStream. 110 mTraceReleaseFile.delete(); 111 mLastMileLogger.reportConnectionEvent( 112 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 113 verifyZeroInteractions(mLog); 114 } 115 116 @Test 117 public void connectionEventStartedDoesNotEnableTracingForInvalidConnectionId() 118 throws Exception { 119 mLastMileLogger.reportConnectionEvent( 120 -1, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 121 assertEquals("0", IoUtils.readFileAsString(mTraceEnableFile.getPath())); 122 } 123 124 @Test 125 public void connectionEventStartedDoesNotCrashIfEnableFileIsMissing() throws Exception { 126 mTraceEnableFile.delete(); 127 mLastMileLogger.reportConnectionEvent( 128 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 129 } 130 131 @Test 132 public void connectionEventStartedDoesNotCrashOnRepeatedCalls() throws Exception { 133 mLastMileLogger.reportConnectionEvent( 134 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 135 mLastMileLogger.reportConnectionEvent( 136 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 137 } 138 139 @Test 140 public void connectionEventSucceededDisablesTracing() throws Exception { 141 mLastMileLogger.reportConnectionEvent( 142 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_SUCCEEDED); 143 assertEquals("0", IoUtils.readFileAsString(mTraceEnableFile.getPath())); 144 } 145 146 @Test 147 public void connectionEventSucceededDoesNotCrashIfEnableFileIsMissing() throws Exception { 148 mTraceEnableFile.delete(); 149 mLastMileLogger.reportConnectionEvent( 150 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_SUCCEEDED); 151 } 152 153 @Test 154 public void connectionEventSucceededDoesNotCrashOnRepeatedCalls() throws Exception { 155 mLastMileLogger.reportConnectionEvent( 156 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_SUCCEEDED); 157 mLastMileLogger.reportConnectionEvent( 158 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_SUCCEEDED); 159 } 160 161 @Test 162 public void connectionEventFailedDisablesTracingWhenPendingFails() throws Exception { 163 mLastMileLogger.reportConnectionEvent( 164 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 165 mLastMileLogger.reportConnectionEvent( 166 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 167 assertEquals("0", IoUtils.readFileAsString(mTraceEnableFile.getPath())); 168 } 169 170 @Test 171 public void connectionEventFailedDoesNotDisableTracingOnFailureOfStaleConnection() 172 throws Exception { 173 mLastMileLogger.reportConnectionEvent( 174 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 175 mLastMileLogger.reportConnectionEvent( 176 FAKE_CONNECTION_ID + 1, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 177 mLastMileLogger.reportConnectionEvent( 178 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 179 assertEquals("1", IoUtils.readFileAsString(mTraceEnableFile.getPath())); 180 } 181 182 @Test 183 public void connectionEventFailedDisablesTracingOnFailureOfFutureConnection() 184 throws Exception { 185 mLastMileLogger.reportConnectionEvent( 186 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 187 mLastMileLogger.reportConnectionEvent( 188 FAKE_CONNECTION_ID + 1, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 189 assertEquals("0", IoUtils.readFileAsString(mTraceEnableFile.getPath())); 190 } 191 192 @Test 193 public void connectionEventFailedDoesNotCrashIfEnableFileIsMissing() throws Exception { 194 mTraceEnableFile.delete(); 195 mLastMileLogger.reportConnectionEvent( 196 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 197 } 198 199 @Test 200 public void connectionEventFailedDoesNotCrashIfDataFileIsMissing() throws Exception { 201 mTraceDataFile.delete(); 202 mLastMileLogger.reportConnectionEvent( 203 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 204 } 205 206 @Test 207 public void connectionEventFailedDoesNotCrashOnRepeatedCalls() throws Exception { 208 mLastMileLogger.reportConnectionEvent( 209 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 210 mLastMileLogger.reportConnectionEvent( 211 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 212 } 213 214 @Test 215 public void dumpShowsFailureTrace() throws Exception { 216 mLastMileLogger.reportConnectionEvent( 217 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 218 FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect"); 219 mLastMileLogger.reportConnectionEvent( 220 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 221 assertTrue(getDumpString().contains("--- Last failed")); 222 assertTrue(getDumpString().contains("rdev_connect")); 223 } 224 225 @Test 226 public void dumpShowsFailureTraceEvenIfConnectionIdIncreases() throws Exception { 227 mLastMileLogger.reportConnectionEvent( 228 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 229 FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect"); 230 mLastMileLogger.reportConnectionEvent( 231 FAKE_CONNECTION_ID + 1, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 232 assertTrue(getDumpString().contains("--- Last failed")); 233 assertTrue(getDumpString().contains("rdev_connect")); 234 } 235 236 @Test 237 public void dumpShowsPendingConnectionTrace() throws Exception { 238 mLastMileLogger.reportConnectionEvent( 239 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 240 FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect"); 241 assertTrue(getDumpString().contains("No last mile log for \"Last failed")); 242 assertTrue(getDumpString().contains("--- Latest")); 243 assertTrue(getDumpString().contains("rdev_connect")); 244 } 245 246 @Test 247 public void dumpShowsLastFailureTraceAndPendingConnectionTrace() throws Exception { 248 mLastMileLogger.reportConnectionEvent( 249 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 250 FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect try #1"); 251 mLastMileLogger.reportConnectionEvent( 252 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 253 mLastMileLogger.reportConnectionEvent( 254 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 255 FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect try #2"); 256 257 String dumpString = getDumpString(); 258 assertTrue(dumpString.contains("rdev_connect try #1")); 259 assertTrue(dumpString.contains("rdev_connect try #2")); 260 } 261 262 @Test 263 public void dumpShowsLastFailureTraceAndCurrentConnectionTrace() throws Exception { 264 mLastMileLogger.reportConnectionEvent( 265 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 266 FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect try #1"); 267 mLastMileLogger.reportConnectionEvent( 268 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 269 mLastMileLogger.reportConnectionEvent( 270 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 271 FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect try #2"); 272 mLastMileLogger.reportConnectionEvent( 273 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_SUCCEEDED); 274 275 String dumpString = getDumpString(); 276 assertTrue(dumpString.contains("rdev_connect try #1")); 277 assertTrue(dumpString.contains("rdev_connect try #2")); 278 } 279 280 @Test 281 public void dumpDoesNotClearLastFailureData() throws Exception { 282 mLastMileLogger.reportConnectionEvent( 283 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 284 FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect"); 285 mLastMileLogger.reportConnectionEvent( 286 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_FAILED); 287 288 getDumpString(); 289 String dumpString = getDumpString(); 290 assertTrue(dumpString.contains("rdev_connect")); 291 } 292 293 @Test 294 public void dumpDoesNotClearPendingConnectionTrace() throws Exception { 295 mLastMileLogger.reportConnectionEvent( 296 FAKE_CONNECTION_ID, BaseWifiDiagnostics.CONNECTION_EVENT_STARTED); 297 FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect"); 298 299 getDumpString(); 300 String dumpString = getDumpString(); 301 assertTrue(dumpString.contains("rdev_connect")); 302 } 303 304 @Test 305 public void dumpDoesNotCrashIfDataFileIsEmpty() throws Exception { 306 getDumpString(); 307 } 308 309 @Test 310 public void dumpDoesNotCrashIfDataFileIsMissing() throws Exception { 311 mTraceDataFile.delete(); 312 getDumpString(); 313 } 314 315 private static final String TRACE_DATA_PREFIX = "last-mile-logger-trace-data"; 316 private static final String TRACE_ENABLE_PREFIX = "last-mile-logger-trace-enable"; 317 private static final String TRACE_RELEASE_PREFIX = "last-mile-logger-trace-release"; 318 private LastMileLogger mLastMileLogger; 319 private File mTraceDataFile; 320 private File mTraceEnableFile; 321 private File mTraceReleaseFile; 322 323 private String getDumpString() { 324 StringWriter sw = new StringWriter(); 325 PrintWriter pw = new PrintWriter(sw); 326 mLastMileLogger.dump(pw); 327 return sw.toString(); 328 } 329} 330