def test_delete_unknown_upload_unknown_group(foss: Fossology): if versiontuple(foss.version) > versiontuple("1.0.16"): upload = Upload( foss.rootFolder, "Root Folder", secrets.randbelow(1000), "", "Non Upload", "2020-05-05", hash={ "sha1": None, "md5": None, "sha256": None, "size": None }, ) else: upload = Upload( foss.rootFolder, "Root Folder", secrets.randbelow(1000), "", "Non Upload", "2020-05-05", filesize="1024", filesha1="597d209fd962f401866f12db9fa1f7301aee15a9", ) with pytest.raises(FossologyApiError): foss.delete_upload(upload) with pytest.raises(AuthorizationError) as excinfo: foss.delete_upload(upload, group="test") assert f"Deleting upload {upload.id} for group test not authorized" in str( excinfo.value)
def test_get_self_error(foss_server: str, foss: Fossology): if versiontuple(foss.version) >= versiontuple("1.2.3"): responses.add( responses.GET, f"{foss_server}/api/v1/users/self", status=500, ) with pytest.raises(FossologyApiError): foss.get_self()
def test_paginated_list_uploads(foss: Fossology, upload: Upload, test_file_path: str): if versiontuple(foss.version) < versiontuple("1.1.1"): # Upload pagination not available yet return # Add a second upload second_upload = foss.upload_file( foss.rootFolder, file=test_file_path, description="Test second upload via fossology-python lib", access_level=AccessLevel.PUBLIC, ) time.sleep(3) uploads, _ = foss.list_uploads(page_size=1, page=1) assert len(uploads) == 1 uploads, _ = foss.list_uploads(page_size=1, page=2) assert len(uploads) == 1 uploads, _ = foss.list_uploads(page_size=2, page=1) assert len(uploads) == 2 uploads, _ = foss.list_uploads(page_size=1, all_pages=True) num_known_uploads = 0 for up in uploads: if up.description in ( "Test upload via fossology-python lib", "Test second upload via fossology-python lib", ): num_known_uploads += 1 assert num_known_uploads >= 2 foss.delete_upload(second_upload)
def list_groups(self) -> List: """Get the list of groups (accessible groups for user, all groups for admin) API Endpoint: GET /groups :return: a list of groups :rtype: list() :raises FossologyApiError: if the REST call failed """ if fossology.versiontuple( self.version) < fossology.versiontuple("1.2.1"): description = f"Endpoint /groups is not supported by your Fossology API version {self.version}" raise FossologyUnsupported(description) response = self.session.get(f"{self.api}/groups") if response.status_code == 200: groups_list = [] response_list = response.json() for group in response_list: single_group = Group.from_json(group) groups_list.append(single_group) return groups_list else: description = f"Unable to get a list of groups for {self.user.name}" raise FossologyApiError(description, response)
def test_paginated_list_jobs(foss: Fossology, scanned_upload: Upload): # Versions prior to 1.3.2 return corrupt number of pages if versiontuple(foss.version) > versiontuple("1.3.1"): jobs, total_pages = foss.list_jobs(upload=scanned_upload, page_size=1, page=1) assert len(jobs) == 1 assert total_pages == 2 jobs, total_pages = foss.list_jobs(upload=scanned_upload, page_size=1, page=2) assert len(jobs) == 1 assert total_pages == 2 jobs, total_pages = foss.list_jobs(upload=scanned_upload, page_size=2, page=1) assert len(jobs) == 2 assert total_pages == 1 jobs, total_pages = foss.list_jobs(upload=scanned_upload, page_size=1, all_pages=True) assert len(jobs) == 2 assert total_pages == 2
def test_filesearch(foss: Fossology, scanned_upload: Upload): if versiontuple(foss.version) > versiontuple("1.0.16"): filelist = [ { "md5": "F921793D03CC6D63EC4B15E9BE8FD3F8" }, { "sha1": scanned_upload.hash.sha1 }, ] search_result = foss.filesearch(filelist=filelist) assert len(search_result) == 2 assert ( f"File with SHA1 {scanned_upload.hash.sha1} doesn't have any concluded license yet" in str(search_result[1])) filelist = [{"sha1": "FAKE"}] result = foss.filesearch(filelist=filelist) assert result == "Unable to get a result with the given filesearch criteria" assert foss.filesearch() == [] else: with pytest.raises(FossologyUnsupported) as excinfo: foss.filesearch(filelist=[], group="test") assert ( "Endpoint /filesearch is not supported by your Fossology API version" in str(excinfo.value))
def test_patch_license_error(foss_server: str, foss: fossology.Fossology, test_license: License): if fossology.versiontuple(foss.version) >= fossology.versiontuple("1.3.0"): responses.add(responses.PATCH, f"{foss_server}/api/v1/license/License-1.0", status=500) with pytest.raises(FossologyApiError) as excinfo: foss.update_license(test_license.shortName) assert f"Unable to update license {test_license.shortName}" in str( excinfo.value)
def test_add_license_error(foss_server: str, foss: fossology.Fossology, test_license: License): if fossology.versiontuple(foss.version) >= fossology.versiontuple("1.3.0"): responses.add(responses.POST, f"{foss_server}/api/v1/license", status=500) with pytest.raises(FossologyApiError) as excinfo: foss.add_license(test_license) assert f"Error while adding new license {test_license.shortName}" in str( excinfo.value)
def test_get_self_with_agents( foss_server: str, foss: Fossology, foss_user: dict, foss_user_agents: dict ): if versiontuple(foss.version) >= versiontuple("1.2.3"): user = foss_user responses.add( responses.GET, f"{foss_server}/api/v1/users/self", status=200, json=user ) user_from_api = foss.get_self() assert user_from_api.agents.to_dict() == foss_user_agents
def test_filesearch_nogroup(foss: Fossology): if versiontuple(foss.version) > versiontuple("1.0.16"): with pytest.raises(AuthorizationError) as excinfo: foss.filesearch(filelist=[], group="test") assert "Searching for group test not authorized" in str(excinfo.value) else: with pytest.raises(FossologyUnsupported) as excinfo: foss.filesearch(filelist=[], group="test") assert ( "Endpoint /filesearch is not supported by your Fossology API version" in str(excinfo.value))
def test_patch_license_and_get_by_shortname(foss: fossology.Fossology, test_another_license: License): if fossology.versiontuple(foss.version) >= fossology.versiontuple("1.3.0"): foss.add_license(test_another_license) foss.update_license(test_another_license.shortName, fullname="Inner Source license 2.0", risk=1) license_found = foss.detail_license(test_another_license.shortName) assert license_found.shortName == "License-2.0" assert license_found.fullName == "Inner Source license 2.0" assert license_found.risk == 1
def test_detail_license(foss: fossology.Fossology): if fossology.versiontuple(foss.version) < fossology.versiontuple("1.1.3"): with pytest.raises(FossologyUnsupported) as excinfo: foss.detail_license(short) assert ( "Endpoint /license is not supported by your Fossology API version" in str(excinfo.value)) else: license = foss.detail_license(short) assert license assert type(license) == License
def test_health_does_not_return_200(foss_server: str, foss: Fossology): if versiontuple(foss.version) < versiontuple("1.3.3"): return responses.add( responses.GET, f"{foss_server}/api/v1/health", status=503, ) with pytest.raises(FossologyApiError) as excinfo: foss.get_health() assert "Error while getting health info" in str(excinfo.value)
def test_filter_uploads(foss: Fossology, upload: Upload): today = date.today().isoformat() tomorrow = (date.today() + timedelta(days=1)).isoformat() # Uploads filtering has been enhance with API version 1.3.4 if versiontuple(foss.version) >= versiontuple("1.3.4"): assert len(foss.list_uploads(assignee="-me-")[0]) == 0 assert len(foss.list_uploads(assignee="-unassigned-")[0]) >= 1 assert len(foss.list_uploads(name="Non-existing upload")[0]) == 0 assert len(foss.list_uploads(name="Test upload")[0]) >= 1 assert len(foss.list_uploads(status=ClearingStatus.CLOSED)[0]) == 0 assert len(foss.list_uploads(status=ClearingStatus.OPEN)[0]) >= 1 assert len(foss.list_uploads(since=tomorrow)[0]) == 0 assert len(foss.list_uploads(since=today)[0]) >= 1
def test_detail_license_error(foss_server: str, foss: fossology.Fossology): if fossology.versiontuple(foss.version) < fossology.versiontuple("1.1.3"): with pytest.raises(FossologyUnsupported) as excinfo: foss.detail_license(short) assert ( "Endpoint /license is not supported by your Fossology API version" in str(excinfo.value)) else: responses.add(responses.GET, f"{foss_server}/api/v1/license", status=500) with pytest.raises(FossologyApiError) as excinfo: foss.detail_license(short) assert f"Unable to get license {short}" in str(excinfo.value)
def test_add_license_already_exists( foss_server: str, foss: fossology.Fossology, monkeypatch, test_license: License, ): if fossology.versiontuple(foss.version) >= fossology.versiontuple("1.3.0"): mocked_logger = MagicMock() monkeypatch.setattr("fossology.license.logger", mocked_logger) responses.add(responses.POST, f"{foss_server}/api/v1/license", status=409) foss.add_license(test_license) mocked_logger.info.assert_called_once()
def test_detail_license_error(foss_server: str, foss: fossology.Fossology): if fossology.versiontuple(foss.version) < fossology.versiontuple("1.3.0"): with pytest.raises(FossologyUnsupported) as excinfo: foss.detail_license(shortname) assert ( "Endpoint /license is not supported by your Fossology API version" in str(excinfo.value)) else: responses.add(responses.GET, f"{foss_server}/api/v1/license/Blah", status=500) with pytest.raises(FossologyApiError) as excinfo: foss.detail_license("Blah") assert "Error while getting license Blah" in str(excinfo.value)
def test_list_groups_error(foss_server: str, foss: fossology.Fossology): if fossology.versiontuple(foss.version) < fossology.versiontuple("1.2.1"): with pytest.raises(FossologyUnsupported) as excinfo: foss.list_groups() assert ( "Endpoint /groups is not supported by your Fossology API version" in str(excinfo.value) ) else: responses.add(responses.GET, f"{foss_server}/api/v1/groups", status=500) with pytest.raises(FossologyApiError) as excinfo: foss.list_groups() assert f"Unable to get a list of groups for {foss.user.name}" in str( excinfo.value )
def test_filesearch_error(foss_server: str, foss: Fossology): responses.add(responses.POST, f"{foss_server}/api/v1/filesearch", status=404) if versiontuple(foss.version) > versiontuple("1.0.16"): with pytest.raises(FossologyApiError) as excinfo: foss.filesearch() assert "Unable to get a result with the given filesearch criteria" in str( excinfo.value) else: with pytest.raises(FossologyUnsupported) as excinfo: foss.filesearch(filelist=[], group="test") assert ( "Endpoint /filesearch is not supported by your Fossology API version" in str(excinfo.value))
def test_list_licenses_error(foss_server: str, foss: fossology.Fossology): if fossology.versiontuple(foss.version) < fossology.versiontuple("1.3.0"): with pytest.raises(FossologyUnsupported) as excinfo: foss.detail_license(shortname) assert ( "Endpoint /license is not supported by your Fossology API version" in str(excinfo.value)) else: responses.add(responses.GET, f"{foss_server}/api/v1/license", status=500) with pytest.raises(FossologyApiError) as excinfo: foss.list_licenses() assert "Unable to retrieve the list of licenses from page 1" in str( excinfo.value)
def test_upload_sha1(foss: Fossology, upload: Upload): assert upload.uploadname == "base-files_11.tar.xz" if versiontuple(foss.version) > versiontuple("1.0.16"): assert upload.hash.sha1 == "D4D663FC2877084362FB2297337BE05684869B00" assert str(upload) == ( f"Upload '{upload.uploadname}' ({upload.id}, {upload.hash.size}B, {upload.hash.sha1}) " f"in folder {upload.foldername} ({upload.folderid})") assert str(upload.hash) == ( f"File SHA1: {upload.hash.sha1} MD5 {upload.hash.md5} " f"SH256 {upload.hash.sha256} Size {upload.hash.size}B") else: assert upload.filesha1 == "D4D663FC2877084362FB2297337BE05684869B00" assert str(upload) == ( f"Upload '{upload.uploadname}' ({upload.id}, {upload.filesize}B, {upload.filesha1}) " f"in folder {upload.foldername} ({upload.folderid})")
def test_backward_compatibility(foss_server: str, foss_token: str): foss = Fossology(foss_server, foss_token, "fossy") assert foss.name == "fossy" if versiontuple(foss.version) >= versiontuple("1.2.3"): foss = Fossology(foss_server, foss_token, "test") assert foss.name == "fossy" else: with pytest.raises(AuthenticationError) as excinfo: Fossology(foss_server, foss_token, "test") assert f"User test was not found on {foss_server}" in str(excinfo.value) with pytest.raises(AuthenticationError) as excinfo: Fossology(foss_server, foss_token) assert "You need to provide a username to create an API session" in str( excinfo.value )
def test_add_license_and_get_by_shortname(foss: fossology.Fossology, test_license: License, monkeypatch): if fossology.versiontuple(foss.version) >= fossology.versiontuple("1.3.0"): mocked_logger = MagicMock() monkeypatch.setattr("fossology.license.logger", mocked_logger) foss.add_license(test_license) license_found = foss.detail_license(test_license.shortName) assert license_found.shortName == "License-1.0" expected_license_repr = ( f"License {license_found.fullName} - {license_found.shortName} ") expected_license_repr += ( f"({license_found.id}) with risk level {license_found.risk}") assert str(license_found) == expected_license_repr foss.add_license(test_license, merge_request=True) mocked_logger.info.assert_called_with( f"License {test_license.shortName} already exists")
def test_search_upload_does_not_exist(foss: Fossology): # Before 1.0.17 Fossology was not able to limit search to a specific upload if versiontuple(foss.version) > versiontuple("1.0.16"): hash = {"sha1": "", "md5": "", "sha256": "", "size": ""} fake_upload = Upload( secrets.randbelow(1000), "fake_folder", secrets.randbelow(1000), "", "fake_upload", "2020-12-30", hash=hash, ) search_result = foss.search( searchType=SearchTypes.ALLFILES, upload=fake_upload, filename="share", ) assert not search_result
def test_get_uploads(foss: Fossology, upload_folder: Folder, test_file_path: str): name = "FossPythonTestUploadsSubfolder" desc = "Created via the Fossology Python API" upload_subfolder = foss.create_folder(upload_folder, name, description=desc) foss.upload_file( upload_folder, file=test_file_path, description="Test upload from github repository via python lib", ) foss.upload_file( upload_subfolder, file=test_file_path, description="Test upload from github repository via python lib", ) # Folder listing is still unstable in version 1.0.16 # Let's skip it since it has been fixed in newest versions if versiontuple(foss.version) > versiontuple("1.0.16"): assert len(foss.list_uploads(folder=upload_folder)) == 2 assert len(foss.list_uploads(folder=upload_folder, recursive=False)) == 1 assert len(foss.list_uploads(folder=upload_subfolder)) == 1
def test_create_group(foss: fossology.Fossology): if fossology.versiontuple(foss.version) < fossology.versiontuple("1.2.1"): with pytest.raises(FossologyUnsupported) as excinfo: foss.create_group("FossGroupTest") assert ( "Endpoint /groups is not supported by your Fossology API version" in str(excinfo.value) ) else: name = secrets.token_urlsafe(8) foss.create_group(name) groups = foss.list_groups() assert groups assert type(groups[0]) == Group # Recreate group to test API response 400 with pytest.raises(FossologyApiError) as excinfo: foss.create_group(name) assert ( f"Group {name} already exists, failed to create group or no group name provided" in str(excinfo.value) )
def detail_license(self, name) -> License: """Get a license from the DB API Endpoint: GET /license :param name: Short name of the license :rtype name: str :return: a list of groups :rtype: License() object :raises FossologyApiError: if the REST call failed """ if fossology.versiontuple( self.version) < fossology.versiontuple("1.1.3"): description = f"Endpoint /license is not supported by your Fossology API version {self.version}" raise FossologyUnsupported(description) headers = {"shortName": f"{name}"} response = self.session.get(f"{self.api}/license", headers=headers) if response.status_code == 200: return License.from_json(response.json()) else: description = f"Unable to get license {name}" raise FossologyApiError(description, response)
def create_group(self, name): """Create a group API Endpoint: POST /groups :param name: the name of the group :type name: str :raises FossologyApiError: if the REST call failed """ if fossology.versiontuple( self.version) < fossology.versiontuple("1.2.1"): description = f"Endpoint /groups is not supported by your Fossology API version {self.version}" raise FossologyUnsupported(description) headers = {"name": f"{name}"} response = self.session.post(f"{self.api}/groups", headers=headers) if response.status_code == 200: logger.info(f"Group '{name}' has been added") return else: description = f"Group {name} already exists, failed to create group or no group name provided" raise FossologyApiError(description, response)
def detail_license( self, shortname, group=None ) -> Tuple[int, License, List[Obligation]]: """Get a license from the DB API Endpoint: GET /license/{shortname} :param shortname: Short name of the license :param group: the group this license belongs to (default: None) :type name: str :type group: int :return: the license id, the license data and the associated obligations :rtype: tuple(int, License, List[Obligation]) :raises FossologyApiError: if the REST call failed """ if fossology.versiontuple(self.version) < fossology.versiontuple("1.3.0"): description = ( f"Endpoint /license/{shortname} is not supported by your API version ", f"{self.version}", ) raise FossologyUnsupported(description) headers = dict() if group: headers["groupName"] = group response = self.session.get( f"{self.api}/license/{quote(shortname)}", headers=headers ) if response.status_code == 200: return License.from_json(response.json()) elif response.status_code == 404: description = f"License {shortname} not found" raise FossologyApiError(description, response) else: description = f"Error while getting license {shortname}" raise FossologyApiError(description, response)
def test_get_health(foss: Fossology): if versiontuple(foss.version) >= versiontuple("1.3.3"): assert foss.health.status == "OK" assert foss.health.scheduler.status == "OK" assert foss.health.db.status == "OK"