• 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.videoencodingquality.cts;
17 
18 import com.android.compatibility.common.util.CddTest;
19 import com.android.tradefed.build.IBuildInfo;
20 import com.android.tradefed.config.Option;
21 import com.android.tradefed.config.OptionClass;
22 import com.android.tradefed.device.ITestDevice;
23 import com.android.tradefed.log.LogUtil;
24 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
25 import com.android.tradefed.testtype.IAbi;
26 import com.android.tradefed.testtype.IAbiReceiver;
27 import com.android.tradefed.testtype.IBuildReceiver;
28 import com.android.tradefed.testtype.IDeviceTest;
29 
30 import org.junit.Assert;
31 import org.junit.Assume;
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 
35 import java.io.BufferedReader;
36 import java.io.File;
37 import java.io.IOException;
38 import java.io.InputStreamReader;
39 import java.util.concurrent.TimeUnit;
40 
41 /**
42  * Run the host-side video encoding quality test (go/pc14-veq)
43  * The body of this test is implemented in a test script, not within the java here. This java
44  * code acquires the testsuite tar file, unpacks it, executes the script (which encodes and
45  * measures) that report either PASS or FAIL.
46  **/
47 @RunWith(DeviceJUnit4ClassRunner.class)
48 @OptionClass(alias = "pc-veq-test")
49 public class CtsVideoEncodingQualityHostTest implements IAbiReceiver, IBuildReceiver, IDeviceTest {
50 
51     static final String BASE_URL =
52             "https://storage.googleapis.com/android_media/cts/hostsidetests/pc14_veq/";
53 
54     @Option(name = "force-to-run",
55             description = "Force to run the test even if the device is not a right performance "
56                     + "class device.")
57     private boolean mForceToRun = false;
58 
59     @Option(name = "disable-b", description = "Disable b-frame-encoding.")
60     private boolean mDisableB = false;
61 
62     @Option(name = "reset", description = "Start with a fresh directory.")
63     private boolean mReset = true;
64 
65     @Option(name = "quick-check", description = "Run a quick check.")
66     private boolean mQuickCheck = false;
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     // media performance class 14
72     static final int MEDIA_PERFORMANCE_CLASS_14 = 34;
73 
74     /** A reference to the build info. */
75     private IBuildInfo mBuildInfo;
76 
77     /** A reference to the device under test. */
78     private ITestDevice mDevice;
79 
80     /** A reference to the ABI under test. */
81     private IAbi mAbi;
82 
83     @Override
setAbi(IAbi abi)84     public void setAbi(IAbi abi) {
85         mAbi = abi;
86     }
87 
88     @Override
setBuild(IBuildInfo buildInfo)89     public void setBuild(IBuildInfo buildInfo) {
90         mBuildInfo = buildInfo;
91     }
92 
93     @Override
setDevice(ITestDevice device)94     public void setDevice(ITestDevice device) {
95         mDevice = device;
96     }
97 
98     @Override
getDevice()99     public ITestDevice getDevice() {
100         return mDevice;
101     }
102 
getProperty(String prop)103     private String getProperty(String prop) throws Exception {
104         return mDevice.executeShellCommand("getprop " + prop).replace("\n", "");
105     }
106 
107     /**
108      * TODO: Add JavaDoc
109      */
110     /**
111      * Verify the video encoding quality requirements for the performance class 14 devices.
112      */
113     @CddTest(requirements = {"2.2.7.1/5.8/H-1-1"})
114     @Test
testEncoding()115     public void testEncoding() throws Exception {
116         String sdkAsString = getProperty("ro.build.version.sdk");
117         int sdk = Integer.parseInt(sdkAsString);
118         Assume.assumeTrue(
119                 "Test requires sdk >= " + MINIMUM_VALID_SDK + " test device has sdk = " + sdk,
120                 sdk >= MINIMUM_VALID_SDK);
121 
122         String os = System.getProperty("os.name").toLowerCase();
123         LogUtil.CLog.i("Host OS = " + os);
124 
125         String pcAsString = getProperty("ro.odm.build.media_performance_class");
126         int mpc = 0;
127         try {
128             mpc = Integer.parseInt("0" + pcAsString);
129         } catch (Exception e) {
130             LogUtil.CLog.i("Invalid pcAsString: " + pcAsString + ", exception: " + e);
131             mpc = 0;
132         }
133 
134         // Enable early termination on errors on the devices whose mpc's are not valid.
135         // Run the entire test til the end on the devices whose mpc's are valid.
136         boolean earlyTermination = mpc < MEDIA_PERFORMANCE_CLASS_14;
137         if (mForceToRun) {
138             earlyTermination = false;       // Force to run the test til the end.
139         }
140 
141         String targetSerial = getDevice().getSerialNumber();
142         LogUtil.CLog.i("serial:\n\n" + targetSerial);
143 
144         String tmpBase = System.getProperty("java.io.tmpdir");
145         String dirName = "CtsVideoEncodingQualityHostTest_" + targetSerial;
146         String tmpDir = tmpBase + "/" + dirName;
147 
148         LogUtil.CLog.i("tmpBase= " + tmpBase + " tmpDir =" + tmpDir);
149 
150         if (mReset) {
151             // start with a fresh directory
152             File cwd = new File(".");
153             runCommand("rm -fr " + tmpDir, cwd);
154         }
155 
156         // set up test directory, make sure it exists
157         File destination = new File(tmpDir);
158         try {
159             if (!destination.isDirectory()) {
160                 destination.mkdirs();
161             }
162         } catch (SecurityException e) {
163             LogUtil.CLog.e("Unable to establish temp directory " + destination.getPath());
164         }
165         Assert.assertTrue("Failed to create test director: " + tmpDir, destination.isDirectory());
166 
167         // Download the testsuit tar file.
168         downloadFile("veqtests.tar.gz", destination);
169 
170         // Unpack the testsuit tar file.
171         int result = runCommand("tar xvzf veqtests.tar.gz", destination);
172         Assert.assertTrue("Failed to untar veqtests.tar.gz", result == 0);
173 
174         // Execute the script to run the test.
175         String testCommand = "./testit.sh --serial " + targetSerial;
176         if (mQuickCheck) testCommand += " --enablequickrun YES";
177         if (mDisableB) testCommand += " --enableb NO";
178         if (earlyTermination) testCommand += " --exitonerror YES";
179         result = runCommand(testCommand, destination);
180 
181         if (mpc >= MEDIA_PERFORMANCE_CLASS_14 || mForceToRun) {
182             Assert.assertTrue(
183                     "test device advertises mpc=" + mpc
184                             + ", but failed to pass the video encoding quality test.",
185                     result == 0);
186         } else {
187             Assume.assumeTrue(
188                     "test device advertises mpc=" + mpc
189                             + ", and did not pass the video encoding quality test.",
190                     result == 0);
191         }
192 
193         LogUtil.CLog.i("Finished executing " + testCommand);
194     }
195 
runCommand(String cmd, File dir)196     private int runCommand(String cmd, File dir) throws IOException, InterruptedException {
197         Process process = Runtime.getRuntime().exec(cmd, null, dir);
198 
199         BufferedReader stdInput =
200                 new BufferedReader(new InputStreamReader(process.getInputStream()));
201         BufferedReader stdError =
202                 new BufferedReader(new InputStreamReader(process.getErrorStream()));
203         String line = "";
204         boolean isOutReady = false;
205         boolean isErrorReady = false;
206         boolean isProcessAlive = false;
207 
208         while (process.isAlive()) {
209             do {
210                 isOutReady = stdInput.ready();
211 
212                 if (isOutReady) {
213                     line = stdInput.readLine();
214                     LogUtil.CLog.i("== " + line + "\n");
215                 }
216 
217                 isErrorReady = stdError.ready();
218                 if (isErrorReady) {
219                     line = stdError.readLine();
220                     LogUtil.CLog.i("xx " + line + "\n");
221                 }
222 
223                 isProcessAlive = process.isAlive();
224                 if (!isProcessAlive) {
225                     LogUtil.CLog.i("::Process DIED! " + line + "\n");
226                     line = null;
227                     process.waitFor(1000, TimeUnit.MILLISECONDS);
228                 }
229 
230             } while (line != null);
231 
232             process.waitFor(100, TimeUnit.MILLISECONDS);
233         }
234 
235         return process.exitValue();
236     }
237 
238     // Download the indicated file (within the base_url folder) to
239     // our desired destination/fileName.
240     // simple caching -- if file exists, we do not redownload
downloadFile(String fileName, File destDir)241     private void downloadFile(String fileName, File destDir) {
242         File destination = new File(destDir, fileName);
243 
244         // save bandwidth, also allows a user to manually preload files
245         LogUtil.CLog.i("Do we already have a copy of file " + destination.getPath());
246         if (destination.isFile()) {
247             LogUtil.CLog.i("Skipping re-download of file " + destination.getPath());
248             return;
249         }
250 
251         String url = BASE_URL + fileName;
252         String cmd = "wget -O " + destination.getPath() + " " + url;
253         LogUtil.CLog.i("wget_cmd = " + cmd);
254 
255         int result = 0;
256 
257         try {
258             result = runCommand(cmd, destDir);
259         } catch (IOException e) {
260             result = -2;
261         } catch (InterruptedException e) {
262             result = -3;
263         }
264         Assert.assertTrue("downloadFile failed.\n", result == 0);
265     }
266 }
267