• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }