1 /* 2 * Copyright (C) 2009 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; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.mockito.Mockito.mock; 21 import static org.mockito.Mockito.verify; 22 import static org.mockito.Mockito.verifyNoMoreInteractions; 23 24 import android.os.Handler; 25 import android.os.SimpleClock; 26 27 import androidx.test.runner.AndroidJUnit4; 28 29 import com.android.server.Watchdog.HandlerChecker; 30 31 import org.junit.Before; 32 import org.junit.Test; 33 import org.junit.runner.RunWith; 34 35 import java.time.ZoneOffset; 36 37 /** Test class for {@link Watchdog}. */ 38 @RunWith(AndroidJUnit4.class) 39 public class WatchdogTest { 40 private static final int TIMEOUT_MS = 10; 41 42 private TestClock mClock; 43 private Handler mHandler; 44 private HandlerChecker mChecker; 45 46 @Before setUp()47 public void setUp() { 48 mClock = new TestClock(); 49 mHandler = mock(Handler.class); 50 mChecker = 51 new HandlerChecker(mHandler, "monitor thread", new Object(), mClock) { 52 @Override 53 public boolean isHandlerPolling() { 54 return false; 55 } 56 }; 57 } 58 59 @Test checkerPausedUntilResume()60 public void checkerPausedUntilResume() { 61 Watchdog.Monitor monitor = mock(Watchdog.Monitor.class); 62 mChecker.addMonitorLocked(monitor); 63 64 mChecker.pauseLocked("pausing"); 65 mChecker.scheduleCheckLocked(TIMEOUT_MS); 66 verifyNoMoreInteractions(mHandler); 67 assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked()); 68 69 mChecker.resumeLocked("resuming"); 70 mChecker.scheduleCheckLocked(10); 71 assertEquals(Watchdog.WAITING, mChecker.getCompletionStateLocked()); 72 } 73 74 @Test checkerPausedUntilDeadline()75 public void checkerPausedUntilDeadline() { 76 Watchdog.Monitor monitor = mock(Watchdog.Monitor.class); 77 mChecker.addMonitorLocked(monitor); 78 79 mChecker.pauseForLocked(10, "pausing"); 80 mChecker.scheduleCheckLocked(TIMEOUT_MS); 81 verifyNoMoreInteractions(mHandler); 82 assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked()); 83 84 mClock.advanceBy(5); 85 verifyNoMoreInteractions(mHandler); 86 assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked()); 87 88 // Above the 10s timeout. Watchdog should not be paused anymore. 89 mClock.advanceBy(6); 90 mChecker.scheduleCheckLocked(TIMEOUT_MS); 91 assertEquals(Watchdog.WAITING, mChecker.getCompletionStateLocked()); 92 } 93 94 @Test checkerPausedDuringScheduledRun()95 public void checkerPausedDuringScheduledRun() { 96 Watchdog.Monitor monitor = mock(Watchdog.Monitor.class); 97 mChecker.addMonitorLocked(monitor); 98 99 mChecker.scheduleCheckLocked(TIMEOUT_MS); 100 mClock.advanceBy(5); 101 mChecker.pauseForLocked(10, "pausing"); 102 verifyNoMoreInteractions(mHandler); 103 assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked()); 104 105 // Above the 10s timeout. Watchdog should not be paused anymore. 106 mClock.advanceBy(11); 107 mChecker.scheduleCheckLocked(TIMEOUT_MS); 108 assertEquals(Watchdog.WAITING, mChecker.getCompletionStateLocked()); 109 } 110 111 @Test blockedThread()112 public void blockedThread() { 113 mChecker.scheduleCheckLocked(TIMEOUT_MS); 114 assertEquals(mChecker.getCompletionStateLocked(), Watchdog.WAITING); 115 116 mClock.advanceBy(6); 117 assertEquals(Watchdog.WAITED_UNTIL_PRE_WATCHDOG, mChecker.getCompletionStateLocked()); 118 119 // Above the 10s timeout. 120 mClock.advanceBy(6); 121 assertEquals(Watchdog.OVERDUE, mChecker.getCompletionStateLocked()); 122 } 123 124 @Test checkNothingBlocked()125 public void checkNothingBlocked() { 126 Watchdog.Monitor monitor = mock(Watchdog.Monitor.class); 127 mChecker.addMonitorLocked(monitor); 128 129 mChecker.scheduleCheckLocked(TIMEOUT_MS); 130 // scheduleCheckLocked calls #postAtFrontOfQueue which will call mChecker.run(). 131 mChecker.run(); 132 assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked()); 133 verify(monitor).monitor(); 134 } 135 136 private static class TestClock extends SimpleClock { 137 long mNowMillis = 1; 138 TestClock()139 TestClock() { 140 super(ZoneOffset.UTC); 141 } 142 143 @Override millis()144 public long millis() { 145 return mNowMillis; 146 } 147 advanceBy(long millis)148 public void advanceBy(long millis) { 149 mNowMillis += millis; 150 } 151 } 152 } 153