Beispiel #1
0
 def _blame_line(self, traceback):
     '''Figures out which line in traceback is to blame for the error.
     Returns a 3-tuple of (ErrorKey, StackTraceEntry, [email recipients])'''
     key = None
     blamed_entry = None
     email_recipients = []
     for stack_line in traceback:
         line_type = self._get_line_type(stack_line)
         if line_type == api_ttypes.LineType.THIRDPARTY_WHITELIST:
             return None, None, None, True
         elif line_type in [
                 api_ttypes.LineType.DEFAULT,
                 api_ttypes.LineType.KNOWN_ERROR
         ]:
             filepath = self._get_basepath(stack_line.filename)
             entry = api_ttypes.CodeIdentifier(filepath,
                                               stack_line.function_name,
                                               stack_line.text)
             blamed_entry = entry
             key = api_ttypes.ErrorKey(filepath, stack_line.line_number,
                                       stack_line.function_name,
                                       stack_line.text)
             if filepath in self.watch_all_errors:
                 email_recipients.extend(self.watch_all_errors[filepath])
     return (key, blamed_entry, email_recipients, False)
Beispiel #2
0
    def _get_line_type(self, line):
        filepath = self._get_basepath(line.filename)
        if not filepath:
            return api_ttypes.LineType.BAD_FILEPATH

        entry = api_ttypes.CodeIdentifier(filepath, line.function_name,
                                          line.text)
        if entry in self.third_party_whitelist[filepath]:
            return api_ttypes.LineType.THIRDPARTY_WHITELIST
        elif not self._matches_filepath_pattern(filepath):
            return api_ttypes.LineType.IGNORED_FILEPATH
        elif entry in self.building_blocks[filepath]:
            return api_ttypes.LineType.BUILDING_BLOCK
        elif entry in self.known_errors[filepath]:
            return api_ttypes.LineType.KNOWN_ERROR
        elif self.raise_exception_pattern.match(line.text):
            return api_ttypes.LineType.RAISED_EXCEPTION
        else:
            return api_ttypes.LineType.DEFAULT
Beispiel #3
0
    def setUp(self):
        super(BaseTestCase, self).setUp()
        self.popen_stub = POpenStub()
        self.popen_stub.stdout = StringIO(
            "75563df6e9d1efe44b48f6643fde9ebbd822b0c5 25 25 1\n"
            "author John Egan\n"
            "author-mail <*****@*****.**>\n"
            "author-time %d\n"
            "author-tz -0800\n"
            "committer John Egan\n"
            "committer-mail <*****@*****.**>\n"
            "committer-time 1356245776\n"
            "committer-tz -0800\n"
            "summary Add more robust support for string keys\n"
            "previous 3491c7b8e298ec81dc7583163a118e7c2250999f safe_access.py\n"
            "filename safe_access.py\n"
            "                             ex: a.b.[myvar] where myvar is passed in as a kwarg\n"
            % int(time.mktime(datetime.datetime(2017, 7, 30).timetuple())))

        self._set_stub_time(datetime.datetime(2020, 1, 1))
        self.smtp_stub = SMTPClientStub()
        self.file_open_stub = OpenFileStub()

        self.watchers = api_ttypes.WatchList([
            api_ttypes.WatchFileEntry(
                email="*****@*****.**",
                filepath="tools/furminator.py",
                watch_all_errors=True,
            ),
            api_ttypes.WatchFileEntry(
                email="*****@*****.**",
                filepath="tools/furminator.py",
                watch_all_errors=True,
            ),
            api_ttypes.WatchFileEntry(
                email="*****@*****.**",
                filepath="lib/no/such/path/for/testing.py",
                watch_all_errors=True,
            ),
        ])

        self.third_party_whitelist = api_ttypes.CodeIdentifierList([
            api_ttypes.CodeIdentifier('facebook.py', 'post_treat_to_facebook',
                                      'urllib.urlencode(args), post_data)'),
            api_ttypes.CodeIdentifier(
                'SQLAlchemy-0.5.6-py2.6.egg/sqlalchemy/pool.py',
                'do_get',
                'raise exc.TimeoutError("QueuePool limit of size %d overflow %d ',
            ),
        ])

        self.known_errors = api_ttypes.KnownErrorList([
            api_ttypes.KnownError(
                'lib/doghouse/authentication.py',
                'check_auth',
                'raise errors.BadAuthenticationError("Something smells off...")',
                max_alert_threshold=0,
            ),
            api_ttypes.KnownError(
                filename='coreservices/waterbowl/rewards/water.py',
                function_name='make_external_api_ttypes_request',
                code_fragment='raise api_ttypes.WaterbowlError(error_code='
                'api_ttypes.WaterbowlErrorCode.OUT_OF_WATER, message=str(e))',
                email_recipients=[
                    "*****@*****.**", "*****@*****.**"
                ],
                email_header=
                'NOTE: This error typically does not require dev team involvement.',
                alert_every_n_occurrences=1,
            ),
        ])

        self.building_blocks = api_ttypes.CodeIdentifierList([
            api_ttypes.CodeIdentifier(
                'apps/shopkick/doghouse/lib/base.py', '_get_request_param',
                'raise errors.BadRequestError("Missing param %s" % name)'),
        ])

        self.ignored_exceptions = api_ttypes.IgnoredExceptionList(
            ['exceptions.BananaException'])

        self.disowned_files = api_ttypes.FileDisownershipList([
            api_ttypes.FileDisownershipEntry(
                email='*****@*****.**',
                filepath='scripts',
                designated_email='*****@*****.**')
        ])

        self.config_storage_stub = StubStorage(partition=None)
        self.config_storage_stub["watch_list"] = self.watchers
        self.config_storage_stub[
            "third_party_whitelist"] = self.third_party_whitelist
        self.config_storage_stub["known_errors"] = self.known_errors
        self.config_storage_stub["building_blocks"] = self.building_blocks
        self.config_storage_stub[
            "ignored_exceptions"] = self.ignored_exceptions
        self.config_storage_stub["disownership_list"] = self.disowned_files
        self.errors_storage_stub = StubStorage(partition=None)

        self.saved_config = copy.deepcopy(flawless.lib.config.get().__dict__)
        self.test_config = flawless.lib.config.get()
        self.test_config.__dict__ = dict(
            (o.name, o.default) for o in flawless.lib.config.OPTIONS)
        self.test_config.repo_dir = "/tmp"
        self.test_config.report_only_after_minimum_date = "2010-01-01"
        self.test_config.report_error_threshold = 1
        self.test_config.only_blame_filepaths_matching = [
            r"^coreservices(?!.*/thrift/).*$", r"lib/.*", r"tools/.*",
            r"scripts/.*"
        ]
        self.test_config.report_runtime_package_directory_names = [
            "site-packages"
        ]
        self.test_config.config_dir_path = "../config"

        self.handler = FlawlessThriftServiceHandler(
            open_process_func=self.popen_stub,
            storage_factory=lambda partition: self.errors_storage_stub
            if partition else self.config_storage_stub,
            smtp_client_cls=self.smtp_stub,
            time_func=lambda: self.stub_time,
            thread_cls=ThreadStub,
        )