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.tradefed.testtype.binary;
17 
18 import com.android.tradefed.config.Option;
19 import com.android.tradefed.config.OptionClass;
20 import com.android.tradefed.device.DeviceNotAvailableException;
21 import com.android.tradefed.device.ITestDevice;
22 import com.android.tradefed.result.FailureDescription;
23 import com.android.tradefed.result.ITestInvocationListener;
24 import com.android.tradefed.result.TestDescription;
25 import com.android.tradefed.result.proto.TestRecordProto.FailureStatus;
26 import com.android.tradefed.testtype.IDeviceTest;
27 import com.android.tradefed.util.CommandResult;
28 import com.android.tradefed.util.CommandStatus;
29 
30 import java.io.IOException;
31 import java.util.concurrent.TimeUnit;
32 
33 /**
34  * Test runner for executable running on the target. The runner implements {@link IDeviceTest} since
35  * the binary run on a device.
36  */
37 @OptionClass(alias = "executable-target-test")
38 public class ExecutableTargetTest extends ExecutableBaseTest implements IDeviceTest {
39 
40     private ITestDevice mDevice = null;
41 
42     @Option(name = "skip-binary-check", description = "Skip the binary check in findBinary().")
43     private boolean mSkipBinaryCheck = false;
44 
45     /** {@inheritDoc} */
46     @Override
setDevice(ITestDevice device)47     public void setDevice(ITestDevice device) {
48         mDevice = device;
49     }
50 
51     /** {@inheritDoc} */
52     @Override
getDevice()53     public ITestDevice getDevice() {
54         return mDevice;
55     }
56 
getSkipBinaryCheck()57     protected boolean getSkipBinaryCheck() {
58         return mSkipBinaryCheck;
59     }
60 
61     @Override
findBinary(String binary)62     public String findBinary(String binary) throws DeviceNotAvailableException {
63         if (getSkipBinaryCheck()) {
64             return binary;
65         }
66         for (String path : binary.split(" ")) {
67             if (getDevice().isExecutable(path)) {
68                 return binary;
69             }
70         }
71         return null;
72     }
73 
74     @Override
runBinary( String binaryPath, ITestInvocationListener listener, TestDescription description)75     public void runBinary(
76             String binaryPath, ITestInvocationListener listener, TestDescription description)
77             throws DeviceNotAvailableException, IOException {
78         if (mDevice == null) {
79             throw new IllegalArgumentException("Device has not been set");
80         }
81         CommandResult result =
82                 mDevice.executeShellV2Command(
83                         binaryPath, getTimeoutPerBinaryMs(), TimeUnit.MILLISECONDS);
84         checkCommandResult(result, listener, description);
85     }
86 
87     /**
88      * Check the result of the test command.
89      *
90      * @param result test result of the command {@link CommandResult}
91      * @param listener the {@link ITestInvocationListener}
92      * @param description The test in progress.
93      */
checkCommandResult( CommandResult result, ITestInvocationListener listener, TestDescription description)94     protected void checkCommandResult(
95             CommandResult result, ITestInvocationListener listener, TestDescription description) {
96         if (!CommandStatus.SUCCESS.equals(result.getStatus())) {
97             String error_message;
98             error_message =
99                     String.format(
100                             "binary returned non-zero. Exit code: %d, stderr: %s, stdout: %s",
101                             result.getExitCode(), result.getStderr(), result.getStdout());
102             listener.testFailed(
103                     description,
104                     FailureDescription.create(error_message)
105                             .setFailureStatus(FailureStatus.TEST_FAILURE));
106         }
107     }
108 }
109