コード例 #1
0
ファイル: plugins_sa_test.py プロジェクト: sporkman/fuglu
    def test_extract_spamstatus(self):
        """Test if the spam status header gets extracted correctly"""

        candidate = SAPlugin(self.config)
        suspect = Suspect(
            '*****@*****.**', '*****@*****.**', '/dev/null')
        headername = 'X-Spam-Status'
        headertests = [  # tuple header content, expected spamstatus, expected spam score
            ('YES', True, None),  # _YESNOCAPS_
            ('NO', False, None),  # _YESNOCAPS_
            (' Yes, score=13.37', True, 13.37),  # _YESNO_, score=_SCORE_
            (' No, score=-2.826', False, -2.826),  # _YESNO_, score=_SCORE_
            # with test names, bug #24
            ("No, score=1.9 required=8.0 tests=BAYES_00,FROM_EQ_TO,TVD_SPACE_RATIO,TVD_SPACE_RATIO_MINFP autolearn=no autolearn_force=no version=3.4.0",
             False, 1.9),
        ]

        for headercontent, expectedspamstatus, expectedscore in headertests:
            msgrep = Message()
            msgrep[headername] = Header(headercontent).encode()
            spamstatus, score = candidate._extract_spamstatus(
                msgrep, headername, suspect)
            self.assertEqual(spamstatus, expectedspamstatus, "spamstatus should be %s from %s" % (
                expectedspamstatus, headercontent))
            self.assertEqual(score, expectedscore, "spamscore should be %s from %s" % (
                expectedscore, headercontent))
コード例 #2
0
ファイル: plugins_sa_test.py プロジェクト: danBLA/fuglu
    def test_extract_spamstatus(self):
        """Test if the spam status header gets extracted correctly"""

        candidate = SAPlugin(self.config)
        suspect = Suspect('*****@*****.**',
                          '*****@*****.**', '/dev/null')
        headername = 'X-Spam-Status'
        headertests = [  # tuple header content, expected spamstatus, expected spam score
            ('YES', True, None),  # _YESNOCAPS_
            ('NO', False, None),  # _YESNOCAPS_
            (' Yes, score=13.37', True, 13.37),  # _YESNO_, score=_SCORE_
            (' No, score=-2.826', False, -2.826),  # _YESNO_, score=_SCORE_
            # with test names, bug #24
            ("No, score=1.9 required=8.0 tests=BAYES_00,FROM_EQ_TO,TVD_SPACE_RATIO,TVD_SPACE_RATIO_MINFP autolearn=no autolearn_force=no version=3.4.0",
             False, 1.9),
        ]

        for headercontent, expectedspamstatus, expectedscore in headertests:
            msgrep = Message()
            msgrep[headername] = Header(headercontent).encode()
            spamstatus, score, report = candidate._extract_spamstatus(
                msgrep, headername, suspect)
            self.assertEqual(
                spamstatus, expectedspamstatus,
                "spamstatus should be %s from %s" %
                (expectedspamstatus, headercontent))
            self.assertEqual(
                score, expectedscore, "spamscore should be %s from %s" %
                (expectedscore, headercontent))
コード例 #3
0
ファイル: plugins_sa_test.py プロジェクト: danBLA/fuglu
 def test_extract_spamstatus_fail(self):
     """Test correct return if extracting spamstatus fails because of missing header"""
     candidate = SAPlugin(self.config)
     suspect = Suspect('*****@*****.**',
                       '*****@*****.**', '/dev/null')
     headername = 'X-Spam-Status'
     msgrep = Message()
     spamstatus, score, report = candidate._extract_spamstatus(
         msgrep, headername, suspect)
コード例 #4
0
    def setUp(self):
        try:
            from configparser import RawConfigParser
        except ImportError:
            from ConfigParser import RawConfigParser
        config = RawConfigParser()
        config.add_section('main')
        config.set('main', 'prependaddedheaders', 'X-Fuglu-')

        config.add_section('SAPlugin')
        config.set('SAPlugin', 'host', '127.0.0.1')
        config.set('SAPlugin', 'port', '783')
        config.set('SAPlugin', 'timeout', '5')
        config.set('SAPlugin', 'retries', '3')
        config.set('SAPlugin', 'peruserconfig', '0')
        config.set('SAPlugin', 'maxsize', '500000')
        config.set('SAPlugin', 'spamheader', 'X-Spam-Status')
        config.set('SAPlugin', 'lowspamaction', 'DUNNO')
        config.set('SAPlugin', 'highspamaction', 'REJECT')
        config.set('SAPlugin', 'problemaction', 'DEFER')
        config.set('SAPlugin', 'highspamlevel', '15')
        config.set('SAPlugin', 'forwardoriginal', 'False')
        config.set('SAPlugin', 'scanoriginal', 'False')
        config.set('SAPlugin', 'rejectmessage', '')
        config.set('SAPlugin', 'strip_oversize', '0')

        # sql blacklist
        testfile = "/tmp/sa_test.db"
        if os.path.exists(testfile):
            os.remove(testfile)
        # important: 4 slashes for absolute paths!
        self.testdb = "sqlite:///%s" % testfile

        sql = """SELECT value FROM userpref WHERE preference='blacklist_from' AND username in ('@GLOBAL','%' || ${to_domain},${to_address})"""

        config.set('SAPlugin', 'sql_blacklist_dbconnectstring', self.testdb)
        config.set('SAPlugin', 'sql_blacklist_sql', sql)
        config.set('SAPlugin', 'check_sql_blacklist', 'False')

        self.candidate = SAPlugin(config)
コード例 #5
0
ファイル: plugins_sa_test.py プロジェクト: gryphius/fuglu
    def setUp(self):
        try:
            from configparser import RawConfigParser
        except ImportError:
            from ConfigParser import RawConfigParser
        config = RawConfigParser()
        config.add_section('main')
        config.set('main', 'prependaddedheaders', 'X-Fuglu-')

        config.add_section('SAPlugin')
        config.set('SAPlugin', 'host', '127.0.0.1')
        config.set('SAPlugin', 'port', '783')
        config.set('SAPlugin', 'timeout', '5')
        config.set('SAPlugin', 'retries', '3')
        config.set('SAPlugin', 'peruserconfig', '0')
        config.set('SAPlugin', 'maxsize', '500000')
        config.set('SAPlugin', 'spamheader', 'X-Spam-Status')
        config.set('SAPlugin', 'lowspamaction', 'DUNNO')
        config.set('SAPlugin', 'highspamaction', 'REJECT')
        config.set('SAPlugin', 'problemaction', 'DEFER')
        config.set('SAPlugin', 'highspamlevel', '15')
        config.set('SAPlugin', 'forwardoriginal', 'False')
        config.set('SAPlugin', 'scanoriginal', 'False')
        config.set('SAPlugin', 'rejectmessage', '')

        # sql blacklist
        testfile = "/tmp/sa_test.db"
        if os.path.exists(testfile):
            os.remove(testfile)
        # important: 4 slashes for absolute paths!
        self.testdb = "sqlite:///%s" % testfile

        sql = """SELECT value FROM userpref WHERE preference='blacklist_from' AND username in ('@GLOBAL','%' || ${to_domain},${to_address})"""

        config.set('SAPlugin', 'sql_blacklist_dbconnectstring', self.testdb)
        config.set('SAPlugin', 'sql_blacklist_sql', sql)
        config.set('SAPlugin', 'check_sql_blacklist', 'False')

        self.candidate = SAPlugin(config)
コード例 #6
0
    def setUp(self):
        from ConfigParser import RawConfigParser

        config = RawConfigParser()
        config.add_section("main")
        config.set("main", "prependaddedheaders", "X-Fuglu-")

        config.add_section("SAPlugin")
        config.set("SAPlugin", "host", "127.0.0.1")
        config.set("SAPlugin", "port", "783")
        config.set("SAPlugin", "timeout", "5")
        config.set("SAPlugin", "retries", "3")
        config.set("SAPlugin", "peruserconfig", "0")
        config.set("SAPlugin", "maxsize", "500000")
        config.set("SAPlugin", "spamheader", "X-Spam-Status")
        config.set("SAPlugin", "lowspamaction", "DUNNO")
        config.set("SAPlugin", "highspamaction", "REJECT")
        config.set("SAPlugin", "problemaction", "DEFER")
        config.set("SAPlugin", "highspamlevel", "15")
        config.set("SAPlugin", "forwardoriginal", "False")
        config.set("SAPlugin", "scanoriginal", "False")
        config.set("SAPlugin", "rejectmessage", "")

        # sql blacklist
        testfile = "/tmp/sa_test.db"
        if os.path.exists(testfile):
            os.remove(testfile)
        # important: 4 slashes for absolute paths!
        self.testdb = "sqlite:///%s" % testfile

        sql = """SELECT value FROM userpref WHERE preference='blacklist_from' AND username in ('@GLOBAL','%' || ${to_domain},${to_address})"""

        config.set("SAPlugin", "sql_blacklist_dbconnectstring", self.testdb)
        config.set("SAPlugin", "sql_blacklist_sql", sql)
        config.set("SAPlugin", "check_sql_blacklist", "False")

        self.candidate = SAPlugin(config)
コード例 #7
0
ファイル: plugins_sa_test.py プロジェクト: danBLA/fuglu
    def setUp(self):
        """Tests a message that is stripped and forwared in a modified way"""

        config = RawConfigParser()
        config.add_section('main')
        config.set('main', 'prependaddedheaders', 'X-Fuglu-')

        config.add_section('SAPlugin')
        config.set('SAPlugin', 'host', '127.0.0.1')
        config.set('SAPlugin', 'port', '783')
        config.set('SAPlugin', 'timeout', '5')
        config.set('SAPlugin', 'retries', '3')
        config.set('SAPlugin', 'peruserconfig', '0')
        config.set('SAPlugin', 'maxsize', '50')
        config.set('SAPlugin', 'spamheader', 'X-Spam-Status')
        config.set('SAPlugin', 'lowspamaction', 'DUNNO')
        config.set('SAPlugin', 'highspamaction', 'REJECT')
        config.set('SAPlugin', 'problemaction', 'DEFER')
        config.set('SAPlugin', 'highspamlevel', '15')
        config.set('SAPlugin', 'forwardoriginal', 'False')
        config.set('SAPlugin', 'scanoriginal', 'False')
        config.set('SAPlugin', 'rejectmessage', '')
        config.set('SAPlugin', 'strip_oversize', '1')
        config.set('SAPlugin', 'spamheader_prepend', 'X-Spam-')

        saplug = SAPlugin(config)
        saplug.safilter = MagicMock()
        saplug.safilter.return_value = b'Received: from localhost by unknown\n' \
                                       b'\twith SpamAssassin (version 3.4.2);\n' \
                                       b'\tWed, 28 Nov 2018 08:43:56 +0100\n' \
                                       b'X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on unknown\n' \
                                       b'X-Spam-Flag: YES\n' \
                                       b'X-Spam-Level: *********\n' \
                                       b'X-Spam-Status: Yes, score=9.8 required=5.0 tests=EMPTY_MESSAGE,\n' \
                                       b'\tMIME_HEADER_CTYPE_ONLY,MISSING_DATE,MISSING_FROM,MISSING_HEADERS,\n' \
                                       b'\tMISSING_MID,MISSING_SUBJECT,NO_HEADERS_MESSAGE,NO_RECEIVED,NO_RELAYS\n' \
                                       b'\tautolearn=no autolearn_force=no version=3.4.2\n' \
                                       b'MIME-Version: 1.0\n' \
                                       b'Content-Type: multipart/mixed; boundary="----------=_5BFE473C.76E9108C"\n' \
                                       b'\n' \
                                       b'This is a multi-part message in MIME format.\n' \
                                       b'\n' \
                                       b'------------=_5BFE473C.76E9108C\n' \
                                       b'Content-Type: text/plain; charset=iso-8859-1\n' \
                                       b'Content-Disposition: inline\n' \
                                       b'Content-Transfer-Encoding: 8bit\n' \
                                       b'\n' \
                                       b'Spam detection software, running on the system "unknown",\n' \
                                       b'has identified this incoming email as possible spam.  The original\n' \
                                       b'message has been attached to this so you can view it or label\n' \
                                       b'similar future email.  If you have any questions, see\n' \
                                       b'@@CONTACT_ADDRESS@@ for details.\n' \
                                       b'\n' \
                                       b'Content preview:  \n' \
                                       b'\n' \
                                       b'Content analysis details:   (9.8 points, 5.0 required)\n' \
                                       b'\n' \
                                       b' pts rule name              description\n' \
                                       b'---- ---------------------- --------------------------------------------------\n' \
                                       b'-0.0 NO_RELAYS              Informational: message was not relayed via SMTP\n' \
                                       b' 1.2 MISSING_HEADERS        Missing To: header\n' \
                                       b' 1.4 MISSING_DATE           Missing Date: header\n' \
                                       b' 2.0 MIME_HEADER_CTYPE_ONLY \'Content-Type\' found without required\n' \
                                       b'                            MIME headers\n' \
                                       b' 1.8 MISSING_SUBJECT        Missing Subject: header\n' \
                                       b' 1.0 MISSING_FROM           Missing From: header\n' \
                                       b' 0.1 MISSING_MID            Missing Message-Id: header\n' \
                                       b' 2.3 EMPTY_MESSAGE          Message appears to have no textual parts and no\n' \
                                       b'                            Subject: text\n' \
                                       b'-0.0 NO_RECEIVED            Informational: message has no Received headers\n' \
                                       b' 0.0 NO_HEADERS_MESSAGE     Message appears to be missing most RFC-822\n' \
                                       b'                            headers\n' \
                                       b'\n' \
                                       b'The original message was not completely plain text, and may be unsafe to\n' \
                                       b'open with some email clients; in particular, it may contain a virus,\n' \
                                       b'or confirm that your address can receive spam.  If you wish to view\n' \
                                       b'it, it may be safer to save it to a file and open it with an editor.\n' \
                                       b'\n' \
                                       b'\n' \
                                       b'------------=_5BFE473C.76E9108C\n' \
                                       b'Content-Type: message/rfc822; x-spam-type=original\n' \
                                       b'Content-Description: original message before SpamAssassin\n' \
                                       b'Content-Disposition: attachment\n' \
                                       b'Content-Transfer-Encoding: 8bit\n' \
                                       b'\n' \
                                       b'Content-Type: multipart/mixed; boundary="========' \
                                       b'\n------------=_5BFE473C.76E9108C--\n' \
                                       b'\n'
        self.saplugin = saplug
コード例 #8
0
class SAPluginTestCase(unittest.TestCase):
    """Testcases for the Stub Plugin"""
    def setUp(self):
        from ConfigParser import RawConfigParser
        config = RawConfigParser()
        config.add_section('main')
        config.set('main', 'prependaddedheaders', 'X-Fuglu-')

        config.add_section('SAPlugin')
        config.set('SAPlugin', 'host', '127.0.0.1')
        config.set('SAPlugin', 'port', '783')
        config.set('SAPlugin', 'timeout', '5')
        config.set('SAPlugin', 'retries', '3')
        config.set('SAPlugin', 'peruserconfig', '0')
        config.set('SAPlugin', 'maxsize', '500000')
        config.set('SAPlugin', 'spamheader', 'X-Spam-Status')
        config.set('SAPlugin', 'lowspamaction', 'DUNNO')
        config.set('SAPlugin', 'highspamaction', 'REJECT')
        config.set('SAPlugin', 'problemaction', 'DEFER')
        config.set('SAPlugin', 'highspamlevel', '15')
        config.set('SAPlugin', 'forwardoriginal', 'False')
        config.set('SAPlugin', 'scanoriginal', 'False')
        config.set('SAPlugin', 'rejectmessage', '')

        # sql blacklist
        testfile = "/tmp/sa_test.db"
        if os.path.exists(testfile):
            os.remove(testfile)
        # important: 4 slashes for absolute paths!
        self.testdb = "sqlite:///%s" % testfile

        sql = """SELECT value FROM userpref WHERE preference='blacklist_from' AND username in ('@GLOBAL','%' || ${to_domain},${to_address})"""

        config.set('SAPlugin', 'sql_blacklist_dbconnectstring', self.testdb)
        config.set('SAPlugin', 'sql_blacklist_sql', sql)
        config.set('SAPlugin', 'check_sql_blacklist', 'False')

        self.candidate = SAPlugin(config)

    def test_score(self):
        suspect = Suspect('*****@*****.**',
                          '*****@*****.**', '/dev/null')
        stream = """Date: Mon, 08 Sep 2008 17:33:54 +0200
To: [email protected]
From: [email protected]
Subject: test scanner

  XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
"""
        suspect.set_source(stream)
        result = self.candidate.examine(suspect)
        if type(result) is tuple:
            result, message = result
        score = int(suspect.get_tag('SAPlugin.spamscore'))
        self.failUnless(score > 999,
                        "GTUBE mails should score ~1000 , we got %s" % score)
        self.failUnless(result == REJECT, 'High spam should be rejected')

    def test_symbols(self):
        stream = """Date: Mon, 08 Sep 2008 17:33:54 +0200
To: [email protected]
From: [email protected]
Subject: test scanner

  XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
"""
        spamstatus, spamscore, rules = self.candidate.safilter_symbols(
            stream, '*****@*****.**')
        self.failUnless('GTUBE' in rules, "GTUBE not found in SYMBOL scan")
        self.failIf(spamscore < 500)
        self.failUnless(spamstatus)

        stream2 = """Received: from mail.python.org (mail.python.org [82.94.164.166])
    by bla.fuglu.org (Postfix) with ESMTPS id 395743E03A5
    for <*****@*****.**>; Sun, 22 Aug 2010 18:15:11 +0200 (CEST)
Date: Tue, 24 Aug 2010 09:20:57 +0200
To: [email protected]
From: [email protected]
Subject: test Tue, 24 Aug 2010 09:20:57 +0200
X-Mailer: swaks v20061116.0 jetmore.org/john/code/#swaks
Message-Id: <*****@*****.**>

This is a test mailing """

        spamstatus, spamscore, rules = self.candidate.safilter_symbols(
            stream2, '*****@*****.**')
        # print rules
        self.failIf(spamstatus, "This message should not be detected as spam")

    def test_sql_blacklist(self):
        self.candidate.config.set('SAPlugin', 'check_sql_blacklist', 'True')
        suspect = Suspect('*****@*****.**',
                          '*****@*****.**', '/dev/null')

        import fuglu.extensions.sql
        if not fuglu.extensions.sql.ENABLED:
            print "Excluding test that needs sqlalchemy extension"
            return

        session = fuglu.extensions.sql.get_session(self.testdb)

        createsql = """CREATE TABLE userpref (
  username varchar(100) NOT NULL DEFAULT '',
  preference varchar(30) NOT NULL DEFAULT '',
  value varchar(100) NOT NULL DEFAULT ''
)"""

        session.execute(createsql)
        self.assertEquals(self.candidate.check_sql_blacklist(suspect),
                          DUNNO), 'sender is not blacklisted'

        insertsql = """INSERT INTO userpref (username,preference,value) VALUES ('%unittests.fuglu.org','blacklist_from','*@unittests.fuglu.org')"""
        session.execute(insertsql)

        self.assertEquals(self.candidate.check_sql_blacklist(suspect),
                          REJECT), 'sender should be blacklisted'

        fuglu.extensions.sql.ENABLED = False
        self.assertEquals(self.candidate.check_sql_blacklist(suspect),
                          DUNNO), 'problem if sqlalchemy is not available'
        fuglu.extensions.sql.ENABLED = True

        self.candidate.config.set('SAPlugin', 'sql_blacklist_sql',
                                  'this is a buggy sql statement')
        self.assertEquals(self.candidate.check_sql_blacklist(suspect),
                          DUNNO), 'error coping with db problems'

        # simulate unavailable db
        self.candidate.config.set('SAPlugin', 'sql_blacklist_dbconnectstring',
                                  'mysql://127.0.0.1:9977/idonotexist')
        self.assertEquals(self.candidate.check_sql_blacklist(suspect),
                          DUNNO), 'error coping with db problems'
コード例 #9
0
class SAPluginTestCase(unittest.TestCase):

    """Testcases for the Stub Plugin"""

    def setUp(self):
        from ConfigParser import RawConfigParser

        config = RawConfigParser()
        config.add_section("main")
        config.set("main", "prependaddedheaders", "X-Fuglu-")

        config.add_section("SAPlugin")
        config.set("SAPlugin", "host", "127.0.0.1")
        config.set("SAPlugin", "port", "783")
        config.set("SAPlugin", "timeout", "5")
        config.set("SAPlugin", "retries", "3")
        config.set("SAPlugin", "peruserconfig", "0")
        config.set("SAPlugin", "maxsize", "500000")
        config.set("SAPlugin", "spamheader", "X-Spam-Status")
        config.set("SAPlugin", "lowspamaction", "DUNNO")
        config.set("SAPlugin", "highspamaction", "REJECT")
        config.set("SAPlugin", "problemaction", "DEFER")
        config.set("SAPlugin", "highspamlevel", "15")
        config.set("SAPlugin", "forwardoriginal", "False")
        config.set("SAPlugin", "scanoriginal", "False")
        config.set("SAPlugin", "rejectmessage", "")

        # sql blacklist
        testfile = "/tmp/sa_test.db"
        if os.path.exists(testfile):
            os.remove(testfile)
        # important: 4 slashes for absolute paths!
        self.testdb = "sqlite:///%s" % testfile

        sql = """SELECT value FROM userpref WHERE preference='blacklist_from' AND username in ('@GLOBAL','%' || ${to_domain},${to_address})"""

        config.set("SAPlugin", "sql_blacklist_dbconnectstring", self.testdb)
        config.set("SAPlugin", "sql_blacklist_sql", sql)
        config.set("SAPlugin", "check_sql_blacklist", "False")

        self.candidate = SAPlugin(config)

    def test_score(self):
        suspect = Suspect("*****@*****.**", "*****@*****.**", "/dev/null")
        stream = """Date: Mon, 08 Sep 2008 17:33:54 +0200
To: [email protected]
From: [email protected]
Subject: test scanner

  XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
"""
        suspect.set_source(stream)
        result = self.candidate.examine(suspect)
        if type(result) is tuple:
            result, message = result
        score = int(suspect.get_tag("SAPlugin.spamscore"))
        self.failUnless(score > 999, "GTUBE mails should score ~1000 , we got %s" % score)
        self.failUnless(result == REJECT, "High spam should be rejected")

    def test_symbols(self):
        stream = """Date: Mon, 08 Sep 2008 17:33:54 +0200
To: [email protected]
From: [email protected]
Subject: test scanner

  XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
"""
        spamstatus, spamscore, rules = self.candidate.safilter_symbols(stream, "*****@*****.**")
        self.failUnless("GTUBE" in rules, "GTUBE not found in SYMBOL scan")
        self.failIf(spamscore < 500)
        self.failUnless(spamstatus)

        stream2 = """Received: from mail.python.org (mail.python.org [82.94.164.166])
    by bla.fuglu.org (Postfix) with ESMTPS id 395743E03A5
    for <*****@*****.**>; Sun, 22 Aug 2010 18:15:11 +0200 (CEST)
Date: Tue, 24 Aug 2010 09:20:57 +0200
To: [email protected]
From: [email protected]
Subject: test Tue, 24 Aug 2010 09:20:57 +0200
X-Mailer: swaks v20061116.0 jetmore.org/john/code/#swaks
Message-Id: <*****@*****.**>

This is a test mailing """

        spamstatus, spamscore, rules = self.candidate.safilter_symbols(stream2, "*****@*****.**")
        # print rules
        self.failIf(spamstatus, "This message should not be detected as spam")

    def test_sql_blacklist(self):
        self.candidate.config.set("SAPlugin", "check_sql_blacklist", "True")
        suspect = Suspect("*****@*****.**", "*****@*****.**", "/dev/null")

        import fuglu.extensions.sql

        if not fuglu.extensions.sql.ENABLED:
            print "Excluding test that needs sqlalchemy extension"
            return

        session = fuglu.extensions.sql.get_session(self.testdb)

        createsql = """CREATE TABLE userpref (
  username varchar(100) NOT NULL DEFAULT '',
  preference varchar(30) NOT NULL DEFAULT '',
  value varchar(100) NOT NULL DEFAULT ''
)"""

        session.execute(createsql)
        self.assertEquals(self.candidate.check_sql_blacklist(suspect), DUNNO), "sender is not blacklisted"

        insertsql = """INSERT INTO userpref (username,preference,value) VALUES ('%unittests.fuglu.org','blacklist_from','*@unittests.fuglu.org')"""
        session.execute(insertsql)

        self.assertEquals(self.candidate.check_sql_blacklist(suspect), REJECT), "sender should be blacklisted"

        fuglu.extensions.sql.ENABLED = False
        self.assertEquals(self.candidate.check_sql_blacklist(suspect), DUNNO), "problem if sqlalchemy is not available"
        fuglu.extensions.sql.ENABLED = True

        self.candidate.config.set("SAPlugin", "sql_blacklist_sql", "this is a buggy sql statement")
        self.assertEquals(self.candidate.check_sql_blacklist(suspect), DUNNO), "error coping with db problems"

        # simulate unavailable db
        self.candidate.config.set("SAPlugin", "sql_blacklist_dbconnectstring", "mysql://127.0.0.1:9977/idonotexist")
        self.assertEquals(self.candidate.check_sql_blacklist(suspect), DUNNO), "error coping with db problems"