class TestCPULimitReachedDuringProfiling: @before 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 test_profiler_terminates(self): self.profiler.start() assert self.profiler.is_running() # With sampling_interval to be 0.01 seconds, having runProfiler as 0.5 seconds should breach # the cpu limit. We need to sample 20 times before we check the CPU limit for i in range(20): self.timer.record('sampleAndAggregate', 0.5) assert wait_for(lambda: not self.profiler.is_running(), timeout_seconds=5)
class TestKillSwitchActivatesDuringExecution: @before 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_profiler_stops_after_killswitch_was_detected(self): self.profiler.start() assert self.profiler.is_running() is True Path(self.temp_filepath).touch() # Force the killswitch check happens immediately self.profiler._profiler_runner_instance.profiler_disabler.killswitch.last_check_for_file_time = None assert (wait_for(lambda: not self.profiler.is_running(), timeout_seconds=5))
class TestEndToEndProfiling: @before 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 test_report_when_stopped(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): with self.client_stubber: self.profiler.start() self.profiler.stop() # stop will trigger the report # check that we have reported. assert_no_pending_responses will fail if post_agent_profile is not called # with the expected parameters. self.client_stubber.assert_no_pending_responses() def test_report_via_invalid_reporting_mode(self): self.profiler = Profiler( profiling_group_name=DUMMY_TEST_PROFILING_GROUP_NAME, environment_override={ "reporting_mode": "invalid_reporting_mode", }) self.profiler.start() assert self.profiler.is_running() is False
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)