blob: 333040bad51e36fb28c039d5da8fb1fab5937dec [file] [log] [blame]
Ang Li93420002016-05-10 19:11:44 -07001#!/usr/bin/env python3.4
2#
3# Copyright 2016 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17from builtins import str
18from builtins import open
19
Ang Li7f0e1c72016-06-14 11:23:49 -070020import logging
Ang Li93420002016-05-10 19:11:44 -070021import os
22import time
23import traceback
Sahil Jain06dd6a22016-06-24 13:47:37 -070024import threading
25import socket
26import Queue
Ang Li93420002016-05-10 19:11:44 -070027
28from vts.runners.host import logger as vts_logger
29from vts.runners.host import signals
30from vts.runners.host import utils
Ang Li7f0e1c72016-06-14 11:23:49 -070031from vts.utils.python.controllers import adb
32from vts.utils.python.controllers import event_dispatcher
33from vts.utils.python.controllers import fastboot
Sahil Jain06dd6a22016-06-24 13:47:37 -070034from vts.runners.host.tcp_client import vts_tcp_client
Ang Li7f0e1c72016-06-14 11:23:49 -070035from vts.utils.python.mirror import hal_mirror
Sahil Jain06dd6a22016-06-24 13:47:37 -070036from vts.runners.host import errors
37import subprocess
Ang Li93420002016-05-10 19:11:44 -070038
39VTS_CONTROLLER_CONFIG_NAME = "AndroidDevice"
40VTS_CONTROLLER_REFERENCE_NAME = "android_devices"
41
42ANDROID_DEVICE_PICK_ALL_TOKEN = "*"
43# Key name for adb logcat extra params in config file.
44ANDROID_DEVICE_ADB_LOGCAT_PARAM_KEY = "adb_logcat_param"
45ANDROID_DEVICE_EMPTY_CONFIG_MSG = "Configuration is empty, abort!"
46ANDROID_DEVICE_NOT_LIST_CONFIG_MSG = "Configuration should be a list, abort!"
47
Sahil Jain06dd6a22016-06-24 13:47:37 -070048# Target-side directory where the VTS binaries are uploaded
49DEFAULT_AGENT_BASE_DIR = "/data/local/tmp"
50# Time for which the current is put on sleep when the client is unable to
51# make a connection.
52THREAD_SLEEP_TIME = 1
53# Max number of attempts that the client can make to connect to the agent
54MAX_AGENT_CONNECT_RETRIES = 10
55
Ang Lie2139f12016-05-12 17:39:06 -070056
Ang Li93420002016-05-10 19:11:44 -070057class AndroidDeviceError(signals.ControllerError):
58 pass
59
Ang Lie2139f12016-05-12 17:39:06 -070060
Ang Li7f0e1c72016-06-14 11:23:49 -070061def create(configs):
Ang Li93420002016-05-10 19:11:44 -070062 if not configs:
63 raise AndroidDeviceError(ANDROID_DEVICE_EMPTY_CONFIG_MSG)
64 elif configs == ANDROID_DEVICE_PICK_ALL_TOKEN:
Ang Li7f0e1c72016-06-14 11:23:49 -070065 ads = get_all_instances()
Ang Li93420002016-05-10 19:11:44 -070066 elif not isinstance(configs, list):
67 raise AndroidDeviceError(ANDROID_DEVICE_NOT_LIST_CONFIG_MSG)
68 elif isinstance(configs[0], str):
69 # Configs is a list of serials.
Ang Li7f0e1c72016-06-14 11:23:49 -070070 ads = get_instances(configs)
Ang Li93420002016-05-10 19:11:44 -070071 else:
72 # Configs is a list of dicts.
Ang Li7f0e1c72016-06-14 11:23:49 -070073 ads = get_instances_with_configs(configs)
Ang Li93420002016-05-10 19:11:44 -070074 connected_ads = list_adb_devices()
75 for ad in ads:
76 if ad.serial not in connected_ads:
Ang Lie2139f12016-05-12 17:39:06 -070077 raise AndroidDeviceError(
78 ("Android device %s is specified in config"
79 " but is not attached.") % ad.serial)
Ang Li93420002016-05-10 19:11:44 -070080 ad.startAdbLogcat()
Ang Li93420002016-05-10 19:11:44 -070081 return ads
82
Ang Lie2139f12016-05-12 17:39:06 -070083
Ang Li93420002016-05-10 19:11:44 -070084def destroy(ads):
85 for ad in ads:
86 try:
87 ad.closeAllSl4aSession()
88 except:
89 pass
90 if ad.adb_logcat_process:
91 ad.stopAdbLogcat()
92
Ang Lie2139f12016-05-12 17:39:06 -070093
Ang Li93420002016-05-10 19:11:44 -070094def _parse_device_list(device_list_str, key):
95 """Parses a byte string representing a list of devices. The string is
96 generated by calling either adb or fastboot.
97
98 Args:
99 device_list_str: Output of adb or fastboot.
100 key: The token that signifies a device in device_list_str.
101
102 Returns:
103 A list of android device serial numbers.
104 """
105 clean_lines = str(device_list_str, 'utf-8').strip().split('\n')
106 results = []
107 for line in clean_lines:
108 tokens = line.strip().split('\t')
109 if len(tokens) == 2 and tokens[1] == key:
110 results.append(tokens[0])
111 return results
112
Ang Lie2139f12016-05-12 17:39:06 -0700113
Ang Li93420002016-05-10 19:11:44 -0700114def list_adb_devices():
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700115 """List all target devices connected to the host and detected by adb.
Ang Li93420002016-05-10 19:11:44 -0700116
117 Returns:
118 A list of android device serials. Empty if there's none.
119 """
120 out = adb.AdbProxy().devices()
121 return _parse_device_list(out, "device")
122
Ang Lie2139f12016-05-12 17:39:06 -0700123
Ang Li93420002016-05-10 19:11:44 -0700124def list_fastboot_devices():
125 """List all android devices connected to the computer that are in in
126 fastboot mode. These are detected by fastboot.
127
128 Returns:
129 A list of android device serials. Empty if there's none.
130 """
131 out = fastboot.FastbootProxy().devices()
132 return _parse_device_list(out, "fastboot")
133
Ang Lie2139f12016-05-12 17:39:06 -0700134
Ang Li7f0e1c72016-06-14 11:23:49 -0700135def get_instances(serials):
Ang Li93420002016-05-10 19:11:44 -0700136 """Create AndroidDevice instances from a list of serials.
137
138 Args:
139 serials: A list of android device serials.
Ang Li93420002016-05-10 19:11:44 -0700140
141 Returns:
142 A list of AndroidDevice objects.
143 """
144 results = []
145 for s in serials:
Ang Li7f0e1c72016-06-14 11:23:49 -0700146 results.append(AndroidDevice(s))
Ang Li93420002016-05-10 19:11:44 -0700147 return results
148
Ang Lie2139f12016-05-12 17:39:06 -0700149
Ang Li7f0e1c72016-06-14 11:23:49 -0700150def get_instances_with_configs(configs):
Ang Li93420002016-05-10 19:11:44 -0700151 """Create AndroidDevice instances from a list of json configs.
152
153 Each config should have the required key-value pair "serial".
154
155 Args:
156 configs: A list of dicts each representing the configuration of one
157 android device.
Ang Li93420002016-05-10 19:11:44 -0700158
159 Returns:
160 A list of AndroidDevice objects.
161 """
162 results = []
163 for c in configs:
164 try:
165 serial = c.pop("serial")
166 except KeyError:
167 raise AndroidDeviceError(('Required value "serial" is missing in '
Ang Lie2139f12016-05-12 17:39:06 -0700168 'AndroidDevice config %s.') % c)
Ang Li7f0e1c72016-06-14 11:23:49 -0700169 ad = AndroidDevice(serial)
Ang Li93420002016-05-10 19:11:44 -0700170 ad.loadConfig(c)
171 results.append(ad)
172 return results
173
Ang Lie2139f12016-05-12 17:39:06 -0700174
Ang Li7f0e1c72016-06-14 11:23:49 -0700175def get_all_instances(include_fastboot=False):
Ang Li93420002016-05-10 19:11:44 -0700176 """Create AndroidDevice instances for all attached android devices.
177
178 Args:
179 include_fastboot: Whether to include devices in bootloader mode or not.
Ang Li93420002016-05-10 19:11:44 -0700180
181 Returns:
182 A list of AndroidDevice objects each representing an android device
183 attached to the computer.
184 """
185 if include_fastboot:
186 serial_list = list_adb_devices() + list_fastboot_devices()
Ang Li7f0e1c72016-06-14 11:23:49 -0700187 return get_instances(serial_list)
188 return get_instances(list_adb_devices())
Ang Li93420002016-05-10 19:11:44 -0700189
Ang Lie2139f12016-05-12 17:39:06 -0700190
Ang Li93420002016-05-10 19:11:44 -0700191def filter_devices(ads, func):
192 """Finds the AndroidDevice instances from a list that match certain
193 conditions.
194
195 Args:
196 ads: A list of AndroidDevice instances.
197 func: A function that takes an AndroidDevice object and returns True
198 if the device satisfies the filter condition.
199
200 Returns:
201 A list of AndroidDevice instances that satisfy the filter condition.
202 """
203 results = []
204 for ad in ads:
205 if func(ad):
206 results.append(ad)
207 return results
208
Ang Lie2139f12016-05-12 17:39:06 -0700209
Ang Li93420002016-05-10 19:11:44 -0700210def get_device(ads, **kwargs):
211 """Finds a unique AndroidDevice instance from a list that has specific
212 attributes of certain values.
213
214 Example:
215 get_device(android_devices, label="foo", phone_number="1234567890")
216 get_device(android_devices, model="angler")
217
218 Args:
219 ads: A list of AndroidDevice instances.
220 kwargs: keyword arguments used to filter AndroidDevice instances.
221
222 Returns:
223 The target AndroidDevice instance.
224
225 Raises:
226 AndroidDeviceError is raised if none or more than one device is
227 matched.
228 """
Ang Lie2139f12016-05-12 17:39:06 -0700229
Ang Li93420002016-05-10 19:11:44 -0700230 def _get_device_filter(ad):
231 for k, v in kwargs.items():
232 if not hasattr(ad, k):
233 return False
234 elif getattr(ad, k) != v:
235 return False
236 return True
Ang Lie2139f12016-05-12 17:39:06 -0700237
Ang Li93420002016-05-10 19:11:44 -0700238 filtered = filter_devices(ads, _get_device_filter)
239 if not filtered:
240 raise AndroidDeviceError(("Could not find a target device that matches"
241 " condition: %s.") % kwargs)
242 elif len(filtered) == 1:
243 return filtered[0]
244 else:
245 serials = [ad.serial for ad in filtered]
246 raise AndroidDeviceError("More than one device matched: %s" % serials)
247
Ang Lie2139f12016-05-12 17:39:06 -0700248
Ang Li93420002016-05-10 19:11:44 -0700249def takeBugReports(ads, test_name, begin_time):
250 """Takes bug reports on a list of android devices.
251
252 If you want to take a bug report, call this function with a list of
253 android_device objects in on_fail. But reports will be taken on all the
254 devices in the list concurrently. Bug report takes a relative long
255 time to take, so use this cautiously.
256
257 Args:
258 ads: A list of AndroidDevice instances.
259 test_name: Name of the test case that triggered this bug report.
260 begin_time: Logline format timestamp taken when the test started.
261 """
262 begin_time = vts_logger.normalizeLogLineTimestamp(begin_time)
Ang Lie2139f12016-05-12 17:39:06 -0700263
Ang Li93420002016-05-10 19:11:44 -0700264 def take_br(test_name, begin_time, ad):
265 ad.takeBugReport(test_name, begin_time)
Ang Lie2139f12016-05-12 17:39:06 -0700266
Ang Li93420002016-05-10 19:11:44 -0700267 args = [(test_name, begin_time, ad) for ad in ads]
268 utils.concurrent_exec(take_br, args)
269
Ang Lie2139f12016-05-12 17:39:06 -0700270
Ang Li7f0e1c72016-06-14 11:23:49 -0700271class AndroidDevice(object):
Ang Li93420002016-05-10 19:11:44 -0700272 """Class representing an android device.
273
274 Each object of this class represents one Android device in ACTS, including
275 handles to adb, fastboot, and sl4a clients. In addition to direct adb
276 commands, this object also uses adb port forwarding to talk to the Android
277 device.
278
279 Attributes:
280 serial: A string that's the serial number of the Androi device.
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700281 device_command_port: int, the port number used on the Android device
282 for adb port forwarding (for command-response sessions).
283 device_callback_port: int, the port number used on the Android device
284 for adb port reverse forwarding (for callback sessions).
Ang Li93420002016-05-10 19:11:44 -0700285 log_path: A string that is the path where all logs collected on this
286 android device should be stored.
287 adb_logcat_process: A process that collects the adb logcat.
288 adb_logcat_file_path: A string that's the full path to the adb logcat
289 file collected, if any.
290 adb: An AdbProxy object used for interacting with the device via adb.
291 fastboot: A FastbootProxy object used for interacting with the device
292 via fastboot.
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700293 host_command_port: the host-side port for runner to agent sessions
294 (to send commands and receive responses).
295 host_callback_port: the host-side port for agent to runner sessions
296 (to get callbacks from agent).
Sahil Jain06dd6a22016-06-24 13:47:37 -0700297 background_thread: a thread that runs in background to upload the
298 agent on the device.
299 queue: an instance of queue.Queue that keeps main thread on wait unless
300 the background_thread indicates it to move.
301 base_dir: target-side directory where the VTS binaries are uploaded.
Ang Li93420002016-05-10 19:11:44 -0700302 """
Sahil Jain06dd6a22016-06-24 13:47:37 -0700303 background_thread = None
304 background_thread_proceed = False
305 base_dir = None
306 queue = Queue.Queue()
Ang Li93420002016-05-10 19:11:44 -0700307
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700308 def __init__(self, serial="", device_port=5001, device_callback_port=5010):
Ang Li93420002016-05-10 19:11:44 -0700309 self.serial = serial
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700310 self.device_command_port = device_port
311 self.device_callback_port = device_callback_port
Ang Li93420002016-05-10 19:11:44 -0700312 self.log = logging.getLogger()
Ang Li7f0e1c72016-06-14 11:23:49 -0700313 base_log_path = getattr(self.log, "log_path", "/tmp/logs/")
314 self.log_path = os.path.join(base_log_path, "AndroidDevice%s" % serial)
Ang Li93420002016-05-10 19:11:44 -0700315 self.adb_logcat_process = None
316 self.adb_logcat_file_path = None
317 self.adb = adb.AdbProxy(serial)
318 self.fastboot = fastboot.FastbootProxy(serial)
319 if not self.isBootloaderMode:
320 self.rootAdb()
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700321 self.host_command_port = adb.get_available_host_port()
322 self.host_callback_port = adb.get_available_host_port()
323 self.adb.tcp_forward(self.host_command_port, self.device_command_port)
324 self.adb.reverse_tcp_forward(
325 self.device_callback_port, self.host_callback_port)
326 self.hal = hal_mirror.HalMirror(
327 self.host_command_port, self.host_callback_port)
Ang Li93420002016-05-10 19:11:44 -0700328
329 def __del__(self):
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700330 if self.host_command_port:
331 self.adb.forward("--remove tcp:%s" % self.host_command_port)
Ang Li93420002016-05-10 19:11:44 -0700332 if self.adb_logcat_process:
333 self.stopAdbLogcat()
334
335 @property
336 def isBootloaderMode(self):
337 """True if the device is in bootloader mode.
338 """
339 return self.serial in list_fastboot_devices()
340
341 @property
342 def isAdbRoot(self):
343 """True if adb is running as root for this device.
344 """
345 return "root" in self.adb.shell("id -u").decode("utf-8")
346
347 @property
348 def model(self):
349 """The Android code name for the device.
350 """
351 # If device is in bootloader mode, get mode name from fastboot.
352 if self.isBootloaderMode:
353 out = self.fastboot.getvar("product").strip()
354 # "out" is never empty because of the "total time" message fastboot
355 # writes to stderr.
356 lines = out.decode("utf-8").split('\n', 1)
357 if lines:
358 tokens = lines[0].split(' ')
359 if len(tokens) > 1:
360 return tokens[1].lower()
361 return None
362 out = self.adb.shell('getprop | grep ro.build.product')
363 model = out.decode("utf-8").strip().split('[')[-1][:-1].lower()
364 if model == "sprout":
365 return model
366 else:
367 out = self.adb.shell('getprop | grep ro.product.name')
368 model = out.decode("utf-8").strip().split('[')[-1][:-1].lower()
369 return model
370
371 @property
Ang Li93420002016-05-10 19:11:44 -0700372 def isAdbLogcatOn(self):
373 """Whether there is an ongoing adb logcat collection.
374 """
375 if self.adb_logcat_process:
376 return True
377 return False
378
379 def loadConfig(self, config):
380 """Add attributes to the AndroidDevice object based on json config.
381
382 Args:
383 config: A dictionary representing the configs.
384
385 Raises:
386 AndroidDeviceError is raised if the config is trying to overwrite
387 an existing attribute.
388 """
389 for k, v in config.items():
390 if hasattr(self, k):
Ang Li7f0e1c72016-06-14 11:23:49 -0700391 raise AndroidDeviceError(
392 "Attempting to set existing attribute %s on %s" %
393 (k, self.serial))
Ang Li93420002016-05-10 19:11:44 -0700394 setattr(self, k, v)
395
396 def rootAdb(self):
397 """Change adb to root mode for this device.
398 """
399 if not self.isAdbRoot:
400 self.adb.root()
401 self.adb.wait_for_device()
402 self.adb.remount()
403 self.adb.wait_for_device()
404
Ang Li93420002016-05-10 19:11:44 -0700405 def startAdbLogcat(self):
406 """Starts a standing adb logcat collection in separate subprocesses and
407 save the logcat in a file.
408 """
409 if self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700410 raise AndroidDeviceError(("Android device %s already has an adb "
Ang Lie2139f12016-05-12 17:39:06 -0700411 "logcat thread going on. Cannot start "
Ang Li7f0e1c72016-06-14 11:23:49 -0700412 "another one.") % self.serial)
Ang Li93420002016-05-10 19:11:44 -0700413 # Disable adb log spam filter.
414 self.adb.shell("logpersist.start")
Ang Li7f0e1c72016-06-14 11:23:49 -0700415 f_name = "adblog,%s,%s.txt" % (self.model, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700416 utils.create_dir(self.log_path)
417 logcat_file_path = os.path.join(self.log_path, f_name)
418 try:
419 extra_params = self.adb_logcat_param
420 except AttributeError:
421 extra_params = "-b all"
Ang Li7f0e1c72016-06-14 11:23:49 -0700422 cmd = "adb -s %s logcat -v threadtime %s >> %s" % (
Ang Li93420002016-05-10 19:11:44 -0700423 self.serial, extra_params, logcat_file_path)
424 self.adb_logcat_process = utils.start_standing_subprocess(cmd)
425 self.adb_logcat_file_path = logcat_file_path
426
427 def stopAdbLogcat(self):
428 """Stops the adb logcat collection subprocess.
429 """
430 if not self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700431 raise AndroidDeviceError(
432 "Android device %s does not have an ongoing adb logcat collection."
433 % self.serial)
Ang Li93420002016-05-10 19:11:44 -0700434 utils.stop_standing_subprocess(self.adb_logcat_process)
435 self.adb_logcat_process = None
436
437 def takeBugReport(self, test_name, begin_time):
438 """Takes a bug report on the device and stores it in a file.
439
440 Args:
441 test_name: Name of the test case that triggered this bug report.
442 begin_time: Logline format timestamp taken when the test started.
443 """
444 br_path = os.path.join(self.log_path, "BugReports")
445 utils.create_dir(br_path)
Ang Li7f0e1c72016-06-14 11:23:49 -0700446 base_name = ",%s,%s.txt" % (begin_time, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700447 test_name_len = utils.MAX_FILENAME_LEN - len(base_name)
448 out_name = test_name[:test_name_len] + base_name
449 full_out_path = os.path.join(br_path, out_name.replace(' ', '\ '))
450 self.log.info("Taking bugreport for %s on %s", test_name, self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700451 self.adb.bugreport(" > %s" % full_out_path)
Ang Li93420002016-05-10 19:11:44 -0700452 self.log.info("Bugreport for %s taken at %s", test_name, full_out_path)
453
Ang Li93420002016-05-10 19:11:44 -0700454 @utils.timeout(15 * 60)
455 def waitForBootCompletion(self):
456 """Waits for Android framework to broadcast ACTION_BOOT_COMPLETED.
457
458 This function times out after 15 minutes.
459 """
460 self.adb.wait_for_device()
461 while True:
462 try:
463 out = self.adb.shell("getprop sys.boot_completed")
464 completed = out.decode('utf-8').strip()
465 if completed == '1':
466 return
467 except adb.AdbError:
468 # adb shell calls may fail during certain period of booting
469 # process, which is normal. Ignoring these errors.
470 pass
471 time.sleep(5)
472
473 def reboot(self):
Ang Li7f0e1c72016-06-14 11:23:49 -0700474 """Reboots the device and wait for device to complete booting.
Ang Li93420002016-05-10 19:11:44 -0700475
476 This is probably going to print some error messages in console. Only
477 use if there's no other option.
478
Ang Li93420002016-05-10 19:11:44 -0700479 Raises:
480 AndroidDeviceError is raised if waiting for completion timed
481 out.
482 """
483 if self.isBootloaderMode:
484 self.fastboot.reboot()
485 return
486 has_adb_log = self.isAdbLogcatOn
487 if has_adb_log:
488 self.stopAdbLogcat()
Ang Li93420002016-05-10 19:11:44 -0700489 self.adb.reboot()
490 self.waitForBootCompletion()
491 self.rootAdb()
Ang Li93420002016-05-10 19:11:44 -0700492 if has_adb_log:
493 self.startAdbLogcat()
Sahil Jain06dd6a22016-06-24 13:47:37 -0700494
495 def startAgent(self):
496 """ To start agent.
497
498 This function starts the target side native agent and is persisted
499 throughout the test run. This process is handled by the VTS runner lib.
500 """
501 # to ensure that only one instance of this agent runs
502 if(self.background_thread is not None):
503 logging.error(
504 "Another instance of background_thread is already "
505 "running.")
506 return
507
508 background_thread = threading.Thread(target=self.runAgent)
509 # Exit the server thread when the main thread terminates
510 background_thread.daemon = True
511 background_thread.start()
512
513 # wait for the flag from child thread
514 self.queue.get(block=True, timeout=None)
515
516 client = vts_tcp_client.VtsTcpClient()
517
518 # Ensure that the connection succeeds before it moves forward.
519 for _ in range(MAX_AGENT_CONNECT_RETRIES):
520 try:
521 time.sleep(THREAD_SLEEP_TIME) # put current thread on sleep
522 response = client.Connect(
523 command_port=self.host_command_port,
524 callback_port=self.host_callback_port)
525
526 if response:
527 return
528 except socket.error as e:
529 pass
530
531 # Throw error if client is unable to make a connection
532 raise errors.VtsTcpClientCreationError(
533 "Couldn't connect to %s:%s" % (
534 vts_tcp_client.TARGET_IP,
535 self.host_command_port))
536
537 def runAgent(self):
538 """This functions runs the child thread that runs the agent."""
539
540 # kill the existing instance of agent in DUT
541 commands = ["killall vts_hal_agent > /dev/null 2&>1",
542 "killall fuzzer32 > /dev/null 2&>1",
543 "killall fuzzer64 > /dev/null 2&>1"]
544
545 for cmd in commands:
546 try:
547 self.adb.shell(cmd)
548 except adb.AdbError as e:
549 logging.info('Exception occurred in command: %s', cmd)
550
551 cmd = '{}{}{} {}{} {}{} {}{} {}{}'.format(
552 'LD_LIBRARY_PATH=',
553 DEFAULT_AGENT_BASE_DIR, "/64",
554 DEFAULT_AGENT_BASE_DIR, "/64/vts_hal_agent",
555 DEFAULT_AGENT_BASE_DIR, "/32/fuzzer32",
556 DEFAULT_AGENT_BASE_DIR, "/64/fuzzer64",
557 DEFAULT_AGENT_BASE_DIR, "/spec")
558
559 self.queue.put('flag')
560 self.adb.shell(cmd)
561
562 # This should never happen.
563 logging.exception("Agent Terminated!")
564
565 def stopAgent(self):
566 """Stop the agent running on target.
567
568 This function stops the target side native agent which is persisted
569 throughout the test run. Obtain the process ID for the agent running
570 on DUT and then kill the process. This assumes each target device runs
571 only one VTS agent at a time.
572
573 """
574 # TODO: figure out if this function is called from unregisterControllers
575 cmd = 'adb shell pgrep vts_hal_agent'
576 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
577 (out, err) = proc.communicate()
578 out = out.strip()
579 processList = out.split('\n')
580
581 # Return if multiple agents are running on the device
582 if len(processList) > 1:
583 logging.error("Multiple instances of vts_hal_agent running on "
584 "device.")
585 return
586
587 # Kill the processes corresponding to the agent
588 for pid in processList:
589 cmd = '{} {}'.format('adb shell kill -9', pid)
590 subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)