| #!/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() |