def test_output_mixed(self): console = MockConsole() target1 = self.make_build_target_address("testprojects/tests/python/pants/passes") target2 = self.make_build_target_address("testprojects/tests/python/pants/fails") def make_result(target): if target == target1: return TestResult(status=Status.SUCCESS, stdout='I passed') elif target == target2: return TestResult(status=Status.FAILURE, stdout='I failed') else: raise Exception("Unrecognised target") with self.assertRaises(GracefulTerminationException) as cm: run_rule(fast_test, console, (target1, target2), { (TestResult, Address): make_result, }) self.assertEqual(1, cm.exception.exit_code) self.assertEquals(console.stdout.getvalue(), """I passed I failed testprojects/tests/python/pants/passes ..... SUCCESS testprojects/tests/python/pants/fails ..... FAILURE """)
def single_target_test(self, result, expected_console_output): console = MockConsole() run_rule(fast_test, console, (self.make_build_target_address("some/target"),), { (TestResult, Address): lambda _: result, }) self.assertEquals(console.stdout.getvalue(), expected_console_output)
def test_coordinator_unknown_test(self): target_adaptor = PythonTestsAdaptor(type_alias='unknown_tests') with self.captured_logging(logging.INFO), self.assertRaises(Exception) as cm: run_rule(coordinator_of_tests, HydratedTarget(Address.parse("some/target"), target_adaptor, ()), { (PyTestResult, HydratedTarget): lambda _: PyTestResult(status=Status.FAILURE, stdout='foo', stderr=''), }) self.assertEqual(str(cm.exception), "Didn't know how to run tests for type unknown_tests")
def test_coordinator_unknown_test(self): target_adaptor = PythonTestsAdaptor(type_alias='unknown_tests') with self.assertRaises(Exception) as cm: run_rule(coordinator_of_tests, HydratedTarget(Address.parse("some/target"), target_adaptor, ()), { (PyTestResult, HydratedTarget): lambda _: PyTestResult(status=Status.FAILURE, stdout='foo'), }) self.assertEqual(str(cm.exception), "Didn't know how to run tests for type unknown_tests")
def _resolve_build_file_addresses(self, specs, address_family, snapshot, address_mapper): pbfas = run_rule( provenanced_addresses_from_address_families, address_mapper, specs, { (Snapshot, PathGlobs): lambda _: snapshot, (AddressFamily, Dir): lambda _: address_family, }) return run_rule(remove_provenance, pbfas)
def test_output_mixed(self): console = MockConsole(use_colors=False) target1 = self.make_build_target_address("testprojects/tests/python/pants/passes") target2 = self.make_build_target_address("testprojects/tests/python/pants/fails") def make_result(target): if target == target1: return TestResult(status=Status.SUCCESS, stdout='I passed\n', stderr='') elif target == target2: return TestResult(status=Status.FAILURE, stdout='I failed\n', stderr='') else: raise Exception("Unrecognised target") res = run_rule(fast_test, console, (target1, target2), { (TestResult, Address): make_result, }) self.assertEqual(1, res.exit_code) self.assertEquals(console.stdout.getvalue(), dedent("""\ testprojects/tests/python/pants/passes stdout: I passed testprojects/tests/python/pants/fails stdout: I failed testprojects/tests/python/pants/passes ..... SUCCESS testprojects/tests/python/pants/fails ..... FAILURE """))
def test_options_parsing_request(self): parse_request = OptionsParseRequest.create( ['./pants', '-ldebug', '--python-setup-wheel-version=3.13.37', 'binary', 'src/python::'], dict(PANTS_ENABLE_PANTSD='True', PANTS_BINARIES_BASEURLS='["https://bins.com"]') ) # TODO: Once we have the ability to get FileContent for arbitrary # paths outside of the buildroot, we can move the construction of # OptionsBootstrapper into an @rule by cooperatively calling # OptionsBootstrapper.produce_and_set_bootstrap_options() which # will yield lists of file paths for use as subject values and permit # us to avoid the direct file I/O that this currently requires. options_bootstrapper = OptionsBootstrapper.from_options_parse_request(parse_request) build_config = BuildConfigInitializer.get(options_bootstrapper) options = run_rule(parse_options, options_bootstrapper, build_config)[0] self.assertIn('binary', options.goals) global_options = options.for_global_scope() self.assertEqual(global_options.level, 'debug') self.assertEqual(global_options.enable_pantsd, True) self.assertEqual(global_options.binaries_baseurls, ['https://bins.com']) python_setup_options = options.for_scope('python-setup') self.assertEqual(python_setup_options.wheel_version, '3.13.37')
def _resolve_build_file_addresses(self, specs, address_family, snapshot, address_mapper): return run_rule( addresses_from_address_families, address_mapper, specs, { (Snapshot, PathGlobs): lambda _: snapshot, (AddressFamily, Dir): lambda _: address_family, })
def test_options_parsing_request(self): parse_request = OptionsParseRequest.create( ['./pants', '-ldebug', '--python-setup-wheel-version=3.13.37', 'binary', 'src/python::'], dict(PANTS_ENABLE_PANTSD='True', PANTS_BINARIES_BASEURLS='["https://bins.com"]') ) # TODO: Once we have the ability to get FileContent for arbitrary # paths outside of the buildroot, we can move the construction of # OptionsBootstrapper into an @rule by cooperatively calling # OptionsBootstrapper.produce_and_set_bootstrap_options() which # will yield lists of file paths for use as subject values and permit # us to avoid the direct file I/O that this currently requires. options_bootstrapper = OptionsBootstrapper.from_options_parse_request(parse_request) build_config = BuildConfigInitializer.get(options_bootstrapper) options = run_rule(parse_options, options_bootstrapper, build_config)[0] self.assertIn('binary', options.goals) global_options = options.for_global_scope() self.assertEquals(global_options.level, 'debug') self.assertEquals(global_options.enable_pantsd, True) self.assertEquals(global_options.binaries_baseurls, ['https://bins.com']) python_setup_options = options.for_scope('python-setup') self.assertEquals(python_setup_options.wheel_version, '3.13.37')
def test_empty(self): """Test that parsing an empty BUILD file results in an empty AddressFamily.""" address_mapper = AddressMapper(JsonParser(TestTable())) af = run_rule(parse_address_family, address_mapper, Dir('/dev/null'), { (FilesContent, PathGlobs): lambda _: FilesContent([FileContent('/dev/null/BUILD', '')]) }) self.assertEquals(len(af.objects_by_name), 0)
def test_output_mixed(self): console = MockConsole(use_colors=False) target1 = self.make_build_target_address("testprojects/tests/python/pants/passes") target2 = self.make_build_target_address("testprojects/tests/python/pants/fails") def make_result(target): if target == target1: tr = TestResult(status=Status.SUCCESS, stdout='I passed\n', stderr='') elif target == target2: tr = TestResult(status=Status.FAILURE, stdout='I failed\n', stderr='') else: raise Exception("Unrecognised target") return AddressAndTestResult(target, tr) res = run_rule(fast_test, console, (target1, target2), { (AddressAndTestResult, Address): make_result, }) self.assertEqual(1, res.exit_code) self.assertEquals(console.stdout.getvalue(), dedent("""\ testprojects/tests/python/pants/passes stdout: I passed testprojects/tests/python/pants/fails stdout: I failed testprojects/tests/python/pants/passes ..... SUCCESS testprojects/tests/python/pants/fails ..... FAILURE """))
def test_empty(self): """Test that parsing an empty BUILD file results in an empty AddressFamily.""" address_mapper = AddressMapper(JsonParser(TEST_TABLE)) af = run_rule(parse_address_family, address_mapper, Dir('/dev/null'), { (Snapshot, PathGlobs): lambda _: Snapshot(Digest('abc', 10), ('/dev/null/BUILD',), ()), (FilesContent, Digest): lambda _: FilesContent([FileContent('/dev/null/BUILD', b'')]), }) self.assertEqual(len(af.objects_by_name), 0)
def test_empty(self): """Test that parsing an empty BUILD file results in an empty AddressFamily.""" address_mapper = AddressMapper(JsonParser(TestTable())) af = run_rule(parse_address_family, address_mapper, Dir('/dev/null'), { (Snapshot, PathGlobs): lambda _: Snapshot(DirectoryDigest('abc', 10), (File('/dev/null/BUILD'),)), (FilesContent, DirectoryDigest): lambda _: FilesContent([FileContent('/dev/null/BUILD', b'')]), }) self.assertEqual(len(af.objects_by_name), 0)
def test_coordinator_python_test(self): target_adaptor = PythonTestsAdaptor(type_alias='python_tests') with self.captured_logging(logging.INFO): result = run_rule(coordinator_of_tests, HydratedTarget(Address.parse("some/target"), target_adaptor, ()), { (PyTestResult, HydratedTarget): lambda _: PyTestResult(status=Status.FAILURE, stdout='foo', stderr=''), }) self.assertEqual(result, TestResult(status=Status.FAILURE, stdout='foo', stderr=''))
def test_coordinator_python_test(self): target_adaptor = PythonTestsAdaptor(type_alias='python_tests') result = run_rule(coordinator_of_tests, HydratedTarget(Address.parse("some/target"), target_adaptor, ()), { (PyTestResult, HydratedTarget): lambda _: PyTestResult(status=Status.FAILURE, stdout='foo'), }) self.assertEqual(result, TestResult(status=Status.FAILURE, stdout='foo'))
def test_empty(self): """Test that parsing an empty BUILD file results in an empty AddressFamily.""" address_mapper = AddressMapper(JsonParser(TestTable())) af = run_rule(parse_address_family, address_mapper, Dir('/dev/null'), { (Snapshot, PathGlobs): lambda _: Snapshot(DirectoryDigest(text_type("abc"), 10), (File('/dev/null/BUILD'),)), (FilesContent, DirectoryDigest): lambda _: FilesContent([FileContent('/dev/null/BUILD', '')]), }) self.assertEquals(len(af.objects_by_name), 0)
def single_target_test(self, result, expected_console_output, success=True): console = MockConsole(use_colors=False) res = run_rule(fast_test, console, (self.make_build_target_address("some/target"),), { (TestResult, Address): lambda _: result, }) self.assertEquals(console.stdout.getvalue(), expected_console_output) self.assertEquals(0 if success else 1, res.exit_code)
def single_target_test(self, result, expected_console_output, success=True): console = MockConsole(use_colors=False) addr = self.make_build_target_address("some/target") res = run_rule(fast_test, console, (addr,), { (AddressAndTestResult, Address): lambda _: AddressAndTestResult(addr, result), }) self.assertEquals(console.stdout.getvalue(), expected_console_output) self.assertEquals(0 if success else 1, res.exit_code)
def test_single_non_test_target(self): bfaddr = BuildFileAddress(None, 'bin', 'some/dir') target_adaptor = PythonBinaryAdaptor(type_alias='python_binary') with self.captured_logging(logging.INFO): # Note that this is not the same error message the end user will see, as we're resolving # union Get requests in run_rule, not the real engine. But this test still asserts that # we error when we expect to error. with self.assertRaisesRegex(AssertionError, r'Rule requested: .* which cannot be satisfied.'): run_rule( coordinator_of_tests, HydratedTarget(bfaddr.to_address(), target_adaptor, ()), UnionMembership(union_rules={TestTarget: [PythonTestsAdaptor]}), AddressProvenanceMap(bfaddr_to_spec={ bfaddr: SingleAddress(directory='some/dir', name='bin') }), { (TestResult, TestTarget): lambda _: TestResult(status=Status.SUCCESS, stdout='foo', stderr=''), })
def test_duplicated(self): """Test that matching the same Spec twice succeeds.""" address = SingleAddress('a', 'a') address_mapper = AddressMapper(JsonParser(TestTable())) snapshot = Snapshot(DirectoryDigest(str('xx'), 2), (Path('a/BUILD', File('a/BUILD')),)) address_family = AddressFamily('a', {'a': ('a/BUILD', 'this is an object!')}) bfas = run_rule(addresses_from_address_families, address_mapper, Specs([address, address]), { (Snapshot, PathGlobs): lambda _: snapshot, (AddressFamily, Dir): lambda _: address_family, }) self.assertEquals(len(bfas.dependencies), 1) self.assertEquals(bfas.dependencies[0].spec, 'a:a')
def test_coordinator_python_test(self): target_adaptor = PythonTestsAdaptor(type_alias='python_tests') with self.captured_logging(logging.INFO): result = run_rule( coordinator_of_tests, HydratedTarget(Address.parse("some/target"), target_adaptor, ()), { (TestResult, PythonTestsAdaptor): lambda _: TestResult( status=Status.FAILURE, stdout='foo', stderr=''), }) self.assertEqual( result, TestResult(status=Status.FAILURE, stdout='foo', stderr=''))
def test_exclude_pattern(self): """Test that targets are filtered based on exclude patterns.""" spec = SiblingAddresses('root') address_mapper = AddressMapper(JsonParser(TestTable())) snapshot = Snapshot(DirectoryDigest(text_type('xx'), 2), (Path('root/BUILD', File('root/BUILD')),)) address_family = AddressFamily('root', {'exclude_me': ('root/BUILD', TargetAdaptor()), 'not_me': ('root/BUILD', TargetAdaptor()), } ) targets = run_rule( addresses_from_address_families, address_mapper, Specs([spec], exclude_patterns=tuple(['.exclude*'])),{ (Snapshot, PathGlobs): lambda _: snapshot, (AddressFamily, Dir): lambda _: address_family, }) self.assertEquals(len(targets.dependencies), 1) self.assertEquals(targets.dependencies[0].spec, 'root:not_me')
def test_exclude_pattern_with_single_address(self): """Test that single address targets are filtered based on exclude patterns.""" spec = SingleAddress('root', 'not_me') address_mapper = AddressMapper(JsonParser(TestTable())) snapshot = Snapshot(DirectoryDigest('xx', 2), (Path('root/BUILD', File('root/BUILD')),)) address_family = AddressFamily('root', { 'not_me': ('root/BUILD', TargetAdaptor()), } ) targets = run_rule( addresses_from_address_families, address_mapper, Specs([spec], exclude_patterns=tuple(['root.*'])),{ (Snapshot, PathGlobs): lambda _: snapshot, (AddressFamily, Dir): lambda _: address_family, }) self.assertEqual(len(targets.dependencies), 0)
def test_coordinator_python_test(self): addr = Address.parse("some/target") target_adaptor = PythonTestsAdaptor(type_alias='python_tests') with self.captured_logging(logging.INFO): result = run_rule( coordinator_of_tests, HydratedTarget(addr, target_adaptor, ()), UnionMembership(union_rules={TestTarget: [PythonTestsAdaptor]}), AddressProvenanceMap(bfaddr_to_spec={}), { (TestResult, PythonTestsAdaptor): lambda _: TestResult(status=Status.FAILURE, stdout='foo', stderr=''), }) self.assertEqual( result, AddressAndTestResult(addr, TestResult(status=Status.FAILURE, stdout='foo', stderr='')) )
def test_exclude_pattern(self): """Test that targets are filtered based on exclude patterns.""" spec = SiblingAddresses('root') address_mapper = AddressMapper(JsonParser(TestTable())) snapshot = Snapshot(DirectoryDigest(text_type('xx'), 2), (Path('root/BUILD', File('root/BUILD')), )) address_family = AddressFamily( 'root', { 'exclude_me': ('root/BUILD', TargetAdaptor()), 'not_me': ('root/BUILD', TargetAdaptor()), }) targets = run_rule( addresses_from_address_families, address_mapper, Specs([spec], exclude_patterns=tuple(['.exclude*'])), { (Snapshot, PathGlobs): lambda _: snapshot, (AddressFamily, Dir): lambda _: address_family, }) self.assertEquals(len(targets.dependencies), 1) self.assertEquals(targets.dependencies[0].spec, 'root:not_me')
def test_globbed_non_test_target(self): bfaddr = BuildFileAddress(None, 'bin', 'some/dir') target_adaptor = PythonBinaryAdaptor(type_alias='python_binary') with self.captured_logging(logging.INFO): result = run_rule( coordinator_of_tests, HydratedTarget(bfaddr.to_address(), target_adaptor, ()), UnionMembership(union_rules={TestTarget: [PythonTestsAdaptor]}), AddressProvenanceMap(bfaddr_to_spec={ bfaddr: DescendantAddresses(directory='some/dir') }), { (TestResult, PythonTestsAdaptor): lambda _: TestResult(status=Status.SUCCESS, stdout='foo', stderr=''), }) self.assertEqual( result, AddressAndTestResult(bfaddr.to_address(), None) )
def test_tag_filter(self): """Test that targets are filtered based on `tags`.""" spec = SiblingAddresses('root') address_mapper = AddressMapper(JsonParser(TestTable())) snapshot = Snapshot(DirectoryDigest(str('xx'), 2), (Path('root/BUILD', File('root/BUILD')),)) address_family = AddressFamily('root', {'a': ('root/BUILD', TargetAdaptor()), 'b': ('root/BUILD', TargetAdaptor(tags={'integration'})), 'c': ('root/BUILD', TargetAdaptor(tags={'not_integration'})) } ) targets = run_rule( addresses_from_address_families, address_mapper, Specs([spec], tags=['+integration']), { (Snapshot, PathGlobs): lambda _: snapshot, (AddressFamily, Dir): lambda _: address_family, }) self.assertEquals(len(targets.dependencies), 1) self.assertEquals(targets.dependencies[0].spec, 'root:b')
def test_tag_filter(self): """Test that targets are filtered based on `tags`.""" spec = SiblingAddresses('root') address_mapper = AddressMapper(JsonParser(TestTable())) snapshot = Snapshot(DirectoryDigest(text_type('xx'), 2), (Path('root/BUILD', File('root/BUILD')),)) address_family = AddressFamily('root', {'a': ('root/BUILD', TargetAdaptor()), 'b': ('root/BUILD', TargetAdaptor(tags={'integration'})), 'c': ('root/BUILD', TargetAdaptor(tags={'not_integration'})) } ) targets = run_rule( addresses_from_address_families, address_mapper, Specs([spec], tags=['+integration']), { (Snapshot, PathGlobs): lambda _: snapshot, (AddressFamily, Dir): lambda _: address_family, }) self.assertEquals(len(targets.dependencies), 1) self.assertEquals(targets.dependencies[0].spec, 'root:b')
def filedeps_rule_test(self, transitive_targets, expected_console_output): console = MockConsole() run_rule(file_deps, console, transitive_targets) self.assertEquals(console.stdout.getvalue(), expected_console_output)
def test_run_rule_console_rule_generator(self): res = run_rule(a_console_rule_generator, Console(), { (A, str): lambda _: A(), }) self.assertEquals(res, Example(0))
def test_all_roots(self): SOURCE = SourceRootCategories.SOURCE TEST = SourceRootCategories.TEST THIRDPARTY = SourceRootCategories.THIRDPARTY options = { 'pants_ignore': [], 'source_root_patterns': ['src/*', 'src/example/*'], 'source_roots': { # Fixed roots should trump patterns which would detect contrib/go/examples/src/go here. 'contrib/go/examples/src/go/src': ['go'], # Dir does not exist, should not be listed as a root. 'java': ['java'] } } options.update(self.options[''] ) # We need inherited values for pants_workdir etc. self.context(for_subsystems=[SourceRootConfig], options={SourceRootConfig.options_scope: options}) source_root_config = SourceRootConfig.global_instance() source_roots = source_root_config.get_source_roots() # Ensure that we see any manually added roots. source_roots.add_source_root('fixed/root/jvm', ('java', 'scala'), TEST) # This function mocks out reading real directories off the file system def provider_rule(path_globs: PathGlobs) -> Snapshot: dirs = ( 'contrib/go/examples/3rdparty/go', 'contrib/go/examples/src/go/src', 'src/java', 'src/python', 'src/kotlin', 'my/project/src/java', 'src/example/java', 'src/example/python', 'fixed/root/jvm', # subdirectories of source roots should not show up in final output 'src/kotlin/additional/directories/that/might/get/matched/src/foo', ) return Snapshot(Digest('abcdef', 10), (), dirs) output = run_rule(list_roots.all_roots, source_root_config, {(Snapshot, PathGlobs): provider_rule}) self.assertEqual( { SourceRoot('contrib/go/examples/3rdparty/go', ('go', ), THIRDPARTY), SourceRoot('contrib/go/examples/src/go/src', ('go', ), SOURCE), SourceRoot('src/java', ('java', ), SOURCE), SourceRoot('src/python', ('python', ), SOURCE), SourceRoot('src/kotlin', ('kotlin', ), SOURCE), SourceRoot('src/example/java', ('java', ), SOURCE), SourceRoot('src/example/python', ('python', ), SOURCE), SourceRoot('my/project/src/java', ('java', ), SOURCE), SourceRoot('fixed/root/jvm', ('java', 'scala'), TEST) }, set(output))
def test_run_rule_console_rule_generator(self): res = run_rule(a_console_rule_generator, Console(), { (A, str): lambda _: A(), }) self.assertEquals(res, _GoalProduct.for_name('example')())
def _resolve_build_file_addresses(self, specs, address_family, snapshot, address_mapper): return run_rule(addresses_from_address_families, address_mapper, specs, { (Snapshot, PathGlobs): lambda _: snapshot, (AddressFamily, Dir): lambda _: address_family, })