def test_invalid_import_role(self): fh = self._get_play_file(PLAY_IMPORT_ROLE_INCOMPLETE) runner = Runner(self.rules, fh.name, [], [], []) with pytest.raises( RuntimeError, match="Failed to find required 'name' key in import_role"): runner.run()
def test_unicode_parseable_colored_formatting(self): filename = 'test/unicode.yml' runner = Runner(self.rules, filename, [], [], []) matches = runner.run() formatter = ansiblelint.formatters.ParseableFormatter( os.getcwd(), True) formatter.format(matches[0], colored=True)
def test_runner_unicode_format(default_rules_collection, formatter_cls, format_kwargs): formatter = formatter_cls(os.getcwd(), True) runner = Runner(default_rules_collection, 'test/unicode.yml', [], [], []) matches = runner.run() formatter.format(matches[0], **format_kwargs)
def test_file(self): success = 'testResources/ansible-smell/invalidIPaddressbinding.yml' good_runner = Runner(self.collection, success, [], [], []) result = good_runner.run() print(result) print(type(result)) print(len(result)) self.assertGreaterEqual(1, len(good_runner.run()))
def test_runner_encrypted_secrets(self): from pkg_resources import parse_version import ansible # Only run this test for ansible 2.3+ # It checks ansible-lint's parsing of yaml files that contain # encrypted secrets. if parse_version(ansible.__version__) >= parse_version('2.3'): filename = 'test/contains_secrets.yml' runner = Runner(self.rules, filename, [], [], []) assert (len(runner.run()) == 0)
def test_post_task_include_playbook(self): filename = 'test/playbook-include/playbook_post.yml' runner = Runner(self.rules, filename, [], [], []) results = runner.run() self.assertEqual(len(runner.playbooks), 2) self.assertEqual(len(results), 3) self.assertIn('Commands should not change things', str(results)) self.assertNotIn('502', str(results)) self.assertNotIn('All tasks should be named', str(results))
def test_files_not_scanned_twice(self): checked_files = set() filename = os.path.abspath('test/common-include-1.yml') runner = Runner(self.rules, filename, [], [], [], 0, checked_files) run1 = runner.run() filename = os.path.abspath('test/common-include-2.yml') runner = Runner(self.rules, filename, [], [], [], 0, checked_files) run2 = runner.run() assert ((len(run1) + len(run2)) == 1)
def test_task_hook_include_playbook(default_rules_collection, stage): playbook_path = ('test/playbook-include/playbook_{stage}.yml'.format_map( locals())) runner = Runner(default_rules_collection, playbook_path, [], [], []) results = runner.run() results_text = str(results) assert len(runner.playbooks) == 2 assert len(results) == 3 assert 'Commands should not change things' in results_text assert '502' not in results_text assert 'All tasks should be named' not in results_text
def test_runner_exclude_var_expansion(monkeypatch): rules = RulesCollection([default_rulesdir]) filename = 'example/lots_of_warnings.yml' monkeypatch.setenv('EXCLUDE_PATH', filename) excludes = ['$EXCLUDE_PATH'] runner = Runner(rules, filename, [], [], excludes) assert filename in runner.exclude_paths
def test_file(self): success = 'testResources/ansible-smell/hardcodepassword.yml' good_runner = Runner(self.collection, success, [], [], []) print(good_runner.run()) print(type(good_runner.run())) print(len(good_runner.run())) self.assertEqual(0, len(good_runner.run()))
def test_file_positive(self): success = 'ansible-lint/test/apt-repository-cache-update-success.yml' good_runner = Runner(self.collection, success, [], [], []) self.assertEqual([], good_runner.run())
def test_runner_count(self): filename = 'test/skiptasks.yml' tags = ['ANSIBLE0004', 'ANSIBLE0005', 'ANSIBLE0006', 'ANSIBLE0007'] runner = Runner(self.rules, filename, tags, [], []) self.assertEqual(len(runner.run()), 6)
def test_import_role_inline_args(self): fh = self._get_play_file(PLAY_IMPORT_ROLE_INLINE) runner = Runner(self.rules, fh.name, [], [], []) results = runner.run() assert 'only when shell functionality is required' in str(results)
def test_runner_excludes_paths(self): filename = 'examples/lots_of_warnings.yml' excludes = ['examples/lots_of_warnings.yml'] runner = Runner(self.rules, filename, [], [], excludes) assert (len(runner.run()) == 0)
def test_file_positive_2_4(self): success = 'test/env-vars-in-command-success_2_4_style.yml' good_runner = Runner(self.collection, success, [], [], []) self.assertEqual([], good_runner.run())
def test_file_negative(self): failure = 'test/use-handler-rather-than-when-changed-failure.yml' bad_runner = Runner(self.collection, failure, [], [], []) errs = bad_runner.run() self.assertEqual(5, len(errs))
def test_file_negative(self): failure = 'test/become-user-without-become-failure.yml' bad_runner = Runner(self.collection, failure, [], [], []) errs = bad_runner.run() self.assertEqual(3, len(errs))
def test_included_tasks(self): filename = 'test/taskincludes.yml' runner = Runner(self.rules, filename, [], [], []) runner.run() self.assertEqual(len(runner.playbooks), 4)
def test_command_changes_positive(self): success = 'test/command-check-success.yml' good_runner = Runner(self.collection, success, [], [], []) self.assertEqual([], good_runner.run())
def test_gitlab_dependency_is_ok(self): filename = 'test/dependency-in-meta/gitlab.yml' good_runner = Runner(self.rules, filename, [], [], []) self.assertEqual([], good_runner.run())
def test_block_included_tasks_with_rescue_and_always(self): filename = 'test/blockincludes2.yml' runner = Runner(self.rules, filename, [], [], []) runner.run() self.assertEqual(len(runner.playbooks), 4)
def test_skip_import_playbook(self): fh = self._get_play_file(MAIN_PLAYBOOK) runner = Runner(self.rules, fh.name, [], [], []) results = runner.run() self.assertEqual(0, len(results))
def test_file_negative(self): failure = 'test/task-has-name-failure.yml' bad_runner = Runner(self.collection, failure, [], [], []) errs = bad_runner.run() self.assertEqual(2, len(errs))
def test_file_positive(self): success = 'test/task-has-name-success.yml' good_runner = Runner(self.collection, success, [], [], []) self.assertEqual([], good_runner.run())
def test_file(self): success = 'testResources/ansible-smell/create.yml' good_runner = Runner(self.collection, success, [], [], []) # print(good_runner.run()) self.assertEqual(1, len(good_runner.run()))
def test_command_changes_negative(self): failure = 'test/command-check-failure.yml' bad_runner = Runner(self.collection, failure, [], [], []) errs = bad_runner.run() self.assertEqual(2, len(errs))
def test_dir_with_fullpath(self): filename = os.path.abspath('test') runner = Runner(self.rules, filename, [], [], []) assert (list(runner.playbooks)[0][1] == 'role')
def test_file_positive(self): success = 'test/env-vars-in-command-success.yml' good_runner = Runner(self.collection, success, [], [], []) self.assertEqual([], good_runner.run())
def test_file_positive(self): success = 'test/become-user-without-become-success.yml' good_runner = Runner(self.collection, success, [], [], []) self.assertEqual([], good_runner.run())
def test_file_negative(self): failure = 'test/env-vars-in-command-failure.yml' bad_runner = Runner(self.collection, failure, [], [], []) errs = bad_runner.run() self.assertEqual(2, len(errs))
def test_runner_become_count(self): filename = 'test/become.yml' runner = Runner(self.rules, filename, [], [], []) assert (len(runner.run()) == 0)
def test_file_positive(self): success = 'test/jinja2-when-success.yml' good_runner = Runner(self.collection, success, [], [], []) self.assertEqual([], good_runner.run())
def main(): formatter = formatters.Formatter() parser = optparse.OptionParser( "%prog [options] [playbook.yml [playbook2 ...]]|roledirectory", version="%prog " + __version__) parser.add_option('-L', dest='listrules', default=False, action='store_true', help="list all the rules") parser.add_option('-q', dest='quiet', default=False, action='store_true', help="quieter, although not silent output") parser.add_option('-p', dest='parseable', default=False, action='store_true', help="parseable output in the format of pep8") parser.add_option('--parseable-severity', dest='parseable_severity', default=False, action='store_true', help="parseable output including severity of rule") parser.add_option('-r', action='append', dest='rulesdir', default=[], type='str', help="specify one or more rules directories using " "one or more -r arguments. Any -r flags override " "the default rules in %s, unless -R is also used." % default_rulesdir) parser.add_option('-R', action='store_true', default=False, dest='use_default_rules', help="Use default rules in %s in addition to any extra " "rules directories specified with -r. There is " "no need to specify this if no -r flags are used" % default_rulesdir) parser.add_option('-t', dest='tags', action='append', default=[], help="only check rules whose id/tags match these values") parser.add_option('-T', dest='listtags', action='store_true', help="list all the tags") parser.add_option('-v', dest='verbosity', action='count', help="Increase verbosity level", default=0) parser.add_option('-x', dest='skip_list', default=[], action='append', help="only check rules whose id/tags do not " + "match these values") parser.add_option('--nocolor', dest='colored', default=hasattr(sys.stdout, 'isatty') and sys.stdout.isatty(), action='store_false', help="disable colored output") parser.add_option( '--force-color', dest='colored', action='store_true', help="Try force colored output (relying on ansible's code)") parser.add_option('--exclude', dest='exclude_paths', action='append', help='path to directories or files to skip. This option' ' is repeatable.', default=[]) parser.add_option( '-c', dest='config_file', help='Specify configuration file to use. Defaults to ".ansible-lint"') options, args = parser.parse_args(sys.argv[1:]) config = load_config(options.config_file) if config: if 'quiet' in config: options.quiet = options.quiet or config['quiet'] if 'parseable' in config: options.parseable = options.parseable or config['parseable'] if 'parseable_severity' in config: options.parseable_severity = options.parseable_severity or \ config['parseable_severity'] if 'use_default_rules' in config: options.use_default_rules = options.use_default_rules or config[ 'use_default_rules'] if 'verbosity' in config: options.verbosity = options.verbosity + config['verbosity'] options.exclude_paths.extend(config.get('exclude_paths', [])) if 'rulesdir' in config: options.rulesdir = options.rulesdir + config['rulesdir'] if 'skip_list' in config: options.skip_list = options.skip_list + config['skip_list'] if 'tags' in config: options.tags = options.tags + config['tags'] if options.quiet: formatter = formatters.QuietFormatter() if options.parseable: formatter = formatters.ParseableFormatter() if options.parseable_severity: formatter = formatters.ParseableSeverityFormatter() # no args triggers auto-detection mode if len(args) == 0 and not (options.listrules or options.listtags): args = get_playbooks_and_roles(options=options) if options.use_default_rules: rulesdirs = options.rulesdir + [default_rulesdir] else: rulesdirs = options.rulesdir or [default_rulesdir] rules = RulesCollection() for rulesdir in rulesdirs: rules.extend(RulesCollection.create_from_directory(rulesdir)) if options.listrules: print(rules) return 0 if options.listtags: print(rules.listtags()) return 0 if isinstance(options.tags, six.string_types): options.tags = options.tags.split(',') skip = set() for s in options.skip_list: skip.update(str(s).split(',')) options.skip_list = frozenset(skip) playbooks = sorted(set(args)) matches = list() checked_files = set() for playbook in playbooks: runner = Runner(rules, playbook, options.tags, options.skip_list, options.exclude_paths, options.verbosity, checked_files) matches.extend(runner.run()) matches.sort(key=lambda x: (normpath(x.filename), x.linenumber, x.rule.id)) for match in matches: print(formatter.format(match, options.colored)) if len(matches): return 2 else: return 0
def test_runner_count(self): filename = 'test/nomatchestest.yml' runner = Runner(self.rules, filename, [], [], []) assert (len(runner.run()) == 0)
def test_unicode_standard_color_formatting(self): filename = 'test/unicode.yml' runner = Runner(self.rules, filename, [], [], []) matches = runner.run() formatter = ansiblelint.formatters.Formatter() formatter.format(matches[0], colored=True)
def test_include_role_inline_args(self): fh = self._get_play_file(PLAY_INCLUDE_ROLE_INLINE) runner = Runner(self.rules, fh.name, [], [], []) results = runner.run() assert 'only when shell functionality is required' in str(results) assert 'All tasks should be named' in str(results)
def test_runner_encrypted_secrets(self): filename = 'test/contains_secrets.yml' runner = Runner(self.rules, filename, [], [], []) assert (len(runner.run()) == 0)
def test_file_negative(self): failure = 'ansible-lint/test/apt-repository-cache-update-failure.yml' bad_runner = Runner(self.collection, failure, [], [], []) errs = bad_runner.run() self.assertEqual(4, len(errs))
def test_runner_empty_tags_count(self): filename = 'test/emptytags.yml' runner = Runner(self.rules, filename, [], [], []) assert (len(runner.run()) == 0)
def _call_runner(self, path): runner = Runner(self.collection, path, [], [], []) return runner.run()
def test_file_negative(self): failure = 'test/octalpermissions-failure.yml' bad_runner = Runner(self.collection, failure, [], [], []) errs = bad_runner.run() self.assertEqual(4, len(errs))
def test_negative_no_param(self): bad_runner = Runner(self.collection, self.file, [], [], []) errs = bad_runner.run() self.assertGreater(len(errs), 0)
def test_file_positive(self): success = 'test/use-handler-rather-than-when-changed-success.yml' good_runner = Runner(self.collection, success, [], [], []) self.assertEqual([], good_runner.run())
def test_runner_exclude_user_expansion(): rules = RulesCollection([default_rulesdir]) filename = 'example/lots_of_warnings.yml' excludes = ['~'] runner = Runner(rules, filename, [], [], excludes) assert os.path.expanduser('~') in runner.exclude_paths
def test_negative_with_id(self): with_id = '201' bad_runner = Runner(self.collection, self.file, [with_id], [], []) errs = bad_runner.run() self.assertGreater(len(errs), 0)
def test_unicode_runner_count(self): filename = 'test/unicode.yml' runner = Runner(self.rules, filename, [], [], []) assert (len(runner.run()) == 1)
def test_negative_with_tag(self): with_tag = 'ANSIBLE0002' bad_runner = Runner(self.collection, self.file, [with_tag], [], []) errs = bad_runner.run() self.assertGreater(len(errs), 0)
def test_positive_skip_id(self): skip_id = '201' good_runner = Runner(self.collection, self.file, [], [skip_id], []) self.assertEqual([], good_runner.run())
def test_positive_skip_tag(self): skip_tag = 'ANSIBLE0002' good_runner = Runner(self.collection, self.file, [], [skip_tag], []) self.assertEqual([], good_runner.run())
def test_dir_with_trailing_slash(self): filename = 'test/' runner = Runner(self.rules, filename, [], [], []) assert (list(runner.playbooks)[0][1] == 'role')
def test_file_positive(self): success = 'test/octalpermissions-success.yml' good_runner = Runner(self.collection, success, [], [], []) self.assertEqual([], good_runner.run())