Example #1
0
class TestLineTooLongRule(unittest.TestCase):
    collection = RulesCollection()
    collection.register(LineTooLongRule())

    def setUp(self):
        self.runner = RunFromText(self.collection)

    def test_long_line(self):
        results = self.runner.run_state(LONG_LINE)
        self.assertEqual(1, len(results))
Example #2
0
class TestTrailingWhitespaceRule(unittest.TestCase):
    collection = RulesCollection()
    collection.register(TrailingWhitespaceRule())

    def setUp(self):
        self.runner = RunFromText(self.collection)

    def test_trailing_whitespace(self):
        results = self.runner.run_state(LINE_AND_WHITESPACE)
        print(results)
        self.assertEqual(1, len(results))
class TestLineTooLongRule(unittest.TestCase):
    collection = RulesCollection()

    def setUp(self):
        self.collection.register(JinjaVariableHasSpacesRule())
        self.runner = RunFromText(self.collection)

    def test_statement_positive(self):
        results = self.runner.run_state(GOOD_VARIABLE_LINE)
        self.assertEqual(0, len(results))

    def test_statement_negative(self):
        results = self.runner.run_state(BAD_VARIABLE_LINE)
        self.assertEqual(1, len(results))
class TestJinjaPillarGrainsGetFormatRule(unittest.TestCase):
    collection = RulesCollection()

    def setUp(self):
        self.collection.register(JinjaPillarGrainsGetFormatRule())
        self.runner = RunFromText(self.collection)

    def test_statement_positive(self):
        results = self.runner.run_state(GOOD_STATEMENT_LINE)
        self.assertEqual(0, len(results))

    def test_statement_negative(self):
        results = self.runner.run_state(BAD_STATEMENT_LINE)
        self.assertEqual(2, len(results))
class TestModeQuotationRule(unittest.TestCase):
    collection = RulesCollection()

    def setUp(self):
        self.collection.register(FileModeQuotationRule())
        self.runner = RunFromText(self.collection)

    def test_statement_positive(self):
        results = self.runner.run_state(GOOD_MODE_QUOTATION_LINE)
        self.assertEqual(0, len(results))

    def test_statement_negative(self):
        results = self.runner.run_state(BAD_MODE_QUOTATION_LINE)
        self.assertEqual(3, len(results))
Example #6
0
class TestYamlHasOctalValueRule(unittest.TestCase):
    collection = RulesCollection()

    def setUp(self):
        self.collection.register(YamlHasOctalValueRule())

    def test_statement_positive(self):
        runner = RunFromText(self.collection)
        results = runner.run_state(GOOD_NUMBER_STATE)
        self.assertEqual(0, len(results))

    def test_statement_negative(self):
        runner = RunFromText(self.collection)
        results = runner.run_state(BAD_NUMBER_STATE)
        self.assertEqual(4, len(results))
class TestFileModeLeadingZeroRule(unittest.TestCase):
    collection = RulesCollection()

    def setUp(self):
        self.collection.register(FileModeLeadingZeroRule())

    def test_statement_positive(self):
        runner = RunFromText(self.collection)
        results = runner.run_state(GOOD_MODE_LEADING_ZERO_LINE)
        self.assertEqual(0, len(results))

    def test_statement_negative(self):
        runner = RunFromText(self.collection)
        results = runner.run_state(BAD_MODE_LEADING_ZERO_LINE)
        self.assertEqual(3, len(results))
class TestNoIrregularSpacesRule(unittest.TestCase):
    collection = RulesCollection()
    collection.register(NoIrregularSpacesRule())

    def setUp(self):
        self.runner = RunFromText(self.collection)

    def test_with_irregular_spaces(self):
        for irregular in NoIrregularSpacesRule.irregular_spaces:
            results = self.runner.run_state(LINE.format(space=irregular))
            self.assertEqual(1, len(results))

    def test_without_irregular_spaces(self):
        results = self.runner.run_state(LINE.format(space=" "))
        self.assertEqual(0, len(results))
Example #9
0
class TestJinjaTemplateHasRightExtensionRule(unittest.TestCase):
    collection = RulesCollection()

    def setUp(self):
        self.collection.register(JinjaTemplateHasRightExtensionRule())

    def test_file_extension_positive(self):
        path = 'tests/test-jinja-template.right.j2'
        runner = Runner(self.collection, path, SaltLintConfig())
        self.assertEqual([], runner.run())

    def test_file_extenion_negative(self):
        path = 'tests/test-jinja-template.bad'
        runner = Runner(self.collection, path, SaltLintConfig())
        errors = runner.run()
        self.assertEqual(1, len(errors))
Example #10
0
class TestLineTooLongRule(unittest.TestCase):
    collection = RulesCollection()

    def setUp(self):
        self.collection.register(FileExtensionRule())

    def test_file_positive(self):
        path = 'tests/test-extension-success.sls'
        runner = Runner(self.collection, path, SaltLintConfig())
        self.assertEqual([], runner.run())

    def test_file_negative(self):
        path = 'tests/test-extension-failure'
        runner = Runner(self.collection, path, SaltLintConfig())
        errors = runner.run()
        self.assertEqual(1, len(errors))
Example #11
0
class TestNoTabsRule(unittest.TestCase):
    collection = RulesCollection()
    collection.register(NoTabsRule())

    def setUp(self):
        self.runner = RunFromText(self.collection)

    def test_with_tabs(self):
        results = self.runner.run_state(LINE_WITH_TABS)
        self.assertEqual(2, len(results))

    def test_with_spaces(self):
        results = self.runner.run_state(LINE_WITH_SPACES)
        self.assertEqual(0, len(results))

    def test_mixed_tab_space(self):
        results = self.runner.run_state(LINE_MIXED_TAB_SPACE)
        self.assertEqual(1, len(results))
Example #12
0
class TestSkipRule(unittest.TestCase):
    collection = RulesCollection()

    def setUp(self):
        self.collection.register(LineTooLongRule())
        self.collection.register(JinjaVariableHasSpacesRule())

    def test_no_skip_rule(self):
        runner = RunFromText(self.collection)
        results = runner.run_state(LINE)
        self.assertEqual(1, len(results))

    def test_skip_multiple_rules(self):
        runner = RunFromText(self.collection)
        results = runner.run_state(LINE_SKIP_MULTIPLE)
        self.assertEqual(0, len(results))

    def test_skip_rule(self):
        runner = RunFromText(self.collection)
        results = runner.run_state(LINE_SKIP)
        self.assertEqual(0, len(results))
class TestJinjaVariableHasSpaces(unittest.TestCase):
    collection = RulesCollection()

    def setUp(self):
        self.collection.register(JinjaVariableHasSpacesRule())
        self.runner = RunFromText(self.collection)

    def test_statement_positive(self):
        results = self.runner.run_state(GOOD_VARIABLE_LINE)
        self.assertEqual(0, len(results))

    def test_statement_negative(self):
        results = self.runner.run_state(BAD_VARIABLE_LINE)
        self.assertEqual(1, len(results))

    def test_double_quoted_integer(self):
        results = self.runner.run_state(DOUBLE_QUOTED_INTEGER_IS_VALID)
        self.assertEqual(0, len(results))

    def test_double_quoted_integer_trailing_space_invalid(self):
        results = self.runner.run_state(
            DOUBLE_QUOTED_INTEGER_TRAILING_SPACE_IS_INVALID)
        self.assertEqual(1, len(results))

    def test_double_quoted_integer_leading_space_invalid(self):
        results = self.runner.run_state(
            DOUBLE_QUOTED_INTEGER_LEADING_SPACE_IS_INVALID)
        self.assertEqual(1, len(results))

    def test_variable_bad_ends_with_integer(self):
        results = self.runner.run_state(BAD_VARIABLE_ENDING_IN_INTEGER)
        self.assertEqual(1, len(results))

    def test_variable_bad_ends_with_integer_right(self):
        results = self.runner.run_state(BAD_VARIABLE_ENDING_IN_INTEGER_RIGHT)
        self.assertEqual(1, len(results))
Example #14
0
def run(args=None):
    # Wrap `sys.stdout` in an object that automatically encodes an unicode
    # string into utf-8, in Python 2 only. The default encoding for Python 3
    # is already utf-8.
    if sys.version_info[0] < 3:
        sys.stdout = codecs.getwriter('utf-8')(sys.stdout)

    parser = optparse.OptionParser("%prog [options] init.sls [state ...]",
                                   version='{} {}'.format(NAME, VERSION))

    parser.add_option('-L',
                      dest='listrules',
                      default=False,
                      action='store_true',
                      help="list all the rules")
    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',
                      '--nocolour',
                      dest='colored',
                      default=hasattr(sys.stdout, 'isatty')
                      and sys.stdout.isatty(),
                      action='store_false',
                      help="disable colored output")
    parser.add_option('--force-color',
                      '--force-colour',
                      dest='colored',
                      action='store_true',
                      help="Try force colored output (relying on salt'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('--json',
                      dest='json',
                      action='store_true',
                      default=False,
                      help='parse the output as JSON')
    parser.add_option('--severity',
                      dest='severity',
                      action='store_true',
                      default=False,
                      help='add the severity to the standard output')
    parser.add_option(
        '-c',
        help='Specify configuration file to use.  Defaults to ".salt-lint"')
    (options, parsed_args
     ) = parser.parse_args(args if args is not None else sys.argv[1:])

    stdin_state = None
    states = set(parsed_args)
    matches = []
    checked_files = set()

    # Read input from stdin
    if not sys.stdin.isatty():
        stdin_state = tempfile.NamedTemporaryFile('w',
                                                  suffix='.sls',
                                                  delete=False)
        stdin_state.write(sys.stdin.read())
        stdin_state.flush()
        states.add(stdin_state.name)

    # Read, parse and validate the configuration
    options_dict = vars(options)
    try:
        config = SaltLintConfig(options_dict)
    except SaltLintConfigError as exc:
        print(exc)
        return 2

    # Show a help message on the screen
    if not states and not (options.listrules or options.listtags):
        parser.print_help(file=sys.stderr)
        return 1

    # Collect the rules from the configution
    rules = RulesCollection(config)
    for rulesdir in config.rulesdirs:
        rules.extend(RulesCollection.create_from_directory(rulesdir, config))

    # Show the rules listing
    if options.listrules:
        print(rules)
        return 0

    # Show the tags listing
    if options.listtags:
        print(rules.listtags())
        return 0

    # Define the formatter
    if config.json:
        formatter = formatters.JsonFormatter()
    elif config.severity:
        formatter = formatters.SeverityFormatter(config.colored)
    else:
        formatter = formatters.Formatter(config.colored)

    for state in states:
        runner = Runner(rules, state, config, checked_files)
        matches.extend(runner.run())

    # Sort the matches
    matches.sort(key=lambda x: (x.filename, x.linenumber, x.rule.id))

    # Show the matches on the screen
    formatter.process(matches)

    # Delete stdin temporary file
    if stdin_state:
        os.unlink(stdin_state.name)

    # Return the exit code
    if matches:
        return 2

    return 0
Example #15
0
def run(args=None):
    formatter = formatters.Formatter()

    parser = optparse.OptionParser("%prog [options] init.sls [state ...]",
                                   version='{} {}'.format(NAME, VERSION))

    parser.add_option('-L', dest='listrules', default=False,
                      action='store_true', help="list all the rules")
    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 salt'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', help='Specify configuration file to use.  Defaults to ".salt-lint"')
    (options, parsed_args) = parser.parse_args(args if args is not None else sys.argv[1:])

    # Read, parse and validate the configration
    options_dict = vars(options)
    try:
        config = SaltLintConfig(options_dict)
    except SaltLintConfigError as exc:
        print(exc)
        return 2

    # Show a help message on the screen
    if len(parsed_args) == 0 and not (options.listrules or options.listtags):
        parser.print_help(file=sys.stderr)
        return 1

    # Collect the rules from the configution
    rules = RulesCollection(config)
    for rulesdir in config.rulesdirs:
        rules.extend(RulesCollection.create_from_directory(rulesdir, config))

    # Show the rules listing
    if options.listrules:
        print(rules)
        return 0

    # Show the tags listing
    if options.listtags:
        print(rules.listtags())
        return 0

    states = set(parsed_args)
    matches = list()
    checked_files = set()
    for state in states:
        runner = Runner(rules, state, config, checked_files)
        matches.extend(runner.run())

    # Sort the matches
    matches.sort(key=lambda x: (x.filename, x.linenumber, x.rule.id))

    # Show the matches on the screen
    for match in matches:
        print(formatter.format(match, config.colored).encode('utf-8'))

    # Return the exit code
    if len(matches):
        return 2
    else:
        return 0