1 /*
2  * Copyright (C) 2016 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 
17 package com.android.monkey;
18 
19 import com.android.tradefed.config.Option;
20 import com.android.tradefed.device.DeviceNotAvailableException;
21 import com.android.tradefed.device.ITestDevice;
22 import com.android.tradefed.invoker.TestInformation;
23 import com.android.tradefed.log.LogUtil.CLog;
24 import com.android.tradefed.result.ITestInvocationListener;
25 import com.android.tradefed.util.clockwork.ClockworkUtils;
26 
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.concurrent.Executors;
30 import java.util.concurrent.ScheduledExecutorService;
31 import java.util.concurrent.TimeUnit;
32 
33 /** Runner for paired stress tests which use the monkey command. */
34 public class MonkeyPairedBase extends MonkeyBase {
35 
36     @Option(
37             name = "companion-recurring-command",
38             description = "recurring shell command " + "on companion")
39     private String mCompanionRecurringCommand = null;
40 
41     @Option(
42             name = "companion-recurring-interval",
43             description = "interval between recurring " + "command in seconds")
44     private int mCompanionRecurringInterval = 25;
45 
46     private ITestDevice mCompanion;
47     private List<ITestDevice> mDeviceList = new ArrayList<>();
48     private ScheduledExecutorService mScheduler;
49 
50     /**
51      * Fetches the companion device allocated for the primary device
52      *
53      * @return the allocated companion device
54      * @throws RuntimeException if no companion device has been allocated
55      */
getCompanion()56     protected ITestDevice getCompanion() {
57         return mCompanion;
58     }
59 
60     /** {@inheritDoc} */
61     @Override
run(TestInformation testInfo, ITestInvocationListener listener)62     public void run(TestInformation testInfo, ITestInvocationListener listener)
63             throws DeviceNotAvailableException {
64         ClockworkUtils cwUtils = new ClockworkUtils();
65         mCompanion =
66                 cwUtils.setUpMultiDevice(testInfo.getContext().getDeviceBuildMap(), mDeviceList);
67         if (mCompanionRecurringCommand != null) {
68             scheduleRecurringCommand();
69         }
70         try {
71             super.run(testInfo, listener);
72         } finally {
73             stopRecurringCommand();
74         }
75     }
76 
scheduleRecurringCommand()77     protected void scheduleRecurringCommand() {
78         mScheduler = Executors.newScheduledThreadPool(1);
79         mScheduler.scheduleAtFixedRate(
80                 new Runnable() {
81                     @Override
82                     public void run() {
83                         try {
84                             getCompanion().executeShellCommand(mCompanionRecurringCommand);
85                         } catch (DeviceNotAvailableException e) {
86                             CLog.e(
87                                     "Recurring command failed on %s (%s)",
88                                     getCompanion().getSerialNumber(), mCompanionRecurringCommand);
89                         }
90                     }
91                 },
92                 mCompanionRecurringInterval,
93                 mCompanionRecurringInterval,
94                 TimeUnit.SECONDS);
95     }
96 
stopRecurringCommand()97     protected void stopRecurringCommand() {
98         mScheduler.shutdownNow();
99         try {
100             mScheduler.awaitTermination(mCompanionRecurringInterval, TimeUnit.SECONDS);
101         } catch (InterruptedException e) {
102             CLog.e(
103                     "Could not terminate recurring command on %s (%s)",
104                     getCompanion().getSerialNumber(), mCompanionRecurringCommand);
105         }
106     }
107 }
108