def test_walk_addressables(self): self.assertEqual({self.addr('//:root'): Struct(name='root', type_alias='struct'), self.addr('a/b:b'): self.a_b_target, self.addr('a/d:d'): Target(name='d', type_alias='target'), self.addr('a/d/e:e'): Target(name='e', type_alias='target'), self.addr('a/d/e:e-prime'): Struct(name='e-prime', type_alias='struct')}, self.resolve_multi(DescendantAddresses('')))
def do_test_codegen_simple(self, scheduler): def address(name): return Address(spec_path='graph_test', target_name=name) resolved_java1 = self.resolve(scheduler, address('java1')) nonstrict = ApacheThriftConfiguration(address=address('nonstrict'), version='0.9.2', strict=False, lang='java') public = Struct(address=address('public'), url='https://oss.sonatype.org/#stagingRepositories') thrift1 = Target(address=address('thrift1')) thrift2 = Target(address=address('thrift2'), dependencies=[thrift1]) expected_java1 = Target( address=address('java1'), configurations=[ ApacheThriftConfiguration(version='0.9.2', strict=True, lang='java'), nonstrict, PublishConfiguration( default_repo=public, repos={ 'jake': Struct(url='https://dl.bintray.com/pantsbuild/maven'), 'jane': public }) ], dependencies=[thrift2]) self.assertEqual(expected_java1, resolved_java1)
def test_walk_addressables(self): self.assertEqual( sorted([(self.addr('//:root'), Struct(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'), Struct(name='e-prime'))]), sorted(self.address_mapper.walk_addressables()))
def test_type_alias(self): self.assertEqual('Struct', Struct().type_alias) self.assertEqual('aliased', Struct(type_alias='aliased').type_alias) class Subclass(Struct): pass self.assertEqual('Subclass', Subclass().type_alias) self.assertEqual('aliased_subclass', Subclass(type_alias='aliased_subclass').type_alias)
def test_walk_addressables_rel_path(self): self.assertEqual( { self.addr('a/d:d'): Target(name='d'), self.addr('a/d/e:e'): Target(name='e'), self.addr('a/d/e:e-prime'): Struct(name='e-prime') }, self.resolve_multi(DescendantAddresses('a/d')))
def test_extend_and_merge(self): extends_and_merges = Struct(age=32, label='green', items=[5], extends=Struct(age=42, other=True, knobs={'a': True}, items=[1, 2]), merges=[Struct(age=52, other=False, items=[1, 3, 4], knobs={'a': False, 'b': True}), Struct(items=[2])]) self.assertEqual(Struct(age=32, label='green', other=True, items=[5, 1, 3, 4, 2], knobs={'a': False, 'b': True}), extends_and_merges.create())
def test_extend_and_merge(self): extends_and_merges = Struct(age=32, label='green', items=[5], extends=Struct(age=42, other=True, knobs={'a': True}, items=[1, 2]), merges=[ Struct(age=52, other=False, items=[1, 3, 4], knobs={ 'a': False, 'b': True }), Struct(items=[2]) ]) self.assertEqual( Struct(age=32, label='green', other=True, items=[5, 1, 3, 4, 2], knobs={ 'a': False, 'b': True }), extends_and_merges.create())
def test_merge(self): merges = Struct(age=32, items=[3], knobs={'b': False}, merges=[Struct(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(Struct(age=32, items=[1, 2, 3], knobs={'a': True, 'b': False}, other=True), merges) # But we do pick it up now. self.assertEqual(Struct(age=32, items=[3, 1, 2], knobs={'a': True, 'b': True}, other=True), merges.create())
def test_merge(self): merges = Struct(age=32, items=[3], knobs={'b': False}, merges=[ Struct(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( Struct(age=32, items=[3, 1, 2], knobs={ 'a': True, 'b': True }, other=True), merges) # But we do pick it up now. self.assertEqual( Struct(age=32, items=[3, 1, 2], knobs={ 'a': True, 'b': True }, other=True), merges.create())
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": "struct", "name": "c"}') resolved = self.address_mapper.resolve(Address.parse('a/c')) self.assertEqual(Struct(name='c'), resolved)
def test_extend(self): extends = Struct(age=32, label='green', items=[], extends=Struct(age=42, other=True, items=[1, 2])) # Extension is lazy, so we don't pick up the other field yet. self.assertNotEqual(Struct(age=32, label='green', items=[], other=True), extends) # But we do pick it up now. self.assertEqual(Struct(age=32, label='green', items=[], other=True), extends.create())
def test_no_address_no_family(self): spec = SingleAddress('a/c', None) # Should fail: does not exist. with self.assertRaises(ResolveError): self.resolve(spec) # Exists on disk, but not yet in memory. # NB: Graph invalidation not yet implemented. 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": "struct", "name": "c"}') with self.assertRaises(ResolveError): self.resolve(spec) # Success. self.scheduler.product_graph.clear() self.assertEqual(Struct(name='c'), self.resolve(spec).struct)
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) self.address_mapper = AddressMapper(build_root=self.build_root, symbol_table_cls=TargetTable, parser_cls=JsonParser, build_pattern=r'.+\.BUILD.json$') self.a_b_target = Target( name='b', dependencies=['//d:e'], configurations=['//a', Struct(embedded='yes')])
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": "struct", "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(Struct(name='c'), resolved) # But success is cached. self.assertIs(resolved, self.address_mapper.resolve(Address.parse('a/b:c')))
def setUp(self): # Set up a scheduler that supports address mapping. symbol_table_cls = TargetTable self.storage = Storage.create(in_memory=True) address_mapper = AddressMapper(symbol_table_cls=symbol_table_cls, parser_cls=JsonParser, build_pattern=r'.+\.BUILD.json$') tasks = create_graph_tasks(address_mapper, symbol_table_cls) build_root_src = os.path.join(os.path.dirname(__file__), 'examples/mapper_test') self.scheduler, _, self.build_root = self.mk_scheduler(tasks=tasks, build_root_src=build_root_src, storage=self.storage, symbol_table_cls=symbol_table_cls) self.a_b = Address.parse('a/b') self.a_b_target = Target(name='b', dependencies=['//d:e'], configurations=['//a', Struct(embedded='yes')], type_alias='target')
def test_invalidate_build_file_added(self): address_family = self.address_mapper.family('a/b') self.assertEqual({Address.parse('a/b'): self.a_b_target}, address_family.addressables) with open(os.path.join(self.build_root, 'a/b/sibling.BUILD.json'), 'w') as fp: fp.write('{"type_alias": "struct", "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'): self.a_b_target, Address.parse('a/b:c'): Struct(name='c') }, newly_formed.addressables)
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) self._goal = 'list' symbol_table_cls = TargetTable self.address_mapper = AddressMapper(symbol_table_cls=symbol_table_cls, parser_cls=JsonParser, build_pattern=r'.+\.BUILD.json$') tasks = (create_fs_tasks(self.build_root) + create_graph_tasks(self.address_mapper, symbol_table_cls)) self.scheduler = LocalScheduler({self._goal: UnhydratedStruct}, symbol_table_cls, tasks) self.a_b = Address.parse('a/b') self.a_b_target = Target( name='b', dependencies=['//d:e'], configurations=['//a', Struct(embedded='yes')])
def test_address_no_name(self): config = Struct(address=Address.parse('a:b')) self.assertEqual('b', config.name)
def do_test_codegen_simple(self, scheduler): def address(name): return Address(spec_path='graph_test', target_name=name) java1_address = address('java1') resolved_java1 = self.resolve(scheduler, java1_address) nonstrict_address = address('nonstrict') expected_nonstrict = ApacheThriftConfiguration( address=nonstrict_address, version='0.9.2', strict=False, lang='java') public_address = address('public') expected_public = Struct( address=public_address, url='https://oss.sonatype.org/#stagingRepositories') thrift2_address = address('thrift2') expected_java1 = Target( address=java1_address, sources={}, configurations=[ PublishConfiguration( default_repo=expected_public, repos={ 'jake': Struct(url='https://dl.bintray.com/pantsbuild/maven'), 'jane': expected_public }), expected_nonstrict, ApacheThriftConfiguration( version='0.9.2', strict=True, lang='java', dependencies=[address(thrift2_address)]), ]) self.assertEqual(expected_java1, resolved_java1) resolved_nonstrict = self.resolve(scheduler, nonstrict_address) self.assertEqual(expected_nonstrict, resolved_nonstrict) self.assertEqual(expected_nonstrict, expected_java1.configurations[1]) self.assertEquals(resolved_java1.configurations[1], resolved_nonstrict) resolved_public = self.resolve(scheduler, public_address) self.assertEqual(expected_public, resolved_public) self.assertEqual(expected_public, expected_java1.configurations[0].default_repo) self.assertEqual(expected_public, expected_java1.configurations[0].repos['jane']) self.assertEquals(resolved_java1.configurations[0].default_repo, resolved_public) self.assertEquals(resolved_java1.configurations[0].repos['jane'], resolved_public) # NB: `dependencies` lists must be explicitly requested by tasks, so we expect an Address. thrift1_address = address('thrift1') expected_thrift2 = Target(address=thrift2_address, dependencies=[thrift1_address]) resolved_thrift2 = self.resolve(scheduler, thrift2_address) self.assertEqual(expected_thrift2, resolved_thrift2) expected_thrift1 = Target(address=thrift1_address) resolved_thrift1 = self.resolve(scheduler, thrift1_address) self.assertEqual(expected_thrift1, resolved_thrift1)
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', dependencies=[resolver(thrift2_address)]), resolver(nonstrict_address), PublishConfiguration( default_repo=resolver(public_address), repos={ 'jake': Struct(url='https://dl.bintray.com/pantsbuild/maven'), 'jane': resolver(public_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 = Struct( 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) resolved_thrift_config = [ config for config in resolved_java1.configurations if isinstance(config, ApacheThriftConfiguration) ] self.assertEqual(expected_thrift2, resolved_thrift_config[0].dependencies[0]) self.assertIs(resolved_thrift_config[0].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'), Struct(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'), Struct(name='e-prime'))]), sorted(self.address_mapper.walk_addressables(rel_path='a/d')))
def test_address_name_conflict(self): with self.assertRaises(ValidationError): Struct(name='a', address=Address.parse('a:b'))
def test_walk_addressables_path_excludes(self): self.assertEqual( { self.addr('//:root'): Struct(name='root'), self.addr('a/d:d'): Target(name='d') }, self.resolve_multi(DescendantAddresses('')))