Ejemplo n.º 1
0
    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):
     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()
Ejemplo n.º 3
0
    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"])
Ejemplo n.º 4
0
 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 _setup_final_environment(self, environment, environment_override):
        environment.update(environment_override)

        # set additional parameters if needed (costly default init or depend on other parameters)
        if environment.get('initial_sampling_interval') is None:
            environment['initial_sampling_interval'] = datetime.timedelta(
                seconds=SystemRandom().uniform(0, AgentConfiguration.get().sampling_interval.total_seconds()))
        environment['excluded_threads'] = \
            frozenset({environment['profiler_thread_name']}.union(environment['excluded_threads']))
        # TODO delay metadata lookup until we need it
        environment['agent_metadata'] = environment.get('agent_metadata') or AgentMetadata()
        environment['collector'] = environment.get('collector') or self._select_collector(environment)
        environment["profiler_disabler"] = environment.get('profiler_disabler') or ProfilerDisabler(environment)
        return UnmodifiableDict(environment)
def _create_lambda_profiler(profiling_group_name, region_name, environment_override, context, env=os.environ):
    """
    Calls build_profiler module to create the profiler object. If we fail to create it we return a no-op profiler
    so that we don't even go through this method again.
    """
    from codeguru_profiler_agent.profiler_builder import build_profiler
    from codeguru_profiler_agent.agent_metadata.agent_metadata import AgentMetadata
    from codeguru_profiler_agent.agent_metadata.aws_lambda import AWSLambda
    override = {'agent_metadata': AgentMetadata(AWSLambda.look_up_metadata(context))}
    override.update(environment_override)
    profiler = build_profiler(pg_name=profiling_group_name, region_name=region_name, override=override, env=env)
    if profiler is None:
        return _EmptyProfiler()
    return profiler
        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")
Ejemplo n.º 9
0
                    [Frame("bottom"),
                     Frame("middle"),
                     Frame("different_top")],
                    [Frame("bottom"), Frame("middle")]],
            attempted_sample_threads_count=10,
            seen_threads_count=15))
    profile.end = end_time
    profile.set_overhead_ms(timedelta(milliseconds=256))
    if platform.system() == "Windows":
        # In Windows, as time.process stays constant if no cpu time was used (https://bugs.python.org/issue37859), we
        # would need to manually override the cpu_time_seconds to ensure the test runs as expected
        profile.cpu_time_seconds = 0.123
    return profile


agent_metadata = AgentMetadata(fleet_info=AWSEC2Instance(
    host_name="testHostName", host_type="testHostType"))

environment = {"timer": Timer(), "agent_metadata": agent_metadata}


class TestSdkProfileEncoder:
    def before(self):
        self.profile = example_profile()
        self.output_stream = io.BytesIO()
        self.subject = \
            ProfileEncoder(gzip=False, environment=environment)
        self.decoded_json_result = self.decoded_json_result.__get__(self)
        self._decoded_json_result = None

    def decoded_json_result(self):
        if not self._decoded_json_result:
    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_it_returns_default_agent_metadata(self):
                subject = AgentMetadata()

                assert subject.agent_info == AgentInfo.default_agent_info()
                assert subject.fleet_info is not None
                assert subject.runtime_version[0] == "3"
    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)