Add PEP8 check and fix related issues

- Add PEP8 section to tox.ini
- Add hacking to requirements to enforce OpenStack style requirements
- Change setup.py to use PBR
- Add setup.cfg
- Fix formatting issues flagged by flake8 check
- Add copyright notices to all remaining files
- Update .gitignore file
- Bump version number

Change-Id: If32d332d3b7800f66fe6ad0f815f178bda739036
This commit is contained in:
Levi Blackstone 2015-05-05 09:37:31 -05:00
parent 2a005502e0
commit b13bcb7513
11 changed files with 152 additions and 148 deletions

5
.gitignore vendored
View File

@ -28,3 +28,8 @@ nosetests.xml
# Translations # Translations
*.mo *.mo
# IDE Project Files
*.project
*.pydev*
*.idea

View File

@ -3,8 +3,6 @@
# #
# Copyright © 2014 Rackspace Hosting. # Copyright © 2014 Rackspace Hosting.
# #
# Author: Monsyne Dragon <mdragon@rackspace.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
@ -27,8 +25,8 @@ import argparse
import json import json
import sys import sys
from stackdistiller import distiller
from stackdistiller import condenser from stackdistiller import condenser
from stackdistiller import distiller
class TestCondenser(condenser.CondenserBase): class TestCondenser(condenser.CondenserBase):
@ -81,28 +79,32 @@ def test_data(args):
yield n yield n
parser = argparse.ArgumentParser(description="Test Distiller configuration") parser = argparse.ArgumentParser(
parser.add_argument('-c', '--config', description="Test Distiller configuration")
default='event_definitions.yaml', parser.add_argument(
help='Name of event definitions file ' '-c', '--config',
'to test (Default: %(default)s)') default='event_definitions.yaml',
parser.add_argument('-l', '--list', action='store_true', help='Name of event definitions file '
help='Test data files contain JSON list of notifications.' 'to test (Default: %(default)s)')
' (By default data files should contain a single ' parser.add_argument(
'notification.)') '-l', '--list', action='store_true',
parser.add_argument('-d', '--add_default_definition', action='store_true', help='Test data files contain JSON list of notifications.'
help='Add default event definition. Normally, ' ' (By default data files should contain a single '
'notifications are dropped if there is no event ' 'notification.)')
'definition for their event_type. Setting this adds a ' parser.add_argument(
'"catchall" that converts unknown notifications to Events' '-d', '--add_default_definition', action='store_true',
' with a few basic traits.') help='Add default event definition. Normally, '
parser.add_argument('-o', '--output', type=argparse.FileType('w'), 'notifications are dropped if there is no event '
'definition for their event_type. Setting this adds a '
'"catchall" that converts unknown notifications to Events'
' with a few basic traits.')
parser.add_argument('-o', '--output', type=argparse.FileType('w'),
default=sys.stdout, help="Output file. Default stdout") default=sys.stdout, help="Output file. Default stdout")
parser.add_argument('test_data', nargs='*', metavar='JSON_FILE', parser.add_argument(
help="Test notifications in JSON format. Defaults to stdin") 'test_data', nargs='*', metavar='JSON_FILE',
help="Test notifications in JSON format. Defaults to stdin")
args = parser.parse_args() args = parser.parse_args()
config = distiller.load_config(args.config) config = distiller.load_config(args.config)
out = args.output out = args.output
@ -115,7 +117,7 @@ drops = 0
cond = TestCondenser() cond = TestCondenser()
for notification in notifications: for notification in notifications:
cond.clear() cond.clear()
nct +=1 nct += 1
if dist.to_event(notification, cond) is None: if dist.to_event(notification, cond) is None:
out.write("Dropped notification: %s\n" % out.write("Dropped notification: %s\n" %
notification['message_id']) notification['message_id'])

View File

@ -1 +1,6 @@
-e . hacking>=0.10.0,<0.11
enum34>=1.0
iso8601>=0.1.10
jsonpath-rw>=1.2.0, < 2.0
PyYAML>=3.1.0
six>=1.5.2

26
setup.cfg Normal file
View File

@ -0,0 +1,26 @@
[metadata]
description-file = README.md
name = stackdistiller
version = 0.12
author = Monsyne Dragon
author_email = mdragon@rackspace.com
summary = A data extraction and transformation library for OpenStack notifications
license = Apache-2
keywords =
OpenStack
notifications
events
extraction
transformation
classifiers =
Development Status :: 3 - Alpha
License :: OSI Approved :: Apache Software License
Operating System :: POSIX :: Linux
Programming Language :: Python :: 2.6
Programming Language :: Python :: 2.7
home-page = https://github.com/stackforge/stacktach-stackdistiller
[files]
packages =
stackdistiller

View File

@ -1,37 +1,8 @@
import os #!/usr/bin/env python
from setuptools import setup, find_packages
from setuptools import setup
def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()
setup( setup(
name='stackdistiller', setup_requires=['pbr'],
version='0.11', pbr=True,
author='Monsyne Dragon',
author_email='mdragon@rackspace.com',
description=("A data extraction and transformation library for "
"OpenStack notifications"),
license='Apache License (2.0)',
keywords='OpenStack notifications events extraction transformation',
packages=find_packages(exclude=['tests']),
classifiers=[
'Development Status :: 3 - Alpha',
'License :: OSI Approved :: Apache Software License',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
],
url='https://github.com/stackforge/stacktach-stackdistiller',
scripts=['bin/test-distiller.py'],
long_description=read('README.md'),
install_requires=[
"enum34 >= 1.0",
"iso8601 >= 0.1.10",
"jsonpath-rw >= 1.2.0, < 2.0",
"PyYAML >= 3.1.0",
"six >= 1.5.2",
],
zip_safe=False
) )

View File

@ -2,8 +2,6 @@
# #
# Copyright © 2014 Rackspace Hosting. # Copyright © 2014 Rackspace Hosting.
# #
# Author: Monsyne Dragon <mdragon@rackspace.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
@ -22,18 +20,23 @@ import six
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class CondenserBase(object): class CondenserBase(object):
"""Base class for Condenser objects that collect data extracted from a """Base class for Condenser objects
Notification by the Distiller, and format it into a usefull datastructure.
A simple Condenser may just colect all the traits received into a dictionary. Collect data extracted from a Notification by the Distiller, and
More complex ones may build collections of application or ORM model objects, format it into a useful data structure.
or XML document trees.
Condensers also have hooks for verification logic, to check that all needed A simple Condenser may just colect all the traits received into
traits are present.""" a dictionary. More complex ones may build collections of application
or ORM model objects, or XML document trees.
Condensers also have hooks for verification logic, to check that
all needed traits are present.
"""
def __init__(self, **kw): def __init__(self, **kw):
"""Setup the condenser. A new instance of the condenser is passed to the """Set up the condenser.
A new instance of the condenser is passed to the
distiller for each notification extracted. distiller for each notification extracted.
:param kw: keyword parameters for condenser. :param kw: keyword parameters for condenser.
@ -43,7 +46,9 @@ class CondenserBase(object):
@abc.abstractmethod @abc.abstractmethod
def add_trait(self, name, trait_type, value): def add_trait(self, name, trait_type, value):
"""Add a trait to the Event datastructure being built by this """Add a trait
Add a trait to the Event data structure being built by this
condenser. The distiller will call this for each extracted trait. condenser. The distiller will call this for each extracted trait.
:param name: (string) name of the trait :param name: (string) name of the trait
@ -54,7 +59,9 @@ class CondenserBase(object):
@abc.abstractmethod @abc.abstractmethod
def add_envelope_info(self, event_type, message_id, when): def add_envelope_info(self, event_type, message_id, when):
"""Add the metadata for this event, extracted from the notification's """Add the metadata for this event
Add metadata extracted from the notification's
envelope. The distiller will call this once. envelope. The distiller will call this once.
:param event_type: (string) Type of event, as a dotted string such as :param event_type: (string) Type of event, as a dotted string such as
@ -66,14 +73,14 @@ class CondenserBase(object):
@abc.abstractmethod @abc.abstractmethod
def get_event(self): def get_event(self):
"""Return the Event datastructure constructed by this condenser.""" """Return the Event data structure constructed by this condenser."""
@abc.abstractmethod @abc.abstractmethod
def clear(self): def clear(self):
"""Clear condenser state.""" """Clear condenser state."""
def validate(self): def validate(self):
"""Check Event against whatever validation logic this condenser may have """Check Event against whatever validation logic this condenser has
:returns: (bool) True if valid. :returns: (bool) True if valid.
@ -83,6 +90,7 @@ class CondenserBase(object):
class DictionaryCondenser(CondenserBase): class DictionaryCondenser(CondenserBase):
"""Return event data as a simple python dictionary""" """Return event data as a simple python dictionary"""
def __init__(self, **kw): def __init__(self, **kw):
self.clear() self.clear()
super(DictionaryCondenser, self).__init__(**kw) super(DictionaryCondenser, self).__init__(**kw)

View File

@ -2,8 +2,6 @@
# #
# Copyright © 2013 Rackspace Hosting. # Copyright © 2013 Rackspace Hosting.
# #
# Author: Monsyne Dragon <mdragon@rackspace.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
@ -20,7 +18,6 @@ import collections
import datetime import datetime
import fnmatch import fnmatch
import logging import logging
import os
from enum import Enum from enum import Enum
import iso8601 import iso8601
@ -60,13 +57,13 @@ def load_config(filename):
if hasattr(err, 'problem_mark'): if hasattr(err, 'problem_mark'):
mark = err.problem_mark mark = err.problem_mark
errmsg = ("Invalid YAML syntax in Event Definitions file " errmsg = ("Invalid YAML syntax in Event Definitions file "
"%(file)s at line: %(line)s, column: %(column)s." "%(file)s at line: %(line)s, column: %(column)s."
% dict(file=filename, % dict(file=filename,
line=mark.line + 1, line=mark.line + 1,
column=mark.column + 1)) column=mark.column + 1))
else: else:
errmsg = ("YAML error reading Event Definitions file " errmsg = ("YAML error reading Event Definitions file "
"%(file)s" "%(file)s"
% dict(file=filename)) % dict(file=filename))
logger.error(errmsg) logger.error(errmsg)
raise raise
@ -100,7 +97,6 @@ Trait = collections.namedtuple('Trait', ('name', 'trait_type', 'value'))
class TraitDefinition(object): class TraitDefinition(object):
def __init__(self, name, trait_cfg, plugin_map): def __init__(self, name, trait_cfg, plugin_map):
self.cfg = trait_cfg self.cfg = trait_cfg
self.name = name self.name = name
@ -110,8 +106,8 @@ class TraitDefinition(object):
type_name = trait_cfg.get('type', 'text') type_name = trait_cfg.get('type', 'text')
except AttributeError as e: except AttributeError as e:
raise EventDefinitionException( raise EventDefinitionException(
"Unable to get type for '%s'" % trait_cfg, "Unable to get type for '%s'" % trait_cfg,
self.cfg) self.cfg)
if 'plugin' in trait_cfg: if 'plugin' in trait_cfg:
plugin_cfg = trait_cfg['plugin'] plugin_cfg = trait_cfg['plugin']
@ -124,7 +120,7 @@ class TraitDefinition(object):
except KeyError: except KeyError:
raise EventDefinitionException( raise EventDefinitionException(
'Plugin specified, but no plugin name supplied for ' 'Plugin specified, but no plugin name supplied for '
'trait %s' % name, self.cfg) 'trait %s' % name, self.cfg)
plugin_params = plugin_cfg.get('parameters') plugin_params = plugin_cfg.get('parameters')
if plugin_params is None: if plugin_params is None:
plugin_params = {} plugin_params = {}
@ -133,8 +129,8 @@ class TraitDefinition(object):
except KeyError: except KeyError:
raise EventDefinitionException( raise EventDefinitionException(
'No plugin named %(plugin)s available for ' 'No plugin named %(plugin)s available for '
'trait %(trait)s' % dict(plugin=plugin_name, 'trait %(trait)s' % dict(plugin=plugin_name,
trait=name), self.cfg) trait=name), self.cfg)
self.plugin = plugin_class(**plugin_params) self.plugin = plugin_class(**plugin_params)
else: else:
self.plugin = None self.plugin = None
@ -142,7 +138,7 @@ class TraitDefinition(object):
if 'fields' not in trait_cfg: if 'fields' not in trait_cfg:
raise EventDefinitionException( raise EventDefinitionException(
"Required field in trait definition not specified: " "Required field in trait definition not specified: "
"'%s'" % 'fields', "'%s'" % 'fields',
self.cfg) self.cfg)
fields = trait_cfg['fields'] fields = trait_cfg['fields']
@ -157,7 +153,7 @@ class TraitDefinition(object):
except Exception as e: except Exception as e:
raise EventDefinitionException( raise EventDefinitionException(
"Parse error in JSONPath specification " "Parse error in JSONPath specification "
"'%(jsonpath)s' for %(trait)s: %(err)s" "'%(jsonpath)s' for %(trait)s: %(err)s"
% dict(jsonpath=fields, trait=name, err=e), self.cfg) % dict(jsonpath=fields, trait=name, err=e), self.cfg)
try: try:
self.trait_type = Datatype[type_name] self.trait_type = Datatype[type_name]
@ -196,7 +192,6 @@ class TraitDefinition(object):
class EventDefinition(object): class EventDefinition(object):
DEFAULT_TRAITS = dict( DEFAULT_TRAITS = dict(
service=dict(type='text', fields='publisher_id'), service=dict(type='text', fields='publisher_id'),
request_id=dict(type='text', fields='_context_request_id'), request_id=dict(type='text', fields='_context_request_id'),
@ -262,8 +257,8 @@ class EventDefinition(object):
@staticmethod @staticmethod
def _extract_when(body): def _extract_when(body):
"""Extract the generated datetime from the notification. """Extract the generated datetime from the notification."""
"""
# NOTE: I am keeping the logic the same as it was in openstack # NOTE: I am keeping the logic the same as it was in openstack
# code, However, *ALL* notifications should have a 'timestamp' # code, However, *ALL* notifications should have a 'timestamp'
# field, it's part of the notification envelope spec. If this was # field, it's part of the notification envelope spec. If this was

View File

@ -2,8 +2,6 @@
# #
# Copyright © 2013 Rackspace Hosting. # Copyright © 2013 Rackspace Hosting.
# #
# Author: Monsyne Dragon <mdragon@rackspace.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
@ -22,9 +20,7 @@ import six
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class TraitPluginBase(object): class TraitPluginBase(object):
"""Base class for plugins that convert notification fields to """Base class for plugins that convert notification fields to Traits"""
Trait values.
"""
def __init__(self, **kw): def __init__(self, **kw):
"""Setup the trait plugin. """Setup the trait plugin.

View File

@ -2,13 +2,11 @@
# #
# Copyright © 2013 Rackspace Hosting. # Copyright © 2013 Rackspace Hosting.
# #
# Author: Monsyne Dragon <mdragon@rackspace.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
@ -18,7 +16,7 @@
import datetime import datetime
#for Python2.6 compatability. # for Python2.6 compatability.
import unittest2 as unittest import unittest2 as unittest
import iso8601 import iso8601
@ -50,13 +48,14 @@ class TestCondenser(object):
class DistillerTestBase(unittest.TestCase): class DistillerTestBase(unittest.TestCase):
def _create_test_notification(self, event_type, message_id, **kw): def _create_test_notification(self, event_type, message_id, **kw):
return dict(event_type=event_type, return dict(
message_id=message_id, event_type=event_type,
priority="INFO", message_id=message_id,
publisher_id="compute.host-1-2-3", priority="INFO",
timestamp="2013-08-08 21:06:37.803826", publisher_id="compute.host-1-2-3",
payload=kw, timestamp="2013-08-08 21:06:37.803826",
) payload=kw,
)
def assertIsValidEvent(self, event, notification): def assertIsValidEvent(self, event, notification):
self.assertIsNot( self.assertIsNot(
@ -113,7 +112,6 @@ class DistillerTestBase(unittest.TestCase):
class TestTraitDefinition(DistillerTestBase): class TestTraitDefinition(DistillerTestBase):
def setUp(self): def setUp(self):
super(TestTraitDefinition, self).setUp() super(TestTraitDefinition, self).setUp()
self.n1 = self._create_test_notification( self.n1 = self._create_test_notification(
@ -126,8 +124,8 @@ class TestTraitDefinition(DistillerTestBase):
host='host-1-2-3', host='host-1-2-3',
bogus_date='', bogus_date='',
image_meta=dict( image_meta=dict(
disk_gb='20', disk_gb='20',
thing='whatzit'), thing='whatzit'),
foobar=50) foobar=50)
self.test_plugin_class = mock.MagicMock(name='mock_test_plugin') self.test_plugin_class = mock.MagicMock(name='mock_test_plugin')
@ -244,14 +242,14 @@ class TestTraitDefinition(DistillerTestBase):
def test_to_trait_multiple_different_nesting(self): def test_to_trait_multiple_different_nesting(self):
cfg = dict(type='int', fields=['payload.foobar', cfg = dict(type='int', fields=['payload.foobar',
'payload.image_meta.disk_gb']) 'payload.image_meta.disk_gb'])
tdef = distiller.TraitDefinition('test_trait', cfg, tdef = distiller.TraitDefinition('test_trait', cfg,
self.fake_plugin_map) self.fake_plugin_map)
t = tdef.to_trait(self.n1) t = tdef.to_trait(self.n1)
self.assertEqual(50, t.value) self.assertEqual(50, t.value)
cfg = dict(type='int', fields=['payload.image_meta.disk_gb', cfg = dict(type='int', fields=['payload.image_meta.disk_gb',
'payload.foobar']) 'payload.foobar'])
tdef = distiller.TraitDefinition('test_trait', cfg, tdef = distiller.TraitDefinition('test_trait', cfg,
self.fake_plugin_map) self.fake_plugin_map)
t = tdef.to_trait(self.n1) t = tdef.to_trait(self.n1)
@ -322,7 +320,7 @@ class TestTraitDefinition(DistillerTestBase):
jsonpath_rw.parse('(payload.test)|(payload.other)')) jsonpath_rw.parse('(payload.test)|(payload.other)'))
def test_invalid_path_config(self): def test_invalid_path_config(self):
#test invalid jsonpath... # test invalid jsonpath...
cfg = dict(fields='payload.bogus(') cfg = dict(fields='payload.bogus(')
self.assertRaises(distiller.EventDefinitionException, self.assertRaises(distiller.EventDefinitionException,
distiller.TraitDefinition, distiller.TraitDefinition,
@ -331,7 +329,7 @@ class TestTraitDefinition(DistillerTestBase):
self.fake_plugin_map) self.fake_plugin_map)
def test_invalid_plugin_config(self): def test_invalid_plugin_config(self):
#test invalid jsonpath... # test invalid jsonpath...
cfg = dict(fields='payload.test', plugin=dict(bogus="true")) cfg = dict(fields='payload.test', plugin=dict(bogus="true"))
self.assertRaises(distiller.EventDefinitionException, self.assertRaises(distiller.EventDefinitionException,
distiller.TraitDefinition, distiller.TraitDefinition,
@ -340,7 +338,7 @@ class TestTraitDefinition(DistillerTestBase):
self.fake_plugin_map) self.fake_plugin_map)
def test_unknown_plugin(self): def test_unknown_plugin(self):
#test invalid jsonpath... # test invalid jsonpath...
cfg = dict(fields='payload.test', plugin=dict(name='bogus')) cfg = dict(fields='payload.test', plugin=dict(name='bogus'))
self.assertRaises(distiller.EventDefinitionException, self.assertRaises(distiller.EventDefinitionException,
distiller.TraitDefinition, distiller.TraitDefinition,
@ -366,7 +364,7 @@ class TestTraitDefinition(DistillerTestBase):
self.assertEqual(distiller.Datatype.datetime, t.trait_type) self.assertEqual(distiller.Datatype.datetime, t.trait_type)
def test_invalid_type_config(self): def test_invalid_type_config(self):
#test invalid jsonpath... # test invalid jsonpath...
cfg = dict(type='bogus', fields='payload.test') cfg = dict(type='bogus', fields='payload.test')
self.assertRaises(distiller.EventDefinitionException, self.assertRaises(distiller.EventDefinitionException,
distiller.TraitDefinition, distiller.TraitDefinition,
@ -376,7 +374,6 @@ class TestTraitDefinition(DistillerTestBase):
class TestEventDefinition(DistillerTestBase): class TestEventDefinition(DistillerTestBase):
def setUp(self): def setUp(self):
super(TestEventDefinition, self).setUp() super(TestEventDefinition, self).setUp()
@ -419,11 +416,13 @@ class TestEventDefinition(DistillerTestBase):
e = edef.to_event(self.test_notification1, self.condenser) e = edef.to_event(self.test_notification1, self.condenser)
self.assertTrue(e is self.condenser) self.assertTrue(e is self.condenser)
self.assertEqual('test.thing', e.event_type) self.assertEqual('test.thing', e.event_type)
self.assertEqual(datetime.datetime(2013, 8, 8, 21, 6, 37, 803826, iso8601.iso8601.UTC), self.assertEqual(datetime.datetime(2013, 8, 8, 21, 6, 37, 803826,
iso8601.iso8601.UTC),
e.when) e.when)
self.assertHasDefaultTraits(e) self.assertHasDefaultTraits(e)
self.assertHasTrait(e, 'host', value='host-1-2-3', trait_type=trait_type) self.assertHasTrait(e, 'host', value='host-1-2-3',
trait_type=trait_type)
self.assertHasTrait(e, 'instance_id', self.assertHasTrait(e, 'instance_id',
value='uuid-for-instance-0001', value='uuid-for-instance-0001',
trait_type=trait_type) trait_type=trait_type)
@ -609,24 +608,25 @@ class TestEventDefinition(DistillerTestBase):
class TestDistiller(DistillerTestBase): class TestDistiller(DistillerTestBase):
def setUp(self): def setUp(self):
super(TestDistiller, self).setUp() super(TestDistiller, self).setUp()
self.valid_event_def1 = [{ self.valid_event_def1 = [
'event_type': 'compute.instance.create.*', {
'traits': { 'event_type': 'compute.instance.create.*',
'instance_id': { 'traits': {
'type': 'text', 'instance_id': {
'fields': ['payload.instance_uuid', 'type': 'text',
'payload.instance_id'], 'fields': ['payload.instance_uuid',
'payload.instance_id'],
},
'host': {
'type': 'text',
'fields': 'payload.host',
},
}, },
'host': { }
'type': 'text', ]
'fields': 'payload.host',
},
},
}]
self.test_notification1 = self._create_test_notification( self.test_notification1 = self._create_test_notification(
"compute.instance.create.start", "compute.instance.create.start",
@ -645,10 +645,7 @@ class TestDistiller(DistillerTestBase):
# test a malformed notification # test a malformed notification
now = datetime.datetime.utcnow().replace(tzinfo=iso8601.iso8601.UTC) now = datetime.datetime.utcnow().replace(tzinfo=iso8601.iso8601.UTC)
mock_utcnow.return_value = now mock_utcnow.return_value = now
c = distiller.Distiller( c = distiller.Distiller([], self.fake_plugin_map, catchall=True)
[],
self.fake_plugin_map,
catchall=True)
message = {'event_type': "foo", message = {'event_type': "foo",
'message_id': "abc", 'message_id': "abc",
'publisher_id': "1"} 'publisher_id': "1"}
@ -674,7 +671,8 @@ class TestDistiller(DistillerTestBase):
e = c.to_event(self.test_notification2, TestCondenser()) e = c.to_event(self.test_notification2, TestCondenser())
self.assertIsValidEvent(e, self.test_notification2) self.assertIsValidEvent(e, self.test_notification2)
self.assertEqual(1, len(e.traits), self.assertEqual(1, len(e.traits),
"Wrong number of traits %s: %s" % (len(e.traits), e.traits)) "Wrong number of traits %s: %s" % (
len(e.traits), e.traits))
self.assertHasDefaultTraits(e) self.assertHasDefaultTraits(e)
self.assertDoesNotHaveTrait(e, 'instance_id') self.assertDoesNotHaveTrait(e, 'instance_id')
self.assertDoesNotHaveTrait(e, 'host') self.assertDoesNotHaveTrait(e, 'host')
@ -696,10 +694,7 @@ class TestDistiller(DistillerTestBase):
self.assertIsNotValidEvent(e, self.test_notification2) self.assertIsNotValidEvent(e, self.test_notification2)
def test_distiller_empty_cfg_with_catchall(self): def test_distiller_empty_cfg_with_catchall(self):
c = distiller.Distiller( c = distiller.Distiller([], self.fake_plugin_map, catchall=True)
[],
self.fake_plugin_map,
catchall=True)
self.assertEqual(1, len(c.definitions)) self.assertEqual(1, len(c.definitions))
e = c.to_event(self.test_notification1, TestCondenser()) e = c.to_event(self.test_notification1, TestCondenser())
self.assertIsValidEvent(e, self.test_notification1) self.assertIsValidEvent(e, self.test_notification1)
@ -712,10 +707,7 @@ class TestDistiller(DistillerTestBase):
self.assertHasDefaultTraits(e) self.assertHasDefaultTraits(e)
def test_distiller_empty_cfg_without_catchall(self): def test_distiller_empty_cfg_without_catchall(self):
c = distiller.Distiller( c = distiller.Distiller([], self.fake_plugin_map, catchall=False)
[],
self.fake_plugin_map,
catchall=False)
self.assertEqual(0, len(c.definitions)) self.assertEqual(0, len(c.definitions))
e = c.to_event(self.test_notification1, TestCondenser()) e = c.to_event(self.test_notification1, TestCondenser())
self.assertIsNotValidEvent(e, self.test_notification1) self.assertIsNotValidEvent(e, self.test_notification1)

View File

@ -2,8 +2,6 @@
# #
# Copyright © 2013 Rackspace Hosting. # Copyright © 2013 Rackspace Hosting.
# #
# Author: Monsyne Dragon <mdragon@rackspace.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
@ -16,14 +14,13 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
#for Python2.6 compatability. # for Python2.6 compatability.
import unittest2 as unittest import unittest2 as unittest
from stackdistiller import trait_plugins from stackdistiller import trait_plugins
class TestSplitterPlugin(unittest.TestCase): class TestSplitterPlugin(unittest.TestCase):
def setUp(self): def setUp(self):
super(TestSplitterPlugin, self).setUp() super(TestSplitterPlugin, self).setUp()
self.pclass = trait_plugins.SplitterTraitPlugin self.pclass = trait_plugins.SplitterTraitPlugin
@ -70,7 +67,6 @@ class TestSplitterPlugin(unittest.TestCase):
class TestBitfieldPlugin(unittest.TestCase): class TestBitfieldPlugin(unittest.TestCase):
def setUp(self): def setUp(self):
super(TestBitfieldPlugin, self).setUp() super(TestBitfieldPlugin, self).setUp()
self.pclass = trait_plugins.BitfieldTraitPlugin self.pclass = trait_plugins.BitfieldTraitPlugin

10
tox.ini
View File

@ -1,5 +1,5 @@
[tox] [tox]
envlist = py26,py27 envlist = py26,py27,pep8
[testenv] [testenv]
deps = deps =
@ -13,3 +13,11 @@ commands =
sitepackages = False sitepackages = False
[testenv:pep8]
commands =
flake8
[flake8]
ignore =
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg
show-source = True