コード例 #1
0
    def setUp(self):
        super(ApiTest, self).setUp()
        self.mock(acl, 'has_projects_access', mock.Mock())
        acl.has_projects_access.side_effect = (
            lambda pids: {pid: pid != 'secret'
                          for pid in pids})

        self.mock(acl, 'has_services_access',
                  lambda sids: {sid: True
                                for sid in sids})
        self.mock(projects, 'get_projects', mock.Mock())
        projects.get_projects.return_value = [
            service_config_pb2.Project(id='chromium'),
            service_config_pb2.Project(id='v8'),
        ]
        self.mock(
            projects, 'get_metadata_async',
            mock.Mock(
                return_value=future({
                    'chromium': project_config_pb2.ProjectCfg(),
                    'v8': project_config_pb2.ProjectCfg(),
                })))
        self.mock(
            projects, 'get_repos_async',
            mock.Mock(return_value=future({
                'chromium': (projects.RepositoryType.GITILES,
                             'https://chromium.example.com'),
                'v8': (projects.RepositoryType.GITILES,
                       'https://v8.example.com'),
            })))
コード例 #2
0
ファイル: api_test.py プロジェクト: stefb965/luci-py
  def test_get_config_multi(self):
    projects.get_projects.return_value.extend([
      service_config_pb2.Project(id='inconsistent'),
      service_config_pb2.Project(id='secret'),
    ])
    projects.get_metadata_async.return_value.get_result().update({
      'inconsistent': project_config_pb2.ProjectCfg(access='all'),
      'secret': project_config_pb2.ProjectCfg(access='administrators'),
    })
    projects.get_repos_async.return_value.get_result().update({
      'inconsistent': (None, None),
      'secret': (projects.RepositoryType.GITILES, 'https://localhost/secret'),
    })

    self.mock(storage, 'get_latest_configs_async', mock.Mock())
    storage.get_latest_configs_async.return_value = future({
      'projects/chromium': (
          'deadbeef',
          'https://x.com/+/deadbeef',
          'abc0123',
          'config text'
      ),
      'projects/v8': (
          'beefdead',
          'https://x.com/+/beefdead',
          'ccc123',
          None  # no content
      ),
      'projects/secret': (
          'badcoffee',
          'https://x.com/+/badcoffee',
          'abcabc',
          'abcsdjksl'
      ),
    })

    req = {'path': 'cq.cfg'}
    resp = self.call_api('get_project_configs', req).json_body

    self.assertEqual(resp, {
      'configs': [{
        'config_set': 'projects/chromium',
        'revision': 'deadbeef',
        'content_hash': 'abc0123',
        'content': base64.b64encode('config text'),
        'url': 'https://x.com/+/deadbeef',
      }],
    })
コード例 #3
0
    def test_get_projects(self):
        projects.get_projects.return_value = [
            service_config_pb2.Project(id='chromium'),
            service_config_pb2.Project(id='v8'),
            service_config_pb2.Project(id='inconsistent'),
            service_config_pb2.Project(id='secret'),
        ]
        projects.get_metadata_async.return_value = future({
            'chromium':
            project_config_pb2.ProjectCfg(name='Chromium, the best browser',
                                          access='all'),
            'v8':
            project_config_pb2.ProjectCfg(access='all'),
            'inconsistent':
            project_config_pb2.ProjectCfg(access='all'),
            'secret':
            project_config_pb2.ProjectCfg(access='administrators'),
        })
        projects.get_repos_async.return_value = future({
            'chromium':
            (projects.RepositoryType.GITILES, 'https://chromium.example.com'),
            'v8': (projects.RepositoryType.GITILES, 'https://v8.example.com'),
            'inconsistent': (None, None),
            'secret':
            (projects.RepositoryType.GITILES, 'https://localhost/secret'),
        })

        resp = self.call_api('get_projects', {}).json_body

        self.assertEqual(
            resp, {
                'projects': [
                    {
                        'id': 'chromium',
                        'name': 'Chromium, the best browser',
                        'repo_type': 'GITILES',
                        'repo_url': 'https://chromium.example.com',
                    },
                    {
                        'id': 'v8',
                        'repo_type': 'GITILES',
                        'repo_url': 'https://v8.example.com',
                    },
                ],
            })
コード例 #4
0
    def test_has_project_access_identity(self):
        self.mock(projects, 'get_metadata', mock.Mock())
        projects.get_metadata.return_value = project_config_pb2.ProjectCfg(
            access=['group:googlers', '*****@*****.**'])

        self.assertFalse(acl.can_read_config_set('projects/secret'))

        auth.get_current_identity.return_value = auth.Identity(
            'user', '*****@*****.**')
        self.assertTrue(acl.can_read_config_set('projects/secret'))
コード例 #5
0
ファイル: api_test.py プロジェクト: rmistry/luci-py
  def test_has_project_access_no_access(self):
    self.set_up_identity()

    self.mock(api, 'get_project_config_async', mock.Mock())
    api.get_project_config_async.return_value = ndb.Future()
    api.get_project_config_async.return_value.set_result(
        project_config_pb2.ProjectCfg(),  # access not configured => internal
    )

    self.assertFalse(config.has_project_access('chromium'))
コード例 #6
0
ファイル: api_test.py プロジェクト: molodiuc/luci-py
    def test_has_project_access_anon_identity(self):
        self.set_up_identity()

        self.mock(api, 'get_project_config_async', mock.Mock())
        api.get_project_config_async.return_value = ndb.Future()
        api.get_project_config_async.return_value.set_result(
            project_config_pb2.ProjectCfg(access=['anonymous:anonymous'], ))

        self.assertTrue(config.has_project_access('chromium'))

        api.get_project_config_async.assert_called_once('chromium')
コード例 #7
0
    def test_has_project_access_group(self):
        self.mock(projects, 'get_metadata', mock.Mock())
        projects.get_metadata.return_value = project_config_pb2.ProjectCfg(
            access=['group:googlers', '*****@*****.**'])

        self.assertFalse(acl.can_read_config_set('projects/secret'))

        auth.is_group_member.side_effect = lambda name: name == 'googlers'
        self.assertTrue(acl.can_read_config_set('projects/secret'))

        auth.is_group_member.side_effect = lambda name: name == 'project-admins'
        self.assertTrue(acl.can_read_config_set('projects/secret'))
コード例 #8
0
    def test_get_projects(self):
        projects.get_projects.return_value = [
            service_config_pb2.Project(id='chromium'),
            service_config_pb2.Project(id='v8'),
            service_config_pb2.Project(id='inconsistent'),
            service_config_pb2.Project(id='secret'),
        ]
        projects.get_metadata.side_effect = [
            project_config_pb2.ProjectCfg(name='Chromium, the best browser',
                                          access='all'),
            project_config_pb2.ProjectCfg(access='all'),
            project_config_pb2.ProjectCfg(access='all'),
            project_config_pb2.ProjectCfg(access='administrators'),
        ]
        projects.get_repo.side_effect = [
            (projects.RepositoryType.GITILES, 'http://localhost/chromium'),
            (projects.RepositoryType.GITILES, 'http://localhost/v8'),
            (None, None),
            (projects.RepositoryType.GITILES, 'http://localhost/secret'),
        ]

        resp = self.call_api('get_projects', {}).json_body

        self.assertEqual(
            resp, {
                'projects': [
                    {
                        'id': 'chromium',
                        'name': 'Chromium, the best browser',
                        'repo_type': 'GITILES',
                        'repo_url': 'http://localhost/chromium',
                    },
                    {
                        'id': 'v8',
                        'repo_type': 'GITILES',
                        'repo_url': 'http://localhost/v8',
                    },
                ],
            })
コード例 #9
0
  def test_has_project_access_group(self):
    self.mock(projects, 'get_metadata_async', mock.Mock(return_value=future({
      'secret': project_config_pb2.ProjectCfg(
          access=['group:googlers', '*****@*****.**']),
    })))

    self.assertFalse(can_read_config_set('projects/secret'))

    auth.is_group_member.side_effect = lambda name, *_: name == 'googlers'
    self.assertTrue(can_read_config_set('projects/secret'))

    auth.is_group_member.side_effect = lambda name, *_: name == 'project-admins'
    self.assertTrue(can_read_config_set('projects/secret'))
コード例 #10
0
def get_metadata_async(project_ids):
    """Returns a mapping {project_id: metadata}.

  If a project does not exist, the metadata is None.

  The project metadata stored in project.cfg files in each project.
  """
    PROJECT_DOES_NOT_EXIST_SENTINEL = (0, )
    cache_ns = 'projects.get_metadata'
    ctx = ndb.get_context()
    # ctx.memcache_get is auto-batching. Internally it makes get_multi RPC.
    cache_futs = {
        pid: ctx.memcache_get(pid, namespace=cache_ns)
        for pid in project_ids
    }
    yield cache_futs.values()
    result = {}
    missing = []
    for pid in project_ids:
        binary = cache_futs[pid].get_result()
        if binary is not None:
            # cache hit
            if binary == PROJECT_DOES_NOT_EXIST_SENTINEL:
                result[pid] = None
            else:
                cfg = project_config_pb2.ProjectCfg()
                cfg.ParseFromString(binary)
                result[pid] = cfg
        else:
            # cache miss
            missing.append(pid)

    if missing:
        fetched = yield _get_project_configs_async(
            missing, common.PROJECT_METADATA_FILENAME,
            project_config_pb2.ProjectCfg)
        result.update(
            fetched)  # at this point result must have all project ids
        # Cache metadata for 10 min. In practice, it never changes.
        # ctx.memcache_set is auto-batching. Internally it makes set_multi RPC.
        yield [
            ctx.memcache_set(pid,
                             cfg.SerializeToString()
                             if cfg else PROJECT_DOES_NOT_EXIST_SENTINEL,
                             namespace=cache_ns,
                             time=60 * 10) for pid, cfg in fetched.items()
        ]

    raise ndb.Return(result)
コード例 #11
0
 def setUp(self):
     super(ApiTest, self).setUp()
     self.mock(acl, 'has_project_access', mock.Mock())
     acl.has_project_access.side_effect = (lambda pid: pid != 'secret')
     self.mock(acl, 'has_service_access', mock.Mock(return_value=True))
     self.mock(projects, 'get_projects', mock.Mock())
     projects.get_projects.return_value = [
         service_config_pb2.Project(id='chromium'),
         service_config_pb2.Project(id='v8'),
     ]
     self.mock(projects, 'get_metadata', mock.Mock())
     projects.get_metadata.return_value = project_config_pb2.ProjectCfg()
     self.mock(projects, 'get_repo', mock.Mock())
     projects.get_repo.return_value = (projects.RepositoryType.GITILES,
                                       'https://localhost/project')