blob: 95204d9add1ba28e0c26e87242ba52c3d6f62586 [file] [log] [blame]
Derek Beckett5fb683c2020-08-19 15:24:13 -07001# Lint as: python2, python3
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +08002# Copyright 2018 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import contextlib
7import json
8import logging
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +08009import os
Kuo Jen Wei987b7eb2020-05-28 15:39:45 +080010import time
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080011
Kuo Jen Wei987b7eb2020-05-28 15:39:45 +080012from autotest_lib.client.common_lib import error, utils
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080013
14
15class ChartFixture:
Derek Beckettd30bb562021-02-23 10:00:34 -080016 """Sets up chart tablet to display placeholder scene image."""
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080017 DISPLAY_SCRIPT = '/usr/local/autotest/bin/display_chart.py'
Kuo Jen Weia10200e2020-03-13 16:03:54 +080018 OUTPUT_LOG = '/tmp/chart_service.log'
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080019
20 def __init__(self, chart_host, scene_uri):
21 self.host = chart_host
22 self.scene_uri = scene_uri
23 self.display_pid = None
Kuo Jen Weia10200e2020-03-13 16:03:54 +080024 self.host.run(['rm', '-f', self.OUTPUT_LOG])
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080025
26 def initialize(self):
27 """Prepare scene file and display it on chart host."""
28 logging.info('Prepare scene file')
Kuo Jen Weia10200e2020-03-13 16:03:54 +080029 tmpdir = self.host.get_tmp_dir()
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080030 scene_path = os.path.join(
Kuo Jen Weia10200e2020-03-13 16:03:54 +080031 tmpdir, self.scene_uri[self.scene_uri.rfind('/') + 1:])
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080032 self.host.run('wget', args=('-O', scene_path, self.scene_uri))
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080033
34 logging.info('Display scene file')
35 self.display_pid = self.host.run_background(
Kuo Jen Weia10200e2020-03-13 16:03:54 +080036 'python2 {script} {scene} >{log} 2>&1'.format(
37 script=self.DISPLAY_SCRIPT,
38 scene=scene_path,
39 log=self.OUTPUT_LOG))
Kuo Jen Wei987b7eb2020-05-28 15:39:45 +080040
41 logging.info(
42 'Poll for "is ready" message for ensuring chart is ready.')
Kuo Jen Weie2766072020-12-08 10:25:45 +080043 timeout = 60
Kuo Jen Wei987b7eb2020-05-28 15:39:45 +080044 poll_time_step = 0.1
45 while timeout > 0:
46 if self.host.run(
47 'grep',
48 args=('-q', 'Chart is ready.', self.OUTPUT_LOG),
49 ignore_status=True).exit_status == 0:
50 break
51 time.sleep(poll_time_step)
52 timeout -= poll_time_step
53 else:
54 raise error.TestError('Timeout waiting for chart ready')
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080055
56 def cleanup(self):
57 """Cleanup display script."""
58 if self.display_pid is not None:
Kuo Jen Weia10200e2020-03-13 16:03:54 +080059 self.host.run(
60 'kill',
61 args=('-2', str(self.display_pid)),
62 ignore_status=True)
63 self.host.get_file(self.OUTPUT_LOG, '.')
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080064
65
66def get_chart_address(host_address, args):
Kuo Jen Wei3e89c442019-01-29 14:27:26 +080067 """Get address of chart tablet from commandline args or mapping logic in
68 test lab.
69
70 @param host_address: a list of hostname strings.
71 @param args: a dict parse from commandline args.
72 @return:
73 A list of strings for chart tablet addresses.
74 """
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080075 address = utils.args_to_dict(args).get('chart')
76 if address is not None:
77 return address.split(',')
78 elif utils.is_in_container():
Kuo Jen Wei377e99b2020-02-25 16:39:42 +080079 return [utils.get_lab_chart_address(host) for host in host_address]
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080080 else:
81 return None
82
83
84class DUTFixture:
85 """Sets up camera filter for target camera facing on DUT."""
86 TEST_CONFIG_PATH = '/var/cache/camera/test_config.json'
Kuo Jen Wei6f854a02020-05-20 12:01:33 +080087 CAMERA_SCENE_LOG = '/tmp/scene.jpg'
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +080088
89 def __init__(self, test, host, facing):
90 self.test = test
91 self.host = host
92 self.facing = facing
93
94 @contextlib.contextmanager
95 def _set_selinux_permissive(self):
96 selinux_mode = self.host.run_output('getenforce')
97 self.host.run('setenforce 0')
98 yield
99 self.host.run('setenforce', args=(selinux_mode, ))
100
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +0800101 def _write_file(self, filepath, content, permission=None, owner=None):
102 """Write content to filepath on remote host.
103 @param permission: set permission to 0xxx octal number of remote file.
104 @param owner: set owner of remote file.
105 """
106 tmp_path = os.path.join(self.test.tmpdir, os.path.basename(filepath))
107 with open(tmp_path, 'w') as f:
108 f.write(content)
109 if permission is not None:
110 os.chmod(tmp_path, permission)
111 self.host.send_file(tmp_path, filepath, delete_dest=True)
112 if owner is not None:
113 self.host.run('chown', args=(owner, filepath))
114
115 def initialize(self):
116 """Filter out camera other than target facing on DUT."""
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +0800117 self._write_file(
118 self.TEST_CONFIG_PATH,
119 json.dumps({
120 'enable_back_camera': self.facing == 'back',
121 'enable_front_camera': self.facing == 'front',
122 'enable_external_camera': False
123 }),
124 owner='arc-camera')
Kuo Jen Weif82a7b92021-06-08 16:14:40 +0800125
126 # cros_camera_service will reference the test config to filter out
127 # undesired cameras.
128 logging.info('Restart camera service with filter option')
Kuo Jen Wei9d68af82020-06-23 10:43:21 +0800129 self.host.upstart_restart('cros-camera')
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +0800130
Kuo Jen Weif82a7b92021-06-08 16:14:40 +0800131 # arc_setup will reference the test config to filter out the media
132 # profile of undesired cameras.
133 logging.info('Restart ARC++ container with camera test config')
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +0800134 self.host.run('restart ui')
135
Kuo Jen Wei6f854a02020-05-20 12:01:33 +0800136 @contextlib.contextmanager
137 def _stop_camera_service(self):
Kuo Jen Wei50ef6e82021-03-29 12:04:47 +0800138 # Ensure camera service is running or the
139 # upstart_stop()/upstart_restart() may failed due to in
140 # "start|post-stop" sleep for respawning state. See b/183904344 for
141 # detail.
142 logging.info('Wait for presence of camera service')
143 self.host.wait_for_service('cros-camera')
144
Kuo Jen Wei9d68af82020-06-23 10:43:21 +0800145 self.host.upstart_stop('cros-camera')
Kuo Jen Wei6f854a02020-05-20 12:01:33 +0800146 yield
Kuo Jen Wei9d68af82020-06-23 10:43:21 +0800147 self.host.upstart_restart('cros-camera')
Kuo Jen Wei6f854a02020-05-20 12:01:33 +0800148
149 def log_camera_scene(self):
150 """Capture an image from camera as the log for debugging scene related
151 problem."""
152
153 gtest_filter = (
154 'Camera3StillCaptureTest/'
155 'Camera3DumpSimpleStillCaptureTest.DumpCaptureResult/0')
156 with self._stop_camera_service():
157 self.host.run(
158 'sudo',
159 args=('--user=arc-camera', 'cros_camera_test',
160 '--gtest_filter=' + gtest_filter,
161 '--camera_facing=' + self.facing,
162 '--dump_still_capture_path=' +
163 self.CAMERA_SCENE_LOG))
164
165 self.host.get_file(self.CAMERA_SCENE_LOG, '.')
166
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +0800167 def cleanup(self):
168 """Cleanup camera filter."""
169 logging.info('Remove filter option and restore camera service')
Kuo Jen Wei50ef6e82021-03-29 12:04:47 +0800170 with self._stop_camera_service():
171 self.host.run('rm', args=('-f', self.TEST_CONFIG_PATH))
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +0800172
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +0800173 logging.info('Restore camera profile in ARC++ container')
Kuo Jen Wei7f00bb32018-11-01 15:35:24 +0800174 self.host.run('restart ui')