def test_ingest_preview(self): self.respond_to_github('https://api.github.com/repos/org/repo', '{"owner":{"login":"******"},"name":"repo"}') self.respond_to_github( 'https://api.github.com/repos/org/repo/contributors', '["a"]') self.respond_to_github( 'https://api.github.com/repos/org/repo/stats/participation', '{}') self.respond_to_github( 'https://raw.githubusercontent.com/org/repo/master/bower.json', '{"license": "MIT"}') response = self.app.get(util.ingest_preview_task('org', 'repo'), params={ 'commit': 'commit-sha', 'url': 'url' }, headers={'X-AppEngine-QueueName': 'default'}) self.assertEqual(response.status_int, 200) library = Library.get_by_id('org/repo') self.assertIsNotNone(library) self.assertIsNone(library.error) self.assertTrue(library.shallow_ingestion) version = Version.get_by_id('commit-sha', parent=library.key) self.assertEquals(version.status, Status.pending) self.assertEquals(version.sha, 'commit-sha') self.assertEquals(version.url, 'url') self.assertTrue(version.preview) tasks = self.tasks.get_filtered_tasks() self.assertEqual(len(tasks), 2) self.assertEqual([ util.ingest_analysis_task('org', 'repo', 'commit-sha'), util.ingest_version_task('org', 'repo', 'commit-sha'), ], [task.url for task in tasks])
def handle_get(self, owner, repo, latest=False): self.init_library(owner, repo) if self.library is None: self.response.set_status(404) self.response.write('could not find library: %s' % Library.id(owner, repo)) return if latest: version_id = Library.default_version_for_key_async( self.library.key).get_result() if version_id: version = Version.get_by_id(version_id, parent=self.library.key) if version is not None: self.trigger_analysis(version_id, version.sha, transactional=False) else: versions = Version.query(Version.status == Status.ready, ancestor=self.library.key).fetch() for version in versions: self.trigger_analysis(version.key.id(), version.sha, transactional=False)
def test_update_collection(self): library_key = Library(id='org/repo', tags=['v0.0.1'], collection_sequence_number=1, kind='collection', spdx_identifier='MIT').put() Version(id='v0.0.1', parent=library_key, sha="old", status=Status.ready).put() self.respond_to_github('https://api.github.com/repos/org/repo', {'status': 304}) self.respond_to_github('https://api.github.com/repos/org/repo/contributors', {'status': 304}) self.respond_to_github('https://api.github.com/repos/org/repo/stats/participation', '{}') self.respond_to_github('https://api.github.com/repos/org/repo/git/refs/heads/master', """{ "ref": "refs/heads/master", "object": {"sha": "new-master-sha"} }""") response = self.app.get(util.update_library_task('org/repo'), headers={'X-AppEngine-QueueName': 'default'}) self.assertEqual(response.status_int, 200) library = library_key.get() self.assertEqual(library.error, None) self.assertEqual(library.status, Status.ready) tasks = self.tasks.get_filtered_tasks() self.assertEqual([ util.ingest_analysis_task('org', 'repo', 'v0.0.2', 'new-master-sha'), util.ingest_version_task('org', 'repo', 'v0.0.2'), ], [task.url for task in tasks]) version = Version.get_by_id('v0.0.2', parent=library_key) self.assertEqual(version.sha, 'new-master-sha') self.assertEqual(version.status, Status.pending)
def test_ingest_version(self): library_key = Library(id='org/repo', metadata='{"full_name": "NSS Bob", "stargazers_count": 420, "subscribers_count": 419, "forks": 418, "updated_at": "2011-8-10T13:47:12Z"}').put() Version(id='v1.0.0', parent=library_key, sha='sha').put() self.respond_to_github(r'https://api.github.com/repos/org/repo/readme\?ref=sha', '{"content":"%s"}' % b64encode('README')) self.respond_to('https://raw.githubusercontent.com/org/repo/sha/bower.json', '{}') self.respond_to_github('https://api.github.com/markdown', '<html>README</html>') response = self.app.get(util.ingest_version_task('org', 'repo', 'v1.0.0'), headers={'X-AppEngine-QueueName': 'default'}) self.assertEqual(response.status_int, 200) version = Version.get_by_id('v1.0.0', parent=library_key) self.assertIsNone(version.error) self.assertEqual(version.status, Status.ready) self.assertFalse(version.preview) versions = Library.versions_for_key_async(library_key).get_result() self.assertEqual(['v1.0.0'], versions) readme = ndb.Key(Library, 'org/repo', Version, 'v1.0.0', Content, 'readme').get() self.assertEqual(readme.content, 'README') readme_html = ndb.Key(Library, 'org/repo', Version, 'v1.0.0', Content, 'readme.html').get() self.assertEqual(readme_html.content, '<html>README</html>') bower = ndb.Key(Library, 'org/repo', Version, 'v1.0.0', Content, 'bower').get() self.assertEqual(bower.get_json(), {})
def test_ingest_preview(self): self.respond_to_github('https://api.github.com/repos/org/repo', '{"owner":{"login":"******"},"name":"repo"}') self.respond_to_github('https://api.github.com/repos/org/repo/contributors', '["a"]') self.respond_to_github('https://api.github.com/repos/org/repo/stats/participation', '{}') self.respond_to_github('https://raw.githubusercontent.com/org/repo/master/bower.json', '{"license": "MIT"}') response = self.app.get(util.ingest_preview_task('org', 'repo'), params={'commit': 'commit-sha', 'url': 'url'}, headers={'X-AppEngine-QueueName': 'default'}) self.assertEqual(response.status_int, 200) library = Library.get_by_id('org/repo') self.assertIsNotNone(library) self.assertIsNone(library.error) self.assertTrue(library.shallow_ingestion) version = Version.get_by_id('commit-sha', parent=library.key) self.assertEquals(version.status, Status.pending) self.assertEquals(version.sha, 'commit-sha') self.assertEquals(version.url, 'url') self.assertTrue(version.preview) tasks = self.tasks.get_filtered_tasks() self.assertEqual(len(tasks), 2) self.assertEqual([ util.ingest_analysis_task('org', 'repo', 'commit-sha'), util.ingest_version_task('org', 'repo', 'commit-sha'), ], [task.url for task in tasks])
def test_ingest_version(self): library_key = Library(id='org/repo', metadata='{"full_name": "NSS Bob", "stargazers_count": 420, "subscribers_count": 419, "forks": 418, "updated_at": "2011-8-10T13:47:12Z"}').put() Version(id='v1.0.0', parent=library_key, sha='sha').put() self.respond_to_github(r'https://api.github.com/repos/org/repo/readme\?ref=sha', '{"content":"%s"}' % b64encode('README')) self.respond_to('https://raw.githubusercontent.com/org/repo/sha/bower.json', '{}') self.respond_to_github('https://api.github.com/markdown', '<html>README</html>') response = self.app.get(util.ingest_version_task('org', 'repo', 'v1.0.0'), headers={'X-AppEngine-QueueName': 'default'}) self.assertEqual(response.status_int, 200) version = Version.get_by_id('v1.0.0', parent=library_key) self.assertIsNone(version.error) self.assertEqual(version.status, Status.ready) self.assertFalse(version.preview) versions = Library.versions_for_key_async(library_key).get_result() self.assertEqual(['v1.0.0'], versions) readme = ndb.Key(Library, 'org/repo', Version, 'v1.0.0', Content, 'readme').get() self.assertEqual(readme.content, 'README') readme_html = ndb.Key(Library, 'org/repo', Version, 'v1.0.0', Content, 'readme.html').get() self.assertEqual(readme_html.content, '<html>README</html>') bower = ndb.Key(Library, 'org/repo', Version, 'v1.0.0', Content, 'bower').get() self.assertEqual(bower.content, '{}')
def trigger_version_ingestion(self, tag, sha, url=None, preview=False): version_object = Version.get_by_id(tag, parent=self.library.key) if version_object is not None and (version_object.status == Status.ready or version_object.status == Status.pending): # Version object is already up to date or pending return False Version(id=tag, parent=self.library.key, sha=sha, url=url, preview=preview).put() task_url = util.ingest_version_task(self.owner, self.repo, tag) util.new_task(task_url, target='manage', transactional=True) self.trigger_analysis(tag, sha, transactional=True) return True
def trigger_version_ingestion(self, tag, sha, url=None, preview=False): version_object = Version.get_by_id(tag, parent=self.library.key) if version_object is not None and (version_object.status == Status.ready or version_object.status == Status.pending): # Version object is already up to date or pending return False Version(id=tag, parent=self.library.key, sha=sha, url=url, preview=preview).put() task_url = util.ingest_version_task(self.scope, self.package, tag) util.new_task(task_url, target='manage', transactional=True) self.trigger_analysis(tag, sha, transactional=True) return True
def handle_get(self, owner, repo, version): self.owner = owner self.repo = repo self.version = version library_key = ndb.Key(Library, Library.id(owner, repo)) self.version_object = Version.get_by_id(version, parent=library_key) if self.version_object is None: return self.error('Version entity does not exist: %s/%s' % (Library.id(owner, repo), version)) self.sha = self.version_object.sha self.version_key = self.version_object.key self.update_readme() self.update_bower() self.set_ready()
def test_ingest_commit(self): self.respond_to_github('https://api.github.com/repos/org/repo', 'metadata bits') self.respond_to_github('https://api.github.com/repos/org/repo/contributors', '["a"]') self.app.get(util.ingest_commit_task('org', 'repo', 'element'), params={'commit': 'commit-sha', 'url': 'url'}) library = Library.get_by_id('org/repo') self.assertIsNotNone(library) self.assertIsNone(library.error) self.assertFalse(library.ingest_versions) version = Version.get_by_id(parent=library.key, id='commit-sha') self.assertEqual(version.sha, 'commit-sha') self.assertEqual(version.url, 'url') tasks = self.tasks.get_filtered_tasks() self.assertEqual(len(tasks), 1) self.assertEqual(tasks[0].url, util.ingest_version_task('org', 'repo', 'commit-sha'))
def handle_get(self, scope, package, latest=False): self.init_library(scope, package) if self.library is None: self.response.set_status(404) self.response.write('could not find library: %s' % Library.id(scope, package)) return if latest: version_id = Library.default_version_for_key_async(self.library.key).get_result() if version_id: version = Version.get_by_id(version_id, parent=self.library.key) if version is not None: self.trigger_analysis(version_id, version.sha, transactional=False) else: versions = Version.query(Version.status == Status.ready, ancestor=self.library.key).fetch() for version in versions: self.trigger_analysis(version.key.id(), version.sha, transactional=False)
def post(self): message_json = json.loads(urllib.unquote(self.request.body).rstrip('=')) message = message_json['message'] data = base64.b64decode(str(message['data'])) attributes = message['attributes'] owner = attributes['owner'] repo = attributes['repo'] version = attributes['version'] logging.info('Ingesting analysis data %s/%s/%s', owner, repo, version) parent = Version.get_by_id(version, parent=ndb.Key(Library, '%s/%s' % (owner, repo))) # Don't accept the analysis data unless the version still exists in the datastore if parent is not None: content = Content(parent=parent.key, id='analysis', content=data) try: content.put() # TODO: Which exception is this for? # pylint: disable=bare-except except: logging.error(sys.exc_info()[0]) self.response.set_status(200)
def get(self, owner, repo, ver=None): owner = owner.lower() repo = repo.lower() library = Library.get_by_id('%s/%s' % (owner, repo), read_policy=ndb.EVENTUAL_CONSISTENCY) if library is None or library.error is not None: self.response.write(str(library)) self.response.set_status(404) return versions = library.versions() if ver is None: ver = versions[-1] version = Version.get_by_id(ver, parent=library.key, read_policy=ndb.EVENTUAL_CONSISTENCY) if version is None or version.error is not None: self.response.write(str(version)) self.response.set_status(404) return metadata = json.loads(library.metadata) dependencies = [] bower = Content.get_by_id('bower', parent=version.key, read_policy=ndb.EVENTUAL_CONSISTENCY) if bower is not None: try: bower_json = json.loads(bower.content) # TODO: Which exception is this for? # pylint: disable=bare-except except: bower_json = {} readme = Content.get_by_id('readme.html', parent=version.key, read_policy=ndb.EVENTUAL_CONSISTENCY) full_name_match = re.match(r'(.*)/(.*)', metadata['full_name']) result = { 'version': ver, 'versions': versions, 'readme': None if readme is None else readme.content, 'subscribers': metadata['subscribers_count'], 'stars': metadata['stargazers_count'], 'forks': metadata['forks'], 'contributors': library.contributor_count, 'open_issues': metadata['open_issues'], 'updated_at': metadata['updated_at'], 'owner': full_name_match.groups()[0], 'repo': full_name_match.groups()[1], 'bower': None if bower is None else { 'description': bower_json.get('description', ''), 'license': bower_json.get('license', ''), 'dependencies': bower_json.get('dependencies', []), 'keywords': bower_json.get('keywords', []), }, 'collections': [] } for collection in library.collections: if not versiontag.match(ver, collection.semver): continue collection_version = collection.version.id() collection_library = collection.version.parent().get() collection_metadata = json.loads(collection_library.metadata) collection_name_match = re.match(r'(.*)/(.*)', collection_metadata['full_name']) result['collections'].append({ 'owner': collection_name_match.groups()[0], 'repo': collection_name_match.groups()[1], 'version': collection_version }) if library.kind == 'collection': dependencies = [] version_futures = [] for dep in version.dependencies: parsed_dep = Dependency.fromString(dep) dep_key = ndb.Key(Library, "%s/%s" % (parsed_dep.owner.lower(), parsed_dep.repo.lower())) version_futures.append(Library.versions_for_key_async(dep_key)) for i, dep in enumerate(version.dependencies): parsed_dep = Dependency.fromString(dep) versions = version_futures[i].get_result() versions.reverse() while len(versions) > 0 and not versiontag.match(versions[0], parsed_dep.version): versions.pop() if len(versions) == 0: dependencies.append({ 'error': 'unsatisfyable dependency', 'owner': parsed_dep.owner, 'repo': parsed_dep.repo, 'versionSpec': parsed_dep.version }) else: dependencies.append(brief_metadata_from_datastore(parsed_dep.owner, parsed_dep.repo, versions[0])) result['dependencies'] = dependencies self.response.headers['Access-Control-Allow-Origin'] = '*' self.response.headers['Content-Type'] = 'application/json' self.response.write(json.dumps(result))