diff --git a/samcli/commands/build/build_context.py b/samcli/commands/build/build_context.py index 817547402c..59f9e4b25c 100644 --- a/samcli/commands/build/build_context.py +++ b/samcli/commands/build/build_context.py @@ -11,6 +11,7 @@ from samcli.commands._utils.experimental import ExperimentalFlag, prompt_experimental from samcli.lib.providers.sam_api_provider import SamApiProvider +from samcli.lib.telemetry.event import EventTracker from samcli.lib.utils.packagetype import IMAGE from samcli.commands._utils.template import get_template_data @@ -267,6 +268,9 @@ def run(self): modified_template = nested_stack_manager.generate_auto_dependency_layer_stack() move_template(stack.location, output_template_path, modified_template) + for f in self.get_resources_to_build().functions: + EventTracker.track_event("BuildFunctionRuntime", f.runtime) + click.secho("\nBuild Succeeded", fg="green") # try to use relpath so the command is easier to understand, however, diff --git a/samcli/lib/telemetry/event.py b/samcli/lib/telemetry/event.py index 60635172a3..c9e8b92d3e 100644 --- a/samcli/lib/telemetry/event.py +++ b/samcli/lib/telemetry/event.py @@ -5,13 +5,15 @@ from enum import Enum from typing import List +from samcli.local.common.runtime_template import INIT_RUNTIMES + class EventName(Enum): """Enum for the names of available events to track.""" USED_FEATURE = "UsedFeature" DEPLOY = "Deploy" - BUILD_RUNTIME = "BuildRuntime" + BUILD_FUNCTION_RUNTIME = "BuildFunctionRuntime" class EventType: @@ -30,6 +32,7 @@ class EventType: "CreateChangeSetFailed", "CreateChangeSetSuccess", ], + EventName.BUILD_FUNCTION_RUNTIME: INIT_RUNTIMES, } @staticmethod diff --git a/tests/unit/commands/buildcmd/test_build_context.py b/tests/unit/commands/buildcmd/test_build_context.py index ef9f2ce913..5460d59812 100644 --- a/tests/unit/commands/buildcmd/test_build_context.py +++ b/tests/unit/commands/buildcmd/test_build_context.py @@ -1,6 +1,6 @@ import os from unittest import TestCase -from unittest.mock import patch, Mock, ANY, call +from unittest.mock import MagicMock, patch, Mock, ANY, call from parameterized import parameterized @@ -661,7 +661,7 @@ def test_run_sync_build_context( root_stack.stack_path: "./build_dir/template.yaml", child_stack.stack_path: "./build_dir/abcd/template.yaml", } - resources_mock.return_value = Mock() + resources_mock.return_value = MagicMock() builder_mock = ApplicationBuilderMock.return_value = Mock() artifacts = "artifacts" diff --git a/tests/unit/lib/build_module/test_app_builder.py b/tests/unit/lib/build_module/test_app_builder.py index 8889741251..e9b348db09 100644 --- a/tests/unit/lib/build_module/test_app_builder.py +++ b/tests/unit/lib/build_module/test_app_builder.py @@ -25,6 +25,7 @@ DockerConnectionError, ) from samcli.commands.local.cli_common.user_exceptions import InvalidFunctionPropertyType +from samcli.lib.telemetry.event import EventName, EventTracker from samcli.lib.utils.architecture import X86_64, ARM64 from samcli.lib.utils.packagetype import IMAGE, ZIP from samcli.lib.utils.stream_writer import StreamWriter @@ -1476,13 +1477,20 @@ def setUp(self): Mock(), "/build/dir", "/base/dir", "/cache/dir", mode="mode", stream_writer=StreamWriter(sys.stderr) ) + def tearDown(self): + EventTracker.clear_trackers() + @parameterized.expand([([],), (["ExpFlag1", "ExpFlag2"],)]) + @patch("samcli.lib.telemetry.event.EventType.get_accepted_values") @patch("samcli.lib.build.app_builder.LambdaBuilder") @patch("samcli.lib.build.app_builder.get_enabled_experimental_flags") - def test_must_use_lambda_builder(self, experimental_flags, experimental_flags_mock, lambda_builder_mock): + def test_must_use_lambda_builder( + self, experimental_flags, experimental_flags_mock, lambda_builder_mock, event_mock + ): experimental_flags_mock.return_value = experimental_flags config_mock = Mock() builder_instance_mock = lambda_builder_mock.return_value = Mock() + event_mock.return_value = ["runtime"] result = self.builder._build_function_in_process( config_mock, @@ -1545,10 +1553,14 @@ def test_must_raise_on_error(self, lambda_builder_mock): True, ) + @patch("samcli.lib.telemetry.event.EventType.get_accepted_values") @patch("samcli.lib.build.app_builder.LambdaBuilder") @patch("samcli.lib.build.app_builder.get_enabled_experimental_flags") - def test_building_with_experimental_flags(self, get_enabled_experimental_flags_mock, lambda_builder_mock): + def test_building_with_experimental_flags( + self, get_enabled_experimental_flags_mock, lambda_builder_mock, event_mock + ): get_enabled_experimental_flags_mock.return_value = ["A", "B", "C"] + event_mock.return_value = ["runtime"] config_mock = Mock() self.builder._build_function_in_process( config_mock, @@ -1600,11 +1612,18 @@ def setUp(self): ) self.builder._parse_builder_response = Mock() + def tearDown(self): + EventTracker.clear_trackers() + + @patch("samcli.lib.telemetry.event.EventType.get_accepted_values") @patch("samcli.lib.build.app_builder.LambdaBuildContainer") @patch("samcli.lib.build.app_builder.lambda_builders_protocol_version") @patch("samcli.lib.build.app_builder.LOG") @patch("samcli.lib.build.app_builder.osutils") - def test_must_build_in_container(self, osutils_mock, LOGMock, protocol_version_mock, LambdaBuildContainerMock): + def test_must_build_in_container( + self, osutils_mock, LOGMock, protocol_version_mock, LambdaBuildContainerMock, event_mock + ): + event_mock.return_value = "runtime" config = Mock() log_level = LOGMock.getEffectiveLevel.return_value = "foo" stdout_data = "container stdout response data"