• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.suite;
17 
18 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
19 import com.android.tradefed.result.FailureDescription;
20 import com.android.tradefed.result.ITestInvocationListener;
21 import com.android.tradefed.result.proto.TestRecordProto.FailureStatus;
22 import com.android.tradefed.testtype.IRemoteTest;
23 
24 import java.time.Duration;
25 import java.util.HashMap;
26 import java.util.concurrent.TimeUnit;
27 
28 /**
29  * Listeners that allows to check the execution time of a given test config and fail it if it goes
30  * over a given timeout.
31  *
32  * <p>Note that this enforcer doesn't interrupt the tests, but will make them fail.
33  */
34 public class RemoteTestTimeOutEnforcer implements ITestInvocationListener {
35 
36     // The option name & description we want to share across class that uses the enforcer.
37     public static final String REMOTE_TEST_TIMEOUT_OPTION = "remote-test-timeout";
38     public static final String REMOTE_TEST_TIMEOUT_DESCRIPTION =
39             "The timeout that will be applied to each remote test object of the run.";
40 
41     private IRemoteTest mIRemoteTest;
42     private Duration mTimeOut;
43     private ModuleDefinition mModuleDefinition;
44     private ModuleListener mListener;
45 
46     /**
47      * Create the {@link RemoteTestTimeOutEnforcer} with the given timeout to enforce.
48      *
49      * @param listener The {@link ModuleListener} for each test run.
50      * @param moduleDefinition The {@link ModuleDefinition} of the test module to be executed.
51      * @param test The {@link IRemoteTest} to be executed.
52      * @param timeOut The {@link Duration} of the time out per test run.
53      */
RemoteTestTimeOutEnforcer( ModuleListener listener, ModuleDefinition moduleDefinition, IRemoteTest test, Duration timeOut)54     public RemoteTestTimeOutEnforcer(
55             ModuleListener listener,
56             ModuleDefinition moduleDefinition,
57             IRemoteTest test,
58             Duration timeOut) {
59         mListener = listener;
60         mIRemoteTest = test;
61         mModuleDefinition = moduleDefinition;
62         mTimeOut = timeOut;
63     }
64 
65     @Override
testRunEnded(long elapsedTime, HashMap<String, Metric> runMetrics)66     public void testRunEnded(long elapsedTime, HashMap<String, Metric> runMetrics) {
67         if (elapsedTime >= mTimeOut.toMillis()) {
68             String failureString = String.format(
69                     "%s defined in %s took %s seconds while timeout is %s seconds",
70                     mModuleDefinition.getId(),
71                     mModuleDefinition.getModuleInvocationContext().getConfigurationDescriptor().
72                             getMetaData(Integer.toString(mIRemoteTest.hashCode())),
73                     TimeUnit.MILLISECONDS.toSeconds(elapsedTime),
74                     mTimeOut.toSeconds());
75             if (!mListener.hasLastAttemptFailed()) {
76                 FailureDescription failure = FailureDescription.create(
77                         failureString, FailureStatus.TIMED_OUT).setRetriable(false);
78                 mListener.testRunFailed(failure);
79             }
80         }
81     }
82 }
83