~ubuntu-branches/ubuntu/saucy/fail2ban/saucy

« back to all changes in this revision

Viewing changes to testcases/misctestcase.py

  • Committer: Package Import Robot
  • Author(s): Yaroslav Halchenko
  • Date: 2013-05-13 11:58:56 UTC
  • mfrom: (1.1.15) (10.2.13 sid)
  • Revision ID: package-import@ubuntu.com-20130513115856-x7six9p53qcie0vl
Tags: 0.8.9-1
* New upstream release
  - significant improvements in documentation (Closes: #400416)
  - roundcube auth filter (Closes: #699442)
  - enforces C locale for dates (Closes: #686341)
  - provides bash_completion.d/fail2ban
* debian/jail.conf:
  - added findtime and documentation on those basic options from jail.conf
    (Closes: #704568)
  - added new sample jails definitions for ssh-route, ssh-iptables-ipset{4,6},
    roundcube-auth, sogo-auth, mysqld-auth
* debian/control:
  - suggest system-log-daemon (Closes: #691001)
  - boost policy compliance to 3.9.4
* debian/rules:
  - run fail2ban's unittests at build time but ignore the failures
    (there are still some known issues to fix up to guarantee robust testing
    in clean chroots etc).
    Only pyinotify was added to build-depends since gamin might still be
    buggy on older releases and get stuck, which would complicate
    backporting

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
 
2
# vi: set ft=python sts=4 ts=4 sw=4 noet :
 
3
 
 
4
# This file is part of Fail2Ban.
 
5
#
 
6
# Fail2Ban is free software; you can redistribute it and/or modify
 
7
# it under the terms of the GNU General Public License as published by
 
8
# the Free Software Foundation; either version 2 of the License, or
 
9
# (at your option) any later version.
 
10
#
 
11
# Fail2Ban is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU General Public License for more details.
 
15
#
 
16
# You should have received a copy of the GNU General Public License
 
17
# along with Fail2Ban; if not, write to the Free Software
 
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
19
 
 
20
__author__ = "Yaroslav Halchenko"
 
21
__copyright__ = "Copyright (c) 2013 Yaroslav Halchenko"
 
22
__license__ = "GPL"
 
23
 
 
24
import logging
 
25
import os, sys, unittest
 
26
import tempfile
 
27
import shutil
 
28
 
 
29
from glob import glob
 
30
 
 
31
from utils import mbasename, TraceBack, FormatterWithTraceBack
 
32
from common.helpers import formatExceptionInfo
 
33
 
 
34
class HelpersTest(unittest.TestCase):
 
35
 
 
36
        def testFormatExceptionInfoBasic(self):
 
37
                try:
 
38
                        raise ValueError("Very bad exception")
 
39
                except:
 
40
                        name, args = formatExceptionInfo()
 
41
                        self.assertEqual(name, "ValueError")
 
42
                        self.assertEqual(args, "Very bad exception")
 
43
 
 
44
        def testFormatExceptionConvertArgs(self):
 
45
                try:
 
46
                        raise ValueError("Very bad", None)
 
47
                except:
 
48
                        name, args = formatExceptionInfo()
 
49
                        self.assertEqual(name, "ValueError")
 
50
                        # might be fragile due to ' vs "
 
51
                        self.assertEqual(args, "('Very bad', None)")
 
52
 
 
53
# based on
 
54
# http://stackoverflow.com/questions/2186525/use-a-glob-to-find-files-recursively-in-python
 
55
def recursive_glob(treeroot, pattern):
 
56
        import fnmatch, os
 
57
        results = []
 
58
        for base, dirs, files in os.walk(treeroot):
 
59
                goodfiles = fnmatch.filter(dirs + files, pattern)
 
60
                results.extend(os.path.join(base, f) for f in goodfiles)
 
61
        return results
 
62
 
 
63
class SetupTest(unittest.TestCase):
 
64
 
 
65
        def setUp(self):
 
66
                setup = os.path.join(os.path.dirname(__file__), '..', 'setup.py')
 
67
                self.setup = os.path.exists(setup) and setup or None
 
68
                if not self.setup and sys.version_info >= (2,7): # running not out of the source
 
69
                        raise unittest.SkipTest(
 
70
                                "Seems to be running not out of source distribution"
 
71
                                " -- cannot locate setup.py")
 
72
 
 
73
        def testSetupInstallRoot(self):
 
74
                if not self.setup: return                         # if verbose skip didn't work out
 
75
                tmp = tempfile.mkdtemp()
 
76
                os.system("%s %s install --root=%s >/dev/null"
 
77
                                  % (sys.executable, self.setup, tmp))
 
78
 
 
79
                def addpath(l):
 
80
                        return [os.path.join(tmp, x) for x in l]
 
81
 
 
82
                def strippath(l):
 
83
                        return [x[len(tmp)+1:] for x in l]
 
84
 
 
85
                got = strippath(sorted(glob('%s/*' % tmp)))
 
86
                need = ['etc', 'usr', 'var']
 
87
 
 
88
                # if anything is missing
 
89
                if set(need).difference(got):
 
90
                        #  below code was actually to print out not missing but
 
91
                        #  rather files in 'excess'.  Left in place in case we
 
92
                        #  decide to revert to such more strict test
 
93
                        files = {}
 
94
                        for missing in set(got).difference(need):
 
95
                                missing_full = os.path.join(tmp, missing)
 
96
                                files[missing] = os.path.exists(missing_full) \
 
97
                                        and strippath(recursive_glob(missing_full, '*')) or None
 
98
 
 
99
                        self.assertEqual(
 
100
                                got, need,
 
101
                                msg="Got: %s Needed: %s under %s. Files under new paths: %s"
 
102
                                % (got, need, tmp, files))
 
103
 
 
104
                # Assure presence of some files we expect to see in the installation
 
105
                for f in ('etc/fail2ban/fail2ban.conf',
 
106
                                  'etc/fail2ban/jail.conf'):
 
107
                        self.assertTrue(os.path.exists(os.path.join(tmp, f)),
 
108
                                                        msg="Can't find %s" % f)
 
109
 
 
110
                # clean up
 
111
                shutil.rmtree(tmp)
 
112
 
 
113
class TestsUtilsTest(unittest.TestCase):
 
114
 
 
115
        def testmbasename(self):
 
116
                self.assertEqual(mbasename("sample.py"), 'sample')
 
117
                self.assertEqual(mbasename("/long/path/sample.py"), 'sample')
 
118
                # this one would include only the directory for the __init__ and base files
 
119
                self.assertEqual(mbasename("/long/path/__init__.py"), 'path.__init__')
 
120
                self.assertEqual(mbasename("/long/path/base.py"), 'path.base')
 
121
                self.assertEqual(mbasename("/long/path/base"), 'path.base')
 
122
 
 
123
        def testTraceBack(self):
 
124
                # pretty much just a smoke test since tests runners swallow all the detail
 
125
 
 
126
                for compress in True, False:
 
127
                        tb = TraceBack(compress=compress)
 
128
 
 
129
                        def func_raise():
 
130
                                raise ValueError()
 
131
 
 
132
                        def deep_function(i):
 
133
                                if i: deep_function(i-1)
 
134
                                else: func_raise()
 
135
 
 
136
                        try:
 
137
                                print deep_function(3)
 
138
                        except ValueError:
 
139
                                s = tb()
 
140
 
 
141
                        # if we run it through 'coverage' (e.g. on travis) then we
 
142
                        # would get a traceback
 
143
                        if 'coverage' in s:
 
144
                                self.assertTrue('>' in s, msg="no '>' in %r" % s)
 
145
                        else:
 
146
                                self.assertFalse('>' in s, msg="'>' present in %r" % s)  # There is only "fail2ban-testcases" in this case, no true traceback
 
147
                        self.assertTrue(':' in s, msg="no ':' in %r" % s)
 
148
 
 
149
 
 
150
        def testFormatterWithTraceBack(self):
 
151
                from StringIO import StringIO
 
152
                strout = StringIO()
 
153
                Formatter = FormatterWithTraceBack
 
154
 
 
155
                # and both types of traceback at once
 
156
                fmt = ' %(tb)s | %(tbc)s : %(message)s'
 
157
                logSys = logging.getLogger("fail2ban_tests")
 
158
                out = logging.StreamHandler(strout)
 
159
                out.setFormatter(Formatter(fmt))
 
160
                logSys.addHandler(out)
 
161
                logSys.error("XXX")
 
162
 
 
163
                s = strout.getvalue()
 
164
                self.assertTrue(s.rstrip().endswith(': XXX'))
 
165
                pindex = s.index('|')
 
166
 
 
167
                # in this case compressed and not should be the same (?)
 
168
                self.assertTrue(pindex > 10)      # we should have some traceback
 
169
                self.assertEqual(s[:pindex], s[pindex+1:pindex*2 + 1])