Test coverage of manager now at 100%
- A few bugs were discovered and fixed - A few tweeks were added Change-Id: Ib3e8850e97726d8c23a33496e2a9609b40160055
This commit is contained in:
@@ -27,10 +27,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BanditConfig():
|
||||
|
||||
_config = dict()
|
||||
_settings = dict()
|
||||
|
||||
def __init__(self, config_file):
|
||||
'''Attempt to initialize a config dictionary from a yaml file.
|
||||
|
||||
@@ -99,6 +95,7 @@ class BanditConfig():
|
||||
possible).
|
||||
:return: -
|
||||
'''
|
||||
self._settings = {}
|
||||
self._init_progress_increment()
|
||||
self._init_output_colors()
|
||||
self._init_plugin_name_pattern()
|
||||
|
||||
@@ -19,7 +19,7 @@ import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from bandit.core import constants as constants
|
||||
from bandit.core import constants as b_constants
|
||||
from bandit.core import extension_loader
|
||||
from bandit.core import meta_ast as b_meta_ast
|
||||
from bandit.core import node_visitor as b_node_visitor
|
||||
@@ -64,9 +64,9 @@ class BanditManager():
|
||||
profile_name, profile
|
||||
)
|
||||
else:
|
||||
logger.error('unable to find profile (%s) in config file: %s',
|
||||
profile_name, self.b_conf.config_file)
|
||||
sys.exit(2)
|
||||
raise RuntimeError('unable to find profile (%s) in config'
|
||||
'file: %s' % (profile_name,
|
||||
self.b_conf.config_file))
|
||||
else:
|
||||
profile = None
|
||||
|
||||
@@ -84,22 +84,15 @@ class BanditManager():
|
||||
def has_tests(self):
|
||||
return self.b_ts.has_tests
|
||||
|
||||
def results_count(self, sev_filter=0, conf_filter=0):
|
||||
def results_count(self, sev_filter=b_constants.LOW,
|
||||
conf_filter=b_constants.LOW):
|
||||
'''Return the count of results
|
||||
|
||||
:param sev_filter: Severity level to filter lower
|
||||
:param conf_filter: Confidence level to filter
|
||||
:return: Number of results in the set
|
||||
'''
|
||||
count = 0
|
||||
|
||||
rank = constants.RANKING
|
||||
|
||||
for issue in self.results:
|
||||
if issue.filter(rank[sev_filter], rank[conf_filter]):
|
||||
count += 1
|
||||
|
||||
return count
|
||||
return sum(i.filter(sev_filter, conf_filter) for i in self.results)
|
||||
|
||||
def output_results(self, lines, sev_level, conf_level, output_filename,
|
||||
output_format):
|
||||
@@ -132,12 +125,12 @@ class BanditManager():
|
||||
lines=lines, out_format=output_format)
|
||||
|
||||
except IOError:
|
||||
print("Unable to write to file: %s" % self.out_file)
|
||||
print("Unable to write to file: %s" % output_filename)
|
||||
|
||||
def discover_files(self, targets, recursive=False):
|
||||
'''Add tests directly and from a directory to the test set
|
||||
|
||||
:param scope: The command line list of files and directories
|
||||
:param targets: The command line list of files and directories
|
||||
:param recursive: True/False - whether to add all files from dirs
|
||||
:return:
|
||||
'''
|
||||
@@ -258,7 +251,7 @@ class BanditManager():
|
||||
return score
|
||||
|
||||
|
||||
def _get_files_from_dir(files_dir, included_globs='*.py',
|
||||
def _get_files_from_dir(files_dir, included_globs=['*.py'],
|
||||
excluded_path_strings=None):
|
||||
if not excluded_path_strings:
|
||||
excluded_path_strings = []
|
||||
|
||||
272
tests/unit/core/test_manager.py
Normal file
272
tests/unit/core/test_manager.py
Normal file
@@ -0,0 +1,272 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
#
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import fixtures
|
||||
import mock
|
||||
import six
|
||||
import os
|
||||
import tempfile
|
||||
import testtools
|
||||
|
||||
from bandit.core import manager
|
||||
from bandit.core import config
|
||||
from bandit.core import issue
|
||||
from bandit.core import constants
|
||||
from bandit.core import extension_loader
|
||||
|
||||
from sys import version_info
|
||||
if version_info.major == 2:
|
||||
import __builtin__ as builtins
|
||||
else:
|
||||
import builtins
|
||||
|
||||
|
||||
class TempFile(fixtures.Fixture):
|
||||
def __init__(self, contents=None):
|
||||
super(TempFile, self).__init__()
|
||||
self.contents = contents
|
||||
|
||||
def setUp(self):
|
||||
super(TempFile, self).setUp()
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='wt', delete=False) as f:
|
||||
if self.contents:
|
||||
f.write(self.contents)
|
||||
|
||||
self.addCleanup(os.unlink, f.name)
|
||||
|
||||
self.name = f.name
|
||||
|
||||
|
||||
class ManagerTests(testtools.TestCase):
|
||||
|
||||
def _get_issue_instance(sev=constants.MEDIUM, conf=constants.MEDIUM):
|
||||
new_issue = issue.Issue(sev, conf, 'Test issue')
|
||||
new_issue.fname = 'code.py'
|
||||
new_issue.test = 'bandit_plugin'
|
||||
new_issue.lineno = 1
|
||||
return new_issue
|
||||
|
||||
def setUp(self):
|
||||
super(ManagerTests, self).setUp()
|
||||
contents = """
|
||||
profiles:
|
||||
Test:
|
||||
include:
|
||||
- any_other_function_with_shell_equals_true
|
||||
- assert_used
|
||||
"""
|
||||
f = self.useFixture(TempFile(contents))
|
||||
self.config = config.BanditConfig(f.name)
|
||||
self.manager = manager.BanditManager(config=self.config,
|
||||
agg_type='file',
|
||||
debug=False,
|
||||
verbose=False,
|
||||
profile_name=None)
|
||||
|
||||
def test_create_manager(self):
|
||||
# make sure we can create a manager
|
||||
self.assertEqual(self.manager.debug, False)
|
||||
self.assertEqual(self.manager.verbose, False)
|
||||
self.assertEqual(self.manager.agg_type, 'file')
|
||||
self.assertTrue(self.manager.has_tests)
|
||||
|
||||
def test_create_manager_with_profile(self):
|
||||
# make sure we can create a manager
|
||||
m = manager.BanditManager(config=self.config, agg_type='file',
|
||||
debug=False, verbose=False,
|
||||
profile_name='Test')
|
||||
|
||||
self.assertEqual(m.debug, False)
|
||||
self.assertEqual(m.verbose, False)
|
||||
self.assertEqual(m.agg_type, 'file')
|
||||
self.assertTrue(self.manager.has_tests)
|
||||
|
||||
|
||||
def test_create_manager_with_profile_bad(self):
|
||||
try:
|
||||
m = manager.BanditManager(config=self.config, agg_type='file',
|
||||
debug=False, verbose=False,
|
||||
profile_name='Bad')
|
||||
except RuntimeError as e:
|
||||
err = str(e)
|
||||
|
||||
self.assertTrue(err.startswith(
|
||||
"unable to find profile (Bad) in configfile:"))
|
||||
|
||||
def test_matches_globlist(self):
|
||||
self.assertTrue(manager._matches_glob_list('test', ['*tes*']))
|
||||
self.assertFalse(manager._matches_glob_list('test', ['*fes*']))
|
||||
|
||||
def test_is_file_included(self):
|
||||
a = manager._is_file_included(path='a.py', included_globs=['*.py'],
|
||||
excluded_path_strings='',
|
||||
enforce_glob=True)
|
||||
|
||||
b = manager._is_file_included(path='a.dd', included_globs=['*.py'],
|
||||
excluded_path_strings='',
|
||||
enforce_glob=False)
|
||||
|
||||
c = manager._is_file_included(path='a.py', included_globs=['*.py'],
|
||||
excluded_path_strings='a.py',
|
||||
enforce_glob=True)
|
||||
|
||||
d = manager._is_file_included(path='a.dd', included_globs=['*.py'],
|
||||
excluded_path_strings='',
|
||||
enforce_glob=True)
|
||||
self.assertTrue(a)
|
||||
self.assertTrue(b)
|
||||
self.assertFalse(c)
|
||||
self.assertFalse(d)
|
||||
|
||||
|
||||
@mock.patch('os.walk')
|
||||
def test_get_files_from_dir(self, os_walk):
|
||||
os_walk.return_value = [
|
||||
('/', ('a'), ()),
|
||||
('/a', (), ('a.py', 'b.py', 'c.ww'))
|
||||
]
|
||||
|
||||
inc, exc = manager._get_files_from_dir(files_dir='',
|
||||
included_globs=['*.py'],
|
||||
excluded_path_strings=None)
|
||||
|
||||
self.assertEqual(exc, set(['/a/c.ww']))
|
||||
self.assertEqual(inc, set(['/a/a.py', '/a/b.py']))
|
||||
|
||||
def test_results_count(self):
|
||||
levels = [constants.LOW, constants.MEDIUM, constants.HIGH]
|
||||
self.manager.results = (
|
||||
[issue.Issue(severity=l, confidence=l) for l in levels])
|
||||
|
||||
r = [self.manager.results_count(sev_filter=l, conf_filter=l) \
|
||||
for l in levels]
|
||||
|
||||
self.assertEqual([3,2,1], r)
|
||||
|
||||
@mock.patch('os.path.isfile')
|
||||
def test_check_output_destination_exists(self, isfile):
|
||||
isfile.return_value = True
|
||||
a = self.manager.check_output_destination('derp')
|
||||
self.assertEqual(a, 'File already exists')
|
||||
|
||||
@mock.patch('os.path.isfile')
|
||||
@mock.patch('os.path.isdir')
|
||||
def test_check_output_destination_dir(self, isdir, isfile):
|
||||
isfile.return_value = False
|
||||
isdir.return_value = True
|
||||
a = self.manager.check_output_destination('derp')
|
||||
self.assertEqual(a, 'Specified destination is a directory')
|
||||
|
||||
@mock.patch('os.path.isfile')
|
||||
@mock.patch('os.path.isdir')
|
||||
def test_check_output_destination_bad(self, isfile, isdir):
|
||||
with mock.patch.object(builtins, 'open') as b_open:
|
||||
isfile.return_value = False
|
||||
isdir.return_value = False
|
||||
b_open.side_effect = IOError()
|
||||
a = self.manager.check_output_destination('derp')
|
||||
self.assertEqual(a, 'Specified destination is not writable')
|
||||
|
||||
@mock.patch('os.path.isfile')
|
||||
@mock.patch('os.path.isdir')
|
||||
def test_check_output_destination_bad(self, isfile, isdir):
|
||||
with mock.patch.object(builtins, 'open'):
|
||||
isfile.return_value = False
|
||||
isdir.return_value = False
|
||||
a = self.manager.check_output_destination('derp')
|
||||
self.assertEqual(a, True)
|
||||
|
||||
@mock.patch('os.path.isdir')
|
||||
def test_discover_files_recurse_skip(self, isdir):
|
||||
isdir.return_value = True
|
||||
self.manager.discover_files(['thing'], False)
|
||||
self.assertEqual(self.manager.files_list, [])
|
||||
self.assertEqual(self.manager.excluded_files, [])
|
||||
|
||||
@mock.patch('os.path.isdir')
|
||||
def test_discover_files_recurse_files(self, isdir):
|
||||
isdir.return_value = True
|
||||
with mock.patch.object(manager, '_get_files_from_dir') as m:
|
||||
m.return_value = (set(['files']), set(['excluded']))
|
||||
self.manager.discover_files(['thing'], True)
|
||||
self.assertEqual(self.manager.files_list, ['files'])
|
||||
self.assertEqual(self.manager.excluded_files, ['excluded'])
|
||||
|
||||
@mock.patch('os.path.isdir')
|
||||
def test_discover_files_exclude(self, isdir):
|
||||
isdir.return_value = False
|
||||
with mock.patch.object(manager, '_is_file_included') as m:
|
||||
m.return_value = False
|
||||
self.manager.discover_files(['thing'], True)
|
||||
self.assertEqual(self.manager.files_list, [])
|
||||
self.assertEqual(self.manager.excluded_files, ['thing'])
|
||||
|
||||
@mock.patch('os.path.isdir')
|
||||
def test_discover_files_include(self, isdir):
|
||||
isdir.return_value = False
|
||||
with mock.patch.object(manager, '_is_file_included') as m:
|
||||
m.return_value = True
|
||||
self.manager.discover_files(['thing'], True)
|
||||
self.assertEqual(self.manager.files_list, ['thing'])
|
||||
self.assertEqual(self.manager.excluded_files, [])
|
||||
|
||||
def test_output_results_bad(self):
|
||||
fmt = mock.MagicMock()
|
||||
with mock.patch('bandit.core.extension_loader.MANAGER') as m:
|
||||
m.formatters_mgr = {'test': fmt}
|
||||
self.assertRaises(KeyError, self.manager.output_results,
|
||||
3, constants.LOW, constants.LOW, None, "txt")
|
||||
|
||||
def test_output_results_txt(self):
|
||||
fmt = mock.MagicMock()
|
||||
with mock.patch('bandit.core.extension_loader.MANAGER') as m:
|
||||
m.formatters_mgr = {'txt': fmt}
|
||||
self.manager.output_results(3, constants.LOW, constants.LOW,
|
||||
None, "test")
|
||||
fmt.plugin.assert_called_with(self.manager, conf_level='LOW',
|
||||
filename=None, lines=3,
|
||||
out_format='txt', sev_level='LOW')
|
||||
|
||||
def test_output_results_csv(self):
|
||||
fmt = mock.MagicMock()
|
||||
with mock.patch('bandit.core.extension_loader.MANAGER') as m:
|
||||
m.formatters_mgr = {'csv': fmt}
|
||||
self.manager.output_results(3, constants.LOW, constants.LOW,
|
||||
None, "csv")
|
||||
fmt.plugin.assert_called_with(self.manager, conf_level='LOW',
|
||||
filename=None, lines=1,
|
||||
out_format='csv', sev_level='LOW')
|
||||
|
||||
def test_output_results_txt_plain(self):
|
||||
fmt = mock.MagicMock()
|
||||
fmt.name = 'txt'
|
||||
with mock.patch('bandit.core.extension_loader.MANAGER') as m:
|
||||
m.formatters_mgr = {'txt': fmt}
|
||||
self.manager.output_results(3, constants.LOW, constants.LOW,
|
||||
"dummy", "test")
|
||||
fmt.plugin.assert_called_with(self.manager, conf_level='LOW',
|
||||
filename="dummy", lines=3,
|
||||
out_format='plain', sev_level='LOW')
|
||||
|
||||
def test_output_results_io_error(self):
|
||||
fmt = mock.MagicMock()
|
||||
fmt.name = 'txt'
|
||||
fmt.plugin.side_effect = IOError
|
||||
with mock.patch('bandit.core.extension_loader.MANAGER') as m:
|
||||
m.formatters_mgr = {'txt': fmt}
|
||||
self.manager.output_results(3, constants.LOW, constants.LOW,
|
||||
"dummy", "test")
|
||||
Reference in New Issue
Block a user