Example #1
0
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))

    def test_missing_quotes(self):
        results = self.runner.run_state(MODE_MISSING_QUOTATION_LINE)
        self.assertEqual(3, len(results))

    def test_network_mode(self):
        """
        Ensure the mode argument in the network.managed state gets ignored. See
        related GitHub issue:
        https://github.com/warpnet/salt-lint/issues/255
        """
        results = self.runner.run_state(NETWORK_MANAGED_MODE)
        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_jinja_raw_positive(self):
        """Check if Jinja looking variables between raw-blocks are ignored."""
        results = self.runner.run_state(GOOD_VARIABLE_LINE_RAW)
        self.assertEqual(0, len(results))

    def test_statement_jinja_raw_negative(self):
        """Check if Jinja looking variables between raw-blocks are ignored."""
        results = self.runner.run_state(BAD_VARIABLE_LINE_RAW)
        # Check if the correct number of matches are found
        self.assertEqual(1, len(results))
        # Check if the match occurred on the correct line
        self.assertEqual(results[0].linenumber, 5)

    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))

    def test_nested_literal_braces(self):
        """
        Check if Jinja variables inside nested literal braces are identified
        correctly. See related GitHub issue:
        https://github.com/warpnet/salt-lint/issues/257
        """
        results = self.runner.run_state(NESTED_LITERAL_BRACES)
        self.assertEqual(0, len(results))
Example #3
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))
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))
Example #5
0
class TestLineTooLongRule(unittest.TestCase):
    collection = RulesCollection()

    def setUp(self):
        self.collection.register(JinjaStatementHasSpacesRule())
        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(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))
Example #7
0
class TestTypoOnchangesRule(unittest.TestCase):
    collection = RulesCollection()

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

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

    def test_statement_negative(self):
        results = self.runner.run_state(BAD_ONCHANGES_LINE)
        self.assertEqual(3, 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))
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 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))
Example #11
0
class TestCmdWaitRecommendRule(unittest.TestCase):
    collection = RulesCollection()

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

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

    def test_statement_negative(self):
        runner = RunFromText(self.collection)
        results = runner.run_state(BAD_CMD_STATE)
        self.assertEqual(1, 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(unicode(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 #13
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, Configuration())
        self.assertEqual([], runner.run())

    def test_file_negative(self):
        path = 'tests/test-extension-failure'
        runner = Runner(self.collection, path, Configuration())
        errors = runner.run()
        self.assertEqual(1, len(errors))
Example #14
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))
class TestCmdRunQuietRule(unittest.TestCase):
    collection = RulesCollection()

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

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

    def test_statement_negative(self):
        runner = RunFromText(self.collection)
        results = runner.run_state(BAD_QUIET_STATE)
        self.assertEqual(2, len(results))

        # Check line numbers of the results
        self.assertEqual(9, results[0].linenumber)
        self.assertEqual(14, results[1].linenumber)
class TestFileManagedReplaceContentRule(unittest.TestCase):
    collection = RulesCollection()

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

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

    def test_statement_negative(self):
        runner = RunFromText(self.collection)
        results = runner.run_state(BAD_FILE_STATE)
        self.assertEqual(3, len(results))

        # Check line numbers of the results
        self.assertEqual(3, results[0].linenumber)
        self.assertEqual(10, results[1].linenumber)
        self.assertEqual(19, results[2].linenumber)
Example #17
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))
Example #18
0
class TestSLSFileNameRule(unittest.TestCase):
    collection = RulesCollection()

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

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

        path = 'tests/test-extension-failure'
        runner = Runner(self.collection, path, Configuration())
        self.assertEqual([], runner.run())

        path = 'tests/test-extension-failure.extra.jinja'
        runner = Runner(self.collection, path, Configuration())
        self.assertEqual([], runner.run())

    def test_file_negative(self):
        path = 'tests/test-extension-failure.extra.sls'
        runner = Runner(self.collection, path, Configuration())
        self.assertEqual(1, len(runner.run()))
Example #19
0
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 #20
0
def run(args=None):
    """Run the linter and return the exit code."""
    # 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 = init_argument_parser()
    options = parser.parse_args(args if args is not None else sys.argv[1:])

    stdin_file = None
    file_names = set(options.files)
    checked_files = set()

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

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

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

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

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

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

    formatter = initialize_formatter(config)

    problems = []
    for file_name in file_names:
        runner = Runner(collection, file_name, config, checked_files)
        problems.extend(runner.run())

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

    if problems:
        sorted_problems = sort_problems(problems)
        formatter.process(sorted_problems)
        return 2
    return 0
Example #21
0
def run(args=None):
    """Run the linter and return the exit code."""
    parser = init_argument_parser()
    options = parser.parse_args(args if args is not None else sys.argv[1:])

    stdin_filename = None
    file_names = set(options.files)
    checked_files = set()

    # Read input from STDIN
    if not sys.stdin.isatty():
        with tempfile.NamedTemporaryFile('w', suffix='.sls',
                                         delete=False) as stdin_tmpfile:
            stdin_tmpfile.write(sys.stdin.read())
            stdin_filename = stdin_tmpfile.name
            file_names.add(stdin_filename)

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

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

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

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

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

    formatter = initialize_formatter(config)

    problems = []
    for file_name in file_names:
        runner = Runner(collection, file_name, config, checked_files)
        problems.extend(runner.run())

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

    if problems:
        sorted_problems = sort_problems(problems)
        formatter.process(sorted_problems)
        return 2
    return 0