예제 #1
0
    def setUp(self):
        # create a build graph with 2 function definitions and 2 layer definitions
        self.build_graph = BuildGraph("build_dir")

        self.function1_1 = Mock()
        self.function1_1.inlinecode = None
        self.function1_2 = Mock()
        self.function1_2.inlinecode = None
        self.function2 = Mock()
        self.function2.inlinecode = None

        self.function_build_definition1 = FunctionBuildDefinition(
            "runtime", "codeuri", ZIP, {})
        self.function_build_definition1.functions = [
            self.function1_1, self.function1_2
        ]
        self.function_build_definition2 = FunctionBuildDefinition(
            "runtime2", "codeuri", ZIP, {})
        self.function_build_definition1.functions = [self.function2]
        self.build_graph.put_function_build_definition(
            self.function_build_definition1, Mock(packagetype=ZIP))
        self.build_graph.put_function_build_definition(
            self.function_build_definition2, Mock(packagetype=ZIP))

        self.layer_build_definition1 = LayerBuildDefinition(
            "layer1", "codeuri", "build_method", [])
        self.layer_build_definition2 = LayerBuildDefinition(
            "layer2", "codeuri", "build_method", [])
        self.build_graph.put_layer_build_definition(
            self.layer_build_definition1, Mock())
        self.build_graph.put_layer_build_definition(
            self.layer_build_definition2, Mock())
예제 #2
0
    def test_if_cached_invalid_with_no_cached_folder(self, build_layer_mock,
                                                     build_function_mock,
                                                     copytree_mock):
        with osutils.mkdir_temp() as temp_base_dir:
            build_dir = Path(temp_base_dir, ".aws-sam", "build")
            build_dir.mkdir(parents=True)
            cache_dir = Path(temp_base_dir, ".aws-sam", "cache")
            cache_dir.mkdir(parents=True)

            build_function_mock.return_value = {
                "HelloWorldPython": "artifact1",
                "HelloWorldPython2": "artifact2"
            }
            build_layer_mock.return_value = {"SumLayer": "artifact3"}

            build_graph_path = Path(build_dir.parent, "build.toml")
            build_graph_path.write_text(
                CachedBuildStrategyTest.BUILD_GRAPH_CONTENTS)
            build_graph = BuildGraph(str(build_dir))
            cached_build_strategy = CachedBuildStrategy(
                build_graph, DefaultBuildStrategy, temp_base_dir, build_dir,
                cache_dir, True)
            cached_build_strategy.build_single_function_definition(
                build_graph.get_function_build_definitions()[0])
            cached_build_strategy.build_single_layer_definition(
                build_graph.get_layer_build_definitions()[0])
            build_function_mock.assert_called_once()
            build_layer_mock.assert_called_once()
            self.assertEqual(copytree_mock.call_count, 2)
예제 #3
0
    def test_functions_should_be_added_existing_build_graph(self):
        with osutils.mkdir_temp() as temp_base_dir:
            build_dir = Path(temp_base_dir, ".aws-sam", "build")
            build_dir.mkdir(parents=True)

            build_graph_path = Path(build_dir.parent, "build.toml")
            build_graph_path.write_text(TestBuildGraph.BUILD_GRAPH_CONTENTS)

            build_graph = BuildGraph(str(build_dir))

            build_definition1 = BuildDefinition(TestBuildGraph.RUNTIME,
                                                TestBuildGraph.CODEURI,
                                                TestBuildGraph.METADATA)
            function1 = generate_function(runtime=TestBuildGraph.RUNTIME,
                                          codeuri=TestBuildGraph.CODEURI,
                                          metadata=TestBuildGraph.METADATA)
            build_graph.put_build_definition(build_definition1, function1)

            self.assertTrue(len(build_graph.get_build_definitions()), 1)
            for build_definition in build_graph.get_build_definitions():
                self.assertTrue(len(build_definition.functions), 1)
                self.assertTrue(build_definition.functions[0], function1)
                self.assertEqual(build_definition.uuid, TestBuildGraph.UUID)

            build_definition2 = BuildDefinition("another_runtime",
                                                "another_codeuri", None)
            function2 = generate_function(name="another_function")
            build_graph.put_build_definition(build_definition2, function2)
            self.assertTrue(len(build_graph.get_build_definitions()), 2)
예제 #4
0
    def test_should_read_existing_build_graph(self):
        with osutils.mkdir_temp() as temp_base_dir:
            build_dir = Path(temp_base_dir, ".aws-sam", "build")
            build_dir.mkdir(parents=True)

            build_graph_path = Path(build_dir.parent, "build.toml")
            build_graph_path.write_text(TestBuildGraph.BUILD_GRAPH_CONTENTS)

            build_graph = BuildGraph(str(build_dir))
            for build_definition in build_graph.get_build_definitions():
                self.assertEqual(build_definition.codeuri, TestBuildGraph.CODEURI)
                self.assertEqual(build_definition.runtime, TestBuildGraph.RUNTIME)
                self.assertEqual(build_definition.metadata, TestBuildGraph.METADATA)
예제 #5
0
    def _get_build_graph(self):
        """
        Converts list of functions and layers into a build graph, where we can iterate on each unique build and trigger
        build
        :return: BuildGraph, which represents list of unique build definitions
        """
        build_graph = BuildGraph(self._build_dir)
        functions = self._resources_to_build.functions
        layers = self._resources_to_build.layers
        for function in functions:
            function_build_details = FunctionBuildDefinition(
                function.runtime, function.codeuri, function.packagetype,
                function.metadata)
            build_graph.put_function_build_definition(function_build_details,
                                                      function)

        for layer in layers:
            layer_build_details = LayerBuildDefinition(
                layer.name, layer.codeuri, layer.build_method,
                layer.compatible_runtimes)
            build_graph.put_layer_build_definition(layer_build_details, layer)

        build_graph.clean_redundant_definitions_and_update(
            not self._is_building_specific_resource)
        return build_graph
    def test_if_cached_valid_when_build_single_function_definition(
            self, dir_checksum_mock, exists_mock, copytree_mock):
        pass
        with osutils.mkdir_temp() as temp_base_dir:
            build_dir = Path(temp_base_dir, ".aws-sam", "build")
            build_dir.mkdir(parents=True)
            cache_dir = Path(temp_base_dir, ".aws-sam", "cache")
            cache_dir.mkdir(parents=True)

            exists_mock.return_value = True
            dir_checksum_mock.return_value = CachedBuildStrategyTest.SOURCE_MD5

            build_graph_path = Path(build_dir.parent, "build.toml")
            build_graph_path.write_text(
                CachedBuildStrategyTest.BUILD_GRAPH_CONTENTS)
            build_graph = BuildGraph(str(build_dir))
            cached_build_strategy = CachedBuildStrategy(
                build_graph, DefaultBuildStrategy, temp_base_dir, build_dir,
                cache_dir, True)
            func1 = Mock()
            func1.name = "func1_name"
            func2 = Mock()
            func2.name = "func2_name"
            build_definition = build_graph.get_function_build_definitions()[0]
            layer_definition = build_graph.get_layer_build_definitions()[0]
            build_graph.put_function_build_definition(build_definition, func1)
            build_graph.put_function_build_definition(build_definition, func2)
            layer = Mock()
            layer.name = "layer_name"
            build_graph.put_layer_build_definition(layer_definition, layer)
            cached_build_strategy.build_single_function_definition(
                build_definition)
            cached_build_strategy.build_single_layer_definition(
                layer_definition)
            self.assertEqual(copytree_mock.call_count, 3)
class BuildStrategyBaseTest(TestCase):
    def setUp(self):
        # create a build graph with 2 function definitions and 2 layer definitions
        self.build_graph = BuildGraph("build_dir")

        self.function1_1 = Mock()
        self.function1_2 = Mock()
        self.function2 = Mock()

        self.function_build_definition1 = FunctionBuildDefinition(
            "runtime", "codeuri", {})
        self.function_build_definition1.functions = [
            self.function1_1, self.function1_2
        ]
        self.function_build_definition2 = FunctionBuildDefinition(
            "runtime2", "codeuri", {})
        self.function_build_definition1.functions = [self.function2]
        self.build_graph.put_function_build_definition(
            self.function_build_definition1, Mock())
        self.build_graph.put_function_build_definition(
            self.function_build_definition2, Mock())

        self.layer_build_definition1 = LayerBuildDefinition(
            "layer1", "codeuri", "build_method", [])
        self.layer_build_definition2 = LayerBuildDefinition(
            "layer2", "codeuri", "build_method", [])
        self.build_graph.put_layer_build_definition(
            self.layer_build_definition1, Mock())
        self.build_graph.put_layer_build_definition(
            self.layer_build_definition2, Mock())
예제 #8
0
    def test_should_instantiate_first_time(self):
        with osutils.mkdir_temp() as temp_base_dir:
            build_dir = Path(temp_base_dir, ".aws-sam", "build")
            build_dir.mkdir(parents=True)
            build_graph1 = BuildGraph(str(build_dir.resolve()))
            build_graph1.clean_redundant_functions_and_update(True)

            build_graph2 = BuildGraph(str(build_dir.resolve()))

            self.assertEqual(build_graph1.get_build_definitions(), build_graph2.get_build_definitions())
예제 #9
0
    def _build_layers(self, build_graph: BuildGraph) -> Dict[str, str]:
        """
        Iterates through build graph and runs each unique build and copies outcome to the corresponding layer folder
        """
        layer_build_results = {}
        for layer_definition in build_graph.get_layer_build_definitions():
            layer_build_results.update(self.build_single_layer_definition(layer_definition))

        return layer_build_results
예제 #10
0
    def _build_functions(self, build_graph: BuildGraph) -> Dict[str, str]:
        """
        Iterates through build graph and runs each unique build and copies outcome to the corresponding function folder
        """
        function_build_results = {}
        for build_definition in build_graph.get_function_build_definitions():
            function_build_results.update(self.build_single_function_definition(build_definition))

        return function_build_results
예제 #11
0
class BuildStrategyBaseTest(TestCase):
    def setUp(self):
        # create a build graph with 2 function definitions and 2 layer definitions
        self.build_graph = BuildGraph("build_dir")

        self.function1_1 = Mock()
        self.function1_1.inlinecode = None
        self.function1_1.get_build_dir = Mock()
        self.function1_1.full_path = Mock()
        self.function1_2 = Mock()
        self.function1_2.inlinecode = None
        self.function1_2.get_build_dir = Mock()
        self.function1_2.full_path = Mock()
        self.function2 = Mock()
        self.function2.inlinecode = None
        self.function2.get_build_dir = Mock()
        self.function2.full_path = Mock()

        self.function_build_definition1 = FunctionBuildDefinition(
            "runtime", "codeuri", ZIP, {})
        self.function_build_definition2 = FunctionBuildDefinition(
            "runtime2", "codeuri", ZIP, {})
        self.build_graph.put_function_build_definition(
            self.function_build_definition1, self.function1_1)
        self.build_graph.put_function_build_definition(
            self.function_build_definition1, self.function1_2)
        self.build_graph.put_function_build_definition(
            self.function_build_definition2, self.function2)

        self.layer1 = Mock()
        self.layer2 = Mock()

        self.layer_build_definition1 = LayerBuildDefinition(
            "layer1", "codeuri", "build_method", [])
        self.layer_build_definition2 = LayerBuildDefinition(
            "layer2", "codeuri", "build_method", [])
        self.build_graph.put_layer_build_definition(
            self.layer_build_definition1, self.layer1)
        self.build_graph.put_layer_build_definition(
            self.layer_build_definition2, self.layer2)
    def test_redundant_cached_should_be_clean(self):
        with osutils.mkdir_temp() as temp_base_dir:
            build_dir = Path(temp_base_dir, ".aws-sam", "build")
            build_dir.mkdir(parents=True)
            build_graph = BuildGraph(str(build_dir.resolve()))
            cache_dir = Path(temp_base_dir, ".aws-sam", "cache")
            cache_dir.mkdir(parents=True)
            redundant_cache_folder = Path(cache_dir, "redundant")
            redundant_cache_folder.mkdir(parents=True)

            cached_build_strategy = CachedBuildStrategy(build_graph, Mock(), temp_base_dir, build_dir, cache_dir, True)
            cached_build_strategy._clean_redundant_cached()
            self.assertTrue(not redundant_cache_folder.exists())
예제 #13
0
    def _get_build_graph(self,
                         inline_env_vars: Optional[Dict] = None,
                         env_vars_file: Optional[str] = None) -> BuildGraph:
        """
        Converts list of functions and layers into a build graph, where we can iterate on each unique build and trigger
        build
        :return: BuildGraph, which represents list of unique build definitions
        """
        build_graph = BuildGraph(self._build_dir)
        functions = self._resources_to_build.functions
        layers = self._resources_to_build.layers
        file_env_vars = {}
        if env_vars_file:
            try:
                with open(env_vars_file, "r", encoding="utf-8") as fp:
                    file_env_vars = json.load(fp)
            except Exception as ex:
                raise IOError(
                    "Could not read environment variables overrides from file {}: {}"
                    .format(env_vars_file, str(ex))) from ex

        for function in functions:
            container_env_vars = self._make_env_vars(function, file_env_vars,
                                                     inline_env_vars)
            function_build_details = FunctionBuildDefinition(
                function.runtime,
                function.codeuri,
                function.packagetype,
                function.metadata,
                env_vars=container_env_vars)
            build_graph.put_function_build_definition(function_build_details,
                                                      function)

        for layer in layers:
            container_env_vars = self._make_env_vars(layer, file_env_vars,
                                                     inline_env_vars)
            layer_build_details = LayerBuildDefinition(
                layer.name,
                layer.codeuri,
                layer.build_method,
                layer.compatible_runtimes,
                env_vars=container_env_vars)
            build_graph.put_layer_build_definition(layer_build_details, layer)

        build_graph.clean_redundant_definitions_and_update(
            not self._is_building_specific_resource)
        return build_graph
예제 #14
0
    def _get_build_graph(self):
        """
        Converts list of functions into a build graph, where we can iterate on each unique build and trigger build
        :return: BuildGraph, which represents list of unique build definitions
        """
        build_graph = BuildGraph(self._build_dir)
        functions = self._resources_to_build.functions
        for function in functions:
            build_details = BuildDefinition(function.runtime, function.codeuri, function.metadata)
            build_graph.put_build_definition(build_details, function)

        build_graph.clean_redundant_functions_and_update(not self._is_building_specific_resource)
        return build_graph
예제 #15
0
    def test_should_instantiate_first_time_and_update(self):
        with osutils.mkdir_temp() as temp_base_dir:
            build_dir = Path(temp_base_dir, ".aws-sam", "build")
            build_dir.mkdir(parents=True)

            # create a build graph and persist it
            build_graph1 = BuildGraph(str(build_dir))
            build_definition1 = BuildDefinition(TestBuildGraph.RUNTIME,
                                                TestBuildGraph.CODEURI,
                                                TestBuildGraph.METADATA)
            function1 = generate_function(runtime=TestBuildGraph.RUNTIME,
                                          codeuri=TestBuildGraph.CODEURI,
                                          metadata=TestBuildGraph.METADATA)
            build_graph1.put_build_definition(build_definition1, function1)
            build_graph1.clean_redundant_functions_and_update(True)

            # read previously persisted graph and compare
            build_graph2 = BuildGraph(str(build_dir))
            self.assertEqual(len(build_graph1.get_build_definitions()),
                             len(build_graph2.get_build_definitions()))
            self.assertEqual(
                list(build_graph1.get_build_definitions())[0],
                list(build_graph2.get_build_definitions())[0])