#!/usr/bin/env vpython3
# Copyright 2022 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""File for testing compatible_utils.py."""
import io
import json
import os
import stat
import tempfile
import unittest
import unittest.mock as mock
import compatible_utils
# Allow access to constants for testing.
# pylint: disable=protected-access
@unittest.skipIf(os.name == 'nt', 'Fuchsia tests not supported on Windows')
class CompatibleUtilsTest(unittest.TestCase):
"""Test compatible_utils.py methods."""
def test_running_unattended_returns_true_if_headless_set(self) -> None:
"""Test |running_unattended| returns True if CHROME_HEADLESS is set."""
with mock.patch('os.environ', {compatible_utils._CHROME_HEADLESS: 0}):
self.assertTrue(compatible_utils.running_unattended())
with mock.patch('os.environ', {'FOO_HEADLESS': 0}):
self.assertFalse(compatible_utils.running_unattended())
def test_get_host_arch(self) -> None:
"""Test |get_host_arch| gets the host architecture and throws
exceptions on errors."""
supported_arches = ['x86_64', 'AMD64', 'aarch64']
with mock.patch('platform.machine', side_effect=supported_arches):
self.assertEqual(compatible_utils.get_host_arch(), 'x64')
self.assertEqual(compatible_utils.get_host_arch(), 'x64')
self.assertEqual(compatible_utils.get_host_arch(), 'arm64')
with mock.patch('platform.machine', return_value=['fake-arch']), \
self.assertRaises(NotImplementedError):
compatible_utils.get_host_arch()
def test_add_exec_to_file(self) -> None:
"""Test |add_exec_to_file| adds executable bit to file."""
with tempfile.NamedTemporaryFile() as f:
original_stat = os.stat(f.name).st_mode
self.assertFalse(original_stat & stat.S_IXUSR)
compatible_utils.add_exec_to_file(f.name)
new_stat = os.stat(f.name).st_mode
self.assertTrue(new_stat & stat.S_IXUSR)
def test_parse_host_port_splits_address_and_strips_brackets(self) -> None:
"""Test |parse_host_port| splits ipv4 and ipv6 addresses correctly."""
self.assertEqual(compatible_utils.parse_host_port('hostname:55'),
('hostname', 55))
self.assertEqual(compatible_utils.parse_host_port('192.168.42.40:443'),
('192.168.42.40', 443))
self.assertEqual(
compatible_utils.parse_host_port('[2001:db8::1]:8080'),
('2001:db8::1', 8080))
def test_map_filter_filter_file_throws_value_error_if_wrong_path(self
) -> None:
"""Test |map_filter_file| throws ValueError if path is missing
FILTER_DIR."""
with self.assertRaises(ValueError):
compatible_utils.map_filter_file_to_package_file('foo')
with self.assertRaises(ValueError):
compatible_utils.map_filter_file_to_package_file('some/other/path')
with self.assertRaises(ValueError):
compatible_utils.map_filter_file_to_package_file('filters/file')
# No error.
compatible_utils.map_filter_file_to_package_file(
'testing/buildbot/filters/some.filter')
def test_map_filter_filter_replaces_filter_dir_with_pkg_path(self) -> None:
"""Test |map_filter_file| throws ValueError if path is missing
FILTER_DIR."""
self.assertEqual(
'/pkg/testing/buildbot/filters/some.filter',
compatible_utils.map_filter_file_to_package_file(
'foo/testing/buildbot/filters/some.filter'))
def test_get_sdk_hash_success(self) -> None:
"""Test |get_sdk_hash| reads product_bundle.json."""
with mock.patch('builtins.open',
return_value=io.StringIO(
json.dumps({'product_version': '12345'}))):
self.assertEqual(
compatible_utils.get_sdk_hash(
'third_party/fuchsia-sdk/images-internal/sherlock-release/'
'smart_display_max_eng_arrested/'),
('smart_display_max_eng_arrested', '12345'))
def test_get_sdk_hash_normalize_path(self) -> None:
"""Test |get_sdk_hash| uses path as product."""
with mock.patch('builtins.open',
return_value=io.StringIO(
json.dumps({'product_version': '23456'}))):
self.assertEqual(
compatible_utils.get_sdk_hash(
'third_party/fuchsia-sdk/images-internal/sherlock-release/'
'smart_display_max_eng_arrested'),
('smart_display_max_eng_arrested', '23456'))
def test_get_sdk_hash_not_found(self) -> None:
"""Test |get_sdk_hash| fails if the product_bundle.json does not exist.
"""
with mock.patch('builtins.open', side_effect=IOError()):
self.assertRaises(IOError, compatible_utils.get_sdk_hash,
'some/image/dir')
def test_install_symbols(self):
"""Test |install_symbols|."""
def trim_noop_prefixes(path):
"""Helper function to trim no-op path name prefixes that are
introduced by os.path.realpath on some platforms. These break
the unit tests, but have no actual effect on behavior."""
# These must all end in the path separator character for the
# string length computation to be correct on all platforms.
noop_prefixes = ['/private/']
for prefix in noop_prefixes:
if path.startswith(prefix):
return path[len(prefix) - 1:]
return path
with tempfile.TemporaryDirectory() as fuchsia_out_dir:
build_id = 'test_build_id'
symbol_file = os.path.join(fuchsia_out_dir, '.build-id',
build_id[:2], build_id[2:] + '.debug')
id_path = os.path.join(fuchsia_out_dir, 'ids.txt')
try:
binary_relpath = 'path/to/binary'
with open(id_path, 'w') as f:
f.write(f'{build_id} {binary_relpath}')
compatible_utils.install_symbols([id_path], fuchsia_out_dir)
self.assertTrue(os.path.islink(symbol_file))
self.assertEqual(
trim_noop_prefixes(os.path.realpath(symbol_file)),
os.path.join(fuchsia_out_dir, binary_relpath))
new_binary_relpath = 'path/to/new/binary'
with open(id_path, 'w') as f:
f.write(f'{build_id} {new_binary_relpath}')
compatible_utils.install_symbols([id_path], fuchsia_out_dir)
self.assertTrue(os.path.islink(symbol_file))
self.assertEqual(
trim_noop_prefixes(os.path.realpath(symbol_file)),
os.path.join(fuchsia_out_dir, new_binary_relpath))
finally:
os.remove(id_path)
def test_ssh_keys(self):
"""Ensures the get_ssh_keys won't return a None."""
self.assertIsNotNone(compatible_utils.get_ssh_keys())
def test_force_running_unattended(self) -> None:
"""Test |force_running_unattended|."""
# force switching the states twice no matter which state we start in.
for _ in range(2):
compatible_utils.force_running_attended()
self.assertFalse(compatible_utils.running_unattended())
compatible_utils.force_running_unattended()
self.assertTrue(compatible_utils.running_unattended())
if __name__ == '__main__':
unittest.main()