| """Tests for puppet_utils.""" |
| |
| from __future__ import absolute_import |
| import os |
| import sys |
| import unittest |
| # Allow imports from cq/scripts folder |
| sys.path.insert( |
| 0, os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir))) |
| |
| from helpers import puppet_utils |
| |
| |
| class PuppetParserUtilsTest(unittest.TestCase): |
| """Tests for the puppet parser utils.""" |
| |
| def testEmptyErrors(self): |
| """Tests converting 0 parser errors to comments.""" |
| errors = [] |
| directory = '' |
| expected_comments = {} |
| actual_comments = puppet_utils.parser_errors_to_comments(errors, directory) |
| self.assertEqual(actual_comments, expected_comments) |
| |
| def testSingleError(self): |
| """Tests converting a single parser error to a comment.""" |
| error = ("Error: Could not parse for environment production: " |
| "Syntax error at '='; expected '}' at " |
| "/abs/path/to/project/dir/manifests/common.pp:43") |
| errors = [error] |
| directory = '/abs/path/to/project/dir' |
| expected_comments = { |
| 'manifests/common.pp': [{ |
| 'line': '43', |
| 'message': |
| "Error: Could not parse for environment production: Syntax " |
| "error at '='; expected '}' at manifests/common.pp:43" |
| }] |
| } |
| actual_comments = puppet_utils.parser_errors_to_comments(errors, directory) |
| self.assertEqual(actual_comments, expected_comments) |
| |
| def testSingleError_WithAnsiColorSequence(self): |
| """Tests stripping ANSI color sequences when converint to comments.""" |
| error = ("\x1b[1;31mError: Could not parse for environment production: " |
| "Syntax error at '='; expected '}' at " |
| "/abs/path/to/project/dir/manifests/common.pp:43\x1b[1;39m") |
| errors = [error] |
| directory = '/abs/path/to/project/dir' |
| expected_comments = { |
| 'manifests/common.pp': [{ |
| 'line': '43', |
| 'message': |
| "Error: Could not parse for environment production: Syntax " |
| "error at '='; expected '}' at manifests/common.pp:43" |
| }] |
| } |
| actual_comments = puppet_utils.parser_errors_to_comments(errors, directory) |
| self.assertEqual(actual_comments, expected_comments) |
| |
| def testMultipleErrors(self): |
| """Tests converting multiple parser errors into separate comments.""" |
| error1 = ("Error: Could not parse for environment production: " |
| "Syntax error at '='; expected '}' at " |
| "/abs/path/to/project/dir/manifests/common.pp:43") |
| error2 = ("Error: Could not parse for environment production: " |
| "Syntax error at ','; expected ']' at " |
| "/abs/path/to/project/dir/manifests/other.pp:1") |
| errors = [error1, error2] |
| directory = '/abs/path/to/project/dir' |
| expected_comments = { |
| 'manifests/common.pp': [{ |
| 'line': '43', |
| 'message': |
| "Error: Could not parse for environment production: Syntax " |
| "error at '='; expected '}' at manifests/common.pp:43" |
| }], |
| 'manifests/other.pp': [{ |
| 'line': '1', |
| 'message': |
| "Error: Could not parse for environment production: Syntax " |
| "error at ','; expected ']' at manifests/other.pp:1" |
| }] |
| } |
| actual_comments = puppet_utils.parser_errors_to_comments(errors, directory) |
| self.assertEqual(actual_comments, expected_comments) |
| |
| |
| class PuppetLinterUtilsTest(unittest.TestCase): |
| """Tests for puppet-lint utils.""" |
| |
| def testEmpty(self): |
| """Tests converting 0 lint errors into comments.""" |
| errors = [] |
| directory = '' |
| expected_comments = {} |
| actual_comments = puppet_utils.linter_errors_to_comments(errors, directory) |
| self.assertEqual(actual_comments, expected_comments) |
| |
| def testSingleError(self): |
| """Tests converting a single linter error into a comment.""" |
| errors = [{ |
| 'kind': 'error', |
| 'check': 'syntax', |
| 'message': 'Bad indentation.', |
| 'line': 34, |
| 'column': 10, |
| 'fullpath': '/full/path/to/project/dir/manifests/common.pp', |
| 'path': 'project/dir/manifests/common.pp', |
| 'filename': 'common.pp', |
| 'KIND': 'ERROR' |
| }] |
| directory = 'project/dir' |
| expected_comments = { |
| 'manifests/common.pp': [{ |
| 'line': '34', |
| 'message': 'Bad indentation.' |
| }] |
| } |
| actual_comments = puppet_utils.linter_errors_to_comments(errors, directory) |
| self.assertEqual(actual_comments, expected_comments) |
| |
| def testMultipleErrors(self): |
| """Tests converting multiple linter errors into separate comments.""" |
| errors = [{ |
| 'kind': 'error', |
| 'check': 'syntax', |
| 'message': 'Bad indentation.', |
| 'line': 34, |
| 'column': 10, |
| 'fullpath': '/full/path/to/project/dir/manifests/common.pp', |
| 'path': 'project/dir/manifests/common.pp', |
| 'filename': 'common.pp', |
| 'KIND': 'ERROR' |
| }, { |
| 'message': 'unquoted resource title', |
| 'line': 6, |
| 'column': 11, |
| 'token': '#<PuppetLint::Lexer::Token:0x00000001088350>', |
| 'kind': 'warning', |
| 'check': 'unquoted_resource_title', |
| 'fullpath': '/path/to/project/dir/manifests/site.pp', |
| 'path': 'project/dir/manifests/site.pp', |
| 'filename': 'site.pp', |
| 'KIND': 'WARNING' |
| }] |
| directory = 'project/dir' |
| expected_comments = { |
| 'manifests/common.pp': [{ |
| 'line': '34', |
| 'message': 'Bad indentation.' |
| }], |
| 'manifests/site.pp': [{ |
| 'line': '6', |
| 'message': 'unquoted resource title' |
| }] |
| } |
| actual_comments = puppet_utils.linter_errors_to_comments(errors, directory) |
| self.assertEqual(actual_comments, expected_comments) |
| |
| |
| def testErrorInNestedList(self): |
| """Tests that if errors are wrapped in a list, things still work.""" |
| errors = [[{ |
| 'kind': 'error', |
| 'check': 'syntax', |
| 'message': 'Bad indentation.', |
| 'line': 34, |
| 'column': 10, |
| 'fullpath': '/full/path/to/project/dir/manifests/common.pp', |
| 'path': 'project/dir/manifests/common.pp', |
| 'filename': 'common.pp', |
| 'KIND': 'ERROR' |
| }]] |
| directory = 'project/dir' |
| expected_comments = { |
| 'manifests/common.pp': [{ |
| 'line': '34', |
| 'message': 'Bad indentation.' |
| }] |
| } |
| actual_comments = puppet_utils.linter_errors_to_comments(errors, directory) |
| self.assertEqual(actual_comments, expected_comments) |
| |
| |
| class PuppetCronUtilsTest(unittest.TestCase): |
| |
| def testGetCronEntries_EmptyFile(self): |
| puppet_lines = [] |
| expected_cron_entries = [] |
| actual_cron_entries = puppet_utils.get_cron_entries(puppet_lines) |
| self.assertEqual(expected_cron_entries, actual_cron_entries) |
| |
| def testGetCronEntries_SingleCron(self): |
| puppet_lines = ['cron { "$cron_name":', |
| ' ensure => present,', |
| ' command => $my_script,', |
| ' hour => 2,', |
| ' minute => 0,', |
| '}'] |
| expected_cron_entries = [ |
| {'_line_number': '1', |
| 'ensure': 'present', |
| 'command': '$my_script', |
| 'hour': '2', |
| 'minute': '0',} |
| ] |
| actual_cron_entries = puppet_utils.get_cron_entries(puppet_lines) |
| self.assertEqual(expected_cron_entries, actual_cron_entries) |
| |
| def testGetCronEntries_MultipleCrons(self): |
| puppet_lines = ['cron { "$cron_name":', |
| ' ensure => present,', |
| ' command => $my_script,', |
| ' hour => 2,', |
| ' minute => 0,', |
| '}', |
| '', |
| 'cron { \'other_cron\':', |
| ' ensure => absent,', |
| ' command => "/usr/bin/bad_thing arg1 arg2,', |
| ' hour => 2,', |
| '}'] |
| expected_cron_entries = [ |
| {'_line_number': '1', |
| 'ensure': 'present', |
| 'command': '$my_script', |
| 'hour': '2', |
| 'minute': '0',}, |
| {'_line_number': '8', |
| 'ensure': 'absent', |
| 'command': '"/usr/bin/bad_thing arg1 arg2', |
| 'hour': '2',}, |
| ] |
| actual_cron_entries = puppet_utils.get_cron_entries(puppet_lines) |
| self.assertEqual(expected_cron_entries, actual_cron_entries) |
| |
| |
| def testGetCronEntries_MultilineAttributeValue(self): |
| puppet_lines = ['cron { "$cron_name":', |
| ' ensure => present,', |
| ' command => "/usr/bin/script ', |
| ' --that-has-very-long-args=yep', |
| ' --and-is-split-over-several-lints"', |
| ' hour => 2,', |
| ' minute => 0,', |
| '}'] |
| # The extra lines in the command attribute are just ignored. |
| expected_cron_entries = [ |
| {'_line_number': '1', |
| 'ensure': 'present', |
| 'command': '"/usr/bin/script ', |
| 'hour': '2', |
| 'minute': '0',} |
| ] |
| actual_cron_entries = puppet_utils.get_cron_entries(puppet_lines) |
| self.assertEqual(expected_cron_entries, actual_cron_entries) |
| |
| def testGetCronEntries_CurlyBraceCounting(self): |
| puppet_lines = ['cron { "$cron_name":', |
| ' ensure => present, ', |
| ' command => "/usr/bin/script ', |
| ' hour => 2,', |
| ' minute => 0,', |
| ' attr => { nested stuff', |
| ' xyz ', |
| ' }', |
| '}'] |
| # The extra lines in the command attribute are just ignored. |
| expected_cron_entries = [ |
| {'_line_number': '1', |
| 'ensure': 'present', |
| 'command': '"/usr/bin/script ', |
| 'hour': '2', |
| 'minute': '0', |
| 'attr': '{ nested stuff',} |
| ] |
| actual_cron_entries = puppet_utils.get_cron_entries(puppet_lines) |
| self.assertEqual(expected_cron_entries, actual_cron_entries) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |