def before(self): self.profiler = Profiler( profiling_group_name=DUMMY_TEST_PROFILING_GROUP_NAME, environment_override={ 'initial_sampling_interval': timedelta(), 'agent_metadata': AgentMetadata(fleet_info=DefaultFleetInfo()) }) self.client_stubber = Stubber( self.profiler._profiler_runner.collector.reporter. codeguru_client_builder.codeguru_client) report_expected_params = { 'agentProfile': ANY, 'contentType': 'application/json', 'profilingGroupName': DUMMY_TEST_PROFILING_GROUP_NAME } self.client_stubber.add_response( 'configure_agent', {'configuration': { 'shouldProfile': True, 'periodInSeconds': 100 }}) self.client_stubber.add_response('post_agent_profile', {}, report_expected_params) yield self.profiler.stop()
def before(self): codeguru_client_builder = CodeGuruClientBuilder( environment={"aws_session": boto3.session.Session()}) self.client_stubber = Stubber(codeguru_client_builder.codeguru_client) self.clear_lambda_specific_environment_variables_for_test_run() profile_encoder = MagicMock(name="profile_encoder", spec=ProfileEncoder) profile_encoder.encode.side_effect = lambda **args: args[ "output_stream"].write(b"test-profile-encoder-output") self.environment = { "profiling_group_name": profiling_group_name, "profile_encoder": profile_encoder, "codeguru_profiler_builder": codeguru_client_builder, "agent_metadata": AgentMetadata(fleet_info=DefaultFleetInfo()), "reporting_interval": timedelta(minutes=13), "sampling_interval": timedelta(seconds=13), "minimum_time_reporting": timedelta(minutes=13), "max_stack_depth": 1300 } default_config = AgentConfiguration( should_profile=True, sampling_interval=self.environment["sampling_interval"], reporting_interval=self.environment["reporting_interval"], minimum_time_reporting=self.environment["minimum_time_reporting"]) self.environment["agent_config_merger"] = AgentConfigurationMerger( default_config) self.subject = SdkReporter(environment=self.environment) self.subject.setup()
def before(self): now_millis = int(time.time()) * 1000 five_minutes_ago_millis = now_millis - (5 * 60 * 1000) sample = Sample( stacks=[[Frame(MY_PROFILING_GROUP_NAME_FOR_INTEG_TESTS)]], attempted_sample_threads_count=1, seen_threads_count=1) self.profile = Profile(MY_PROFILING_GROUP_NAME_FOR_INTEG_TESTS, 1.0, 1.0, five_minutes_ago_millis) # FIXME: Remove adding the end time manually below after feature fully support self.profile.end = now_millis self.profile.add(sample) self.environment = { "should_profile": True, "profiling_group_name": MY_PROFILING_GROUP_NAME_FOR_INTEG_TESTS, "aws_session": boto3.session.Session(), "reporting_interval": timedelta(minutes=13), "sampling_interval": timedelta(seconds=1), "minimum_time_reporting": timedelta(minutes=6), "max_stack_depth": 2345, "cpu_limit_percentage": 29, "agent_metadata": AgentMetadata(fleet_info=DefaultFleetInfo()) } self.environment["codeguru_profiler_builder"] = CodeGuruClientBuilder( self.environment) self.agent_config = AgentConfiguration( should_profile=True, sampling_interval=self.environment["sampling_interval"], reporting_interval=self.environment["reporting_interval"], minimum_time_reporting=self.environment["minimum_time_reporting"], max_stack_depth=self.environment["max_stack_depth"], cpu_limit_percentage=self.environment["cpu_limit_percentage"])
def before(self): self.timer = Timer() self.profiler = Profiler( profiling_group_name=DUMMY_TEST_PROFILING_GROUP_NAME, environment_override={ "timer": self.timer, "cpu_limit_percentage": 40, "sampling_interval": timedelta(seconds=0.01), 'agent_metadata': AgentMetadata(fleet_info=DefaultFleetInfo()) }, ) yield self.profiler.stop()
def before(self): temporary_directory = tempfile.mkdtemp() self.temp_filepath = str( Path(temporary_directory, 'test_profiler_stops_after_killswitch_was_detected')) self.profiler = Profiler( profiling_group_name="test-application", environment_override={ "cpu_limit_percentage": None, "killswitch_filepath": self.temp_filepath, "sampling_interval": timedelta(seconds=0.1), 'agent_metadata': AgentMetadata(fleet_info=DefaultFleetInfo()) }) yield shutil.rmtree(temporary_directory) self.profiler.stop()
def test_it_samples_and_saves_a_profile_to_a_file(self): with \ patch( "codeguru_profiler_agent.reporter.agent_configuration.AgentConfiguration.is_under_min_reporting_time", return_value=False): file_prefix = str(Path(self.temporary_directory, FILE_PREFIX)) test_start_time = time_utils.current_milli_time() profiler = Profiler( profiling_group_name=DUMMY_TEST_PROFILING_GROUP_NAME, environment_override={ "initial_sampling_interval": timedelta(), "reporting_mode": "file", "file_prefix": file_prefix, 'agent_metadata': AgentMetadata(fleet_info=DefaultFleetInfo()) }) try: profiler.start() finally: profiler.stop() test_end_time = time_utils.current_milli_time() resulting_profile_path = str( Path(self.temporary_directory, os.listdir(self.temporary_directory)[0])) with (open(resulting_profile_path)) as profiling_result_file: resulting_json = json.loads(profiling_result_file.read()) self.assert_valid_agent_metadata(resulting_json["agentMetadata"]) assert test_start_time <= resulting_json[ "start"] <= resulting_json["end"] <= test_end_time assert frames_in_callgraph_are_in_expected_order( resulting_json["callgraph"], "test.help_utils:HelperThreadRunner:dummy_parent_method", "test.help_utils:HelperThreadRunner:dummy_method")
def test_live_profiling(self): with \ patch( "codeguru_profiler_agent.reporter.agent_configuration.AgentConfiguration.is_under_min_reporting_time", return_value=False), \ patch( "codeguru_profiler_agent.reporter.agent_configuration.AgentConfiguration._is_reporting_interval_smaller_than_minimum_allowed", return_value=False): profiler = Profiler( profiling_group_name=DUMMY_TEST_PROFILING_GROUP_NAME, region_name='eu-west-2', environment_override={ "initial_sampling_interval": timedelta(), "sampling_interval": timedelta(seconds=1), "reporting_interval": timedelta(seconds=2), 'agent_metadata': AgentMetadata(fleet_info=DefaultFleetInfo()) }) client = profiler._profiler_runner.collector.reporter.codeguru_client_builder.codeguru_client aggregator = profiler._profiler_runner.collector assert AgentConfiguration.get().sampling_interval == timedelta( seconds=1) assert AgentConfiguration.get().reporting_interval == timedelta( seconds=2) with \ patch.object(client, "post_agent_profile", wraps=client.post_agent_profile) as wrapped_post_agent_profile, \ patch.object(client, "configure_agent", wraps=client.configure_agent) as wrapped_configure_agent, \ patch.object(aggregator, "add", wraps=aggregator.add) as wrapped_add, \ patch( "codeguru_profiler_agent.reporter.agent_configuration.AgentConfiguration.is_under_min_reporting_time", return_value=False), \ patch( "codeguru_profiler_agent.reporter.agent_configuration.AgentConfiguration._is_reporting_interval_smaller_than_minimum_allowed", return_value=False): wrapped_configure_agent.return_value = { "configuration": { "agentParameters": { "SamplingIntervalInMilliseconds": "100", "MinimumTimeForReportingInMilliseconds": "1000", "MaxStackDepth": "1000", "MemoryUsageLimitPercent": "29" }, "periodInSeconds": 2, "shouldProfile": True } } try: start_status = profiler.start() assert start_status assert profiler.is_running() time.sleep(3) finally: profiler.stop() assert wrapped_add.call_count >= 3 assert wrapped_post_agent_profile.call_count >= 1 assert wrapped_configure_agent.call_count >= 1 assert AgentConfiguration.get().sampling_interval == timedelta( seconds=1) assert AgentConfiguration.get( ).reporting_interval == timedelta(seconds=2)
def test_live_profiling(self): with \ patch( "codeguru_profiler_agent.reporter.agent_configuration.AgentConfiguration.is_under_min_reporting_time", return_value=False), \ patch( "codeguru_profiler_agent.sdk_reporter.sdk_reporter.SdkReporter.check_create_pg_called_during_submit_profile", return_value=False), \ patch( "codeguru_profiler_agent.reporter.agent_configuration.AgentConfiguration._is_reporting_interval_smaller_than_minimum_allowed", return_value=False): profiler = Profiler( profiling_group_name=DUMMY_TEST_PROFILING_GROUP_NAME, region_name='eu-west-2', environment_override={ "initial_sampling_interval": timedelta(), "sampling_interval": timedelta(seconds=1), "reporting_interval": timedelta(seconds=2), 'agent_metadata': AgentMetadata(fleet_info=DefaultFleetInfo()) }) client = profiler._profiler_runner.collector.reporter.codeguru_client_builder.codeguru_client aggregator = profiler._profiler_runner.collector assert AgentConfiguration.get().sampling_interval == timedelta( seconds=1) assert AgentConfiguration.get().reporting_interval == timedelta( seconds=2) with \ patch.object(client, "post_agent_profile", wraps=client.post_agent_profile) as wrapped_post_agent_profile, \ patch.object(client, "configure_agent", wraps=client.configure_agent) as wrapped_configure_agent, \ patch.object(aggregator, "add", wraps=aggregator.add) as wrapped_add, \ patch( "codeguru_profiler_agent.reporter.agent_configuration.AgentConfiguration.is_under_min_reporting_time", return_value=False), \ patch( "codeguru_profiler_agent.reporter.agent_configuration.AgentConfiguration._is_reporting_interval_smaller_than_minimum_allowed", return_value=False): wrapped_configure_agent.return_value = { "configuration": { "agentParameters": { "SamplingIntervalInMilliseconds": "100", "MinimumTimeForReportingInMilliseconds": "1000", "MaxStackDepth": "1000", "MemoryUsageLimitPercent": "29" }, "periodInSeconds": 2, "shouldProfile": True } } try: start_status = profiler.start() assert start_status assert profiler.is_running() time.sleep(4) finally: profiler.stop() # We should see at least 2 samples in 4 seconds as the sequence should happen in the order of # initial delay (1 second) # After 1 second, no flush -> sample # After 2 seconds, it attempt to flush (possibly succeed) -> sample/ no sample # After 3 seconds, it attempt to flush (must succeed if it did not flush before) -> no sample/ sample # After 4 seconds, no flush -> sample (if profiler has not stopped yet) assert wrapped_add.call_count >= 2 assert wrapped_post_agent_profile.call_count >= 1 assert wrapped_configure_agent.call_count >= 1 assert AgentConfiguration.get().sampling_interval == timedelta( seconds=1) assert AgentConfiguration.get( ).reporting_interval == timedelta(seconds=2)