Ejemplo n.º 1
0
    def test_must_return_function_value(self):
        provider = SamFunctionProvider({})
        provider.functions = {
            "func1": "value"
        }  # Cheat a bit here by setting the value of this property directly

        self.assertEqual("value", provider.get("func1"))
Ejemplo n.º 2
0
    def test_must_default_missing_code_uri(self):

        name = "myname"
        properties = {"Runtime": "myruntime"}

        result = SamFunctionProvider._convert_sam_function_resource(name, properties, [])
        self.assertEqual(result.codeuri, ".")  # Default value
Ejemplo n.º 3
0
    def test_must_handle_code_s3_uri(self):

        name = "myname"
        properties = {"CodeUri": "s3://bucket/key"}

        result = SamFunctionProvider._convert_sam_function_resource(name, properties, [])
        self.assertEqual(result.codeuri, ".")  # Default value
Ejemplo n.º 4
0
    def test_must_skip_unknown_resource(self):
        resources = {"Func1": {"Type": "AWS::SomeOther::Function", "Properties": {"a": "b"}}}

        expected = {}

        result = SamFunctionProvider._extract_functions(resources)
        self.assertEqual(expected, result)
Ejemplo n.º 5
0
    def test_must_convert(self):

        name = "myname"
        properties = {
            "CodeUri": "/usr/local",
            "Runtime": "myruntime",
            "MemorySize": "mymemorysize",
            "Timeout": "mytimeout",
            "Handler": "myhandler",
            "Environment": "myenvironment",
            "Role": "myrole",
            "Layers": ["Layer1", "Layer2"]
        }

        expected = Function(name="myname",
                            runtime="myruntime",
                            memory="mymemorysize",
                            timeout="mytimeout",
                            handler="myhandler",
                            codeuri="/usr/local",
                            environment="myenvironment",
                            rolearn="myrole",
                            layers=["Layer1", "Layer2"])

        result = SamFunctionProvider._convert_sam_function_resource(
            name, properties, ["Layer1", "Layer2"])

        self.assertEquals(expected, result)
    def test_must_fail_with_InvalidSamTemplateException(self):

        name = "myname"
        properties = {
            "CodeUri": "/usr/local",
            "Runtime": "myruntime",
            "MemorySize": "mymemorysize",
            "Timeout": "timeout",
            "Handler": "myhandler",
            "Environment": "myenvironment",
            "Role": "myrole",
            "Layers": ["Layer1", "Layer2"],
        }

        with self.assertRaises(InvalidSamTemplateException):
            SamFunctionProvider._convert_sam_function_resource(name, properties, ["Layer1", "Layer2"])
Ejemplo n.º 7
0
    def test_must_convert(self):

        name = "myname"
        properties = {
            "Code": {
                "Bucket": "bucket"
            },
            "Runtime": "myruntime",
            "MemorySize": "mymemorysize",
            "Timeout": "30",
            "Handler": "myhandler",
            "Environment": "myenvironment",
            "Role": "myrole",
            "Layers": ["Layer1", "Layer2"],
        }

        expected = Function(
            name="myname",
            runtime="myruntime",
            memory="mymemorysize",
            timeout="30",
            handler="myhandler",
            codeuri=".",
            environment="myenvironment",
            rolearn="myrole",
            layers=["Layer1", "Layer2"],
        )

        result = SamFunctionProvider._convert_lambda_function_resource(
            name, properties, ["Layer1", "Layer2"])

        self.assertEqual(expected, result)
    def test_layers_created_from_template_resources(self):
        resources = {
            "Layer": {
                "Type": "AWS::Lambda::LayerVersion",
                "Properties": {
                    "Content": {
                        "Bucket": "bucket"
                    }
                }
            },
            "ServerlessLayer": {
                "Type": "AWS::Serverless::LayerVersion",
                "Properties": {
                    "ContentUri": "/somepath"
                }
            }
        }

        list_of_layers = [{"Ref": "Layer"},
                          {"Ref": "ServerlessLayer"},
                          "arn:aws:lambda:region:account-id:layer:layer-name:1",
                          {"NonRef": "Something"}]
        actual = SamFunctionProvider._parse_layer_info(list_of_layers, resources)

        for (actual_layer, expected_layer) in zip(actual, [LayerVersion("Layer", "."),
                                                           LayerVersion("ServerlessLayer", "/somepath"),
                                                           LayerVersion(
                                                               "arn:aws:lambda:region:account-id:layer:layer-name:1",
                                                               None)]):
            self.assertEquals(actual_layer, expected_layer)
    def test_must_convert(self):

        name = "myname"
        properties = {
            "Code": {
                "Bucket": "bucket"
            },
            "Runtime": "myruntime",
            "MemorySize": "mymemorysize",
            "Timeout": "mytimeout",
            "Handler": "myhandler",
            "Environment": "myenvironment",
            "Role": "myrole",
            "Layers": ["Layer1", "Layer2"]
        }

        expected = Function(
            name="myname",
            runtime="myruntime",
            memory="mymemorysize",
            timeout="mytimeout",
            handler="myhandler",
            codeuri=".",
            environment="myenvironment",
            rolearn="myrole",
            layers=["Layer1", "Layer2"]
        )

        result = SamFunctionProvider._convert_lambda_function_resource(name, properties, ["Layer1", "Layer2"])

        self.assertEquals(expected, result)
    def test_must_handle_code_s3_uri(self):

        name = "myname"
        properties = {
            "CodeUri": "s3://bucket/key"
        }

        result = SamFunctionProvider._convert_sam_function_resource(name, properties, [])
        self.assertEquals(result.codeuri, ".")  # Default value
    def test_must_default_missing_code_uri(self):

        name = "myname"
        properties = {
            "Runtime": "myruntime"
        }

        result = SamFunctionProvider._convert_sam_function_resource(name, properties, [])
        self.assertEquals(result.codeuri, ".")  # Default value
    def test_must_extract_functions(self, SamBaseProviderMock, extract_mock):
        extract_result = {"foo": "bar"}
        extract_mock.return_value = extract_result

        template = {"Resources": {"a": "b"}}
        SamBaseProviderMock.get_template.return_value = template
        provider = SamFunctionProvider(template)

        extract_mock.assert_called_with({"a": "b"})
        SamBaseProviderMock.get_template.assert_called_with(template)
        self.assertEquals(provider.functions, extract_result)
    def test_must_default_to_empty_resources(self, SamBaseProviderMock, extract_mock):
        extract_result = {"foo": "bar"}
        extract_mock.return_value = extract_result

        template = {"a": "b"}  # Template does *not* have 'Resources' key
        SamBaseProviderMock.get_template.return_value = template
        provider = SamFunctionProvider(template)

        extract_mock.assert_called_with({})  # Empty Resources value must be passed
        self.assertEquals(provider.functions, extract_result)
        self.assertEquals(provider.resources, {})
Ejemplo n.º 14
0
    def test_must_work_for_lambda_function(self, convert_mock):
        convertion_result = "some result"
        convert_mock.return_value = convertion_result

        resources = {"Func1": {"Type": "AWS::Lambda::Function", "Properties": {"a": "b"}}}

        expected = {"Func1": "some result"}

        result = SamFunctionProvider._extract_functions(resources)
        self.assertEqual(expected, result)
        convert_mock.assert_called_with("Func1", {"a": "b"}, [])
Ejemplo n.º 15
0
    def test_return_empty_list_on_no_layers(self):
        resources = {
            "Function": {
                "Type": "AWS::Serverless::Function",
                "Properties": {}
            }
        }

        actual = SamFunctionProvider._parse_layer_info([], resources)

        self.assertEqual(actual, [])
    def test_return_empty_list_on_no_layers(self):
        resources = {
            "Function": {
                "Type": "AWS::Serverless::Function",
                "Properties": {
                }
            }
        }

        actual = SamFunctionProvider._parse_layer_info([], resources)

        self.assertEquals(actual, [])
    def test_must_handle_code_dict(self):

        name = "myname"
        properties = {
            "CodeUri": {
                # CodeUri is some dictionary
                "a": "b"
            }
        }

        result = SamFunctionProvider._convert_sam_function_resource(name, properties)
        self.assertEquals(result.codeuri, ".")  # Default value
    def test_must_handle_code_dict(self):

        name = "myname"
        properties = {
            "CodeUri": {
                # CodeUri is some dictionary
                "a": "b"
            }
        }

        result = SamFunctionProvider._convert_sam_function_resource(name, properties, [])
        self.assertEquals(result.codeuri, ".")  # Default value
    def test_must_skip_unknown_resource(self):
        resources = {
            "Func1": {
                "Type": "AWS::SomeOther::Function",
                "Properties": {"a": "b"}
            }
        }

        expected = {}

        result = SamFunctionProvider._extract_functions(resources)
        self.assertEquals(expected, result)
Ejemplo n.º 20
0
    def test_must_ignore_opt_in_AmazonLinux1803_layer(self):
        resources = {}

        list_of_layers = [
            "arn:aws:lambda:region:account-id:layer:layer-name:1",
            "arn:aws:lambda:::awslayer:AmazonLinux1803",
        ]
        actual = SamFunctionProvider._parse_layer_info(list_of_layers, resources)

        for (actual_layer, expected_layer) in zip(
            actual, [LayerVersion("arn:aws:lambda:region:account-id:layer:layer-name:1", None)]
        ):
            self.assertEqual(actual_layer, expected_layer)
Ejemplo n.º 21
0
    def __enter__(self):
        try:
            self._template_dict = get_template_data(self._template_file)
        except ValueError as ex:
            raise UserException(str(ex))

        self._function_provider = SamFunctionProvider(
            self._template_dict, self._parameter_overrides)

        if not self._base_dir:
            # Base directory, if not provided, is the directory containing the template
            self._base_dir = str(
                pathlib.Path(self._template_file).resolve().parent)

        self._build_dir = self._setup_build_dir(self._build_dir, self._clean)

        if self._use_container:
            self._container_manager = ContainerManager(
                docker_network_id=self._docker_network,
                skip_pull_image=self._skip_pull_image)

        return self
Ejemplo n.º 22
0
    def test_must_work_with_no_properties(self, convert_mock):
        convertion_result = "some result"
        convert_mock.return_value = convertion_result

        resources = {
            "Func1": {
                "Type": "AWS::Serverless::Function"
                # No Properties
            }
        }

        expected = {"Func1": "some result"}

        result = SamFunctionProvider._extract_functions(resources)
        self.assertEqual(expected, result)
        convert_mock.assert_called_with("Func1", {}, [])
    def test_must_work_for_lambda_function(self, convert_mock):
        convertion_result = "some result"
        convert_mock.return_value = convertion_result

        resources = {
            "Func1": {
                "Type": "AWS::Lambda::Function",
                "Properties": {"a": "b"}
            }
        }

        expected = {
            "Func1": "some result"
        }

        result = SamFunctionProvider._extract_functions(resources)
        self.assertEquals(expected, result)
        convert_mock.assert_called_with('Func1', {"a": "b"}, [])
    def test_must_work_with_no_properties(self, convert_mock):
        convertion_result = "some result"
        convert_mock.return_value = convertion_result

        resources = {
            "Func1": {
                "Type": "AWS::Serverless::Function"
                # No Properties
            }
        }

        expected = {
            "Func1": "some result"
        }

        result = SamFunctionProvider._extract_functions(resources)
        self.assertEquals(expected, result)
        convert_mock.assert_called_with('Func1', {}, [])
Ejemplo n.º 25
0
    def test_layers_created_from_template_resources(self):
        resources = {
            "Layer": {
                "Type": "AWS::Lambda::LayerVersion",
                "Properties": {
                    "Content": {
                        "Bucket": "bucket"
                    }
                }
            },
            "ServerlessLayer": {
                "Type": "AWS::Serverless::LayerVersion",
                "Properties": {
                    "ContentUri": "/somepath"
                }
            },
        }

        list_of_layers = [
            {
                "Ref": "Layer"
            },
            {
                "Ref": "ServerlessLayer"
            },
            "arn:aws:lambda:region:account-id:layer:layer-name:1",
            {
                "NonRef": "Something"
            },
        ]
        actual = SamFunctionProvider._parse_layer_info(list_of_layers,
                                                       resources)

        for (actual_layer, expected_layer) in zip(
                actual,
            [
                LayerVersion("Layer", "."),
                LayerVersion("ServerlessLayer", "/somepath"),
                LayerVersion(
                    "arn:aws:lambda:region:account-id:layer:layer-name:1",
                    None),
            ],
        ):
            self.assertEqual(actual_layer, expected_layer)
Ejemplo n.º 26
0
    def test_must_skip_non_existent_properties(self):

        name = "myname"
        properties = {"Code": {"Bucket": "bucket"}}

        expected = Function(name="myname",
                            runtime=None,
                            memory=None,
                            timeout=None,
                            handler=None,
                            codeuri=".",
                            environment=None,
                            rolearn=None,
                            layers=[])

        result = SamFunctionProvider._convert_lambda_function_resource(
            name, properties, [])

        self.assertEquals(expected, result)
Ejemplo n.º 27
0
    def test_must_skip_non_existent_properties(self):

        name = "myname"
        properties = {"CodeUri": "/usr/local"}

        expected = Function(
            name="myname",
            runtime=None,
            memory=None,
            timeout=None,
            handler=None,
            codeuri="/usr/local",
            environment=None,
            rolearn=None,
            layers=[],
        )

        result = SamFunctionProvider._convert_sam_function_resource(name, properties, [])

        self.assertEqual(expected, result)
    def test_must_skip_non_existent_properties(self):

        name = "myname"
        properties = {
            "CodeUri": "/usr/local"
        }

        expected = Function(
            name="myname",
            runtime=None,
            memory=None,
            timeout=None,
            handler=None,
            codeuri="/usr/local",
            environment=None,
            rolearn=None,
            layers=[]
        )

        result = SamFunctionProvider._convert_sam_function_resource(name, properties, [])

        self.assertEquals(expected, result)
Ejemplo n.º 29
0
    def test_raise_on_invalid_name(self):
        provider = SamFunctionProvider({})

        with self.assertRaises(ValueError):
            provider.get(None)
Ejemplo n.º 30
0
 def test_raise_on_AmazonLinux1703_layer_provided(self, resources,
                                                  layer_reference):
     with self.assertRaises(InvalidLayerVersionArn):
         SamFunctionProvider._parse_layer_info([layer_reference], resources)
Ejemplo n.º 31
0
 def test_raise_on_invalid_layer_resource(self, resources, layer_reference):
     with self.assertRaises(InvalidLayerReference):
         SamFunctionProvider._parse_layer_info([layer_reference], resources)
    def test_must_return_function_value(self):
        provider = SamFunctionProvider({})
        provider.functions = {"func1": "value"}  # Cheat a bit here by setting the value of this property directly

        self.assertEquals("value", provider.get("func1"))
Ejemplo n.º 33
0
    def test_must_work_with_no_functions(self):
        provider = SamFunctionProvider({})

        result = [f for f in provider.get_all()]
        self.assertEqual(result, [])
Ejemplo n.º 34
0
class TestSamFunctionProviderEndToEnd(TestCase):
    """
    Test all public methods with an input template
    """

    TEMPLATE = {
        "Resources": {
            "SamFunc1": {
                "Type": "AWS::Serverless::Function",
                "Properties": {
                    "CodeUri": "/usr/foo/bar",
                    "Runtime": "nodejs4.3",
                    "Handler": "index.handler"
                },
            },
            "SamFunc2": {
                "Type": "AWS::Serverless::Function",
                "Properties": {
                    # CodeUri is unsupported S3 location
                    "CodeUri": "s3://bucket/key",
                    "Runtime": "nodejs4.3",
                    "Handler": "index.handler",
                },
            },
            "SamFunc3": {
                "Type": "AWS::Serverless::Function",
                "Properties": {
                    # CodeUri is unsupported S3 location
                    "CodeUri": {
                        "Bucket": "bucket",
                        "Key": "key"
                    },
                    "Runtime": "nodejs4.3",
                    "Handler": "index.handler",
                },
            },
            "LambdaFunc1": {
                "Type": "AWS::Lambda::Function",
                "Properties": {
                    "Code": {
                        "S3Bucket": "bucket",
                        "S3Key": "key"
                    },
                    "Runtime": "nodejs4.3",
                    "Handler": "index.handler",
                },
            },
            "LambdaFuncWithLocalPath": {
                "Type": "AWS::Lambda::Function",
                "Properties": {
                    "Code": "./some/path/to/code",
                    "Runtime": "nodejs4.3",
                    "Handler": "index.handler"
                },
            },
            "OtherResource": {
                "Type": "AWS::Serverless::Api",
                "Properties": {
                    "StageName": "prod",
                    "DefinitionUri": "s3://bucket/key"
                },
            },
        }
    }

    EXPECTED_FUNCTIONS = ["SamFunc1", "SamFunc2", "SamFunc3", "LambdaFunc1"]

    def setUp(self):
        self.parameter_overrides = {}
        self.provider = SamFunctionProvider(
            self.TEMPLATE, parameter_overrides=self.parameter_overrides)

    @parameterized.expand([
        (
            "SamFunc1",
            Function(
                name="SamFunc1",
                runtime="nodejs4.3",
                handler="index.handler",
                codeuri="/usr/foo/bar",
                memory=None,
                timeout=None,
                environment=None,
                rolearn=None,
                layers=[],
            ),
        ),
        (
            "SamFunc2",
            Function(
                name="SamFunc2",
                runtime="nodejs4.3",
                handler="index.handler",
                codeuri=".",
                memory=None,
                timeout=None,
                environment=None,
                rolearn=None,
                layers=[],
            ),
        ),
        (
            "SamFunc3",
            Function(
                name="SamFunc3",
                runtime="nodejs4.3",
                handler="index.handler",
                codeuri=".",
                memory=None,
                timeout=None,
                environment=None,
                rolearn=None,
                layers=[],
            ),
        ),
        (
            "LambdaFunc1",
            Function(
                name="LambdaFunc1",
                runtime="nodejs4.3",
                handler="index.handler",
                codeuri=".",
                memory=None,
                timeout=None,
                environment=None,
                rolearn=None,
                layers=[],
            ),
        ),
        (
            "LambdaFuncWithLocalPath",
            Function(
                name="LambdaFuncWithLocalPath",
                runtime="nodejs4.3",
                handler="index.handler",
                codeuri="./some/path/to/code",
                memory=None,
                timeout=None,
                environment=None,
                rolearn=None,
                layers=[],
            ),
        ),
    ])
    def test_get_must_return_each_function(self, name, expected_output):

        actual = self.provider.get(name)
        self.assertEqual(actual, expected_output)

    def test_get_all_must_return_all_functions(self):

        result = {f.name for f in self.provider.get_all()}
        expected = {
            "SamFunc1", "SamFunc2", "SamFunc3", "LambdaFunc1",
            "LambdaFuncWithLocalPath"
        }

        self.assertEqual(result, expected)
 def setUp(self):
     self.provider = SamFunctionProvider(self.TEMPLATE)
 def test_raise_on_invalid_layer_resource(self, resources, layer_reference):
     with self.assertRaises(InvalidLayerReference):
         SamFunctionProvider._parse_layer_info([layer_reference], resources)
    def test_raise_on_invalid_name(self):
        provider = SamFunctionProvider({})

        with self.assertRaises(ValueError):
            provider.get(None)
Ejemplo n.º 38
0
class BuildContext(object):

    # Build directories need not be world writable.
    # This is usually a optimal permission for directories
    _BUILD_DIR_PERMISSIONS = 0o755

    def __init__(self,
                 function_identifier,
                 template_file,
                 base_dir,
                 build_dir,
                 mode,
                 manifest_path=None,
                 clean=False,
                 use_container=False,
                 parameter_overrides=None,
                 docker_network=None,
                 skip_pull_image=False):

        self._function_identifier = function_identifier
        self._template_file = template_file
        self._base_dir = base_dir
        self._build_dir = build_dir
        self._manifest_path = manifest_path
        self._clean = clean
        self._use_container = use_container
        self._parameter_overrides = parameter_overrides
        self._docker_network = docker_network
        self._skip_pull_image = skip_pull_image
        self._mode = mode

        self._function_provider = None
        self._template_dict = None
        self._app_builder = None
        self._container_manager = None

    def __enter__(self):
        try:
            self._template_dict = get_template_data(self._template_file)
        except ValueError as ex:
            raise UserException(str(ex))

        self._function_provider = SamFunctionProvider(
            self._template_dict, self._parameter_overrides)

        if not self._base_dir:
            # Base directory, if not provided, is the directory containing the template
            self._base_dir = str(
                pathlib.Path(self._template_file).resolve().parent)

        self._build_dir = self._setup_build_dir(self._build_dir, self._clean)

        if self._use_container:
            self._container_manager = ContainerManager(
                docker_network_id=self._docker_network,
                skip_pull_image=self._skip_pull_image)

        return self

    def __exit__(self, *args):
        pass

    @staticmethod
    def _setup_build_dir(build_dir, clean):
        build_path = pathlib.Path(build_dir)

        if os.path.abspath(str(build_path)) == os.path.abspath(
                str(pathlib.Path.cwd())):
            exception_message = "Failing build: Running a build with build-dir as current working directory is extremely dangerous since the build-dir contents is first removed. This is no longer supported, please remove the '--build-dir' option from the command to allow the build artifacts to be placed in the directory your template is in."
            raise InvalidBuildDirException(exception_message)

        if build_path.exists() and os.listdir(build_dir) and clean:
            # build folder contains something inside. Clear everything.
            shutil.rmtree(build_dir)

        build_path.mkdir(mode=BuildContext._BUILD_DIR_PERMISSIONS,
                         parents=True,
                         exist_ok=True)

        # ensure path resolving is done after creation: https://bugs.python.org/issue32434
        return str(build_path.resolve())

    @property
    def container_manager(self):
        return self._container_manager

    @property
    def function_provider(self):
        return self._function_provider

    @property
    def template_dict(self):
        return self._template_dict

    @property
    def build_dir(self):
        return self._build_dir

    @property
    def base_dir(self):
        return self._base_dir

    @property
    def use_container(self):
        return self._use_container

    @property
    def output_template_path(self):
        return os.path.join(self._build_dir, "template.yaml")

    @property
    def original_template_path(self):
        return os.path.abspath(self._template_file)

    @property
    def manifest_path_override(self):
        if self._manifest_path:
            return os.path.abspath(self._manifest_path)

        return None

    @property
    def mode(self):
        return self._mode

    @property
    def functions_to_build(self):
        if self._function_identifier:
            function = self._function_provider.get(self._function_identifier)

            if not function:
                all_functions = [
                    f.name for f in self._function_provider.get_all()
                ]
                available_function_message = "{} not found. Possible options in your template: {}" \
                    .format(self._function_identifier, all_functions)
                LOG.info(available_function_message)
                raise FunctionNotFound(
                    "Unable to find a Function with name '%s'",
                    self._function_identifier)

            return [function]

        return self._function_provider.get_all()
Ejemplo n.º 39
0
    def test_return_none_if_function_not_found(self):
        provider = SamFunctionProvider({})

        self.assertIsNone(provider.get("somefunc"),
                          "Must return None when Function is not found")
    def test_return_none_if_function_not_found(self):
        provider = SamFunctionProvider({})

        self.assertIsNone(provider.get("somefunc"), "Must return None when Function is not found")
Ejemplo n.º 41
0
 def setUp(self):
     self.parameter_overrides = {}
     self.provider = SamFunctionProvider(
         self.TEMPLATE, parameter_overrides=self.parameter_overrides)
class TestSamFunctionProviderEndToEnd(TestCase):
    """
    Test all public methods with an input template
    """

    TEMPLATE = {
        "Resources": {

            "SamFunc1": {
                "Type": "AWS::Serverless::Function",
                "Properties": {
                    "CodeUri": "/usr/foo/bar",
                    "Runtime": "nodejs4.3",
                    "Handler": "index.handler"
                }
            },
            "SamFunc2": {
                "Type": "AWS::Serverless::Function",
                "Properties": {
                    # CodeUri is unsupported S3 location
                    "CodeUri": "s3://bucket/key",
                    "Runtime": "nodejs4.3",
                    "Handler": "index.handler"
                }
            },
            "SamFunc3": {
                "Type": "AWS::Serverless::Function",
                "Properties": {
                    # CodeUri is unsupported S3 location
                    "CodeUri": {
                        "Bucket": "bucket",
                        "Key": "key"
                    },
                    "Runtime": "nodejs4.3",
                    "Handler": "index.handler"
                }
            },
            "LambdaFunc1": {
                "Type": "AWS::Lambda::Function",
                "Properties": {
                    "Code": {
                        "S3Bucket": "bucket",
                        "S3Key": "key"
                    },
                    "Runtime": "nodejs4.3",
                    "Handler": "index.handler"
                }
            },
            "LambdaFuncWithLocalPath": {
                "Type": "AWS::Lambda::Function",
                "Properties": {
                    "Code": "./some/path/to/code",
                    "Runtime": "nodejs4.3",
                    "Handler": "index.handler"
                }
            },
            "OtherResource": {
                "Type": "AWS::Serverless::Api",
                "Properties": {
                    "StageName": "prod",
                    "DefinitionUri": "s3://bucket/key"
                }
            }
        }
    }

    EXPECTED_FUNCTIONS = ["SamFunc1", "SamFunc2", "SamFunc3", "LambdaFunc1"]

    def setUp(self):
        self.parameter_overrides = {}
        self.provider = SamFunctionProvider(self.TEMPLATE, parameter_overrides=self.parameter_overrides)

    @parameterized.expand([
        ("SamFunc1", Function(
            name="SamFunc1",
            runtime="nodejs4.3",
            handler="index.handler",
            codeuri="/usr/foo/bar",
            memory=None,
            timeout=None,
            environment=None,
            rolearn=None,
            layers=[]
        )),
        ("SamFunc2", Function(
            name="SamFunc2",
            runtime="nodejs4.3",
            handler="index.handler",
            codeuri=".",
            memory=None,
            timeout=None,
            environment=None,
            rolearn=None,
            layers=[]
        )),
        ("SamFunc3", Function(
            name="SamFunc3",
            runtime="nodejs4.3",
            handler="index.handler",
            codeuri=".",
            memory=None,
            timeout=None,
            environment=None,
            rolearn=None,
            layers=[]
        )),
        ("LambdaFunc1", Function(
            name="LambdaFunc1",
            runtime="nodejs4.3",
            handler="index.handler",
            codeuri=".",
            memory=None,
            timeout=None,
            environment=None,
            rolearn=None,
            layers=[]
        )),
        ("LambdaFuncWithLocalPath", Function(
            name="LambdaFuncWithLocalPath",
            runtime="nodejs4.3",
            handler="index.handler",
            codeuri="./some/path/to/code",
            memory=None,
            timeout=None,
            environment=None,
            rolearn=None,
            layers=[]
        ))
    ])
    def test_get_must_return_each_function(self, name, expected_output):

        actual = self.provider.get(name)
        self.assertEquals(actual, expected_output)

    def test_get_all_must_return_all_functions(self):

        result = {f.name for f in self.provider.get_all()}
        expected = {"SamFunc1", "SamFunc2", "SamFunc3", "LambdaFunc1", "LambdaFuncWithLocalPath"}

        self.assertEquals(result, expected)
 def setUp(self):
     self.parameter_overrides = {}
     self.provider = SamFunctionProvider(self.TEMPLATE, parameter_overrides=self.parameter_overrides)
    def test_must_work_with_no_functions(self):
        provider = SamFunctionProvider({})

        result = [f for f in provider.get_all()]
        self.assertEquals(result, [])