def test_create_response_list(_clean_specs_table): """ GIVEN database with single spec and list type request, authorization info and uri WHEN create_response is called with the type, uri and authorization info THEN a list response is returned. """ spec_id = "spec 1" version = "version 1" uri = f"/{spec_id}/" sub = "sub 1" auth_info = types.CredentialsAuthInfo( sub=sub, secret_key_hash=b"secret key 1", salt=b"salt 1" ) request_type = types.TRequestType.LIST package_database.get().create_update_spec( sub=sub, name=spec_id, version=version, model_count=1 ) public_key = "public key 1" secret_key = "secret key 1" authorization = types.TAuthorization(public_key=public_key, secret_key=secret_key) returned_response = library.create_response( authorization=authorization, request_type=request_type, uri=uri, auth_info=auth_info, ) assert returned_response.type == request_type assert "<body>" in returned_response.value assert spec_id in returned_response.value assert version in returned_response.value assert public_key in returned_response.value assert secret_key in returned_response.value
def sub(): """Generates a sub and cleans up after any tests.""" sub_value = f"test.{uuid.uuid4()}" yield sub_value package_database.get().delete_all(sub=sub_value)
def test_put_too_many_models_error(monkeypatch, _clean_specs_table): """ GIVEN body spec and spec id and user that already has too many models WHEN put is called with the body and spec id THEN a 402 with an invalid spec is returned. """ mock_request = mock.MagicMock() mock_headers = {"X-LANGUAGE": "JSON"} mock_request.headers = mock_headers monkeypatch.setattr(server.Request, "request", mock_request) version = "1" schemas = { "Schema": { "type": "object", "x-tablename": "schema", "properties": {"id": {"type": "integer"}}, } } body = json.dumps( {"info": {"version": version}, "components": {"schemas": schemas}} ) spec_name_1 = "id 1" user = "******" package_database.get().create_update_spec( sub=user, name=spec_name_1, version="1", model_count=100 ) spec_name_2 = "id 2" response = specs.put(body=body.encode(), spec_name=spec_name_2, user=user) assert response.status_code == 402 assert response.mimetype == "text/plain" assert "exceeded" in response.data.decode() assert ": 100," in response.data.decode() assert "spec: 1" in response.data.decode()
def test_delete_storage_error(monkeypatch, _clean_specs_table): """ GIVEN database and storage that raises a StorageError with spec and user and spec id WHEN put is called with the body and spec id THEN the spec is deleted from the database. """ spec_name = "id 1" user = "******" version = "1" package_database.get().create_update_spec( sub=user, name=spec_name, version=version, model_count=1 ) mock_storage_delete_spec = mock.MagicMock() mock_storage_delete_spec.side_effect = storage.exceptions.StorageError monkeypatch.setattr( storage.get_storage_facade(), "delete_spec", mock_storage_delete_spec, ) response = specs.delete(spec_name=spec_name, user=user) assert package_database.get().count_customer_models(sub=user) == 0 assert response.status_code == 204
def test_get(_clean_specs_table): """ GIVEN user and database and storage with a single spec WHEN get is called with the user and spec id THEN the spec value is returned. """ user = "******" spec_name = "spec name 1" version = "1" package_database.get().create_update_spec( sub=user, name=spec_name, version=version, model_count=1 ) spec = {"components": {}} storage.get_storage_facade().create_update_spec( user=user, name=spec_name, version=version, spec_str=json.dumps(spec, separators=(",", ":")), ) response = specs.get(user=user, spec_name=spec_name) assert response.status_code == 200 assert response.mimetype == "application/json" response_data_json = json.loads(response.data.decode()) assert f"version: '{version}'" in response_data_json["value"] assert "components: {}" in response_data_json["value"] assert response_data_json["name"] == spec_name assert response_data_json["version"] == version
def test_check_within_limit( initial_items, user, spec_name, model_count, expected_result, expected_contents, _clean_specs_table, ): """ GIVE database with initial items, a user, the name of a spec and a model count WHEN check_within_limit is called with the user, spec name and model count THEN the expected result and reason is returned. """ free_tier_model_count = 10 config.get().free_tier_model_count = free_tier_model_count for item in initial_items: package_database.get().create_update_spec(**item) returned_result = free_tier.check_within_limit(user=user, spec_name=spec_name, model_count=model_count) assert returned_result.value == expected_result if expected_result: assert returned_result.reason is None else: assert str(free_tier_model_count) in returned_result.reason for content in expected_contents: assert content in returned_result.reason
def test_list_(_clean_specs_table): """ GIVEN user and database with a single spec WHEN list_ is called with the user THEN all the specs stored on the user are returned. """ user = "******" spec_name = "spec name 1" version = "1" model_count = 1 package_database.get().create_update_spec( sub=user, name=spec_name, version=version, model_count=model_count ) response = specs.list_(user=user) assert response.status_code == 200 assert response.mimetype == "application/json" spec_infos = json.loads(response.data.decode()) assert len(spec_infos) == 1 spec_info = spec_infos[0] assert spec_info["name"] == spec_name assert spec_info["id"] == spec_name assert spec_info["version"] == version assert spec_info["model_count"] == model_count assert "updated_at" in spec_info
def test_put_database_update_error(monkeypatch, _clean_specs_table): """ GIVEN body and spec id WHEN put is called with the body and spec id THEN the spec is stored against the spec id. """ mock_request = mock.MagicMock() mock_headers = {"X-LANGUAGE": "JSON"} mock_request.headers = mock_headers monkeypatch.setattr(server.Request, "request", mock_request) version = "1" spec = { "info": { "version": version }, "components": { "schemas": { "Schema": { "type": "object", "x-tablename": "schema", "properties": { "id": { "type": "integer" } }, } } }, } body = json.dumps(spec) spec_name = "id 1" user = "******" mock_database_create_update_spec = mock.MagicMock() mock_database_create_update_spec.side_effect = package_database.exceptions.BaseError monkeypatch.setattr( package_database.get(), "create_update_spec", mock_database_create_update_spec, ) response = versions.put(body=body.encode(), spec_name=spec_name, version=version, user=user) spec_str = storage.get_storage_facade().get_spec(user=user, name=spec_name, version=version) assert f'"{version}"' in spec_str assert '"Schema"' in spec_str assert '"x-tablename"' in spec_str assert '"schema"' in spec_str assert package_database.get().count_customer_models(sub=user) == 0 assert response.status_code == 500 assert response.mimetype == "text/plain" assert "database" in response.data.decode()
def get(spec_name: types.TSpecId, user: types.TUser) -> server.Response: """ Retrieve a spec for a user. Args: spec_name: The id of the spec. user: The user from the token. Returns: The response to the request. """ try: version = package_database.get().get_latest_spec_version( sub=user, name=spec_name ) spec_str = storage.get_storage_facade().get_spec( user=user, name=spec_name, version=version ) prepared_spec_str = spec.prepare(spec_str=spec_str, version=version) spec_info = package_database.get().get_spec(sub=user, name=spec_name) response_data = json.dumps({**spec_info, "value": prepared_spec_str}) return server.Response( response_data, status=200, mimetype="application/json", ) except package_database.exceptions.NotFoundError: return server.Response( f"could not find the spec with id {spec_name}", status=404, mimetype="text/plain", ) except package_database.exceptions.BaseError: return server.Response( "something went wrong whilst reading from the database", status=500, mimetype="text/plain", ) except storage.exceptions.ObjectNotFoundError: return server.Response( f"could not find the spec with id {spec_name}", status=404, mimetype="text/plain", ) except storage.exceptions.StorageError: return server.Response( "something went wrong whilst reading the spec", status=500, mimetype="text/plain", )
def test_put(monkeypatch, _clean_specs_table): """ GIVEN body, spec id and user WHEN put is called with the body, spec id and user THEN the spec is stored against the spec id. """ mock_request = mock.MagicMock() mock_headers = {"X-LANGUAGE": "JSON"} mock_request.headers = mock_headers monkeypatch.setattr(server.Request, "request", mock_request) version = "1" title = "title 1" description = "description 1" spec = { "info": {"version": version, "title": title, "description": description}, "components": { "schemas": { "Schema": { "type": "object", "x-tablename": "schema", "properties": {"id": {"type": "integer"}}, } } }, } body = json.dumps(spec) spec_name = "id 1" user = "******" response = specs.put(body=body.encode(), spec_name=spec_name, user=user) spec_str = storage.get_storage_facade().get_spec( user=user, name=spec_name, version=version ) assert f'"{version}"' in spec_str assert '"Schema"' in spec_str assert '"x-tablename"' in spec_str assert '"schema"' in spec_str assert package_database.get().count_customer_models(sub=user) == 1 spec_infos = package_database.get().list_specs(sub=user) assert len(spec_infos) == 1 spec_info = spec_infos[0] assert spec_info["name"] == spec_name assert spec_info["id"] == spec_name assert spec_info["version"] == version assert spec_info["title"] == title assert spec_info["description"] == description assert spec_info["model_count"] == 1 assert "updated_at" in spec_info assert response.status_code == 204
def delete(user: types.TUser) -> server.Response: """ Retrieve the credentials for the user. Args: user: The user from the token. Returns: The credentials for the user. """ package_database.get().delete_credentials( sub=user, id_=config.get().default_credentials_id) return server.Response(status=204)
def test_credentials_create_list_delete_all(sub): """ GIVEN credentials values WHEN credentials are created, listed and all are deleted THEN the credentials are returned in the list after creation but not after deletion. """ id_ = "id 1" public_key = "public key 1" secret_key_hash = b"secret key has 1" salt = b"salt 1" database_instance = package_database.get() assert len(database_instance.list_credentials(sub=sub)) == 0 database_instance.create_update_credentials( sub=sub, id_=id_, public_key=public_key, secret_key_hash=secret_key_hash, salt=salt, ) infos = database_instance.list_credentials(sub=sub) assert len(infos) == 1 info = infos[0] assert info["id"] == id_ assert info["public_key"] == public_key assert info["salt"] == salt database_instance.delete_all_credentials(sub=sub) assert len(database_instance.list_credentials(sub=sub)) == 0
def test_count_customer_models(_clean_specs_table): """ GIVEN sub, name, version and model count WHEN create_update_spec is called with the spec info and count_customer_models is called THEN the model count is returned. """ sub = "sub 1" database_instance = package_database.get() assert database_instance.count_customer_models(sub=sub) == 0 name = "name 1" version = "version 1" model_count_1 = 1 database_instance.create_update_spec( sub=sub, name=name, version=version, model_count=model_count_1 ) assert database_instance.count_customer_models(sub=sub) == model_count_1 model_count_2 = 2 database_instance.create_update_spec( sub=sub, name=name, version=version, model_count=model_count_2 ) assert database_instance.count_customer_models(sub=sub) == model_count_2 assert database_instance.count_customer_models(sub="sub 2") == 0
def test_get_latest_spec_version(_clean_specs_table): """ GIVEN sub, name, version and model count WHEN create_update_spec is called with the spec info and get_latest_spec_version is called THEN the latest version is returned. """ sub = "sub 1" name = "name 1" database_instance = package_database.get() with pytest.raises(package_database.exceptions.BaseError): database_instance.get_latest_spec_version(sub=sub, name=name) version_1 = "version 1" model_count = 1 database_instance.create_update_spec( sub=sub, name=name, version=version_1, model_count=model_count ) assert database_instance.get_latest_spec_version(sub=sub, name=name) == version_1 version_2 = "version 2" database_instance.create_update_spec( sub=sub, name=name, version=version_2, model_count=model_count ) assert database_instance.get_latest_spec_version(sub=sub, name=name) == version_2 with pytest.raises(package_database.exceptions.BaseError): database_instance.get_latest_spec_version(sub=sub, name="name 2") with pytest.raises(package_database.exceptions.BaseError): database_instance.get_latest_spec_version(sub="sub 2", name=name)
def test_delete_all(_clean_specs_table, _clean_credentials_table): """ GIVEN database with spec and credentials WHEN delete_all is called THEN all spec and credentials are deleted. """ sub = "sub 1" database_instance = package_database.get() database_instance.create_update_credentials( sub=sub, id_="id 1", public_key="public key 1", secret_key_hash=b"secret key hash 1", salt=b"salt 1", ) database_instance.create_update_spec( sub=sub, name="name 1", version="version 1", model_count=1 ) assert len(database_instance.list_specs(sub=sub)) == 1 assert len(database_instance.list_credentials(sub=sub)) == 1 database_instance.delete_all(sub=sub) assert len(database_instance.list_specs(sub=sub)) == 0 assert len(database_instance.list_credentials(sub=sub)) == 0
def test_delete_spec(_clean_specs_table): """ GIVEN sub, name, version and model count WHEN create_update_spec is called with the spec info and delete_spec is called THEN the spec is deleted. """ sub = "sub 1" name = "name 1" version = "version 1" model_count = 1 database_instance = package_database.get() database_instance.create_update_spec( sub=sub, name=name, version=version, model_count=model_count ) assert len(database_instance.list_specs(sub=sub)) == 1 assert database_instance.count_customer_models(sub=sub) == model_count assert database_instance.get_latest_spec_version(sub=sub, name=name) == version database_instance.delete_spec(sub=sub, name=name) assert len(database_instance.list_specs(sub=sub)) == 0 assert database_instance.count_customer_models(sub=sub) == 0 with pytest.raises(package_database.exceptions.NotFoundError): database_instance.get_latest_spec_version(sub=sub, name=name)
def test_get_spec(_clean_specs_table): """ GIVEN sub, name, version and model count WHEN create_update_spec is called with the spec info and get_spec is called THEN the spec info is returned. """ sub = "sub 1" name = "name 1" database_instance = package_database.get() with pytest.raises(package_database.exceptions.NotFoundError): database_instance.get_spec(sub=sub, name=name) version = "version 1" model_count = 1 database_instance.create_update_spec( sub=sub, name=name, version=version, model_count=model_count ) returned_info = database_instance.get_spec(sub=sub, name=name) assert returned_info["name"] == name assert returned_info["id"] == name assert returned_info["version"] == version assert returned_info["model_count"] == model_count
def list_(spec_name: types.TSpecId, user: types.TUser) -> server.Response: """ List all available versions of a spec. Args: spec_name: The id of the spec. user: The user from the token. Returns: The response to the request. """ try: return server.Response( json.dumps(package_database.get().list_spec_versions( sub=user, name=spec_name)), status=200, mimetype="application/json", ) except package_database.exceptions.NotFoundError: return server.Response( f"could not find spec with id {spec_name}", status=404, mimetype="text/plain", ) except package_database.exceptions.BaseError: return server.Response( "something went wrong whilst reading from the database", status=500, mimetype="text/plain", )
def test_delete_database_error(monkeypatch, _clean_specs_table): """ GIVEN database that raises a DatabaseError and storage with spec and user and spec id WHEN put is called with the body and spec id THEN the spec is deleted from the storage. """ spec_name = "id 1" user = "******" version = "1" mock_database_delete_spec = mock.MagicMock() mock_database_delete_spec.side_effect = package_database.exceptions.BaseError monkeypatch.setattr( package_database.get(), "delete_spec", mock_database_delete_spec, ) storage.get_storage_facade().create_update_spec( user=user, name=spec_name, version=version, spec_str="spec str 1" ) response = specs.delete(spec_name=spec_name, user=user) with pytest.raises(storage.exceptions.StorageError): storage.get_storage_facade().get_spec( user=user, name=spec_name, version=version ) assert response.status_code == 204
def test_main_list(_clean_credentials_table, _clean_specs_table): """ GIVEN list event and database with the spec WHEN main is called with the event THEN a list response is returned. """ secret_key = "secret key 1" salt = b"salt 1" secret_key_hash = package_security.calculate_secret_key_hash( secret_key=secret_key, salt=salt) credentials = factory.CredentialsFactory(secret_key_hash=secret_key_hash, salt=salt) credentials.save() token = base64.b64encode( f"{credentials.public_key}:{secret_key}".encode()).decode() authorization_value = f"Basic {token}" spec_id = "spec 1" version = "version 1" uri = f"/{spec_id}/" package_database.get().create_update_spec(sub=credentials.sub, name=spec_id, version=version, model_count=1) request = { "headers": { "authorization": [{ "key": "Authorization", "value": authorization_value }] }, "uri": uri, } event = {"Records": [{"cf": {"request": copy.deepcopy(request)}}]} returned_response = app.main(event, None) assert returned_response["status"] == "200" assert returned_response["statusDescription"] == "OK" assert returned_response["headers"]["cache-control"][0][ "value"] == "max-age=0" assert returned_response["headers"]["content-type"][0][ "value"] == "text/html" assert spec_id in returned_response["body"] assert version in returned_response["body"] assert credentials.public_key in returned_response["body"] assert secret_key in returned_response["body"]
def test_list_miss(_clean_specs_table): """ GIVEN user and database with a single spec for a different user WHEN list_ is called with the user THEN empty list is returned. """ user = "******" spec_name = "spec name 1" package_database.get().create_update_spec( sub="user 2", name=spec_name, version="1", model_count=1 ) response = specs.list_(user=user) assert response.status_code == 200 assert response.mimetype == "application/json" assert json.loads(response.data.decode()) == []
def test_list_spec_versions(monkeypatch, _clean_specs_table): """ GIVEN sub, name, version and model count WHEN create_update_spec is called with the spec info and list_spec_versions is called THEN all specs for the customer are returned or NotFoundError is raised. """ mock_time = mock.MagicMock() monkeypatch.setattr(time, "time", mock_time) sub = "sub 1" name = "name 1" database_instance = package_database.get() with pytest.raises(package_database.exceptions.NotFoundError): database_instance.list_spec_versions(sub=sub, name=name) mock_time.return_value = 1000000 version_1 = "version 1" title = "title 1" description = "description 1" model_count_1 = 1 database_instance.create_update_spec( sub=sub, name=name, version=version_1, model_count=model_count_1, title=title, description=description, ) spec_infos = database_instance.list_spec_versions(sub=sub, name=name) assert len(spec_infos) == 1 spec_info = spec_infos[0] assert spec_info["name"] == name assert spec_info["id"] == name assert spec_info["version"] == version_1 assert spec_info["title"] == title assert spec_info["description"] == description assert spec_info["model_count"] == model_count_1 assert "updated_at" in spec_info mock_time.return_value = 2000000 version_2 = "version 2" model_count_2 = 2 database_instance.create_update_spec( sub=sub, name=name, version=version_2, model_count=model_count_2 ) spec_infos = database_instance.list_spec_versions(sub=sub, name=name) assert len(spec_infos) == 2 assert spec_infos[0]["name"] == name assert spec_infos[0]["id"] == name spec_info = spec_infos[1] assert spec_info["name"] == name assert spec_info["id"] == name assert spec_info["version"] == version_2 assert spec_info["model_count"] == model_count_2 assert "updated_at" in spec_info
def test_list_delete_all_spec(_clean_specs_table): """ GIVEN sub, name, version and model count WHEN create_update_spec is called with the spec info and list_specs is called THEN all specs for the customer are returned. """ sub = "sub 1" database_instance = package_database.get() assert database_instance.list_specs(sub=sub) == [] name_1 = "name 1" version_1 = "version 1" title = "title 1" description = "description 1" model_count_1 = 1 database_instance.create_update_spec( sub=sub, name=name_1, version=version_1, model_count=model_count_1, title=title, description=description, ) spec_infos = database_instance.list_specs(sub=sub) assert len(spec_infos) == 1 spec_info = spec_infos[0] assert spec_info["name"] == name_1 assert spec_info["id"] == name_1 assert spec_info["version"] == version_1 assert spec_info["title"] == title assert spec_info["description"] == description assert spec_info["model_count"] == model_count_1 assert "updated_at" in spec_info name_2 = "name 2" version_2 = "version 2" model_count_2 = 2 database_instance.create_update_spec( sub=sub, name=name_2, version=version_2, model_count=model_count_2 ) spec_infos = database_instance.list_specs(sub=sub) assert len(spec_infos) == 2 assert spec_infos[0]["name"] == name_1 assert spec_infos[0]["id"] == name_1 spec_info = spec_infos[1] assert spec_info["name"] == name_2 assert spec_info["id"] == name_2 assert spec_info["version"] == version_2 assert spec_info["model_count"] == model_count_2 assert "updated_at" in spec_info database_instance.delete_all_specs(sub=sub) assert database_instance.list_specs(sub=sub) == []
def check_within_limit( *, user: types.TUser, spec_name: types.TSpecName, model_count: types.TSpecModelCount ) -> types.TResult: """ Check whether adding a spec would exceed the free tier limit. Algorithm: 1. retrieve the information for the spec, 2. retrieve the model count for the user and 3. return whether the user model count plus the new model count minus the existing model count would exceed the free tier. Args: user: The user to run the check for spec_name: The name of the spec model_count: The new model count of the spec Returns: The result and the reason if the result is true. """ current_spec_model_count = 0 try: spec_info = package_database.get().get_spec(sub=user, name=spec_name) current_spec_model_count = spec_info["model_count"] except package_database.exceptions.BaseError: pass user_model_count = package_database.get().count_customer_models(sub=user) new_user_model_count = user_model_count + model_count - current_spec_model_count result = new_user_model_count <= config.get().free_tier_model_count reason: typing.Optional[str] = None if not result: reason = ( "with this spec the maximum number of " f"{config.get().free_tier_model_count} models for the free " f"tier would be exceeded, current models count: {user_model_count}, " f"current models in the spec: {current_spec_model_count}, " f"models in the new version of th spec: {model_count}, " f"new total model count: {new_user_model_count}, " ) return types.TResult(value=result, reason=reason)
def test_get_storage_facade_miss(_clean_specs_table): """ GIVEN user and database with a spec but empty storage WHEN get is called with the user and spec id THEN a 404 is returned. """ user = "******" spec_name = "spec name 1" version = "1" package_database.get().create_update_spec( sub=user, name=spec_name, version=version, model_count=1 ) response = specs.get(user=user, spec_name=spec_name) assert response.status_code == 404 assert response.mimetype == "text/plain" assert spec_name in response.data.decode() assert "not find" in response.data.decode()
def get(user: types.TUser) -> server.Response: """ Retrieve the credentials for the user. Args: user: The user from the token. Returns: The credentials for the user. """ public_key: str secret_key: str id_ = config.get().default_credentials_id # Retrieve or create credentials stored_credentials = package_database.get().get_credentials(sub=user, id_=id_) if stored_credentials is not None: public_key = stored_credentials["public_key"] secret_key = package_security.retrieve_secret_key( sub=user, salt=stored_credentials["salt"]) else: created_credentials = package_security.create(sub=user) public_key = created_credentials.public_key secret_key = created_credentials.secret_key package_database.get().create_update_credentials( sub=user, id_=id_, public_key=public_key, secret_key_hash=created_credentials.secret_key_hash, salt=created_credentials.salt, ) return server.Response( json.dumps({ "public_key": public_key, "secret_key": secret_key, }), status=200, mimetype="application/json", )
def create_list_response_value( *, authorization: types.TAuthorization, uri: types.TUri, auth_info: types.CredentialsAuthInfo, ) -> types.TResponseValue: """ Calculate the response for a list type response. Raises NotFoundError when the uri is not linked to a known spec. Args: uri: The requested uri. auth_info: Information about the user. Returns: The html to return to the user for the request. """ assert uri.startswith("/") assert uri.endswith("/") spec_id = uri[1:-1] try: version_infos = package_database.get().list_spec_versions( sub=auth_info.sub, name=spec_id ) except package_database.exceptions.NotFoundError as exc: raise exceptions.NotFoundError( f"could not find package with {spec_id=}" ) from exc host = "index.package.openalchemy.io" def package_name(version: str) -> str: """Calculate the name of the package.""" return f"{spec_id.replace('-', '_')}-{version}.tar.gz" install_links = list( map( lambda version_info: ( f'<a href="https://' f"{authorization.public_key}:{authorization.secret_key}" f"@{host}/{spec_id}/" f'{package_name(version_info["version"])}">' f'{package_name(version_info["version"])}</a><br>' ), version_infos, ) ) joined_install_links = "\n".join(install_links) return f"""
def test_get_storage_facade_error(_clean_specs_table, monkeypatch): """ GIVEN user and database with a spec but storage that raises an error WHEN get is called with the user and spec id THEN a 500 is returned. """ user = "******" spec_name = "spec name 1" version = "1" package_database.get().create_update_spec( sub=user, name=spec_name, version=version, model_count=1 ) mock_storage_get_spec = mock.MagicMock() mock_storage_get_spec.side_effect = storage.exceptions.StorageError monkeypatch.setattr(storage.get_storage_facade(), "get_spec", mock_storage_get_spec) response = specs.get(user=user, spec_name=spec_name) assert response.status_code == 500 assert response.mimetype == "text/plain" assert "reading" in response.data.decode()
def delete(spec_name: types.TSpecId, user: types.TUser) -> server.Response: """ Delete a spec for a user. Args: spec_name: The id of the spec. user: The user from the token. Returns: The response to the request. """ try: package_database.get().delete_spec(sub=user, name=spec_name) except package_database.exceptions.BaseError: pass try: storage.get_storage_facade().delete_spec(user=user, name=spec_name) except storage.exceptions.StorageError: pass return server.Response(status=204)
def test_spec_create_count_models_get_latest_version_list_versions_delete(sub): """ GIVEN spec values WHEN the models are counted, the latest version is retrieved, versions are listed and deleted THEN the model count for the spec is returned, the version of the spec is returned, the version of the spec is listed after creation but not after deletion. """ name = "name 1" model_count = 1 version = "version 1" database_instance = package_database.get() assert len(database_instance.list_specs(sub=sub)) == 0 database_instance.create_update_spec(sub=sub, name=name, model_count=model_count, version=version) assert database_instance.count_customer_models(sub=sub) == model_count info = database_instance.get_spec(sub=sub, name=name) assert info["name"] == name assert info["id"] == name assert info["version"] == version assert info["model_count"] == model_count assert database_instance.get_latest_spec_version(sub=sub, name=name) == version infos = database_instance.list_spec_versions(sub=sub, name=name) assert len(infos) == 1 info = infos[0] assert info["name"] == name assert info["id"] == name assert info["model_count"] == model_count assert info["version"] == version database_instance.delete_spec(sub=sub, name=name) assert database_instance.count_customer_models(sub=sub) == 0 with pytest.raises(package_database.exceptions.NotFoundError): database_instance.get_latest_spec_version(sub=sub, name=name) with pytest.raises(package_database.exceptions.NotFoundError): database_instance.list_spec_versions(sub=sub, name=name)