• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 android.videoqualityfloor.cts;
17 
18 import android.platform.test.annotations.Presubmit;
19 
20 import com.android.tradefed.build.IBuildInfo;
21 import com.android.tradefed.device.ITestDevice;
22 import com.android.tradefed.log.LogUtil;
23 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
24 import com.android.tradefed.testtype.IAbi;
25 import com.android.tradefed.testtype.IAbiReceiver;
26 import com.android.tradefed.testtype.IBuildReceiver;
27 import com.android.tradefed.testtype.IDeviceTest;
28 
29 import java.io.BufferedReader;
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.FileNotFoundException;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.InputStreamReader;
37 import java.io.OutputStream;
38 import java.lang.Process;
39 import java.lang.Runtime;
40 import java.lang.SecurityException;
41 
42 import org.junit.Assert;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 
46 /**
47  * Run the host-side video quality floor tests.
48  * These encode a set of videos at particular resolutions/bitrates and
49  * measure the quality of the output.
50  * Measurement is with the VMAF tool.
51  *
52  * The body of this test is implemented in a test script, not within the java here.
53  * This java code acquires the videos and the test script, unpacks them, executes the
54  * script (which encodes and measures).
55  */
56 @RunWith(DeviceJUnit4ClassRunner.class)
57 public class CtsVideoQualityFloorHostTest implements IAbiReceiver, IBuildReceiver, IDeviceTest {
58 
59     public static final String TAG = CtsVideoQualityFloorHostTest.class.getSimpleName();
60     String BASE_URL =
61               "https://dl.google.com/android/xts/cts/hostsidetests/videoqualityfloor/";
62     String[] testClips = {
63         "Fireworks.mp4",
64         "Motorcycle.mp4",
65         "MountainBike.mp4",
66         "TreesAndGrass.mp4"
67     };
68     // test is not valid before sdk 31, aka Android 12, aka Android S
69     static final int MINIMUM_VALID_SDK = 31;
70 
71     /**
72      * A reference to the build info.
73      */
74     private IBuildInfo mBuildInfo;
75 
76     /**
77      * A reference to the device under test.
78      */
79     private ITestDevice mDevice;
80 
81     /**
82      * A reference to the ABI under test.
83      */
84     private IAbi mAbi;
85 
86     @Override
setAbi(IAbi abi)87     public void setAbi(IAbi abi) {
88         mAbi = abi;
89     }
90 
91     @Override
setBuild(IBuildInfo buildInfo)92     public void setBuild(IBuildInfo buildInfo) {
93         mBuildInfo = buildInfo;
94     }
95 
96     @Override
setDevice(ITestDevice device)97     public void setDevice(ITestDevice device) {
98         mDevice = device;
99     }
100 
101     @Override
getDevice()102     public ITestDevice getDevice() {
103         return mDevice;
104     }
105 
getProperty(String prop)106     private String getProperty(String prop) throws Exception {
107         return mDevice.executeShellCommand("getprop " + prop).replace("\n", "");
108     }
109 
110     /**
111      * TODO: Add JavaDoc
112      */
113     @Test
testEncoding()114     public void testEncoding() throws Exception {
115 
116         String sdkAsString = getProperty("ro.build.version.sdk");
117         int sdk = Integer.parseInt(sdkAsString);
118         if (sdk < MINIMUM_VALID_SDK) {
119             LogUtil.CLog.d("Test requires sdk >= " + MINIMUM_VALID_SDK
120                             + " test device has sdk =" + sdk );
121             return;
122         }
123 
124         Runtime runtime = Runtime.getRuntime();
125         Process subproc;
126         String tmpBase = System.getProperty("java.io.tmpdir");
127         String dirName = "CtsVideoQualityFloorHostTest";
128         String tmpDir = tmpBase + "/" + dirName;
129 
130         LogUtil.CLog.d("tmpBase= " + tmpBase + " tmpDir =" + tmpDir);
131 
132         if (false) {
133             // start with a fresh directory
134             File cwd = new File(".");
135             runCmd("rm -fr " + tmpDir, cwd);
136         }
137 
138         // set up test directory, make sure it exists
139         File destination = new File(tmpDir);
140         try {
141             if (!destination.isDirectory()) {
142                 destination.mkdirs();
143             }
144         } catch (SecurityException e) {
145             LogUtil.CLog.d("Unable to establish temp directory " + destination.getPath());
146         }
147         Assert.assertTrue(destination.isDirectory());
148 
149         /*
150          *
151          * https://dl.google.com/android/xts/cts/hostsidetests/videoqualityfloor/
152          * + the name of the file
153          *
154          * turning the filename into the appropriate URL is done within downloadFile()
155          */
156 
157         for (String clip : testClips) {
158             LogUtil.CLog.d("downloading " + clip);
159             downloadFile(clip, destination);
160         }
161 
162         // get the test script
163         downloadFile("tests.tar.gz", destination);
164 
165         // we *always* unpack and setup, even if the downloads were cached.
166         // this avoids any /tmp cleanup problems.
167         //
168         // unpack the test scripts
169         runCmd("tar xzf tests.tar.gz", destination);
170 
171         // run the setup scripts
172         runCmd("./set_up.sh", destination);
173 
174         // run the test script
175         // return code is # of failures, so 0 == success
176         String clipArgs = "";
177         for (String clip : testClips) {
178             clipArgs= clipArgs + " " + clip;
179         }
180         String targetSerial = getDevice().getSerialNumber();
181         String testOutput = runCmd("./testit.sh -serial " + targetSerial + clipArgs, destination);
182 
183         LogUtil.CLog.d("(Successful) Output from testit.sh:\n\n" + testOutput);
184 
185     }
186 
187     // run the indicated command, in the indicated directory
188     // returns the command output
189     // asserts if the command finishes with non-zero exit code.
runCmd(String cmd, File cwd)190     private String runCmd(String cmd, File cwd) {
191         Runtime runtime = Runtime.getRuntime();
192         Process subproc;
193         LogUtil.CLog.d("runCmd()  cmd=" + cmd + "  cwd=" + cwd.getPath());
194         int result = 0;
195         String childStdout = "";
196         try {
197             subproc = runtime.exec(cmd, null, cwd);
198             subproc.waitFor();      // may wait forever; there are versions with timeout
199             BufferedReader kidstream =
200                             new BufferedReader(new InputStreamReader(subproc.getInputStream()));
201             String line;
202             StringBuilder kidStdout = new StringBuilder();
203             while ((line = kidstream.readLine()) != null) {
204                 kidStdout.append(line);
205                 kidStdout.append("\n");
206             }
207             childStdout = kidStdout.toString();
208             result = subproc.exitValue();
209         } catch (IOException e) {
210             result = -2;
211         } catch (InterruptedException e) {
212             result = -3;
213         }
214         Assert.assertTrue("runCmd() fails with output\n" + childStdout, result == 0);
215 
216         return childStdout;
217     }
218 
219     // download the indicated file (within the base_url folder) to
220     // our desired destination/fileName.
221     // simple caching -- if file exists, we do not redownload
downloadFile(String fileName, File destDir)222     private void downloadFile(String fileName, File destDir) {
223         Runtime runtime = Runtime.getRuntime();
224         Process subproc;
225 
226         File destination = new File(destDir, fileName);
227 
228         // save bandwidth, also allows a user to manually preload files
229         LogUtil.CLog.d("Do we already have a copy of file " + destination.getPath());
230         if (destination.isFile()) {
231             LogUtil.CLog.d("Skipping re-download of file " + destination.getPath());
232             return;
233         }
234 
235         String url = BASE_URL + fileName;
236         String cmd = "wget -O " + destination.getPath() + " " + url;
237         runCmd(cmd, destDir);
238     }
239 
240 }
241 
242