def test_must_get_body_directly(self, parse_mock): body = {'this': 'swagger'} reader = SamSwaggerReader(definition_body=body) parse_mock.return_value = None # No location is returned from aws_include parser actual = reader._read_from_definition_body() self.assertEquals(actual, body)
def test_must_return_none_if_file_not_found(self, yaml_parse_mock): expected = "parsed result" yaml_parse_mock.return_value = expected reader = SamSwaggerReader(definition_uri="somepath") actual = reader._download_swagger("abcdefgh.txt") self.assertIsNone(actual) yaml_parse_mock.assert_not_called()
def test_must_skip_non_s3_dictionaries(self, yaml_parse_mock): location = {"some": "value"} reader = SamSwaggerReader(definition_uri=location) reader._download_from_s3 = Mock() actual = reader._download_swagger(location) self.assertIsNone(actual) reader._download_from_s3.assert_not_called() yaml_parse_mock.assert_not_called()
def test_read_from_definition_uri(self): uri = "./file.txt" expected = {"some": "value"} reader = SamSwaggerReader(definition_uri=uri) reader._download_swagger = Mock() reader._download_swagger.return_value = expected actual = reader.read() self.assertEquals(actual, expected) reader._download_swagger.assert_called_with(uri)
def test_must_fail_on_download_from_s3(self, tempfilemock, botomock): s3_mock = Mock() botomock.client.return_value = s3_mock fp_mock = Mock() tempfilemock.TemporaryFile.return_value.__enter__.return_value = fp_mock # mocking context manager s3_mock.download_fileobj.side_effect = botocore.exceptions.ClientError({"Error": {}}, "download_file") with self.assertRaises(Exception) as cm: SamSwaggerReader._download_from_s3(self.bucket, self.key) self.assertIn(cm.exception.__class__, (botocore.exceptions.NoCredentialsError, botocore.exceptions.ClientError))
def test_must_work_with_include_transform(self, parse_mock): body = {'this': 'swagger'} expected = {'k': 'v'} location = "some location" reader = SamSwaggerReader(definition_body=body) reader._download_swagger = Mock() reader._download_swagger.return_value = expected parse_mock.return_value = location actual = reader._read_from_definition_body() self.assertEquals(actual, expected) parse_mock.assert_called_with(body)
def _extract_from_serverless_api(self, logical_id, api_resource, collector): """ Extract APIs from AWS::Serverless::Api resource by reading and parsing Swagger documents. The result is added to the collector. Parameters ---------- logical_id : str Logical ID of the resource api_resource : dict Resource definition, including its properties collector : ApiCollector Instance of the API collector that where we will save the API information """ properties = api_resource.get("Properties", {}) body = properties.get("DefinitionBody") uri = properties.get("DefinitionUri") binary_media = properties.get("BinaryMediaTypes", []) stage_name = properties.get("StageName") stage_variables = properties.get("Variables") if not body and not uri: # Swagger is not found anywhere. LOG.debug( "Skipping resource '%s'. Swagger document not found in DefinitionBody and DefinitionUri", logical_id) return reader = SamSwaggerReader(definition_body=body, definition_uri=uri, working_dir=self.cwd) swagger = reader.read() parser = SwaggerParser(swagger) apis = parser.get_apis() LOG.debug("Found '%s' APIs in resource '%s'", len(apis), logical_id) collector.add_apis(logical_id, apis) collector.add_binary_media_types( logical_id, parser.get_binary_media_types()) # Binary media from swagger collector.add_binary_media_types( logical_id, binary_media) # Binary media specified on resource in template collector.add_stage_name(logical_id, stage_name) collector.add_stage_variables(logical_id, stage_variables)
def test_must_log_on_download_exception(self, tempfilemock, botomock): s3_mock = Mock() botomock.client.return_value = s3_mock fp_mock = Mock() tempfilemock.TemporaryFile.return_value.__enter__.return_value = fp_mock # mocking context manager s3_mock.download_fileobj.side_effect = botocore.exceptions.ClientError({"Error": {}}, "download_file") with self.assertRaises(botocore.exceptions.ClientError): SamSwaggerReader._download_from_s3(self.bucket, self.key) fp_mock.read.assert_not_called()
def test_must_fail_on_download_from_s3(self, tempfilemock, botomock): s3_mock = Mock() botomock.client.return_value = s3_mock fp_mock = Mock() tempfilemock.TemporaryFile.return_value.__enter__.return_value = fp_mock # mocking context manager s3_mock.download_fileobj.side_effect = botocore.exceptions.ClientError( {"Error": {}}, "download_file") with self.assertRaises(Exception) as cm: SamSwaggerReader._download_from_s3(self.bucket, self.key) self.assertIn(cm.exception.__class__, (botocore.exceptions.NoCredentialsError, botocore.exceptions.ClientError))
def test_must_log_on_download_exception(self, tempfilemock, botomock): s3_mock = Mock() botomock.client.return_value = s3_mock fp_mock = Mock() tempfilemock.TemporaryFile.return_value.__enter__.return_value = fp_mock # mocking context manager s3_mock.download_fileobj.side_effect = botocore.exceptions.ClientError( {"Error": {}}, "download_file") with self.assertRaises(botocore.exceptions.ClientError): SamSwaggerReader._download_from_s3(self.bucket, self.key) fp_mock.read.assert_not_called()
def test_must_read_first_from_definition_body(self): body = {"this is": "swagger"} uri = "./file.txt" expected = {"some": "value"} reader = SamSwaggerReader(definition_body=body, definition_uri=uri) reader._download_swagger = Mock() reader._read_from_definition_body = Mock() reader._read_from_definition_body.return_value = expected actual = reader.read() self.assertEquals(actual, expected) reader._read_from_definition_body.assert_called_with() reader._download_swagger.assert_not_called()
def test_must_read_from_local_file_without_working_directory(self, yaml_parse_mock): data = {"some": "value"} expected = "parsed result" yaml_parse_mock.return_value = expected with tempfile.NamedTemporaryFile(mode='w') as fp: filepath = fp.name json.dump(data, fp) fp.flush() reader = SamSwaggerReader(definition_uri=filepath) actual = reader._download_swagger(filepath) self.assertEquals(actual, expected) yaml_parse_mock.assert_called_with('{"some": "value"}') # data was read back from the file as JSON string
def test_must_parse_dict_without_version(self): location = { "Bucket": self.bucket, "Key": self.key } result = SamSwaggerReader._parse_s3_location(location) self.assertEquals(result, (self.bucket, self.key, None))
def test_must_use_definition_uri_if_body_does_not_exist(self): body = {"this is": "swagger"} uri = "./file.txt" expected = {"some": "value"} reader = SamSwaggerReader(definition_body=body, definition_uri=uri) reader._download_swagger = Mock() reader._download_swagger.return_value = expected # Set the output of reading the definition body to be None reader._read_from_definition_body = Mock() reader._read_from_definition_body.return_value = None actual = reader.read() self.assertEquals(actual, expected) reader._read_from_definition_body.assert_called_with() reader._download_swagger.assert_called_with(uri)
def test_must_parse_valid_dict(self): location = { "Bucket": self.bucket, "Key": self.key, "Version": self.version } result = SamSwaggerReader._parse_s3_location(location) self.assertEquals(result, (self.bucket, self.key, self.version))
def test_must_read_from_local_file_without_working_directory( self, yaml_parse_mock): data = {"some": "value"} expected = "parsed result" yaml_parse_mock.return_value = expected with tempfile.NamedTemporaryFile(mode='w') as fp: filepath = fp.name json.dump(data, fp) fp.flush() reader = SamSwaggerReader(definition_uri=filepath) actual = reader._download_swagger(filepath) self.assertEquals(actual, expected) yaml_parse_mock.assert_called_with( '{"some": "value"}' ) # data was read back from the file as JSON string
def test_must_download_from_s3_for_s3_locations(self, yaml_parse_mock): location = { "Bucket": "mybucket", "Key": "swagger.yaml", "Version": "versionId" } swagger_str = "some swagger str" expected = "some data" reader = SamSwaggerReader(definition_uri=location) reader._download_from_s3 = Mock() reader._download_from_s3.return_value = swagger_str yaml_parse_mock.return_value = expected actual = reader._download_swagger(location) self.assertEquals(actual, expected) reader._download_from_s3.assert_called_with(location["Bucket"], location["Key"], location["Version"]) yaml_parse_mock.assert_called_with(swagger_str)
def test_must_work_without_object_version_id(self, tempfilemock, botomock): s3_mock = Mock() botomock.client.return_value = s3_mock fp_mock = Mock() tempfilemock.TemporaryFile.return_value.__enter__.return_value = fp_mock # mocking context manager expected = "data from file" fp_mock.read.return_value = expected actual = SamSwaggerReader._download_from_s3(self.bucket, self.key) self.assertEquals(actual, expected) s3_mock.download_fileobj.assert_called_with(self.bucket, self.key, fp_mock, ExtraArgs={})
def test_must_download_file_from_s3(self, tempfilemock, botomock): s3_mock = Mock() botomock.client.return_value = s3_mock fp_mock = Mock() tempfilemock.TemporaryFile.return_value.__enter__.return_value = fp_mock # mocking context manager expected = "data from file" fp_mock.read.return_value = expected actual = SamSwaggerReader._download_from_s3(self.bucket, self.key, self.version) self.assertEquals(actual, expected) s3_mock.download_fileobj.assert_called_with(self.bucket, self.key, fp_mock, ExtraArgs={"VersionId": self.version}) fp_mock.seek.assert_called_with(0) # make sure we seek the file before reading fp_mock.read.assert_called_with()
def test_must_download_file_from_s3(self, tempfilemock, botomock): s3_mock = Mock() botomock.client.return_value = s3_mock fp_mock = Mock() tempfilemock.TemporaryFile.return_value.__enter__.return_value = fp_mock # mocking context manager expected = "data from file" fp_mock.read.return_value = expected actual = SamSwaggerReader._download_from_s3(self.bucket, self.key, self.version) self.assertEquals(actual, expected) s3_mock.download_fileobj.assert_called_with( self.bucket, self.key, fp_mock, ExtraArgs={"VersionId": self.version}) fp_mock.seek.assert_called_with( 0) # make sure we seek the file before reading fp_mock.read.assert_called_with()
def test_must_parse_invalid_location(self, location): result = SamSwaggerReader._parse_s3_location(location) self.assertEquals(result, (None, None, None))
def test_definition_body_and_uri_required(self): with self.assertRaises(ValueError): SamSwaggerReader()
def test_must_parse_s3_uri_string_without_version_id(self): location = "s3://{}/{}".format(self.bucket, self.key) result = SamSwaggerReader._parse_s3_location(location) self.assertEquals(result, (self.bucket, self.key, None))
def test_must_parse_s3_uri_string(self): location = "s3://{}/{}?versionId={}".format(self.bucket, self.key, self.version) result = SamSwaggerReader._parse_s3_location(location) self.assertEquals(result, (self.bucket, self.key, self.version))
def test_must_parse_dict_without_version(self): location = {"Bucket": self.bucket, "Key": self.key} result = SamSwaggerReader._parse_s3_location(location) self.assertEquals(result, (self.bucket, self.key, None))
def test_with_invalid_location(self): reader = SamSwaggerReader(definition_uri="something") actual = reader._download_swagger({}) self.assertIsNone(actual)