| #!/usr/bin/env python3.8 |
| # Copyright 2020 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 |
| |
| from . import test_env |
| from ..lib.factory import Factory |
| from .test_case import TestCaseWithFactory |
| |
| |
| class FactoryTest(TestCaseWithFactory): |
| |
| def test_create_buildenv(self): |
| # FUCHSIA_DIR isn't set |
| factory = Factory(host=self.host) |
| self.assertError( |
| lambda: factory.buildenv, 'FUCHSIA_DIR not set.', |
| 'Have you sourced "scripts/fx-env.sh"?') |
| fuchsia_dir = self.buildenv.fuchsia_dir |
| self.host.setenv('FUCHSIA_DIR', None) |
| self.host.mkdir(fuchsia_dir) |
| self.host.setenv('FUCHSIA_DIR', fuchsia_dir) |
| |
| # Use an empty directory to simulate an unconfigured $FUCHSIA_DIR |
| build_dir = self.buildenv.build_dir |
| fx_build_dir = self.buildenv.abspath('//.fx-build-dir') |
| self.assertError( |
| lambda: factory.buildenv, |
| 'Failed to read build directory from {}.'.format(fx_build_dir), |
| 'Have you run "fx set ... --fuzz-with <sanitizer>"?') |
| with self.host.open(fx_build_dir, 'w') as opened: |
| opened.write(self.buildenv.build_dir + '\n') |
| |
| # No $FUCHSIA_DIR/out/default/fuzzer.json |
| fuzzers_json = self.buildenv.abspath(build_dir, 'fuzzers.json') |
| self.assertError( |
| lambda: factory.buildenv, |
| 'Failed to read fuzzers from {}.'.format(fuzzers_json), |
| 'Have you run "fx set ... --fuzz-with <sanitizer>"?', |
| ) |
| |
| # Minimally valid |
| with self.host.open(fuzzers_json, 'w') as opened: |
| json.dump([], opened) |
| buildenv = factory.buildenv |
| self.assertEqual(buildenv.build_dir, buildenv.abspath(build_dir)) |
| self.assertEqual(buildenv.fuzzers(), []) |
| |
| def test_create_device(self): |
| factory = Factory(host=self.host) |
| # Can't create buildenv, FUCHSIA_DIR isn't set |
| self.assertError( |
| lambda: factory.device, 'FUCHSIA_DIR not set.', |
| 'Have you sourced "scripts/fx-env.sh"?') |
| |
| # Use the fake BuildEnv. |
| factory._buildenv = self.buildenv |
| |
| # No $FUCHSIA_DIR/out/default.device |
| build_dir = self.buildenv.build_dir |
| device_addr = '::1' |
| cmd = [ |
| self.buildenv.abspath('//.jiri_root/bin/fx'), 'device-finder', |
| 'list' |
| ] |
| self.set_outputs(cmd, [device_addr]) |
| self.host.touch( |
| self.buildenv.abspath(build_dir, 'ssh-keys', 'ssh_config')) |
| self.assertEqual(factory.device.addr, device_addr) |
| |
| # Clear the device to force re-initialization. |
| factory._device = None |
| |
| # $FUCHSIA_DIR/out/default.device present |
| device_file = self.buildenv.abspath('{}.device'.format(build_dir)) |
| device_name = 'device_name' |
| device_addr = '::2' |
| with self.host.open(device_file, 'w') as opened: |
| opened.write(device_name + '\n') |
| cmd = [ |
| self.buildenv.abspath('//.jiri_root/bin/fx'), 'device-finder', |
| 'resolve', '-device-limit', '1', device_name |
| ] |
| self.set_outputs(cmd, [device_addr]) |
| self.assertEqual(factory.device.addr, device_addr) |
| |
| def test_create_fuzzer(self): |
| factory = Factory(host=self.host) |
| |
| # Use the fake BuildEnv and Device. |
| factory._buildenv = self.buildenv |
| factory._device = self.device |
| |
| self.host.mkdir( |
| os.path.join('fuchsia_dir', 'local', 'fake-package2_fake-target1')) |
| self.host.mkdir( |
| os.path.join('fuchsia_dir', 'local', 'fake-package2_fake-target11')) |
| self.host.mkdir('output') |
| |
| # No match |
| args = self.parse_args('check', 'no/match') |
| self.assertError( |
| lambda: factory.create_fuzzer(args), |
| 'No matching fuzzers found.', |
| 'Try "fx fuzz list".', |
| ) |
| |
| # Multiple matches |
| self.set_input('1') |
| args = self.parse_args('check', '2/1') |
| fuzzer = factory.create_fuzzer(args) |
| self.assertLogged( |
| 'More than one match found.', |
| 'Please pick one from the list (or enter 0 to cancel):', |
| ' 1) fake-package2/fake-target1', |
| ' 2) fake-package2/fake-target11') |
| self.assertEqual(fuzzer.package, 'fake-package2') |
| self.assertEqual(fuzzer.executable, 'fake-target1') |
| self.assertEqual( |
| fuzzer.executable_url, |
| 'fuchsia-pkg://fuchsia.com/fake-package2#meta/fake-target1.cmx') |
| |
| # Exact match |
| args = self.parse_args('check', '2/11') |
| fuzzer = factory.create_fuzzer(args) |
| self.assertEqual(fuzzer.package, 'fake-package2') |
| self.assertEqual(fuzzer.executable, 'fake-target11') |
| self.assertEqual( |
| fuzzer.executable_url, |
| 'fuchsia-pkg://fuchsia.com/fake-package2#meta/fake-target11.cmx') |
| |
| # Infer from test |
| args = self.parse_args('check', '1/4') |
| self.assertError( |
| lambda: factory.create_fuzzer(args), |
| 'No matching fuzzers found.', |
| 'Try "fx fuzz list".', |
| ) |
| fuzzer = factory.create_fuzzer(args, include_tests=True) |
| self.assertEqual(fuzzer.package, 'fake-package1') |
| self.assertEqual(fuzzer.executable, 'fake-target4') |
| |
| # Fuzzer properties get set by args |
| args = self.parse_args( |
| 'start', |
| '--debug', |
| '--foreground', |
| '--monitor', |
| '--output', |
| 'output', |
| '2/11', |
| '-output=foo', |
| '--', |
| 'sub1', |
| 'sub2', |
| ) |
| fuzzer = factory.create_fuzzer(args) |
| self.assertEqual(fuzzer.package, 'fake-package2') |
| self.assertEqual(fuzzer.executable, 'fake-target11') |
| self.assertEqual( |
| fuzzer.executable_url, |
| 'fuchsia-pkg://fuchsia.com/fake-package2#meta/fake-target11.cmx') |
| self.assertTrue(fuzzer.debug) |
| self.assertTrue(fuzzer.foreground) |
| self.assertTrue(fuzzer.monitor) |
| self.assertEqual(fuzzer.output, 'output') |
| self.assertEqual(fuzzer.libfuzzer_opts, {'output': 'foo'}) |
| self.assertEqual(fuzzer.subprocess_args, ['sub1', 'sub2']) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |