def test_invalidate_build_file_added(self): address_family = self.address_mapper.family('a/b') a_b_target = Target( name='b', dependencies=['//d:e'], configurations=['//a', Configuration(embedded='yes')]) self.assertEqual({Address.parse('a/b'): a_b_target}, address_family.addressables) with open(os.path.join(self.build_root, 'a/b/sibling.BUILD.json'), 'w') as fp: fp.write('{"typename": "configuration", "name": "c"}') still_valid = self.address_mapper.family('a/b') self.assertIs(address_family, still_valid) self.address_mapper.invalidate_build_file('a/b/sibling.BUILD.json') newly_formed = self.address_mapper.family('a/b') self.assertIsNot(address_family, newly_formed) self.assertEqual( { Address.parse('a/b'): a_b_target, Address.parse('a/b:c'): Configuration(name='c') }, newly_formed.addressables)
def do_test_codegen_simple(self, graph): def address(name): return Address(spec_path='examples/graph_test', target_name=name) resolved_java1 = graph.resolve(address('java1')) nonstrict = ApacheThriftConfiguration(address=address('nonstrict'), version='0.9.2', strict=False, lang='java') public = Configuration(address=address('public'), url='https://oss.sonatype.org/#stagingRepositories') thrift1 = Target(address=address('thrift1'), sources=[]) thrift2 = Target(address=address('thrift2'), sources=[], dependencies=[thrift1]) expected_java1 = Target(address=address('java1'), sources=[], configurations=[ ApacheThriftConfiguration(version='0.9.2', strict=True, lang='java'), nonstrict, PublishConfiguration( default_repo=public, repos={ 'jake': Configuration(url='https://dl.bintray.com/pantsbuild/maven'), 'jane': public } ) ], dependencies=[thrift2]) self.assertEqual(expected_java1, resolved_java1)
def test_extend_and_merge(self): # Resolution should be lazy, so - although its invalid to both extend and merge, we should be # able to create the config. config = Configuration(extends=Configuration(), merges=Configuration()) with self.assertRaises(ValidationError): # But we should fail when we go to actually inherit. config.create()
def test_walk_addressables(self): self.assertEqual(sorted([(self.addr('//:root'), Configuration(name='root')), (self.addr('a/b:b'), self.a_b_target), (self.addr('a/d:d'), Target(name='d')), (self.addr('a/d/e:e'), Target(name='e')), (self.addr('a/d/e:e-prime'), Configuration(name='e-prime'))]), sorted(self.address_mapper.walk_addressables()))
def test_extend(self): extends = Configuration(age=32, label='green', items=[], extends=Configuration(age=42, other=True, items=[1, 2])) # Extension is lazy, so we don't pick up the other field yet. self.assertNotEqual(Configuration(age=32, label='green', items=[], other=True), extends) # But we do pick it up now. self.assertEqual(Configuration(age=32, label='green', items=[], other=True), extends.create())
def test_type_alias(self): self.assertEqual('Configuration', Configuration().type_alias) self.assertEqual('aliased', Configuration(type_alias='aliased').type_alias) class Subclass(Configuration): pass self.assertEqual('Subclass', Subclass().type_alias) self.assertEqual('aliased_subclass', Subclass(type_alias='aliased_subclass').type_alias)
def test_extend_and_merge(self): extends_and_merges = Configuration( age=32, label="green", items=[5], extends=Configuration(age=42, other=True, knobs={"a": True}, items=[1, 2]), merges=[ Configuration(age=52, other=False, items=[1, 3, 4], knobs={"a": False, "b": True}), Configuration(items=[2]), ], ) self.assertEqual( Configuration(age=32, label="green", other=True, items=[5, 1, 3, 4, 2], knobs={"a": False, "b": True}), extends_and_merges.create(), )
def test_resolve(self): resolved = self.address_mapper.resolve(Address.parse('a/b')) self.assertEqual( Target(name='b', dependencies=['//d:e'], configurations=['//a', Configuration(embedded='yes')]), resolved)
def test_merge(self): merges = Configuration(age=32, items=[3], knobs={'b': False}, merges=Configuration(age=42, other=True, items=[1, 2], knobs={'a': True, 'b': True})) # Merging is lazy, so we don't pick up the other field yet. self.assertNotEqual(Configuration(age=32, items=[1, 2, 3], knobs={'a': True, 'b': False}, other=True), merges) # But we do pick it up now. self.assertEqual(Configuration(age=32, items=[1, 2, 3], knobs={'a': True, 'b': False}, other=True), merges.create())
def test_merge(self): merges = Configuration(age=32, items=[3], knobs={'b': False}, merges=Configuration(age=42, other=True, items=[1, 2], knobs={ 'a': True, 'b': True })) # Merging is lazy, so we don't pick up the other field yet. self.assertNotEqual( Configuration(age=32, items=[1, 2, 3], knobs={ 'a': True, 'b': False }, other=True), merges) # But we do pick it up now. self.assertEqual( Configuration(age=32, items=[1, 2, 3], knobs={ 'a': True, 'b': False }, other=True), merges.create())
def setUp(self): self.work_dir = safe_mkdtemp() self.addCleanup(safe_rmtree, self.work_dir) self.build_root = os.path.join(self.work_dir, 'build_root') shutil.copytree(os.path.join(os.path.dirname(__file__), 'examples/mapper_test'), self.build_root) parser = partial(parse_json, symbol_table={'configuration': Configuration, 'target': Target}) self.address_mapper = AddressMapper(build_root=self.build_root, build_pattern=r'.+\.BUILD.json$', parser=parser) self.a_b_target = Target(name='b', dependencies=['//d:e'], configurations=['//a', Configuration(embedded='yes')])
def test_invalidation_relative(self): resolved = self.address_mapper.resolve(Address.parse('a/b')) a_b_target = Target( name='b', dependencies=['//d:e'], configurations=['//a', Configuration(embedded='yes')]) self.assertEqual(a_b_target, resolved) build_file = os.path.join(self.build_root, 'a/b/b.BUILD.json') os.unlink(build_file) self.assertIs(resolved, self.address_mapper.resolve(Address.parse('a/b'))) self.address_mapper.invalidate_build_file('a/b/b.BUILD.json') with self.assertRaises(ResolveError): self.address_mapper.resolve(Address.parse('a/b'))
def test_no_address_no_family(self): with self.assertRaises(ResolveError): self.address_mapper.resolve(Address.parse('a/c')) # Errors are not cached. with self.assertRaises(ResolveError): self.address_mapper.resolve(Address.parse('a/c')) build_file = os.path.join(self.build_root, 'a/c/c.BUILD.json') with safe_open(build_file, 'w') as fp: fp.write('{"type_alias": "configuration", "name": "c"}') resolved = self.address_mapper.resolve(Address.parse('a/c')) self.assertEqual(Configuration(name='c'), resolved) # But success is cached. self.assertIs(resolved, self.address_mapper.resolve(Address.parse('a/c')))
def test_invalidate_build_file_changed(self): with self.assertRaises(ResolveError): self.address_mapper.resolve(Address.parse('a/b:c')) build_file = os.path.join(self.build_root, 'a/b/b.BUILD.json') with safe_open(build_file, 'w+') as fp: fp.write('{"type_alias": "configuration", "name": "c"}') with self.assertRaises(ResolveError): self.address_mapper.resolve(Address.parse('a/b:c')) self.address_mapper.invalidate_build_file('a/b/b.BUILD.json') resolved = self.address_mapper.resolve(Address.parse('a/b:c')) self.assertEqual(Configuration(name='c'), resolved) # But success is cached. self.assertIs(resolved, self.address_mapper.resolve(Address.parse('a/b:c')))
def test_extend_and_merge(self): extends_and_merges = Configuration(age=32, label='green', items=[5], extends=Configuration(age=42, other=True, knobs={'a': True}, items=[1, 2]), merges=[Configuration(age=52, other=False, items=[1, 3, 4], knobs={'a': False, 'b': True}), Configuration(items=[2])]) self.assertEqual(Configuration(age=32, label='green', other=True, items=[5, 1, 3, 4, 2], knobs={'a': False, 'b': True}), extends_and_merges.create())
def test_invalidation_un_normalized(self): resolved = self.address_mapper.resolve(Address.parse('a/b')) a_b_target = Target( name='b', dependencies=['//d:e'], configurations=['//a', Configuration(embedded='yes')]) self.assertEqual(a_b_target, resolved) os.unlink(os.path.join(self.build_root, 'a/b/b.BUILD.json')) self.assertIs(resolved, self.address_mapper.resolve(Address.parse('a/b'))) un_normalized_build_root = os.path.join(self.work_dir, 'build_root_linked') os.symlink(self.build_root, un_normalized_build_root) un_normalized_build_file = os.path.join(un_normalized_build_root, 'a/b/b.BUILD.json') self.address_mapper.invalidate_build_file(un_normalized_build_file) with self.assertRaises(ResolveError): self.address_mapper.resolve(Address.parse('a/b'))
def test_address_name_conflict(self): with self.assertRaises(ValidationError): Configuration(name='a', address=Address.parse('a:b'))
def test_address_no_name(self): config = Configuration(address=Address.parse('a:b')) self.assertEqual('b', config.name)
def do_test_codegen_simple(self, graph): def address(name): return Address(spec_path='examples/graph_test', target_name=name) def resolver(addr): return Resolver(graph, addr) java1_address = address('java1') resolved_java1 = graph.resolve(java1_address) nonstrict_address = address('nonstrict') public_address = address('public') thrift2_address = address('thrift2') expected_java1 = Target( address=java1_address, sources={}, configurations=[ ApacheThriftConfiguration(version='0.9.2', strict=True, lang='java'), resolver(nonstrict_address), PublishConfiguration( default_repo=resolver(public_address), repos={ 'jake': Configuration( url='https://dl.bintray.com/pantsbuild/maven'), 'jane': resolver(public_address) }) ], dependencies=[resolver(thrift2_address)]) self.assertEqual(expected_java1, resolved_java1) expected_nonstrict = ApacheThriftConfiguration( address=nonstrict_address, version='0.9.2', strict=False, lang='java') resolved_nonstrict = graph.resolve(nonstrict_address) self.assertEqual(expected_nonstrict, resolved_nonstrict) self.assertEqual(expected_nonstrict, expected_java1.configurations[1]) self.assertIs(expected_java1.configurations[1], resolved_nonstrict) expected_public = Configuration( address=public_address, url='https://oss.sonatype.org/#stagingRepositories') resolved_public = graph.resolve(public_address) self.assertEqual(expected_public, resolved_public) self.assertEqual(expected_public, expected_java1.configurations[2].default_repo) self.assertEqual(expected_public, expected_java1.configurations[2].repos['jane']) self.assertIs(expected_java1.configurations[2].default_repo, resolved_public) self.assertIs(expected_java1.configurations[2].repos['jane'], resolved_public) thrift1_address = address('thrift1') expected_thrift2 = Target(address=thrift2_address, dependencies=[resolver(thrift1_address)]) resolved_thrift2 = graph.resolve(thrift2_address) self.assertEqual(expected_thrift2, resolved_thrift2) self.assertEqual(expected_thrift2, resolved_java1.dependencies[0]) self.assertIs(resolved_java1.dependencies[0], resolved_thrift2) expected_thrift1 = Target(address=thrift1_address) resolved_thrift1 = graph.resolve(thrift1_address) self.assertEqual(expected_thrift1, resolved_thrift1) self.assertEqual(expected_thrift1, resolved_thrift2.dependencies[0]) self.assertIs(resolved_thrift2.dependencies[0], resolved_thrift1)
def test_walk_addressables_path_excludes(self): self.assertEqual([(self.addr('//:root'), Configuration(name='root')), (self.addr('a/d:d'), Target(name='d'))], list(self.address_mapper.walk_addressables(path_excludes=['a/b', 'a/d/e'])))
def test_walk_addressables_rel_path(self): self.assertEqual(sorted([(self.addr('a/d:d'), Target(name='d')), (self.addr('a/d/e:e'), Target(name='e')), (self.addr('a/d/e:e-prime'), Configuration(name='e-prime'))]), sorted(self.address_mapper.walk_addressables(rel_path='a/d')))