xref: /aosp_15_r20/test/catbox/runner/src/com/android/catbox/runner/MopedRunner.java (revision cf2b7170afc0c862dd83220c810a915824e7d4c6)
1 
2 // Copyright 2023 Google Inc. All Rights Reserved.
3 package com.google.android.car.aaosbt;
4 import com.android.ddmlib.Log.LogLevel;
5 import com.android.tradefed.config.Option;
6 import com.android.tradefed.config.OptionClass;
7 import com.android.tradefed.device.DeviceNotAvailableException;
8 import com.android.tradefed.invoker.TestInformation;
9 import com.android.tradefed.log.LogUtil.CLog;
10 import com.android.tradefed.targetprep.TargetSetupError;
11 import java.io.File;
12 import java.nio.file.Files;
13 import java.nio.file.Path;
14 import java.nio.file.Paths;
15 import java.io.IOException;
16 import java.io.BufferedReader;
17 import java.io.InputStreamReader;
18 import java.io.InputStream;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.concurrent.TimeoutException;
22 import java.util.concurrent.TimeUnit;
23 import com.android.tradefed.result.ITestInvocationListener;
24 import com.android.tradefed.testtype.IRemoteTest;
25 import java.net.URISyntaxException;
26 import com.android.tradefed.device.ITestDevice;
27 import java.util.Map;
28 import java.util.HashMap;
29 import java.util.Collections;
30 
31 @OptionClass(alias = "aaos-moped-test")
32 public class MopedRunner implements IRemoteTest {
33     @Option(name = "test-artifact", description = "test artifact")
34     private File test_artifact = null;
35 
36     @Option(name = "artifact", description = "test artifact")
37     private String artifact_str = null;
38 
39     @Option(name = "unzip-build-timeout-min", description = "unzip build timeout in minutes")
40     private int unzip_build_timeout_min = 10;
41 
42     @Option(name = "test-timeout-min", description = "test timeout in minutes")
43     private int test_timeout_min = 60;
44 
45     @Option(name = "testcase", description = "which moped test binary to run")
46     private String test_case = null;
47 
48     private File mLocalDestFile;
49     private File mLocalSrcFile;
50     private String mArtifactLocation;
51 
52     private static final Map<String, String> autoDic = initDeviceMap();
53 
unTarTestArtifact(TestInformation testInfo)54     private void unTarTestArtifact(TestInformation testInfo) throws TargetSetupError, TimeoutException, URISyntaxException {
55         if (test_artifact != null && artifact_str == null) {
56             artifact_str = test_artifact.toPath().toString();
57         }
58         String jarPath = getClass()
59           .getProtectionDomain()
60           .getCodeSource()
61           .getLocation()
62           .toURI()
63           .getPath();
64         File jarFile = new File(jarPath);
65         mLocalSrcFile = new File(jarFile.getParent() + "/../testcases/" + artifact_str);
66         mLocalDestFile = new File(testInfo.dependenciesFolder().toString());
67         mArtifactLocation =
68                 mLocalDestFile.getPath()
69                         + "/"
70                         + mLocalSrcFile.getName().replaceAll(".tar.*gz", "/");
71         Path localArtifactPath = Paths.get(mArtifactLocation);
72         if (!Files.exists(localArtifactPath)) {
73             // untar file
74             executeHostCommand(
75                     new String[] {
76                         "bash",
77                         "-c",
78                         "tar xf " + mLocalSrcFile.getPath() + " -C " + mLocalDestFile.getPath()
79                     },
80                     unzip_build_timeout_min);
81         }
82     }
83 
initDeviceMap()84     private static Map<String, String> initDeviceMap() {
85       Map<String, String> map = new HashMap<>();
86       map.put("seahawk", "AUTO");
87       map.put("seahawk_hwasan", "AUTO");
88       map.put("cf_x86_auto", "AUTO");
89       return Collections.unmodifiableMap(map);
90     }
91 
checkDevice(ITestDevice device)92     private String checkDevice(ITestDevice device) throws DeviceNotAvailableException {
93       String buildFlavor = device.getBuildFlavor().split("-")[0];
94       return autoDic.get(buildFlavor);
95     }
96 
getDevicesString(TestInformation testInfo)97     private String getDevicesString(TestInformation testInfo) throws DeviceNotAvailableException {
98       StringBuilder deviceString = new StringBuilder();
99       int deviceNum = 0;
100       int companionDeviceNum = 0;
101       for(ITestDevice device : testInfo.getDevices()) {
102         String deviceType = checkDevice(device);
103         if (deviceType.equals("AUTO")) {
104           deviceString.append(String.format(" --hu %s", device.getSerialNumber()));
105         } else {
106           companionDeviceNum++;
107           deviceString.append(String.format(" --phone%s %s", String.valueOf(companionDeviceNum), device.getSerialNumber()));
108         }
109         deviceNum++;
110       }
111       deviceString.append(String.format(" --devicenum %s", String.valueOf(deviceNum)));
112       return deviceString.toString();
113     }
114 
115     @Override
run(TestInformation testInfo, ITestInvocationListener listener)116     public void run(TestInformation testInfo, ITestInvocationListener listener)
117             throws DeviceNotAvailableException {
118         // Download Moped binanry / config and run test
119         try {
120             unTarTestArtifact(testInfo);
121             executeHostCommand(
122                     new String[] {"bash", "-c", "bash " +
123                                           String.format("%s/run.sh %s --testcase %s", mArtifactLocation,
124                                           getDevicesString(testInfo),
125                                           test_case)},
126                                           test_timeout_min);
127         } catch (TargetSetupError e) {
128             CLog.logAndDisplay(LogLevel.VERBOSE, "There are problems running tests! %s", e);
129         } catch (TimeoutException e) {
130             CLog.logAndDisplay(LogLevel.VERBOSE, "Test execution timeout! %s", e);
131         } catch (URISyntaxException e) {
132             CLog.logAndDisplay(LogLevel.VERBOSE, "Test artifact not found! %s", e);
133         }
134     }
135 
executeHostCommand(String[] command, int timeout)136     private ArrayList<String> executeHostCommand(String[] command, int timeout)
137             throws TargetSetupError, TimeoutException {
138         ArrayList<String> ret = new ArrayList<String>();
139         try {
140             CLog.logAndDisplay(
141                     LogLevel.VERBOSE, "Output of running %s is:", Arrays.toString(command));
142             Process p = Runtime.getRuntime().exec(command);
143             if (!p.waitFor(timeout, TimeUnit.MINUTES)) {
144                 p.destroy();
145                 throw new TimeoutException();
146             }
147             InputStream is = p.getInputStream();
148             InputStreamReader isr = new InputStreamReader(is);
149             BufferedReader br = new BufferedReader(isr);
150             String line;
151             while ((line = br.readLine()) != null) {
152                 CLog.logAndDisplay(LogLevel.VERBOSE, line);
153                 ret.add(line);
154             }
155             int exitCode = p.waitFor();
156             if (exitCode != 0) {
157                 throw new TargetSetupError(
158                         "Execution of command " + Arrays.toString(command) + " failed!");
159             }
160         } catch (IOException e) {
161             CLog.logAndDisplay(LogLevel.VERBOSE, "There are problems with IO! %s", e);
162         } catch (InterruptedException e) {
163             CLog.logAndDisplay(LogLevel.VERBOSE, "User interruption!");
164         }
165         return ret;
166     }
167 }
168 
169