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