Skip to content

Commit 84e381b

Browse files
DeviceInfracopybara-github
authored andcommitted
Internal change
PiperOrigin-RevId: 710853691
1 parent dd70ac6 commit 84e381b

File tree

10 files changed

+400
-2
lines changed

10 files changed

+400
-2
lines changed

src/devtools/mobileharness/infra/ats/console/result/proto/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ java_proto_library(
5050
"//src/java/com/google/devtools/mobileharness/infra/ats/console/controller/sessionplugin:__pkg__",
5151
"//src/java/com/google/devtools/mobileharness/infra/ats/console/result:__subpackages__",
5252
"//src/java/com/google/devtools/mobileharness/infra/ats/console/util/result:__pkg__",
53+
"//src/java/com/google/devtools/mobileharness/infra/ats/console/util/verifier:__subpackages__",
5354
"//src/java/com/google/devtools/mobileharness/infra/ats/server:__subpackages__",
5455
"//src/java/com/google/devtools/mobileharness/platform/android/xts/suite:__subpackages__",
5556
"//src/javatests/com/google/devtools/mobileharness/infra/ats/console/controller/sessionplugin:__subpackages__",
5657
"//src/javatests/com/google/devtools/mobileharness/infra/ats/console/result:__subpackages__",
58+
"//src/javatests/com/google/devtools/mobileharness/infra/ats/console/util/verifier:__pkg__",
5759
"//src/javatests/com/google/devtools/mobileharness/infra/ats/server:__subpackages__",
5860
"//src/javatests/com/google/devtools/mobileharness/platform/android/xts/suite:__subpackages__",
5961
],

src/java/com/google/devtools/mobileharness/infra/ats/console/controller/sessionplugin/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ java_library(
176176
"//src/java/com/google/devtools/mobileharness/infra/ats/common:session_result_handler_util",
177177
"//src/java/com/google/devtools/mobileharness/infra/ats/common/jobcreator:xts_job_creator",
178178
"//src/java/com/google/devtools/mobileharness/infra/ats/console/util/result:result_lister_helper",
179+
"//src/java/com/google/devtools/mobileharness/infra/ats/console/util/verifier:verifier_result_helper",
179180
"//src/java/com/google/devtools/mobileharness/infra/client/longrunningservice/constant:session_properties",
180181
"//src/java/com/google/devtools/mobileharness/infra/client/longrunningservice/model:session_info",
181182
"//src/java/com/google/devtools/mobileharness/platform/android/xts/common/util:xts_constants",
@@ -188,6 +189,7 @@ java_library(
188189
"//src/java/com/google/devtools/mobileharness/shared/util/file/local",
189190
"//src/java/com/google/devtools/mobileharness/shared/util/flags",
190191
"//src/java/com/google/devtools/mobileharness/shared/util/logging:google_logger",
192+
"//src/java/com/google/wireless/qa/mobileharness/shared/constant:property",
191193
"//src/java/com/google/wireless/qa/mobileharness/shared/model/job",
192194
"@maven//:com_google_code_findbugs_jsr305",
193195
"@maven//:com_google_guava_guava",

src/java/com/google/devtools/mobileharness/infra/ats/console/controller/sessionplugin/RunCommandHandler.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
package com.google.devtools.mobileharness.infra.ats.console.controller.sessionplugin;
1818

1919
import static com.google.common.base.Ascii.toUpperCase;
20+
import static com.google.common.collect.ImmutableSet.toImmutableSet;
2021
import static com.google.devtools.mobileharness.shared.constant.LogRecordImportance.IMPORTANCE;
2122
import static com.google.devtools.mobileharness.shared.constant.LogRecordImportance.Importance.IMPORTANT;
2223
import static com.google.devtools.mobileharness.shared.util.base.ProtoTextFormat.shortDebugString;
24+
import static java.util.Arrays.stream;
2325

2426
import com.google.common.annotations.VisibleForTesting;
2527
import com.google.common.collect.ImmutableList;
2628
import com.google.common.collect.ImmutableMap;
29+
import com.google.common.collect.ImmutableSet;
2730
import com.google.common.flogger.FluentLogger;
2831
import com.google.devtools.mobileharness.api.model.error.MobileHarnessException;
2932
import com.google.devtools.mobileharness.infra.ats.common.SessionRequestHandlerUtil;
@@ -38,6 +41,7 @@
3841
import com.google.devtools.mobileharness.infra.ats.console.controller.proto.SessionPluginProto.RunCommandState;
3942
import com.google.devtools.mobileharness.infra.ats.console.result.proto.ReportProto.Result;
4043
import com.google.devtools.mobileharness.infra.ats.console.util.result.ResultListerHelper;
44+
import com.google.devtools.mobileharness.infra.ats.console.util.verifier.VerifierResultHelper;
4145
import com.google.devtools.mobileharness.infra.client.longrunningservice.constant.SessionProperties;
4246
import com.google.devtools.mobileharness.infra.client.longrunningservice.model.SessionInfo;
4347
import com.google.devtools.mobileharness.platform.android.xts.common.util.XtsConstants;
@@ -47,13 +51,15 @@
4751
import com.google.devtools.mobileharness.platform.android.xts.suite.retry.RetryType;
4852
import com.google.devtools.mobileharness.shared.util.file.local.LocalFileUtil;
4953
import com.google.devtools.mobileharness.shared.util.flags.Flags;
54+
import com.google.wireless.qa.mobileharness.shared.constant.PropertyName.Test;
5055
import com.google.wireless.qa.mobileharness.shared.model.job.JobInfo;
5156
import java.io.File;
5257
import java.nio.file.Path;
5358
import java.time.Instant;
5459
import java.time.ZoneId;
5560
import java.time.format.DateTimeFormatter;
5661
import java.util.List;
62+
import java.util.Optional;
5763
import java.util.OptionalInt;
5864
import java.util.concurrent.ThreadLocalRandom;
5965
import javax.annotation.Nullable;
@@ -76,6 +82,7 @@ class RunCommandHandler {
7682
private final XtsJobCreator xtsJobCreator;
7783
private final PreviousResultLoader previousResultLoader;
7884
private final ResultListerHelper resultListerHelper;
85+
private final VerifierResultHelper verifierResultHelper;
7986

8087
/** Set in {@link #initialize}. */
8188
private volatile boolean initialized;
@@ -92,7 +99,8 @@ class RunCommandHandler {
9299
SuiteResultReporter suiteResultReporter,
93100
XtsJobCreator xtsJobCreator,
94101
PreviousResultLoader previousResultLoader,
95-
ResultListerHelper resultListerHelper) {
102+
ResultListerHelper resultListerHelper,
103+
VerifierResultHelper verifierResultHelper) {
96104
this.localFileUtil = localFileUtil;
97105
this.sessionRequestHandlerUtil = sessionRequestHandlerUtil;
98106
this.sessionResultHandlerUtil = sessionResultHandlerUtil;
@@ -101,6 +109,7 @@ class RunCommandHandler {
101109
this.xtsJobCreator = xtsJobCreator;
102110
this.previousResultLoader = previousResultLoader;
103111
this.resultListerHelper = resultListerHelper;
112+
this.verifierResultHelper = verifierResultHelper;
104113
}
105114

106115
void initialize(RunCommand command) throws MobileHarnessException, InterruptedException {
@@ -231,6 +240,20 @@ void handleResultProcessing(RunCommand command, RunCommandState runCommandState)
231240
}
232241
}
233242
}
243+
if (Flags.instance().enableCtsVerifierResultReporter.getNonNull() && result != null) {
244+
ImmutableSet<String> serials =
245+
allJobs.stream()
246+
.flatMap(jobInfo -> jobInfo.tests().getAll().values().stream())
247+
.map(testInfo -> testInfo.properties().getOptional(Test.DEVICE_ID_LIST))
248+
.filter(Optional::isPresent)
249+
.flatMap(ids -> stream(ids.get().split(",")))
250+
.collect(toImmutableSet());
251+
logger
252+
.atInfo()
253+
.with(IMPORTANCE, IMPORTANT)
254+
.log("Push cts-v-interactive results to %s", serials);
255+
verifierResultHelper.broadcastResults(result, serials);
256+
}
234257
} finally {
235258
sessionResultHandlerUtil.cleanUpJobGenDirs(allJobs);
236259

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
load("@rules_java//java:defs.bzl", "java_library")
17+
18+
package(default_applicable_licenses = ["//:license"])
19+
20+
java_library(
21+
name = "verifier_result_helper",
22+
srcs = ["VerifierResultHelper.java"],
23+
visibility = [
24+
"//src/java/com/google/devtools/mobileharness/infra/ats/console/controller/sessionplugin:__pkg__",
25+
"//src/javatests/com/google/devtools/mobileharness/infra/ats/console/controller/sessionplugin:__pkg__",
26+
"//src/javatests/com/google/devtools/mobileharness/infra/ats/console/util/verifier:__pkg__",
27+
],
28+
deps = [
29+
"//src/devtools/mobileharness/infra/ats/console/result/proto:report_java_proto",
30+
"//src/java/com/google/devtools/deviceinfra/platform/android/lightning/internal/sdk/adb",
31+
"//src/java/com/google/devtools/mobileharness/api/model/error",
32+
"//src/java/com/google/devtools/mobileharness/shared/util/auto:auto_value",
33+
"//src/java/com/google/devtools/mobileharness/shared/util/logging:google_logger",
34+
"@maven//:com_google_code_gson_gson",
35+
"@maven//:com_google_guava_guava",
36+
"@maven//:javax_inject_jsr330_api",
37+
],
38+
)
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* Copyright 2022 Google LLC
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+
* https://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+
17+
package com.google.devtools.mobileharness.infra.ats.console.util.verifier;
18+
19+
import com.google.auto.value.AutoValue;
20+
import com.google.common.annotations.VisibleForTesting;
21+
import com.google.common.collect.ImmutableMap;
22+
import com.google.common.flogger.FluentLogger;
23+
import com.google.devtools.deviceinfra.platform.android.lightning.internal.sdk.adb.Adb;
24+
import com.google.devtools.mobileharness.api.model.error.MobileHarnessException;
25+
import com.google.devtools.mobileharness.infra.ats.console.result.proto.ReportProto.Module;
26+
import com.google.devtools.mobileharness.infra.ats.console.result.proto.ReportProto.Result;
27+
import com.google.devtools.mobileharness.infra.ats.console.result.proto.ReportProto.Test;
28+
import com.google.devtools.mobileharness.infra.ats.console.result.proto.ReportProto.TestCase;
29+
import com.google.gson.Gson;
30+
import java.util.Collection;
31+
import javax.inject.Inject;
32+
33+
/** Helper class to broadcast results to CTS-V * */
34+
public class VerifierResultHelper {
35+
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
36+
37+
private static final String BROADCAST_TEST_RESULT_PASS = "PASS";
38+
private static final String BROADCAST_TEST_RESULT_FAIL = "FAIL";
39+
private static final String FAIL_RESULT = "fail";
40+
41+
private static final int MAX_DETAIL_LENGTH = 100;
42+
43+
@VisibleForTesting
44+
static final String START_INTERACTIVE_ACTIVITY_COMMAND =
45+
"am start com.android.cts.verifier/.InteractiveTestsActivity --activity-brought-to-front";
46+
47+
@VisibleForTesting
48+
static final String BROADCAST_COMMAND =
49+
"am broadcast -a com.android.cts.verifier.ACTION_HOST_TEST_RESULT --es"
50+
+ " com.android.cts.verifier.extra.HOST_TEST_RESULT ";
51+
52+
private final Adb adb;
53+
54+
@Inject
55+
VerifierResultHelper(Adb adb) {
56+
this.adb = adb;
57+
}
58+
59+
public void broadcastResults(Result result, Collection<String> serials)
60+
throws InterruptedException {
61+
startInteractiveActivity(serials);
62+
Gson gson = new Gson();
63+
for (Module module : result.getModuleInfoList()) {
64+
ImmutableMap.Builder<String, VerifierResult> testCases = new ImmutableMap.Builder<>();
65+
for (TestCase testCase : module.getTestCaseList()) {
66+
ImmutableMap.Builder<String, VerifierResult> tests = new ImmutableMap.Builder<>();
67+
for (Test test : testCase.getTestList()) {
68+
if (test.getResult().isEmpty()) {
69+
continue;
70+
}
71+
tests.put(
72+
test.getName(),
73+
VerifierResult.of(
74+
getTestResult(test),
75+
test.hasFailure() ? getShortDetails(test.getFailure().getMsg()) : "",
76+
ImmutableMap.of()));
77+
}
78+
testCases.put(testCase.getName(), VerifierResult.of("", "", tests.buildOrThrow()));
79+
}
80+
ImmutableMap<String, VerifierResult> modules =
81+
ImmutableMap.of(
82+
module.getName(),
83+
VerifierResult.of(
84+
getModuleResult(module),
85+
module.hasReason() ? getShortDetails(module.getReason().getMsg()) : "",
86+
testCases.buildOrThrow()));
87+
broadcastResult(serials, gson.toJson(modules));
88+
}
89+
}
90+
91+
private void startInteractiveActivity(Collection<String> serials) throws InterruptedException {
92+
for (String serial : serials) {
93+
try {
94+
var unused = adb.runShell(serial, START_INTERACTIVE_ACTIVITY_COMMAND);
95+
} catch (MobileHarnessException e) {
96+
logger.atInfo().withCause(e).log("Unable to start interactive activity on %s", serial);
97+
}
98+
}
99+
}
100+
101+
private void broadcastResult(Collection<String> serials, String msg) throws InterruptedException {
102+
logger.atInfo().log("Broadcast result size: %d", msg.length());
103+
for (String serial : serials) {
104+
try {
105+
var unused = adb.runShell(serial, BROADCAST_COMMAND + String.format("'%s'", msg));
106+
} catch (MobileHarnessException e) {
107+
logger.atInfo().withCause(e).log("Unable to broadcast results to %s", serial);
108+
}
109+
}
110+
}
111+
112+
private String getShortDetails(String details) {
113+
if (details.length() <= MAX_DETAIL_LENGTH) {
114+
return details;
115+
}
116+
return details.substring(0, MAX_DETAIL_LENGTH) + "...";
117+
}
118+
119+
private String getModuleResult(Module module) {
120+
return module.getDone() && module.getFailedTests() == 0
121+
? BROADCAST_TEST_RESULT_PASS
122+
: BROADCAST_TEST_RESULT_FAIL;
123+
}
124+
125+
private String getTestResult(Test test) {
126+
// IGNORE and ASSUMPTION_FAILURE are regarded as pass
127+
return test.getResult().equals(FAIL_RESULT)
128+
? BROADCAST_TEST_RESULT_FAIL
129+
: BROADCAST_TEST_RESULT_PASS;
130+
}
131+
132+
/** Represents a CTS-V result. */
133+
@AutoValue
134+
public abstract static class VerifierResult {
135+
public abstract String result();
136+
137+
public abstract String details();
138+
139+
public abstract ImmutableMap<String, VerifierResult> subtests();
140+
141+
public static VerifierResult of(
142+
String result, String details, ImmutableMap<String, VerifierResult> subtests) {
143+
return new AutoValue_VerifierResultHelper_VerifierResult(result, details, subtests);
144+
}
145+
}
146+
}

src/java/com/google/devtools/mobileharness/shared/util/flags/Flags.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,14 @@ public class Flags {
761761
converter = Flag.BooleanConverter.class)
762762
public Flag<Boolean> enableCloudFileTransfer = enableCloudFileTransferDefault;
763763

764+
private static final Flag<Boolean> enableCtsVerifierResultReporterDefault = Flag.value(false);
765+
766+
@com.beust.jcommander.Parameter(
767+
names = "--enable_cts_verifier_result_reporter",
768+
description = "Whether enable result reporter for cts verifier.",
769+
converter = Flag.BooleanConverter.class)
770+
public Flag<Boolean> enableCtsVerifierResultReporter = enableCtsVerifierResultReporterDefault;
771+
764772
private static final Flag<Boolean> enableDebugModeDefault = Flag.value(false);
765773

766774
@com.beust.jcommander.Parameter(

src/javatests/com/google/devtools/mobileharness/infra/ats/console/controller/sessionplugin/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ java_library(
5151
"//src/java/com/google/devtools/mobileharness/infra/ats/console/result/report:compatibility_report_merger",
5252
"//src/java/com/google/devtools/mobileharness/infra/ats/console/result/report:compatibility_report_parser",
5353
"//src/java/com/google/devtools/mobileharness/infra/ats/console/util/result:result_lister_helper",
54+
"//src/java/com/google/devtools/mobileharness/infra/ats/console/util/verifier:verifier_result_helper",
5455
"//src/java/com/google/devtools/mobileharness/infra/client/api/controller/device:querier",
5556
"//src/java/com/google/devtools/mobileharness/infra/client/longrunningservice:annotations",
5657
"//src/java/com/google/devtools/mobileharness/infra/client/longrunningservice/model:session_info",

src/javatests/com/google/devtools/mobileharness/infra/ats/console/controller/sessionplugin/RunCommandHandlerTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import com.google.devtools.mobileharness.infra.ats.console.result.report.CompatibilityReportMerger;
4343
import com.google.devtools.mobileharness.infra.ats.console.result.report.CompatibilityReportParser;
4444
import com.google.devtools.mobileharness.infra.ats.console.util.result.ResultListerHelper;
45+
import com.google.devtools.mobileharness.infra.ats.console.util.verifier.VerifierResultHelper;
4546
import com.google.devtools.mobileharness.infra.client.api.controller.device.DeviceQuerier;
4647
import com.google.devtools.mobileharness.infra.client.longrunningservice.Annotations.SessionGenDir;
4748
import com.google.devtools.mobileharness.infra.client.longrunningservice.Annotations.SessionTempDir;
@@ -113,6 +114,7 @@ public final class RunCommandHandlerTest {
113114
@Bind @Mock private XtsJobCreator xtsJobCreator;
114115
@Bind @Mock private PreviousResultLoader previousResultLoader;
115116
@Bind @Mock private ResultListerHelper resultListerHelper;
117+
@Bind @Mock private VerifierResultHelper verifierResultHelper;
116118

117119
private RunCommandHandler runCommandHandler;
118120
@Inject private SessionRequestHandlerUtil sessionRequestHandlerUtil;
@@ -152,7 +154,8 @@ public void setUp() throws Exception {
152154
suiteResultReporter,
153155
xtsJobCreator,
154156
previousResultLoader,
155-
resultListerHelper);
157+
resultListerHelper,
158+
verifierResultHelper);
156159
}
157160

158161
@Test

0 commit comments

Comments
 (0)