blob: f23352d2e6fbac0a3627f0b4af83d1c5b0b81c61 [file] [log] [blame]
simonhatch1730cec2015-02-17 21:05:391#!/usr/bin/env python
2# Copyright 2015 The Chromium 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 json
7import multiprocessing
8import os
9import platform
10import subprocess
11import sys
12
simonhatch1730cec2015-02-17 21:05:3913import common
14
15
16def is_linux():
17 return sys.platform.startswith('linux')
18
19
20def get_free_disk_space(failures):
21 """Returns the amount of free space on the current disk, in GiB.
22
23 Returns:
24 The amount of free space on the current disk, measured in GiB.
25 """
26 if os.name == 'posix':
27 # Stat the current path for info on the current disk.
28 stat_result = os.statvfs('.')
29 # Multiply block size by number of free blocks, express in GiB.
skyostil97369cf42016-04-01 18:22:0730 return stat_result.f_frsize * stat_result.f_bavail / (1024.0 ** 3)
simonhatch1730cec2015-02-17 21:05:3931
32 failures.append('get_free_disk_space: OS %s not supported.' % os.name)
33 return 0
34
35
36def get_num_cpus(failures):
37 """Returns the number of logical CPUs on this machine.
38
39 Returns:
40 The number of logical CPUs on this machine, or 'unknown' if indeterminate.
41 """
42 try:
43 return multiprocessing.cpu_count()
44 except NotImplementedError:
45 failures.append('get_num_cpus')
46 return 'unknown'
47
48
49def get_device_info(args, failures):
50 """Parses the device info for each attached device, and returns a summary
51 of the device info and any mismatches.
52
53 Returns:
54 A dict indicating the result.
55 """
56 if not is_linux():
57 return {}
58
59 with common.temporary_file() as tempfile_path:
rnephewcd0530d62016-08-08 16:11:3560 test_cmd = [
simonhatch1730cec2015-02-17 21:05:3961 sys.executable,
62 os.path.join(args.paths['checkout'],
rnephew4991dac2016-07-06 19:38:1663 'third_party',
64 'catapult',
65 'devil',
66 'devil',
simonhatch1730cec2015-02-17 21:05:3967 'android',
rnephew4991dac2016-07-06 19:38:1668 'tools',
69 'device_status.py'),
jbudoricka583ba32015-09-11 17:23:1970 '--json-output', tempfile_path,
71 '--blacklist-file', os.path.join(
rnephewcd0530d62016-08-08 16:11:3572 args.paths['checkout'], 'out', 'bad_devices.json')
73 ]
74 if args.args:
75 test_cmd.extend(args.args)
simonhatch1730cec2015-02-17 21:05:3976
rnephewcd0530d62016-08-08 16:11:3577 rc = common.run_command(test_cmd)
simonhatch1730cec2015-02-17 21:05:3978 if rc:
rnephew4991dac2016-07-06 19:38:1679 failures.append('device_status')
simonhatch1730cec2015-02-17 21:05:3980 return {}
81
82 with open(tempfile_path, 'r') as src:
83 device_info = json.load(src)
84
85 results = {}
86 results['devices'] = sorted(v['serial'] for v in device_info)
87
rnephew4991dac2016-07-06 19:38:1688 details = [
89 v['ro.build.fingerprint'] for v in device_info if not v['blacklisted']]
simonhatch1730cec2015-02-17 21:05:3990
91 def unique_build_details(index):
92 return sorted(list(set([v.split(':')[index] for v in details])))
93
94 parsed_details = {
95 'device_names': unique_build_details(0),
96 'build_versions': unique_build_details(1),
97 'build_types': unique_build_details(2),
98 }
99
100 for k, v in parsed_details.iteritems():
101 if len(v) == 1:
102 results[k] = v[0]
103 else:
104 results[k] = 'MISMATCH'
105 results['%s_list' % k] = v
106 failures.append(k)
107
simonhatch08bab382015-12-15 17:04:21108 for v in device_info:
109 if v['blacklisted']:
110 failures.append('Device %s blacklisted' % v['serial'])
111
simonhatch1730cec2015-02-17 21:05:39112 return results
113
114
115def main_run(args):
116 failures = []
117 host_info = {}
118 host_info['os_system'] = platform.system()
119 host_info['os_release'] = platform.release()
120
121 host_info['processor'] = platform.processor()
122 host_info['num_cpus'] = get_num_cpus(failures)
123 host_info['free_disk_space'] = get_free_disk_space(failures)
124
125 host_info['python_version'] = platform.python_version()
126 host_info['python_path'] = sys.executable
127
128 host_info['devices'] = get_device_info(args, failures)
129
130 json.dump({
131 'valid': True,
132 'failures': failures,
133 '_host_info': host_info,
134 }, args.output)
135
rnephew4991dac2016-07-06 19:38:16136 if len(failures) != 0:
137 return common.INFRA_FAILURE_EXIT_CODE
138 return 0
simonhatch1730cec2015-02-17 21:05:39139
140
141def main_compile_targets(args):
142 json.dump([], args.output)
143
144
145if __name__ == '__main__':
146 funcs = {
147 'run': main_run,
148 'compile_targets': main_compile_targets,
149 }
150 sys.exit(common.run_script(sys.argv[1:], funcs))