blob: 09df2a51d4c50f8d8a2adb9131253bbd7c97527a [file] [log] [blame]
#!/usr/bin/env python2.7
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import json
import os
import unittest
import test_env
from lib.buildenv import BuildEnv
from test_case import TestCaseWithFactory
class BuildEnvTest(TestCaseWithFactory):
def test_fuchsia_dir(self):
self.assertError(
lambda: BuildEnv(self.factory), 'FUCHSIA_DIR not set.',
'Have you sourced "scripts/fx-env.sh"?')
def test_configure(self):
fuchsia_dir = os.path.abspath('/test_configure')
self.host.mkdir(fuchsia_dir)
self.host.setenv('FUCHSIA_DIR', fuchsia_dir)
# Fails due to missing paths
buildenv = BuildEnv(self.factory)
build_dir = os.path.join(fuchsia_dir, 'build_dir')
self.host.mkdir(build_dir)
# No $FUCHSIA_DIR/out/default/host_x64/symbolize
symbolizer_exec = os.path.join(build_dir, 'host_x64', 'symbolize')
self.assertError(
lambda: buildenv.configure(build_dir),
'Invalid symbolizer executable: {}'.format(symbolizer_exec))
self.host.touch(symbolizer_exec)
# No $FUCHSIA_DIR/out/default/host_x64/symbolize
clang_dir = os.path.join(
fuchsia_dir, 'prebuilt', 'third_party', 'clang', self.host.platform)
llvm_symbolizer = os.path.join(clang_dir, 'bin', 'llvm-symbolizer')
self.assertError(
lambda: buildenv.configure(build_dir),
'Invalid LLVM symbolizer: {}'.format(llvm_symbolizer))
self.host.touch(llvm_symbolizer)
# No $FUCHSIA_DIR/.../.build-id
build_id_dirs = [
os.path.join(clang_dir, 'lib', 'debug', '.build-id'),
os.path.join(build_dir, '.build-id'),
os.path.join(build_dir + '.zircon', '.build-id'),
]
for build_id_dir in build_id_dirs:
srcpath = buildenv.srcpath(build_id_dir)
self.assertError(
lambda: buildenv.configure(build_dir),
'Invalid build ID directory: {}'.format(srcpath),
)
self.host.mkdir(build_id_dir)
buildenv.configure(build_dir)
clang_dir = '//prebuilt/third_party/clang/' + self.host.platform
self.assertEqual(buildenv.build_dir, buildenv.abspath(build_dir))
self.assertEqual(
buildenv.symbolizer_exec,
buildenv.abspath(build_dir + '/host_x64/symbolize'))
self.assertEqual(
buildenv.llvm_symbolizer,
buildenv.abspath(clang_dir + '/bin/llvm-symbolizer'))
self.assertEqual(
buildenv.build_id_dirs, [
buildenv.abspath(clang_dir + '/lib/debug/.build-id'),
buildenv.abspath(build_dir + '/.build-id'),
buildenv.abspath(build_dir + '.zircon/.build-id'),
])
# Unit tests
def test_read_fuzzers(self):
fuchsia_dir = 'test_read_fuzzers'
self.host.mkdir(fuchsia_dir)
self.host.setenv('FUCHSIA_DIR', fuchsia_dir)
buildenv = BuildEnv(self.factory)
expected_fuzzers = [
'fake-package1/fake-target1',
'fake-package1/fake-target2',
'fake-package1/fake-target3',
'fake-package2/an-extremely-verbose-target-name',
'fake-package2/fake-target1',
'fake-package2/fake-target11',
]
expected_fuzzer_tests = [
'fake-package1/fake-target4',
'fake-package1/fake-target5',
]
# v1 doesn't include fuzzer tests
golden = 'data/v1.fuzzers.json'
self.host.add_golden(golden)
buildenv.read_fuzzers(golden)
fuzzers = [str(fuzzer) for fuzzer in buildenv.fuzzers()]
self.assertEqual(fuzzers, expected_fuzzers)
self.assertFalse(buildenv.fuzzer_tests())
# v2 can select fuzzers...
golden = 'data/v2.fuzzers.json'
self.host.add_golden(golden)
buildenv.read_fuzzers(golden)
fuzzers = [str(fuzzer) for fuzzer in buildenv.fuzzers()]
self.assertEqual(fuzzers, expected_fuzzers)
# ...or fuzzer tests...
fuzzer_tests = [str(fuzzer) for fuzzer in buildenv.fuzzer_tests()]
self.assertEqual(fuzzer_tests, expected_fuzzer_tests)
# ...or both!
fuzzers = [
str(fuzzer) for fuzzer in buildenv.fuzzers(include_tests=True)
]
self.assertEqual(
fuzzers, sorted(expected_fuzzers + expected_fuzzer_tests))
def test_fuzzers(self):
self.assertEqual(len(self.buildenv.fuzzers('/')), 6)
self.assertEqual(len(self.buildenv.fuzzers('fake')), 6)
self.assertEqual(len(self.buildenv.fuzzers('package1')), 3)
self.assertEqual(len(self.buildenv.fuzzers('target1')), 3)
self.assertEqual(len(self.buildenv.fuzzers('package2/target1')), 2)
self.assertEqual(
len(self.buildenv.fuzzers('fake-package2/fake-target1')), 1)
self.assertEqual(len(self.buildenv.fuzzers('1/2')), 1)
self.assertEqual(len(self.buildenv.fuzzers('target4')), 0)
with self.assertRaises(ValueError):
self.buildenv.fuzzers('a/b/c')
def test_fuzzer_tests(self):
self.assertEqual(len(self.buildenv.fuzzer_tests('/')), 2)
self.assertEqual(len(self.buildenv.fuzzer_tests('fake')), 2)
self.assertEqual(len(self.buildenv.fuzzer_tests('package1')), 2)
self.assertEqual(len(self.buildenv.fuzzer_tests('target1')), 0)
self.assertEqual(len(self.buildenv.fuzzer_tests('package2/target1')), 0)
self.assertEqual(
len(self.buildenv.fuzzer_tests('fake-package1/fake-target5')), 1)
self.assertEqual(len(self.buildenv.fuzzer_tests('1/5')), 1)
self.assertEqual(len(self.buildenv.fuzzer_tests('target4')), 1)
with self.assertRaises(ValueError):
self.buildenv.fuzzer_tests('a/b/c')
def test_abspath(self):
self.host.cwd = os.path.join(self.buildenv.fuchsia_dir, 'foo')
self.assertEqual(
self.buildenv.abspath('//bar/baz'),
os.path.join(self.buildenv.fuchsia_dir, 'bar', 'baz'))
self.assertEqual(
self.buildenv.abspath('/bar/baz'), os.path.abspath('/bar/baz'))
self.assertEqual(
self.buildenv.abspath('baz'),
os.path.join(self.buildenv.fuchsia_dir, 'foo/baz'))
def test_srcpath(self):
self.assertEqual(self.buildenv.srcpath('//foo/bar'), '//foo/bar')
self.assertEqual(self.buildenv.srcpath('//foo/bar:baz'), '//foo/bar')
self.host.cwd = os.path.join(self.buildenv.fuchsia_dir, 'foo')
self.assertEqual(self.buildenv.srcpath('bar'), '//foo/bar')
self.assertEqual(self.buildenv.srcpath('bar:baz'), '//foo/bar')
self.assertError(
lambda: self.buildenv.srcpath('/foo/bar'),
'/foo/bar is not a path in the source tree.')
self.assertError(
lambda: self.buildenv.srcpath('/foo/bar:baz'),
'/foo/bar is not a path in the source tree.')
self.host.cwd = '/qux'
self.assertError(
lambda: self.buildenv.srcpath('bar'),
'/qux/bar is not a path in the source tree.')
self.assertError(
lambda: self.buildenv.srcpath('bar:baz'),
'/qux/bar is not a path in the source tree.')
def test_find_device(self):
device_name = 'test_find_device'
addrs = ['::1', '::2']
cmd = [
self.buildenv.abspath('//.jiri_root/bin/fx'),
'device-finder',
'resolve',
'-device-limit',
'1',
device_name,
]
self.set_outputs(cmd, addrs[:1])
self.assertEqual(self.buildenv.find_device(device_name), addrs[0])
# No results from 'fx device-finder list'
self.assertError(
lambda: self.buildenv.find_device(None), 'Unable to find device.',
'Try "fx set-device".')
# Multiple results from `fx device-finder list`
cmd = [
self.buildenv.abspath('//.jiri_root/bin/fx'), 'device-finder',
'list'
]
self.set_outputs(cmd, addrs)
self.assertError(
lambda: self.buildenv.find_device(None), 'Multiple devices found.',
'Try "fx set-device".')
# Reset output
self.set_outputs(cmd, addrs[:1])
self.assertEqual(self.buildenv.find_device(None), addrs[0])
def test_symbolize(self):
stacktrace = [
'a line',
'another line',
'yet another line',
]
cmd = self.symbolize_cmd()
self.set_outputs(
cmd, [
'[000001.234567][123][456][klog] INFO: Symbolized line 1',
'[000001.234568][123][456][klog] INFO: Symbolized line 2',
'[000001.234569][123][456][klog] INFO: Symbolized line 3'
])
symbolized = self.buildenv.symbolize('\n'.join(stacktrace))
self.assertRan(*cmd)
process = self.get_process(cmd)
self.assertEqual(process.inputs, stacktrace)
self.assertEqual(
symbolized.strip().split('\n'), [
'Symbolized line 1',
'Symbolized line 2',
'Symbolized line 3',
])
if __name__ == '__main__':
unittest.main()