• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 package com.android.compatibility.targetprep;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import static org.testng.Assert.assertThrows;
21 
22 import com.android.ddmlib.Log;
23 import com.android.ddmlib.Log.ILogOutput;
24 import com.android.ddmlib.Log.LogLevel;
25 import com.android.tradefed.build.BuildInfo;
26 import com.android.tradefed.config.OptionSetter;
27 import com.android.tradefed.device.ITestDevice;
28 import com.android.tradefed.invoker.IInvocationContext;
29 import com.android.tradefed.invoker.InvocationContext;
30 import com.android.tradefed.invoker.TestInformation;
31 import com.android.tradefed.targetprep.TargetSetupError;
32 import com.android.tradefed.util.CommandResult;
33 import com.android.tradefed.util.CommandStatus;
34 
35 import com.google.common.truth.Correspondence;
36 
37 import org.junit.After;
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 import org.junit.runners.JUnit4;
42 import org.mockito.Mockito;
43 
44 import java.util.ArrayList;
45 
46 @RunWith(JUnit4.class)
47 public final class CheckGmsPreparerTest {
48     private CheckGmsPreparer mPreparer;
49     private LogCaptor mLogCaptor;
50 
51     @Before
setUp()52     public void setUp() throws Exception {
53         mPreparer = new CheckGmsPreparer();
54         new OptionSetter(mPreparer).setOptionValue(CheckGmsPreparer.OPTION_ENABLE, "true");
55 
56         mLogCaptor = new LogCaptor();
57         Log.addLogger(mLogCaptor);
58     }
59 
60     @After
tearDown()61     public void tearDown() {
62         Log.removeLogger(mLogCaptor);
63     }
64 
65     @Test
setUp_checkDisabledAndGmsAbsent_doesNotReboot()66     public void setUp_checkDisabledAndGmsAbsent_doesNotReboot() throws Exception {
67         ITestDevice device = createDeviceWithGmsAbsent();
68         disablePreparer(mPreparer);
69 
70         mPreparer.setUp(createTestInfo(device));
71 
72         Mockito.verify(device, Mockito.never()).reboot();
73         assertThat(mLogCaptor.getLogItems())
74                 .comparingElementsUsing(createContainsErrorLogCorrespondence())
75                 .doesNotContain("GMS");
76     }
77 
78     @Test
tearDown_checkDisabledAndGmsAbsent_doesNotLog()79     public void tearDown_checkDisabledAndGmsAbsent_doesNotLog() throws Exception {
80         ITestDevice device = createDeviceWithGmsAbsent();
81         disablePreparer(mPreparer);
82 
83         mPreparer.tearDown(createTestInfo(device), null);
84 
85         assertThat(mLogCaptor.getLogItems())
86                 .comparingElementsUsing(createContainsErrorLogCorrespondence())
87                 .doesNotContain("GMS");
88     }
89 
90     @Test
tearDown_setUpThrows_doesNotCheck()91     public void tearDown_setUpThrows_doesNotCheck() throws Exception {
92         ITestDevice device = createDeviceWithGmsAbsent();
93         TestInformation testInfo = createTestInfo(device);
94         assertThrows(TargetSetupError.class, () -> mPreparer.setUp(testInfo));
95         mLogCaptor.reset();
96         Mockito.reset(device);
97         Mockito.when(device.executeShellV2Command(Mockito.any()))
98                 .thenReturn(createFailedCommandResult());
99 
100         mPreparer.tearDown(testInfo, null);
101 
102         Mockito.verify(device, Mockito.never()).executeShellV2Command(Mockito.any());
103     }
104 
105     @Test
tearDown_setUpRecoveredGms_checksGms()106     public void tearDown_setUpRecoveredGms_checksGms() throws Exception {
107         ITestDevice device = createDeviceWithGmsAbsentAndRecoverable();
108         TestInformation testInfo = createTestInfo(device);
109         mPreparer.setUp(testInfo);
110         mLogCaptor.reset();
111         Mockito.reset(device);
112         Mockito.when(device.executeShellV2Command(CheckGmsPreparer.CHECK_GMS_COMMAND))
113                 .thenReturn(createSuccessfulCommandResult());
114 
115         mPreparer.tearDown(testInfo, null);
116 
117         Mockito.verify(device, Mockito.atLeast(1))
118                 .executeShellV2Command(CheckGmsPreparer.CHECK_GMS_COMMAND);
119     }
120 
121     @Test
tearDown_setUpFoundGms_checksGms()122     public void tearDown_setUpFoundGms_checksGms() throws Exception {
123         ITestDevice device = createDeviceWithGmsPresent();
124         TestInformation testInfo = createTestInfo(device);
125         mPreparer.setUp(testInfo);
126         Mockito.reset(device);
127         mLogCaptor.reset();
128         Mockito.when(device.executeShellV2Command(CheckGmsPreparer.CHECK_GMS_COMMAND))
129                 .thenReturn(createSuccessfulCommandResult());
130 
131         mPreparer.tearDown(testInfo, null);
132 
133         Mockito.verify(device, Mockito.atLeast(1))
134                 .executeShellV2Command(CheckGmsPreparer.CHECK_GMS_COMMAND);
135     }
136 
137     @Test
setUp_gmsPresent_doesNotReboot()138     public void setUp_gmsPresent_doesNotReboot() throws Exception {
139         ITestDevice device = createDeviceWithGmsPresent();
140 
141         mPreparer.setUp(createTestInfo(device));
142 
143         Mockito.verify(device, Mockito.never()).reboot();
144         assertThat(mLogCaptor.getLogItems())
145                 .comparingElementsUsing(createContainsErrorLogCorrespondence())
146                 .doesNotContain("GMS");
147     }
148 
149     @Test
setUp_gmsProcessRecoveredAfterReboot_doesNotThrow()150     public void setUp_gmsProcessRecoveredAfterReboot_doesNotThrow() throws Exception {
151         ITestDevice device = createDeviceWithGmsAbsentAndRecoverable();
152 
153         mPreparer.setUp(createTestInfo(device));
154     }
155 
156     @Test
setUp_gmsProcessNotRecoveredAfterReboot_throwsException()157     public void setUp_gmsProcessNotRecoveredAfterReboot_throwsException() throws Exception {
158         ITestDevice device = createDeviceWithGmsAbsent();
159 
160         assertThrows(TargetSetupError.class, () -> mPreparer.setUp(createTestInfo(device)));
161     }
162 
163     @Test
tearDown_gmsProcessPresent_doesNotLog()164     public void tearDown_gmsProcessPresent_doesNotLog() throws Exception {
165         ITestDevice device = createDeviceWithGmsPresent();
166 
167         mPreparer.tearDown(createTestInfo(device), null);
168 
169         assertThat(mLogCaptor.getLogItems())
170                 .comparingElementsUsing(createContainsErrorLogCorrespondence())
171                 .doesNotContain("GMS");
172     }
173 
disablePreparer(CheckGmsPreparer preparer)174     private static void disablePreparer(CheckGmsPreparer preparer) throws Exception {
175         new OptionSetter(preparer).setOptionValue(CheckGmsPreparer.OPTION_ENABLE, "false");
176     }
177 
createContainsErrorLogCorrespondence()178     private static Correspondence<LogItem, String> createContainsErrorLogCorrespondence() {
179         return Correspondence.from(
180                 (LogItem actual, String expected) -> {
181                     return actual.getLogLevel() == LogLevel.ERROR
182                             && actual.getMessage().contains(expected);
183                 },
184                 "has an error log that contains");
185     }
186 
createDeviceWithGmsAbsentAndRecoverable()187     private static ITestDevice createDeviceWithGmsAbsentAndRecoverable() throws Exception {
188         ITestDevice device = Mockito.mock(ITestDevice.class);
189         Mockito.doReturn(createFailedCommandResult())
190                 .doReturn(createSuccessfulCommandResult())
191                 .when(device)
192                 .executeShellV2Command(CheckGmsPreparer.CHECK_GMS_COMMAND);
193         return device;
194     }
195 
createDeviceWithGmsPresent()196     private static ITestDevice createDeviceWithGmsPresent() throws Exception {
197         ITestDevice device = Mockito.mock(ITestDevice.class);
198         Mockito.when(device.executeShellV2Command(CheckGmsPreparer.CHECK_GMS_COMMAND))
199                 .thenReturn(createSuccessfulCommandResult());
200         return device;
201     }
202 
createDeviceWithGmsAbsent()203     private static ITestDevice createDeviceWithGmsAbsent() throws Exception {
204         ITestDevice device = Mockito.mock(ITestDevice.class);
205         Mockito.when(device.executeShellV2Command(CheckGmsPreparer.CHECK_GMS_COMMAND))
206                 .thenReturn(createFailedCommandResult());
207         return device;
208     }
209 
210     private static final class LogCaptor implements ILogOutput {
211         private ArrayList<LogItem> mLogItems = new ArrayList<>();
212 
reset()213         void reset() {
214             mLogItems.clear();
215         }
216 
getLogItems()217         ArrayList<LogItem> getLogItems() {
218             return mLogItems;
219         }
220 
221         @Override
printLog(LogLevel logLevel, String tag, String message)222         public void printLog(LogLevel logLevel, String tag, String message) {
223             mLogItems.add(new LogItem(logLevel, tag, message));
224         }
225 
226         @Override
printAndPromptLog(LogLevel logLevel, String tag, String message)227         public void printAndPromptLog(LogLevel logLevel, String tag, String message) {
228             printLog(logLevel, tag, message);
229         }
230     }
231 
232     private static final class LogItem {
233         private LogLevel mLogLevel;
234         private String mMessage;
235 
getLogLevel()236         LogLevel getLogLevel() {
237             return mLogLevel;
238         }
239 
getMessage()240         String getMessage() {
241             return mMessage;
242         }
243 
LogItem(LogLevel logLevel, @SuppressWarnings("unused") String tag, String message)244         LogItem(LogLevel logLevel, @SuppressWarnings("unused") String tag, String message) {
245             mLogLevel = logLevel;
246             mMessage = message;
247         }
248     }
249 
createTestInfo(ITestDevice device)250     private static TestInformation createTestInfo(ITestDevice device) {
251         IInvocationContext context = new InvocationContext();
252         context.addAllocatedDevice("device1", device);
253         context.addDeviceBuildInfo("device1", new BuildInfo());
254         return TestInformation.newBuilder().setInvocationContext(context).build();
255     }
256 
createSuccessfulCommandResult()257     private static CommandResult createSuccessfulCommandResult() {
258         CommandResult commandResult = new CommandResult(CommandStatus.SUCCESS);
259         commandResult.setExitCode(0);
260         return commandResult;
261     }
262 
createFailedCommandResult()263     private static CommandResult createFailedCommandResult() {
264         CommandResult commandResult = new CommandResult(CommandStatus.FAILED);
265         commandResult.setExitCode(1);
266         return commandResult;
267     }
268 }
269 
270