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 package com.android.tradefed.targetprep.suite;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertNotNull;
20 import static org.junit.Assert.fail;
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.times;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 
26 import com.android.tradefed.build.IBuildInfo;
27 import com.android.tradefed.build.IDeviceBuildInfo;
28 import com.android.tradefed.device.ITestDevice;
29 import com.android.tradefed.invoker.ExecutionFiles.FilesKey;
30 import com.android.tradefed.invoker.IInvocationContext;
31 import com.android.tradefed.invoker.InvocationContext;
32 import com.android.tradefed.invoker.TestInformation;
33 import com.android.tradefed.targetprep.TargetSetupError;
34 import com.android.tradefed.util.FileUtil;
35 
36 import org.junit.After;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.junit.runners.JUnit4;
41 import org.mockito.Mockito;
42 
43 import java.io.File;
44 import java.io.IOException;
45 
46 /** Unit test for {@link SuiteApkInstaller} */
47 @RunWith(JUnit4.class)
48 public class SuiteApkInstallerTest {
49 
50     private SuiteApkInstaller mPreparer;
51     private IBuildInfo mMockBuildInfo;
52     private ITestDevice mMockDevice;
53     private TestInformation mTestInfo;
54     private File mTmpDepDir;
55 
56     @Before
setUp()57     public void setUp() throws IOException {
58         mPreparer = new SuiteApkInstaller();
59         mMockBuildInfo = Mockito.mock(IBuildInfo.class);
60         mMockDevice = Mockito.mock(ITestDevice.class);
61         IInvocationContext context = new InvocationContext();
62         context.addAllocatedDevice("device", mMockDevice);
63         context.addDeviceBuildInfo("device", mMockBuildInfo);
64         mTmpDepDir = FileUtil.createTempDir("suite-apk-installer-dep");
65         mTestInfo =
66                 TestInformation.newBuilder()
67                         .setInvocationContext(context)
68                         .setDependenciesFolder(mTmpDepDir)
69                         .build();
70     }
71 
72     @After
tearDown()73     public void tearDown() {
74         FileUtil.recursiveDelete(mTmpDepDir);
75     }
76 
77     /**
78      * Tests that when $ANDROID_TARGET_OUT_TESTCASES is defined it is returned, we do not check
79      * ROOT_DIR.
80      */
81     @Test
testGetLocalPathForFilename_withVariable()82     public void testGetLocalPathForFilename_withVariable() throws Exception {
83         File apk = FileUtil.createTempFile("testapk", ".apk", mTmpDepDir);
84         File res = mPreparer.getLocalPathForFilename(mTestInfo, apk.getName());
85         verify(mMockBuildInfo, times(0)).getBuildAttributes();
86         assertNotNull(res);
87         assertEquals(apk.getAbsolutePath(), res.getAbsolutePath());
88     }
89 
90     /**
91      * Tests that when $ANDROID_TARGET_OUT_TESTCASES is defined but is not a directory, we check and
92      * return ROOT_DIR instead.
93      */
94     @Test
testGetTestsDir_notDir()95     public void testGetTestsDir_notDir() throws Exception {
96         File varDir = FileUtil.createTempFile("suite-apk-installer-var", ".txt");
97         mTestInfo.executionFiles().put(FilesKey.TARGET_TESTS_DIRECTORY, varDir);
98         File tmpDir = FileUtil.createTempDir("suite-apk-installer");
99         mTestInfo.executionFiles().put(FilesKey.TESTS_DIRECTORY, tmpDir);
100         File apkFile = FileUtil.createTempFile("apk-test", ".apk", tmpDir);
101         try {
102             File res = mPreparer.getLocalPathForFilename(mTestInfo, apkFile.getName());
103             assertNotNull(res);
104             assertEquals(apkFile.getAbsolutePath(), res.getAbsolutePath());
105         } finally {
106             FileUtil.recursiveDelete(varDir);
107             FileUtil.recursiveDelete(tmpDir);
108         }
109     }
110 
111     /**
112      * Test that {@link SuiteApkInstaller#getLocalPathForFilename(TestInformation, String)} returns
113      * the apk file when found.
114      */
115     @Test
testGetLocalPathForFileName()116     public void testGetLocalPathForFileName() throws Exception {
117         File tmpApk = FileUtil.createTempFile("suite-apk-installer", ".apk");
118         mTestInfo.executionFiles().put(tmpApk.getName(), tmpApk);
119         try {
120             File apk = mPreparer.getLocalPathForFilename(mTestInfo, tmpApk.getName());
121             assertEquals(tmpApk.getAbsolutePath(), apk.getAbsolutePath());
122         } finally {
123             FileUtil.deleteFile(tmpApk);
124         }
125     }
126 
127     /**
128      * Test that {@link SuiteApkInstaller#getLocalPathForFilename(TestInformation, String)} throws
129      * an exception when the apk file is not found.
130      */
131     @Test
testGetLocalPathForFileName_noFound()132     public void testGetLocalPathForFileName_noFound() throws Exception {
133         File tmpApk = FileUtil.createTempFile("suite-apk-installer", ".apk");
134         try {
135             mPreparer.getLocalPathForFilename(mTestInfo, "no_exist");
136             fail("Should have thrown an exception.");
137         } catch (TargetSetupError expected) {
138             // expected
139         } finally {
140             FileUtil.deleteFile(tmpApk);
141         }
142     }
143 
144     /**
145      * Test that {@link SuiteApkInstaller#getLocalPathForFilename(TestInformation, String)} returns
146      * the apk file located in IDeviceBuildInfo.getTestsDir().
147      */
148     @Test
testGetLocalPathForFileName_testsDir()149     public void testGetLocalPathForFileName_testsDir() throws Exception {
150         IDeviceBuildInfo deviceBuildInfo = mock(IDeviceBuildInfo.class);
151         File tmpDir = null;
152         try {
153             tmpDir = FileUtil.createTempDir("test");
154             mTestInfo.executionFiles().put(FilesKey.TESTS_DIRECTORY, tmpDir);
155             File tmpApk = FileUtil.createTempFile("suite-apk-installer", ".apk", tmpDir);
156 
157             mTestInfo.getContext().addDeviceBuildInfo("device", deviceBuildInfo);
158             File apk = mPreparer.getLocalPathForFilename(mTestInfo, tmpApk.getName());
159             assertEquals(tmpApk.getAbsolutePath(), apk.getAbsolutePath());
160         } finally {
161             FileUtil.recursiveDelete(tmpDir);
162         }
163     }
164 
165     /** If the file is found directly in the build info keys, use it. */
166     @Test
testGetLocalPathForFileName_inBuildKey()167     public void testGetLocalPathForFileName_inBuildKey() throws Exception {
168         File tmpApk = FileUtil.createTempFile("suite-apk-installer", ".apk");
169         mTestInfo.executionFiles().put("foo.apk", tmpApk);
170         try {
171             File apk = mPreparer.getLocalPathForFilename(mTestInfo, "foo.apk");
172             assertEquals(tmpApk.getAbsolutePath(), apk.getAbsolutePath());
173         } finally {
174             FileUtil.deleteFile(tmpApk);
175         }
176     }
177 
178     /**
179      * Test that {@link SuiteApkInstaller#getLocalPathForFilename(TestInformation, String)} returns
180      * the apk file retrieved from remote artifacts.
181      */
182     @Test
testGetLocalPathForFileName_remoteZip()183     public void testGetLocalPathForFileName_remoteZip() throws Exception {
184         IDeviceBuildInfo deviceBuildInfo = mock(IDeviceBuildInfo.class);
185         File tmpDir = null;
186         try {
187             tmpDir = FileUtil.createTempDir("test");
188             mTestInfo.executionFiles().put(FilesKey.TESTS_DIRECTORY, tmpDir);
189             // Change the name so direct file search will return null.
190             File tmpApk = FileUtil.createTempFile("suite-apk-installer-2", ".apk", tmpDir);
191             when(deviceBuildInfo.stageRemoteFile(
192                             Mockito.eq("suite-apk-installer.apk"), Mockito.eq(tmpDir)))
193                     .thenReturn(tmpApk);
194             mTestInfo.getContext().addDeviceBuildInfo("device", deviceBuildInfo);
195 
196             File apk = mPreparer.getLocalPathForFilename(mTestInfo, "suite-apk-installer.apk");
197             assertEquals(tmpApk.getAbsolutePath(), apk.getAbsolutePath());
198         } finally {
199             FileUtil.recursiveDelete(tmpDir);
200         }
201     }
202 
203     /** If the file is found in the build shared resources directory, use it. */
204     @Test
testGetLocalPathForFileName_inDependenciesDir()205     public void testGetLocalPathForFileName_inDependenciesDir() throws Exception {
206         File tmpApk = FileUtil.createTempFile("suite-apk-installer", ".apk", mTmpDepDir);
207         try {
208             File apk = mPreparer.getLocalPathForFilename(mTestInfo, tmpApk.getName());
209             assertEquals(tmpApk.getAbsolutePath(), apk.getAbsolutePath());
210         } finally {
211             FileUtil.deleteFile(tmpApk);
212         }
213     }
214 }
215