def test_logging_level(self): rebase_environment('app_without_logging_configuration') command = StubbedSearchCommand() warning = logging.getLevelName(logging.WARNING) notset = logging.getLevelName(logging.NOTSET) logging.root.setLevel(logging.WARNING) self.assertEqual(command.logging_level, warning) # logging_level accepts all logging levels and returns their canonical string values self.assertEquals(warning, command.logging_level) for level in logging._levelNames: if type(level) is int: command.logging_level = level level_name = logging.getLevelName(level) self.assertEquals( command.logging_level, warning if level_name == notset else level_name) else: level_name = logging.getLevelName(logging.getLevelName(level)) for variant in level, level.lower(), level.capitalize(): command.logging_level = variant self.assertEquals( command.logging_level, warning if level_name == notset else level_name) # logging_level accepts any numeric value for level in 999, 999.999: command.logging_level = level self.assertEqual(command.logging_level, 'Level 999') # logging_level raises a value error for unknown logging level names current_value = command.logging_level try: command.logging_level = 'foo' except ValueError: pass except BaseException as e: self.fail('Expected ValueError, but {} was raised'.format(type(e))) else: self.fail('Expected ValueError, but logging_level={}'.format( command.logging_level)) self.assertEqual(command.logging_level, current_value)
def test_logging_level(self): rebase_environment('app_without_logging_configuration') command = StubbedSearchCommand() warning = logging.getLevelName(logging.WARNING) notset = logging.getLevelName(logging.NOTSET) logging.root.setLevel(logging.WARNING) self.assertEqual(command.logging_level, warning) # logging_level accepts all logging levels and returns their canonical string values self.assertEquals(warning, command.logging_level) for level in logging._levelNames: if type(level) is int: command.logging_level = level level_name = logging.getLevelName(level) self.assertEquals(command.logging_level, warning if level_name == notset else level_name) else: level_name = logging.getLevelName(logging.getLevelName(level)) for variant in level, level.lower(), level.capitalize(): command.logging_level = variant self.assertEquals(command.logging_level, warning if level_name == notset else level_name) # logging_level accepts any numeric value for level in 999, 999.999: command.logging_level = level self.assertEqual(command.logging_level, 'Level 999') # logging_level raises a value error for unknown logging level names current_value = command.logging_level try: command.logging_level = 'foo' except ValueError: pass except BaseException as e: self.fail('Expected ValueError, but {} was raised'.format(type(e))) else: self.fail('Expected ValueError, but logging_level={}'.format(command.logging_level)) self.assertEqual(command.logging_level, current_value)
def _test_boolean_option(self, option): rebase_environment('app_without_logging_configuration') command = StubbedSearchCommand() # show_configuration accepts Splunk boolean values boolean_values = { '0': False, '1': True, 'f': False, 't': True, 'n': False, 'y': True, 'no': False, 'yes': True, 'false': False, 'true': True } for value in boolean_values: for variant in value, value.capitalize(), value.upper(): for s in variant, bytes(variant): option.fset(command, s) self.assertEquals(option.fget(command), boolean_values[value]) option.fset(command, None) self.assertEquals(option.fget(command), None) for value in 13, b'bytes', 'string', object(): try: option.fset(command, value) except ValueError: pass except BaseException as error: self.fail( 'Expected ValueError when setting {}={}, but {} was raised' .format(option.name, repr(value), type(error))) else: self.fail( 'Expected ValueError, but {}={} was accepted.'.format( option.name, repr(option.fget(command)))) return
def _test_boolean_option(self, option): rebase_environment('app_without_logging_configuration') command = StubbedSearchCommand() # show_configuration accepts Splunk boolean values boolean_values = { '0': False, '1': True, 'f': False, 't': True, 'n': False, 'y': True, 'no': False, 'yes': True, 'false': False, 'true': True} for value in boolean_values: for variant in value, value.capitalize(), value.upper(): for s in variant, bytes(variant): option.fset(command, s) self.assertEquals(option.fget(command), boolean_values[value]) option.fset(command, None) self.assertEquals(option.fget(command), None) for value in 13, b'bytes', 'string', object(): try: option.fset(command, value) except ValueError: pass except BaseException as error: self.fail('Expected ValueError when setting {}={}, but {} was raised'.format( option.name, repr(value), type(error))) else: self.fail('Expected ValueError, but {}={} was accepted.'.format( option.name, repr(option.fget(command)))) return
def test_option(self): rebase_environment('app_with_logging_configuration') presets = [ 'logging_configuration=' + json_encode_string(environment.logging_configuration), 'logging_level="WARNING"', 'record="f"', 'show_configuration="f"'] command = TestSearchCommand() options = command.options itervalues = options.itervalues options.reset() missing = options.get_missing() self.assertListEqual(missing, [option.name for option in itervalues() if option.is_required]) self.assertListEqual(presets, [unicode(option) for option in itervalues() if option.value is not None]) self.assertListEqual(presets, [unicode(option) for option in itervalues() if unicode(option) != option.name + '=None']) test_option_values = { validators.Boolean: ('0', 'non-boolean value'), validators.Code: ('foo == "bar"', 'bad code'), validators.Duration: ('24:59:59', 'non-duration value'), validators.Fieldname: ('some.field_name', 'non-fieldname value'), validators.File: (__file__, 'non-existent file'), validators.Integer: ('100', 'non-integer value'), validators.List: ('a,b,c', '"non-list value'), validators.Map: ('foo', 'non-existent map entry'), validators.Match: ('123-45-6789', 'not a social security number'), validators.OptionName: ('some_option_name', 'non-option name value'), validators.RegularExpression: ('\\s+', '(poorly formed regular expression'), validators.Set: ('bar', 'non-existent set entry')} for option in itervalues(): validator = option.validator if validator is None: self.assertIn(option.name, ['logging_configuration', 'logging_level']) continue legal_value, illegal_value = test_option_values[type(validator)] option.value = legal_value self.assertEqual( validator.format(option.value), validator.format(validator.__call__(legal_value)), "{}={}".format(option.name, legal_value)) try: option.value = illegal_value except ValueError: pass except BaseException as error: self.assertFalse('Expected ValueError for {}={}, not this {}: {}'.format( option.name, illegal_value, type(error).__name__, error)) else: self.assertFalse('Expected ValueError for {}={}, not a pass.'.format(option.name, illegal_value)) expected = ( "Option.View([" "(u'foo', u'f')," "('boolean', u'f')," "('code', u'foo == \"bar\"')," "('duration', u'24:59:59')," "('fieldname', u'some.field_name')," "('file', u" + unicode(repr(__file__)) + ")," "('integer', u'100')," "('logging_configuration', " + repr(environment.logging_configuration) + ")," "('logging_level', u'WARNING')," "('map', 'foo')," "('match', u'123-45-6789')," "('optionname', u'some_option_name')," "('record', u'f')," "('regularexpression', u'\\\\s+')," "('required_boolean', u'f')," "('required_code', u'foo == \"bar\"')," "('required_duration', u'24:59:59')," "('required_fieldname', u'some.field_name')," "('required_file', u" + unicode(repr(__file__)) + ")," "('required_integer', u'100')," "('required_map', 'foo')," "('required_match', u'123-45-6789')," "('required_optionname', u'some_option_name')," "('required_regularexpression', u'\\\\s+')," "('required_set', u'bar')," "('set', u'bar')," "('show_configuration', u'f')])") observed = unicode(repr(command.options)) self.assertEqual(observed, expected) expected = ( 'foo="f" boolean="f" code="foo == \\"bar\\"" duration="24:59:59" fieldname="some.field_name" ' 'file=' + json_encode_string(__file__) + ' integer="100" map="foo" match="123-45-6789" ' 'optionname="some_option_name" record="f" regularexpression="\\\\s+" required_boolean="f" ' 'required_code="foo == \\"bar\\"" required_duration="24:59:59" required_fieldname="some.field_name" ' 'required_file=' + json_encode_string(__file__) + ' required_integer="100" required_map="foo" ' 'required_match="123-45-6789" required_optionname="some_option_name" required_regularexpression="\\\\s+" ' 'required_set="bar" set="bar" show_configuration="f"') observed = unicode(command.options) self.assertEqual(observed, expected) return
def test_logging_configuration(self): # Test that logging is properly initialized when there is no logging configuration file rebase_environment('app_without_logging_configuration') self.assertIsInstance(environment.splunklib_logger, logging.Logger) self.assertIsNone(environment.logging_configuration) self.assertEqual(len(logging.root.handlers), 1) self.assertEqual(len(logging.Logger.manager.loggerDict), 1) self.assertIsInstance(logging.root.handlers[0], logging.StreamHandler) self.assertIs(environment.splunklib_logger, logging.getLogger('splunklib')) self.assertIsNone(environment.logging_configuration) command = StubbedSearchCommand() self.assertIs(command.logger, logging.getLogger('StubbedSearchCommand')) self.assertEqual(len(command.logger.handlers), 0) self.assertIsNone(command.logging_configuration) self.assertIs(command.logger.root, logging.root) self.assertEqual(len(logging.root.handlers), 1) root_handler = logging.root.handlers[0] self.assertIsInstance(root_handler, logging.StreamHandler) self.assertEqual(root_handler.stream, sys.stderr) self.assertEqual(command.logging_level, logging.getLevelName(logging.WARNING)) root_handler.stream = StringIO() message = 'Test that output is directed to stderr without formatting' command.logger.warning(message) self.assertEqual(root_handler.stream.getvalue(), message + '\n') # A search command loads {local,default}/logging.conf when it is available rebase_environment('app_with_logging_configuration') command = StubbedSearchCommand() self.assertEqual( command.logging_configuration, os.path.join(environment.app_root, 'default', 'logging.conf')) self.assertIs(command.logger, logging.getLogger('StubbedSearchCommand')) # Setting logging_configuration loads a new logging configuration file relative to the app root command.logging_configuration = 'alternative-logging.conf' self.assertEqual( command.logging_configuration, os.path.join(environment.app_root, 'default', 'alternative-logging.conf')) self.assertIs(command.logger, logging.getLogger('StubbedSearchCommand')) # Setting logging_configuration loads a new logging configuration file on an absolute path app_root_logging_configuration = os.path.join(environment.app_root, 'logging.conf') command.logging_configuration = app_root_logging_configuration self.assertEqual(command.logging_configuration, app_root_logging_configuration) self.assertIs(command.logger, logging.getLogger('StubbedSearchCommand')) # logging_configuration raises a value error, if a non-existent logging configuration file is provided try: command.logging_configuration = 'foo' except ValueError: pass except BaseException as e: self.fail('Expected ValueError, but {} was raised'.format(type(e))) else: self.fail( 'Expected ValueError, but logging_configuration={}'.format( command.logging_configuration)) try: command.logging_configuration = os.path.join( package_directory, 'non-existent.logging.conf') except ValueError: pass except BaseException as e: self.fail('Expected ValueError, but {} was raised'.format(type(e))) else: self.fail( 'Expected ValueError, but logging_configuration={}'.format( command.logging_configuration))
def test_option(self): rebase_environment('app_with_logging_configuration') presets = [ 'logging_configuration=' + json_encode_string(environment.logging_configuration), 'logging_level="WARNING"', 'record="f"', 'show_configuration="f"'] command = TestSearchCommand() options = command.options itervalues = lambda: six.itervalues(options) options.reset() missing = options.get_missing() self.assertListEqual(missing, [option.name for option in itervalues() if option.is_required]) self.assertListEqual(presets, [six.text_type(option) for option in itervalues() if option.value is not None]) self.assertListEqual(presets, [six.text_type(option) for option in itervalues() if six.text_type(option) != option.name + '=None']) test_option_values = { validators.Boolean: ('0', 'non-boolean value'), validators.Code: ('foo == "bar"', 'bad code'), validators.Duration: ('24:59:59', 'non-duration value'), validators.Fieldname: ('some.field_name', 'non-fieldname value'), validators.File: (__file__, 'non-existent file'), validators.Integer: ('100', 'non-integer value'), validators.List: ('a,b,c', '"non-list value'), validators.Map: ('foo', 'non-existent map entry'), validators.Match: ('123-45-6789', 'not a social security number'), validators.OptionName: ('some_option_name', 'non-option name value'), validators.RegularExpression: ('\\s+', '(poorly formed regular expression'), validators.Set: ('bar', 'non-existent set entry')} for option in itervalues(): validator = option.validator if validator is None: self.assertIn(option.name, ['logging_configuration', 'logging_level']) continue legal_value, illegal_value = test_option_values[type(validator)] option.value = legal_value self.assertEqual( validator.format(option.value), validator.format(validator.__call__(legal_value)), "{}={}".format(option.name, legal_value)) try: option.value = illegal_value except ValueError: pass except BaseException as error: self.assertFalse('Expected ValueError for {}={}, not this {}: {}'.format( option.name, illegal_value, type(error).__name__, error)) else: self.assertFalse('Expected ValueError for {}={}, not a pass.'.format(option.name, illegal_value)) expected = { u'foo': False, 'boolean': False, 'code': u'foo == \"bar\"', 'duration': 89999, 'fieldname': u'some.field_name', 'file': six.text_type(repr(__file__)), 'integer': 100, 'logging_configuration': environment.logging_configuration, 'logging_level': u'WARNING', 'map': 'foo', 'match': u'123-45-6789', 'optionname': u'some_option_name', 'record': False, 'regularexpression': u'\\s+', 'required_boolean': False, 'required_code': u'foo == \"bar\"', 'required_duration': 89999, 'required_fieldname': u'some.field_name', 'required_file': six.text_type(repr(__file__)), 'required_integer': 100, 'required_map': 'foo', 'required_match': u'123-45-6789', 'required_optionname': u'some_option_name', 'required_regularexpression': u'\\s+', 'required_set': u'bar', 'set': u'bar', 'show_configuration': False, } self.maxDiff = None tuplewrap = lambda x: x if isinstance(x, tuple) else (x,) invert = lambda x: {v: k for k, v in six.iteritems(x)} for x in six.itervalues(command.options): # isinstance doesn't work for some reason if type(x.value).__name__ == 'Code': self.assertEqual(expected[x.name], x.value.source) elif type(x.validator).__name__ == 'Map': self.assertEqual(expected[x.name], invert(x.validator.membership)[x.value]) elif type(x.validator).__name__ == 'RegularExpression': self.assertEqual(expected[x.name], x.value.pattern) elif isinstance(x.value, TextIOWrapper): self.assertEqual(expected[x.name], "'%s'" % x.value.name) elif not isinstance(x.value, (bool,) + (six.text_type,) + (six.binary_type,) + tuplewrap(six.integer_types)): self.assertEqual(expected[x.name], repr(x.value)) else: self.assertEqual(expected[x.name], x.value) expected = ( 'foo="f" boolean="f" code="foo == \\"bar\\"" duration="24:59:59" fieldname="some.field_name" ' 'file=' + json_encode_string(__file__) + ' integer="100" map="foo" match="123-45-6789" ' 'optionname="some_option_name" record="f" regularexpression="\\\\s+" required_boolean="f" ' 'required_code="foo == \\"bar\\"" required_duration="24:59:59" required_fieldname="some.field_name" ' 'required_file=' + json_encode_string(__file__) + ' required_integer="100" required_map="foo" ' 'required_match="123-45-6789" required_optionname="some_option_name" required_regularexpression="\\\\s+" ' 'required_set="bar" set="bar" show_configuration="f"') observed = six.text_type(command.options) self.assertEqual(observed, expected) return
def test_logging_configuration(self): # Test that logging is properly initialized when there is no logging configuration file rebase_environment('app_without_logging_configuration') self.assertIsInstance(environment.splunklib_logger, logging.Logger) self.assertIsNone(environment.logging_configuration) self.assertEqual(len(logging.root.handlers), 1) self.assertEqual(len(logging.Logger.manager.loggerDict), 1) self.assertIsInstance(logging.root.handlers[0], logging.StreamHandler) self.assertIs(environment.splunklib_logger, logging.getLogger('splunklib')) self.assertIsNone(environment.logging_configuration) command = StubbedSearchCommand() self.assertIs(command.logger, logging.getLogger('StubbedSearchCommand')) self.assertEqual(len(command.logger.handlers), 0) self.assertIsNone(command.logging_configuration) self.assertIs(command.logger.root, logging.root) self.assertEqual(len(logging.root.handlers), 1) root_handler = logging.root.handlers[0] self.assertIsInstance(root_handler, logging.StreamHandler) self.assertEqual(root_handler.stream, sys.stderr) self.assertEqual(command.logging_level, logging.getLevelName(logging.root.level)) root_handler.stream = StringIO() message = 'Test that output is directed to stderr without formatting' command.logger.warning(message) self.assertEqual(root_handler.stream.getvalue(), message + '\n') # A search command loads {local,default}/logging.conf when it is available rebase_environment('app_with_logging_configuration') command = StubbedSearchCommand() self.assertEqual(command.logging_configuration, os.path.join(environment.app_root, 'default', 'logging.conf')) self.assertIs(command.logger, logging.getLogger('StubbedSearchCommand')) # Setting logging_configuration loads a new logging configuration file relative to the app root command.logging_configuration = 'alternative-logging.conf' self.assertEqual( command.logging_configuration, os.path.join(environment.app_root, 'default', 'alternative-logging.conf')) self.assertIs(command.logger, logging.getLogger('StubbedSearchCommand')) # Setting logging_configuration loads a new logging configuration file on an absolute path app_root_logging_configuration = os.path.join(environment.app_root, 'logging.conf') command.logging_configuration = app_root_logging_configuration self.assertEqual(command.logging_configuration, app_root_logging_configuration) self.assertIs(command.logger, logging.getLogger('StubbedSearchCommand')) # logging_configuration raises a value error, if a non-existent logging configuration file is provided try: command.logging_configuration = 'foo' except ValueError: pass except BaseException as e: self.fail('Expected ValueError, but {} was raised'.format(type(e))) else: self.fail('Expected ValueError, but logging_configuration={}'.format(command.logging_configuration)) try: command.logging_configuration = os.path.join(package_directory, 'non-existent.logging.conf') except ValueError: pass except BaseException as e: self.fail('Expected ValueError, but {} was raised'.format(type(e))) else: self.fail('Expected ValueError, but logging_configuration={}'.format(command.logging_configuration))