示例#1
0
class AddressMapperTest(unittest.TestCase):
  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)

    subjects = Subjects()
    self._goal = 'list'
    symbol_table_cls = TargetTable

    project_tree_key = subjects.put(
        FileSystemProjectTree(self.build_root))
    address_mapper_key = subjects.put(
        AddressMapper(symbol_table_cls=symbol_table_cls,
                      parser_cls=JsonParser,
                      build_pattern=r'.+\.BUILD.json$'))
    tasks = (
        create_fs_tasks(project_tree_key) +
        create_graph_tasks(address_mapper_key, symbol_table_cls)
      )
    self.scheduler = LocalScheduler({self._goal: UnhydratedStruct},
                                    tasks,
                                    subjects,
                                    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 resolve(self, spec):
    request = self.scheduler.build_request(goals=[self._goal], subjects=[spec])
    result = LocalSerialEngine(self.scheduler).execute(request)
    if result.error:
      raise result.error

    # Expect a single root.
    state, = result.root_products.values()
    if type(state) is Throw:
      raise state.exc
    return state.value

  def resolve_multi(self, spec):
    return {uhs.address: uhs.struct for uhs in self.resolve(spec)}

  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()
    resolved = self.resolve(spec)
    self.assertEqual(1, len(resolved))
    self.assertEqual(Struct(name='c', type_alias='struct'), resolved[0].struct)

  def test_resolve(self):
    resolved = self.resolve(SingleAddress('a/b', None))
    self.assertEqual(1, len(resolved))
    self.assertEqual(self.a_b, resolved[0].address)

  @staticmethod
  def addr(spec):
    return Address.parse(spec)

  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 test_walk_addressables_rel_path(self):
    self.assertEqual({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('a/d')))

  @pytest.mark.xfail(reason='''Excludes are not implemented: expects excludes=['a/b', 'a/d/e'])''')
  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('')))