1 /* 2 * Copyright (C) 2015 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.telecom.tests; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.os.Handler; 22 import android.os.HandlerThread; 23 import android.os.Message; 24 import android.test.suitebuilder.annotation.MediumTest; 25 26 import com.android.internal.os.SomeArgs; 27 import com.android.server.telecom.Runnable; 28 import com.android.server.telecom.Session; 29 import com.android.server.telecom.SystemLoggingContainer; 30 import com.android.server.telecom.Log; 31 32 import org.junit.Assert; 33 import org.mockito.MockitoAnnotations; 34 35 import java.lang.ref.WeakReference; 36 import java.util.ArrayList; 37 import java.util.Random; 38 import java.util.concurrent.atomic.AtomicInteger; 39 40 import static org.mockito.Matchers.eq; 41 import static org.mockito.Mockito.verify; 42 43 /** 44 * Unit tests for Telecom's Logging system. 45 */ 46 public class LogTest extends TelecomTestCase{ 47 48 /** 49 * This helper class captures the logs that are sent to Log and stores them in an array to be 50 * verified by LogTest. 51 */ 52 private class TestLoggingContainer extends SystemLoggingContainer { 53 public ArrayList<String> receivedStrings; 54 TestLoggingContainer()55 public TestLoggingContainer() { 56 receivedStrings = new ArrayList<>(100); 57 } 58 59 @Override v(String msgTag, String msg)60 public synchronized void v(String msgTag, String msg) { 61 if (msgTag.equals(LogTest.TESTING_TAG)) { 62 synchronized (this) { 63 receivedStrings.add(processMessage(msg)); 64 } 65 } 66 } 67 68 @Override i(String msgTag, String msg)69 public synchronized void i(String msgTag, String msg) { 70 if (msgTag.equals(LogTest.TESTING_TAG)) { 71 synchronized (this) { 72 receivedStrings.add(processMessage(msg)); 73 } 74 } 75 } 76 didReceiveMessage(int timeoutMs, String msg)77 public boolean didReceiveMessage(int timeoutMs, String msg) { 78 String matchedString = null; 79 // Wait for timeout to expire before checking received messages 80 if (timeoutMs > 0) { 81 try { 82 Thread.sleep(timeoutMs); 83 } catch (InterruptedException e) { 84 Log.w(LogTest.TESTING_TAG, "TestLoggingContainer: Thread Interrupted!"); 85 } 86 } 87 synchronized (this) { 88 for (String receivedString : receivedStrings) { 89 if (receivedString.contains(msg)) { 90 matchedString = receivedString; 91 break; 92 } 93 } 94 if (matchedString != null) { 95 receivedStrings.remove(matchedString); 96 return true; 97 } 98 } 99 android.util.Log.i(TESTING_TAG, "Did not receive message: " + msg); 100 return false; 101 } 102 isMessagesEmpty()103 public boolean isMessagesEmpty() { 104 boolean isEmpty = receivedStrings.isEmpty(); 105 if (!isEmpty) { 106 printMessagesThatAreLeft(); 107 } 108 return isEmpty; 109 } 110 printMessagesThatAreLeft()111 public synchronized void printMessagesThatAreLeft() { 112 android.util.Log.i(TESTING_TAG, "Remaining Messages in Log Queue:"); 113 for (String receivedString : receivedStrings) { 114 android.util.Log.i(TESTING_TAG, "\t- " + receivedString); 115 } 116 } 117 118 // Remove Unnecessary parts of message string before processing processMessage(String msg)119 private String processMessage(String msg) { 120 if(msg.contains(Session.CREATE_SUBSESSION)) { 121 return clipMsg(Session.CREATE_SUBSESSION, msg); 122 } 123 if(msg.contains(Session.CONTINUE_SUBSESSION)) { 124 return clipMsg(Session.CONTINUE_SUBSESSION, msg); 125 } 126 if (msg.contains(Session.END_SUBSESSION)) { 127 return clipMsg(Session.END_SUBSESSION, msg); 128 } 129 if (msg.contains(Session.END_SESSION)) { 130 return clipMsg(Session.END_SESSION, msg); 131 } 132 return msg; 133 } 134 clipMsg(String id, String msg)135 private String clipMsg(String id, String msg) { 136 int clipStartIndex = msg.indexOf(id) + id.length(); 137 int clipEndIndex = msg.lastIndexOf(":"); 138 return msg.substring(0, clipStartIndex) + msg.substring(clipEndIndex, msg.length()); 139 } 140 } 141 142 public static final int TEST_THREAD_COUNT = 150; 143 public static final int TEST_SLEEP_TIME_MS = 50; 144 // Should be larger than TEST_SLEEP_TIME_MS! 145 public static final int TEST_VERIFY_TIMEOUT_MS = 100; 146 public static final String TEST_ENTER_METHOD1 = "TEM1"; 147 public static final String TEST_ENTER_METHOD2 = "TEM2"; 148 public static final String TEST_ENTER_METHOD3 = "TEM3"; 149 public static final String TEST_ENTER_METHOD4 = "TEM4"; 150 public static final String TEST_CLASS_NAME = "LogTest"; 151 152 private static final int EVENT_START_TEST_SLEEPY_METHOD = 0; 153 private static final int EVENT_START_TEST_SLEEPY_MULTIPLE_METHOD = 1; 154 private static final int EVENT_LAST_MESSAGE = 2; 155 156 private static final long RANDOM_NUMBER_SEED = 6191991; 157 158 Random rng = new Random(RANDOM_NUMBER_SEED); 159 160 private Handler mSleepyHandler = new Handler( 161 new HandlerThread("sleepyThread"){{start();}}.getLooper()) { 162 @Override 163 public void handleMessage(Message msg) { 164 SomeArgs args = (SomeArgs) msg.obj; 165 Session subsession = (Session) args.arg1; 166 Log.continueSession(subsession, "lTSH.hM"); 167 switch (msg.what) { 168 case EVENT_START_TEST_SLEEPY_METHOD: 169 sleepyMethod(TEST_SLEEP_TIME_MS); 170 break; 171 } 172 Log.endSession(); 173 } 174 }; 175 176 private boolean isHandlerCompleteWithEvents; 177 private Handler mSleepyMultipleHandler = new Handler( 178 new HandlerThread("sleepyMultipleThread"){{start();}}.getLooper()){ 179 @Override 180 public void handleMessage(Message msg) { 181 switch (msg.what) { 182 case EVENT_START_TEST_SLEEPY_MULTIPLE_METHOD: 183 SomeArgs args = (SomeArgs) msg.obj; 184 Session subsession = (Session) args.arg1; 185 Log.continueSession(subsession, "lTSCH.hM"); 186 sleepyMultipleMethod(); 187 Log.endSession(); 188 break; 189 case EVENT_LAST_MESSAGE: 190 isHandlerCompleteWithEvents = true; 191 break; 192 } 193 } 194 }; 195 196 private AtomicInteger mCompleteCount; 197 class LogTestRunnable implements java.lang.Runnable { 198 private String mshortMethodName; LogTestRunnable(String shortMethodName)199 public LogTestRunnable(String shortMethodName) { 200 mshortMethodName = shortMethodName; 201 } 202 run()203 public void run() { 204 Log.startSession(mshortMethodName); 205 sleepyCallerMethod(TEST_SLEEP_TIME_MS); 206 Log.endSession(); 207 mCompleteCount.incrementAndGet(); 208 } 209 } 210 211 TestLoggingContainer mTestSystemLogger; 212 213 @Override setUp()214 public void setUp() throws Exception { 215 super.setUp(); 216 MockitoAnnotations.initMocks(this); 217 mTestSystemLogger = new TestLoggingContainer(); 218 Log.setLoggingContainer(mTestSystemLogger); 219 Log.setIsExtendedLoggingEnabled(true); 220 Log.restartSessionCounter(); 221 Log.sCleanStaleSessions = null; 222 Log.sSessionMapper.clear(); 223 Log.setContext(mComponentContextFixture.getTestDouble().getApplicationContext()); 224 Log.sSessionCleanupTimeoutMs = new Log.ISessionCleanupTimeoutMs() { 225 @Override 226 // Set to the default value of Timeouts.getStaleSessionCleanupTimeoutMillis without 227 // needing to query. 228 public long get() { 229 return Log.DEFAULT_SESSION_TIMEOUT_MS; 230 } 231 }; 232 } 233 234 @Override tearDown()235 public void tearDown() throws Exception { 236 mTestSystemLogger = null; 237 Log.setLoggingContainer(new SystemLoggingContainer()); 238 super.tearDown(); 239 } 240 241 @MediumTest testSingleThreadSession()242 public void testSingleThreadSession() throws Exception { 243 String sessionName = "LT.sTS"; 244 Log.startSession(sessionName); 245 sleepyMethod(TEST_SLEEP_TIME_MS); 246 Log.endSession(); 247 248 verifyEventResult(Session.START_SESSION, sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 249 verifyMethodCall("", sessionName, 0, "", TEST_ENTER_METHOD1, TEST_VERIFY_TIMEOUT_MS); 250 verifyEventResult(Session.END_SUBSESSION, sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 251 verifyEndEventResult(sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 252 253 assertEquals(Log.sSessionMapper.size(), 0); 254 assertEquals(true, mTestSystemLogger.isMessagesEmpty()); 255 } 256 257 @MediumTest testSingleHandlerThreadSession()258 public void testSingleHandlerThreadSession() throws Exception { 259 String sessionName = "LT.tSHTS"; 260 Log.startSession(sessionName); 261 Session subsession = Log.createSubsession(); 262 SomeArgs args = SomeArgs.obtain(); 263 args.arg1 = subsession; 264 mSleepyHandler.obtainMessage(EVENT_START_TEST_SLEEPY_METHOD, args).sendToTarget(); 265 Log.endSession(); 266 267 verifyEventResult(Session.START_SESSION, sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 268 verifyEventResult(Session.CREATE_SUBSESSION, sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 269 verifyContinueEventResult(sessionName, "lTSH.hM", "_0", 0, TEST_VERIFY_TIMEOUT_MS); 270 verifyEventResult(Session.END_SUBSESSION, sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 271 verifyMethodCall(sessionName, "lTSH.hM", 0, "_0", TEST_ENTER_METHOD1, 272 TEST_VERIFY_TIMEOUT_MS); 273 verifyEventResult(Session.END_SUBSESSION, sessionName + "->lTSH.hM", "_0", 0, 274 TEST_VERIFY_TIMEOUT_MS); 275 verifyEndEventResult(sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 276 277 assertEquals(Log.sSessionMapper.size(), 0); 278 assertEquals(true, mTestSystemLogger.isMessagesEmpty()); 279 } 280 281 @MediumTest testSpawnMultipleThreadSessions()282 public void testSpawnMultipleThreadSessions() throws Exception { 283 final String sessionName = "LT.lTR"; 284 mCompleteCount = new AtomicInteger(0); 285 for (int i = 0; i < TEST_THREAD_COUNT; i++) { 286 Thread.sleep(10); 287 new Thread(new LogTestRunnable(sessionName)).start(); 288 } 289 290 // Poll until all of the threads have completed 291 while (mCompleteCount.get() < TEST_THREAD_COUNT) { 292 Thread.sleep(1000); 293 } 294 295 // Loop through verification separately to spawn threads fast so there is possible overlap 296 // (verifyEventResult(...) delays) 297 for (int i = 0; i < TEST_THREAD_COUNT; i++) { 298 verifyEventResult(Session.START_SESSION, sessionName, "", i, 0); 299 verifyMethodCall("", sessionName, i, "", TEST_ENTER_METHOD2, 0); 300 verifyMethodCall("", sessionName, i, "", TEST_ENTER_METHOD1, 0); 301 verifyEventResult(Session.END_SUBSESSION, sessionName, "", i, 0); 302 verifyEndEventResult(sessionName, "", i, 0); 303 } 304 305 assertEquals(Log.sSessionMapper.size(), 0); 306 assertEquals(true, mTestSystemLogger.isMessagesEmpty()); 307 } 308 309 @MediumTest testSpawnMultipleThreadMultipleHandlerSession()310 public void testSpawnMultipleThreadMultipleHandlerSession() throws Exception { 311 String sessionName = "LT.tSMTMHS"; 312 Log.startSession(sessionName); 313 Session subsession = Log.createSubsession(); 314 SomeArgs args = SomeArgs.obtain(); 315 args.arg1 = subsession; 316 mSleepyMultipleHandler.obtainMessage(EVENT_START_TEST_SLEEPY_MULTIPLE_METHOD, 317 args).sendToTarget(); 318 Log.endSession(); 319 320 verifyEventResult(Session.START_SESSION, sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 321 verifyEventResult(Session.END_SUBSESSION, sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 322 verifyEventResult(Session.CREATE_SUBSESSION, sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 323 verifyContinueEventResult(sessionName, "lTSCH.hM", "_0", 0, TEST_VERIFY_TIMEOUT_MS); 324 verifyMethodCall(sessionName, "lTSCH.hM", 0, "_0", TEST_ENTER_METHOD3, 325 TEST_VERIFY_TIMEOUT_MS); 326 verifyEventResult(Session.END_SUBSESSION, sessionName + "->lTSCH.hM", "_0", 0, 327 TEST_VERIFY_TIMEOUT_MS); 328 verifyEventResult(Session.CREATE_SUBSESSION, sessionName + "->lTSCH.hM", "_0", 0, 329 TEST_VERIFY_TIMEOUT_MS); 330 verifyContinueEventResult(sessionName + "->" + "lTSCH.hM", "lTSH.hM", "_0_0", 0, 331 TEST_VERIFY_TIMEOUT_MS); 332 verifyMethodCall(sessionName + "->lTSCH.hM", "lTSH.hM", 0, "_0_0", TEST_ENTER_METHOD1, 333 TEST_VERIFY_TIMEOUT_MS); 334 verifyEventResult(Session.END_SUBSESSION, sessionName + "->lTSCH.hM->lTSH.hM", "_0_0", 0, 335 TEST_VERIFY_TIMEOUT_MS); 336 verifyEndEventResult(sessionName, "", 0, TEST_VERIFY_TIMEOUT_MS); 337 338 assertEquals(Log.sSessionMapper.size(), 0); 339 assertEquals(true, mTestSystemLogger.isMessagesEmpty()); 340 } 341 342 @MediumTest testSpawnMultipleThreadMultipleHandlerSessions()343 public void testSpawnMultipleThreadMultipleHandlerSessions() throws Exception { 344 String sessionName = "LT.tSMTMHSs"; 345 isHandlerCompleteWithEvents = false; 346 for (int i = 0; i < TEST_THREAD_COUNT; i++) { 347 Log.startSession(sessionName); 348 Session subsession = Log.createSubsession(); 349 SomeArgs args = SomeArgs.obtain(); 350 args.arg1 = subsession; 351 mSleepyMultipleHandler.obtainMessage(EVENT_START_TEST_SLEEPY_MULTIPLE_METHOD, 352 args).sendToTarget(); 353 Log.endSession(); 354 } 355 // Send a message that denotes the last message that is sent. We poll until this message 356 // is processed in order to verify the results without waiting an arbitrary amount of time 357 // (that can change per device). 358 mSleepyMultipleHandler.obtainMessage(EVENT_LAST_MESSAGE).sendToTarget(); 359 360 while (!isHandlerCompleteWithEvents) { 361 Thread.sleep(1000); 362 } 363 364 for (int i = 0; i < TEST_THREAD_COUNT; i++) { 365 verifyEventResult(Session.START_SESSION, sessionName, "", i, 0); 366 verifyEventResult(Session.END_SUBSESSION, sessionName, "", i, 0); 367 verifyEventResult(Session.CREATE_SUBSESSION, sessionName, "", i, 0); 368 verifyContinueEventResult(sessionName, "lTSCH.hM", "_0", i, 0); 369 verifyMethodCall(sessionName, "lTSCH.hM", i, "_0", TEST_ENTER_METHOD3, 0); 370 verifyEventResult(Session.END_SUBSESSION, sessionName + "->lTSCH.hM", "_0", i, 0); 371 verifyEventResult(Session.CREATE_SUBSESSION, sessionName + "->lTSCH.hM", "_0", i, 0); 372 verifyContinueEventResult(sessionName + "->" + "lTSCH.hM", "lTSH.hM", "_0_0", i, 0); 373 verifyMethodCall(sessionName + "->lTSCH.hM", "lTSH.hM", i, "_0_0", TEST_ENTER_METHOD1, 374 0); 375 verifyEventResult(Session.END_SUBSESSION, sessionName + "->lTSCH.hM->lTSH.hM", "_0_0", 376 i, 0); 377 verifyEndEventResult(sessionName, "", i, 0); 378 } 379 380 assertEquals(Log.sSessionMapper.size(), 0); 381 assertEquals(true, mTestSystemLogger.isMessagesEmpty()); 382 } 383 384 @MediumTest testCancelSubsession()385 public void testCancelSubsession() throws Exception { 386 String sessionName = "LT.tCS"; 387 Log.startSession(sessionName); 388 Session subsession = Log.createSubsession(); 389 Log.cancelSubsession(subsession); 390 Log.endSession(); 391 392 verifyEventResult(Session.START_SESSION, sessionName, "", 0, 0); 393 verifyEventResult(Session.CREATE_SUBSESSION, sessionName, "", 0, 0); 394 verifyEventResult(Session.END_SUBSESSION, sessionName, "", 0, 0); 395 verifyEndEventResult(sessionName, "", 0, 0); 396 397 assertEquals(Log.sSessionMapper.size(), 0); 398 assertEquals(true, mTestSystemLogger.isMessagesEmpty()); 399 } 400 401 @MediumTest testInternalExternalCallToMethod()402 public void testInternalExternalCallToMethod() throws Exception { 403 String sessionName = "LT.tIECTM"; 404 Log.startSession(sessionName); 405 internalExternalMethod(); 406 Log.endSession(); 407 408 verifyEventResult(Session.START_SESSION, sessionName, "", 0, 0); 409 verifyEventResult(Session.CREATE_SUBSESSION, sessionName, "", 0, 0); 410 verifyContinueEventResult(sessionName, "", "", 0, 0); 411 verifyEventResult(Session.END_SUBSESSION, sessionName, "", 0, 0); 412 verifyMethodCall("", sessionName, 0, "", TEST_ENTER_METHOD4, 0); 413 verifyEventResult(Session.END_SUBSESSION, sessionName, "", 0, 0); 414 verifyEndEventResult(sessionName, "", 0, 0); 415 416 assertEquals(Log.sSessionMapper.size(), 0); 417 assertEquals(true, mTestSystemLogger.isMessagesEmpty()); 418 } 419 420 @MediumTest testGarbageCollectionWithTimeout()421 public void testGarbageCollectionWithTimeout() throws Exception { 422 String sessionName = "LT.tGCWT"; 423 424 // Don't end session (Oops!) 425 Log.startSession(sessionName); 426 internalDanglingMethod(); 427 Log.sSessionCleanupHandler.postDelayed(new java.lang.Runnable() { 428 @Override 429 public void run() { 430 android.util.Log.i(TESTING_TAG, "Running Test SessionCleanupHandler method."); 431 Log.cleanupStaleSessions(1000); 432 } 433 }, 1000); 434 435 verifyEventResult(Session.START_SESSION, sessionName, "", 0, 0); 436 verifyEventResult(Session.CREATE_SUBSESSION, sessionName, "", 0, 0); 437 verifyContinueEventResult(sessionName, "", "", 0, 0); 438 verifyMethodCall("", sessionName, 0, "", TEST_ENTER_METHOD4, 0); 439 440 // Verify the session is still active in sSessionMapper 441 assertEquals(Log.sSessionMapper.size(), 1); 442 assertEquals(true, mTestSystemLogger.isMessagesEmpty()); 443 444 // Keep a weak reference to the object to check if it eventually gets garbage collected. 445 int threadId = Log.getCallingThreadId(); 446 WeakReference<Session> sessionRef = new WeakReference<>( 447 Log.sSessionMapper.get(threadId)); 448 449 Thread.sleep(1100); 450 assertEquals(0, Log.sSessionMapper.size()); 451 // "Suggest" that the GC collects the now isolated Session and subsession and wait for it 452 // to occur. "System.gc()" was previously used, but it does not always perform GC, so the 453 // internal method is now called. 454 Runtime.getRuntime().gc(); 455 Thread.sleep(1000); 456 assertEquals(null, sessionRef.get()); 457 } 458 verifyMethodCall(String parentSessionName, String methodName, int sessionId, String subsession, String shortMethodName, int timeoutMs)459 private void verifyMethodCall(String parentSessionName, String methodName, int sessionId, 460 String subsession, String shortMethodName, int timeoutMs) { 461 if (!parentSessionName.isEmpty()){ 462 parentSessionName += "->"; 463 } 464 boolean isMessageReceived = mTestSystemLogger.didReceiveMessage(timeoutMs, 465 buildExpectedResult(parentSessionName + methodName, sessionId, subsession, 466 shortMethodName)); 467 468 assertEquals(true, isMessageReceived); 469 } 470 buildExpectedSession(String shortMethodName, int sessionId)471 private String buildExpectedSession(String shortMethodName, int sessionId) { 472 return shortMethodName + "@" + Log.getBase64Encoding(sessionId); 473 } 474 buildExpectedResult(String shortMethodName, int sessionId, String subsessionId, String logText)475 private String buildExpectedResult(String shortMethodName, int sessionId, 476 String subsessionId, String logText) { 477 return TEST_CLASS_NAME + ": " + logText + ": " + 478 buildExpectedSession(shortMethodName, sessionId) + subsessionId; 479 } 480 verifyContinueEventResult(String shortOldMethodName, String shortNewMethodName, String subsession, int sessionId, int timeoutMs)481 private void verifyContinueEventResult(String shortOldMethodName, String shortNewMethodName, 482 String subsession, int sessionId, int timeoutMs) { 483 String expectedSession = buildExpectedSession(shortNewMethodName, sessionId); 484 if(!shortNewMethodName.isEmpty()) { 485 shortOldMethodName += "->"; 486 } 487 boolean isMessageReceived = mTestSystemLogger.didReceiveMessage(timeoutMs, 488 Session.CONTINUE_SUBSESSION + ": " + shortOldMethodName + expectedSession + 489 subsession); 490 assertEquals(true, isMessageReceived); 491 } 492 verifyEventResult(String event, String shortMethodName, String subsession, int sessionId, int timeoutMs)493 private void verifyEventResult(String event, String shortMethodName, String subsession, 494 int sessionId, int timeoutMs) { 495 String expectedSession = buildExpectedSession(shortMethodName, sessionId); 496 boolean isMessageReceived = mTestSystemLogger.didReceiveMessage(timeoutMs,event + ": " + 497 expectedSession + subsession); 498 assertEquals(true, isMessageReceived); 499 } 500 verifyEndEventResult(String shortMethodName, String subsession, int sessionId, int timeoutMs)501 private void verifyEndEventResult(String shortMethodName, String subsession, int sessionId, 502 int timeoutMs) { 503 String expectedSession = buildExpectedSession(shortMethodName, sessionId); 504 boolean isMessageReceived = mTestSystemLogger.didReceiveMessage(timeoutMs, 505 Session.END_SESSION + ": " + expectedSession + subsession); 506 assertEquals(true, isMessageReceived); 507 } 508 internalExternalMethod()509 private void internalExternalMethod() { 510 Log.startSession("LT.iEM"); 511 Log.i(TEST_CLASS_NAME, TEST_ENTER_METHOD4); 512 Log.endSession(); 513 } 514 internalDanglingMethod()515 private void internalDanglingMethod() { 516 Log.startSession("LT.iEM"); 517 Log.i(TEST_CLASS_NAME, TEST_ENTER_METHOD4); 518 } 519 sleepyCallerMethod(int timeToSleepMs)520 private void sleepyCallerMethod(int timeToSleepMs) { 521 Log.i(TEST_CLASS_NAME, TEST_ENTER_METHOD2); 522 try { 523 Thread.sleep(timeToSleepMs); 524 sleepyMethod(rng.nextInt(TEST_SLEEP_TIME_MS)); 525 } catch (InterruptedException e) { 526 // This should not happen 527 Assert.fail("Thread sleep interrupted: " + e.getMessage()); 528 } 529 530 } 531 sleepyMultipleMethod()532 private void sleepyMultipleMethod() { 533 Log.i(TEST_CLASS_NAME, TEST_ENTER_METHOD3); 534 Session subsession = Log.createSubsession(); 535 SomeArgs args = SomeArgs.obtain(); 536 args.arg1 = subsession; 537 mSleepyHandler.obtainMessage(EVENT_START_TEST_SLEEPY_METHOD, args).sendToTarget(); 538 try { 539 Thread.sleep(TEST_SLEEP_TIME_MS); 540 } catch (InterruptedException e) { 541 // This should not happen 542 Assert.fail("Thread sleep interrupted: " + e.getMessage()); 543 } 544 } 545 sleepyMethod(int timeToSleepMs)546 private void sleepyMethod(int timeToSleepMs) { 547 Log.i(TEST_CLASS_NAME, TEST_ENTER_METHOD1); 548 try { 549 Thread.sleep(timeToSleepMs); 550 } catch (InterruptedException e) { 551 // This should not happen 552 Assert.fail("Thread sleep interrupted: " + e.getMessage()); 553 } 554 } 555 }