8892801205
- Add PEP8 section to tox.ini - Add hacking to requirements to enforce OpenStack style requirements - Fix large number of formatting issues flagged by flake8 check - Add copyright notices to all remaining files - Fix bug in trigger_manager related to logging calls - Add .gitignore file Change-Id: I755ab9c8bcc436836f9006fcd671408cc77214c4
406 lines
20 KiB
Python
406 lines
20 KiB
Python
# Copyright (c) 2014 Dark Secret Software Inc.
|
|
# Copyright (c) 2015 Rackspace
|
|
#
|
|
# 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 a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# for Python2.6 compatability.
|
|
import unittest2 as unittest
|
|
|
|
import datetime
|
|
import timex
|
|
|
|
from winchester import debugging
|
|
from winchester import definition
|
|
|
|
|
|
class TestCriterion(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
super(TestCriterion, self).setUp()
|
|
self.fake_group = debugging.NoOpGroup()
|
|
self.fake_debugger = debugging.NoOpDebugger()
|
|
|
|
def test_basic_criterion(self):
|
|
c = definition.Criterion(3, 'foo')
|
|
self.assertTrue(c.match({'foo': 3}, self.fake_group))
|
|
self.assertFalse(c.match({'foo': 5}, self.fake_group))
|
|
self.assertFalse(c.match({'bar': 5}, self.fake_group))
|
|
self.assertFalse(c.match({'foo': "booga"}, self.fake_group))
|
|
|
|
def test_numeric_criterion(self):
|
|
c = definition.NumericCriterion("3", 'foo')
|
|
self.assertTrue(c.match({'foo': 3}, self.fake_group))
|
|
self.assertFalse(c.match({'foo': 5}, self.fake_group))
|
|
self.assertFalse(c.match({'bar': 5}, self.fake_group))
|
|
self.assertFalse(c.match({'foo': "booga"}, self.fake_group))
|
|
c = definition.NumericCriterion("> 3", 'foo')
|
|
self.assertFalse(c.match({'foo': 3}, self.fake_group))
|
|
self.assertTrue(c.match({'foo': 5}, self.fake_group))
|
|
c = definition.NumericCriterion("< 3", 'foo')
|
|
self.assertFalse(c.match({'foo': 3}, self.fake_group))
|
|
self.assertFalse(c.match({'foo': 5}, self.fake_group))
|
|
self.assertTrue(c.match({'foo': 1}, self.fake_group))
|
|
with self.assertRaises(definition.DefinitionError):
|
|
c = definition.NumericCriterion("zazz", "foo")
|
|
with self.assertRaises(definition.DefinitionError):
|
|
c = definition.NumericCriterion("", "foo")
|
|
|
|
def test_float_criterion(self):
|
|
c = definition.FloatCriterion("3.14", 'foo')
|
|
self.assertTrue(c.match({'foo': 3.14}, self.fake_group))
|
|
self.assertFalse(c.match({'foo': 5.2}, self.fake_group))
|
|
self.assertFalse(c.match({'bar': 5.2}, self.fake_group))
|
|
self.assertFalse(c.match({'foo': "booga"}, self.fake_group))
|
|
c = definition.FloatCriterion("> 3.14", 'foo')
|
|
self.assertFalse(c.match({'foo': 3.14}, self.fake_group))
|
|
self.assertTrue(c.match({'foo': 5.2}, self.fake_group))
|
|
c = definition.FloatCriterion("< 3.14", 'foo')
|
|
self.assertFalse(c.match({'foo': 3.14}, self.fake_group))
|
|
self.assertFalse(c.match({'foo': 3.5}, self.fake_group))
|
|
self.assertTrue(c.match({'foo': 3.02}, self.fake_group))
|
|
with self.assertRaises(definition.DefinitionError):
|
|
c = definition.FloatCriterion("zazz", "foo")
|
|
with self.assertRaises(definition.DefinitionError):
|
|
c = definition.FloatCriterion("", "foo")
|
|
|
|
def test_time_criterion(self):
|
|
c = definition.TimeCriterion("day", "foo")
|
|
e = dict(timestamp=datetime.datetime(2014, 8, 1, 7, 52, 31, 2),
|
|
foo=datetime.datetime(2014, 8, 1, 1, 2, 0, 0))
|
|
self.assertTrue(c.match(e, self.fake_group))
|
|
e = dict(timestamp=datetime.datetime(2014, 8, 1, 7, 52, 31, 2),
|
|
foo=datetime.datetime(2014, 8, 2, 1, 2, 0, 0))
|
|
self.assertFalse(c.match(e, self.fake_group))
|
|
e = dict(timestamp=datetime.datetime(2014, 8, 1, 7, 52, 31, 2),
|
|
bar=datetime.datetime(2014, 8, 1, 1, 2, 0, 0))
|
|
self.assertFalse(c.match(e, self.fake_group))
|
|
e = dict(timestamp=datetime.datetime(2014, 8, 1, 7, 52, 31, 2),
|
|
message_id='1234-5678',
|
|
quux=4,
|
|
foo=datetime.datetime(2014, 8, 1, 1, 2, 0, 0))
|
|
self.assertTrue(c.match(e, self.fake_group))
|
|
|
|
|
|
class TestCriteria(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
super(TestCriteria, self).setUp()
|
|
self.fake_group = debugging.NoOpGroup()
|
|
self.fake_debugger = debugging.NoOpDebugger()
|
|
|
|
def test_defaults(self):
|
|
criteria = definition.Criteria({})
|
|
self.assertEqual(len(criteria.included_types), 1)
|
|
self.assertEqual(len(criteria.excluded_types), 0)
|
|
self.assertEqual(criteria.included_types[0], '*')
|
|
self.assertEqual(criteria.number, 1)
|
|
self.assertIsNone(criteria.timestamp)
|
|
self.assertEqual(len(criteria.map_distinguished_by), 0)
|
|
self.assertEqual(len(criteria.traits), 0)
|
|
|
|
def test_event_type_configs(self):
|
|
config = dict(event_type="test.foo.bar")
|
|
criteria = definition.Criteria(config)
|
|
self.assertEqual(len(criteria.included_types), 1)
|
|
self.assertEqual(len(criteria.excluded_types), 0)
|
|
self.assertEqual(criteria.included_types[0], 'test.foo.bar')
|
|
config = dict(event_type="!test.foo.bar")
|
|
criteria = definition.Criteria(config)
|
|
self.assertEqual(len(criteria.included_types), 1)
|
|
self.assertEqual(len(criteria.excluded_types), 1)
|
|
self.assertEqual(criteria.included_types[0], '*')
|
|
self.assertEqual(criteria.excluded_types[0], 'test.foo.bar')
|
|
config = dict(event_type=["test.foo.bar", "!test.wakka.wakka"])
|
|
criteria = definition.Criteria(config)
|
|
self.assertEqual(len(criteria.included_types), 1)
|
|
self.assertEqual(len(criteria.excluded_types), 1)
|
|
self.assertEqual(criteria.included_types[0], 'test.foo.bar')
|
|
self.assertEqual(criteria.excluded_types[0], 'test.wakka.wakka')
|
|
|
|
def test_match_type(self):
|
|
config = dict(event_type=["test.foo.bar", "!test.wakka.wakka"])
|
|
criteria = definition.Criteria(config)
|
|
self.assertTrue(criteria.match_type('test.foo.bar'))
|
|
self.assertFalse(criteria.match_type('test.wakka.wakka'))
|
|
self.assertFalse(criteria.match_type('test.foo.baz'))
|
|
config = dict(event_type=["test.foo.*", "!test.wakka.*"])
|
|
criteria = definition.Criteria(config)
|
|
self.assertTrue(criteria.match_type('test.foo.bar'))
|
|
self.assertTrue(criteria.match_type('test.foo.baz'))
|
|
self.assertFalse(criteria.match_type('test.wakka.wakka'))
|
|
|
|
def test_match_for_type(self):
|
|
config = dict(event_type=["test.foo.*", "!test.wakka.*"])
|
|
criteria = definition.Criteria(config)
|
|
event1 = dict(event_type="test.foo.zazz")
|
|
event2 = dict(event_type="test.wakka.zazz")
|
|
event3 = dict(event_type="test.boingy")
|
|
self.assertTrue(criteria.match(event1, self.fake_group))
|
|
self.assertFalse(criteria.match(event2, self.fake_group))
|
|
self.assertFalse(criteria.match(event3, self.fake_group))
|
|
|
|
def test_match_for_timestamp(self):
|
|
config = dict(timestamp='day($launched_at)')
|
|
criteria = definition.Criteria(config)
|
|
event1 = dict(event_type='test.thing',
|
|
timestamp=datetime.datetime(2014, 8, 1, 17, 16, 15, 14),
|
|
launched_at=datetime.datetime(2014, 8, 1, 1, 2, 3, 4))
|
|
event2 = dict(event_type='test.thing',
|
|
timestamp=datetime.datetime(2014, 8, 2, 17, 16, 15, 14),
|
|
launched_at=datetime.datetime(2014, 8, 1, 1, 2, 3, 4))
|
|
event3 = dict(event_type='test.thing',
|
|
timestamp=datetime.datetime(2014, 8, 2, 17, 16, 15, 14))
|
|
self.assertTrue(criteria.match(event1, self.fake_group))
|
|
self.assertFalse(criteria.match(event2, self.fake_group))
|
|
self.assertFalse(criteria.match(event3, self.fake_group))
|
|
|
|
def test_match_for_traits(self):
|
|
config = dict(traits=dict(some_trait="test",
|
|
launched_at={'datetime': "day"},
|
|
memory_mb={'int': "> 2048"},
|
|
test_weight={'float': "< 4.02"},
|
|
other_trait={'string': 'text here'}))
|
|
criteria = definition.Criteria(config)
|
|
event1 = dict(event_type='test.thing',
|
|
timestamp=datetime.datetime(2014, 8, 1, 17, 16, 15, 14),
|
|
launched_at=datetime.datetime(2014, 8, 1, 1, 2, 3, 4),
|
|
some_trait='test',
|
|
other_trait='text here',
|
|
memory_mb=4096,
|
|
test_weight=3.1415)
|
|
event2 = dict(event_type='test.thing',
|
|
timestamp=datetime.datetime(2014, 8, 1, 17, 16, 15, 14),
|
|
launched_at=datetime.datetime(2014, 8, 1, 1, 2, 3, 4),
|
|
some_trait='foo',
|
|
other_trait='text here',
|
|
memory_mb=4096,
|
|
test_weight=3.1415)
|
|
event3 = dict(event_type='test.thing',
|
|
timestamp=datetime.datetime(2014, 8, 1, 17, 16, 15, 14),
|
|
launched_at=datetime.datetime(2014, 8, 1, 1, 2, 3, 4),
|
|
other_trait='text here',
|
|
memory_mb=4096,
|
|
test_weight=3.1415)
|
|
event4 = dict(event_type='test.thing',
|
|
timestamp=datetime.datetime(2014, 8, 1, 17, 16, 15, 14),
|
|
launched_at=datetime.datetime(2014, 8, 2, 1, 2, 3, 4),
|
|
some_trait='test',
|
|
other_trait='text here',
|
|
memory_mb=4096,
|
|
test_weight=3.1415)
|
|
event5 = dict(event_type='test.thing',
|
|
timestamp=datetime.datetime(2014, 8, 1, 17, 16, 15, 14),
|
|
launched_at=datetime.datetime(2014, 8, 1, 1, 2, 3, 4),
|
|
some_trait='test',
|
|
other_trait='text here',
|
|
memory_mb=1024,
|
|
test_weight=3.1415)
|
|
event6 = dict(event_type='test.thing',
|
|
timestamp=datetime.datetime(2014, 8, 1, 17, 16, 15, 14),
|
|
launched_at=datetime.datetime(2014, 8, 1, 1, 2, 3, 4),
|
|
some_trait='test',
|
|
other_trait='text here',
|
|
memory_mb=4096,
|
|
test_weight=6.283)
|
|
self.assertTrue(criteria.match(event1, self.fake_group))
|
|
self.assertFalse(criteria.match(event2, self.fake_group))
|
|
self.assertFalse(criteria.match(event3, self.fake_group))
|
|
self.assertFalse(criteria.match(event4, self.fake_group))
|
|
self.assertFalse(criteria.match(event5, self.fake_group))
|
|
self.assertFalse(criteria.match(event6, self.fake_group))
|
|
|
|
|
|
class TestTriggerDefinition(unittest.TestCase):
|
|
def setUp(self):
|
|
super(TestTriggerDefinition, self).setUp()
|
|
self.debug_manager = debugging.DebugManager()
|
|
|
|
def test_config_error_check_and_defaults(self):
|
|
with self.assertRaises(definition.DefinitionError):
|
|
definition.TriggerDefinition(dict(), self.debug_manager)
|
|
with self.assertRaises(definition.DefinitionError):
|
|
definition.TriggerDefinition(dict(name='test_trigger'),
|
|
self.debug_manager)
|
|
with self.assertRaises(definition.DefinitionError):
|
|
definition.TriggerDefinition(dict(name='test_trigger',
|
|
expiration='$last + 1d'),
|
|
self.debug_manager)
|
|
with self.assertRaises(definition.DefinitionError):
|
|
definition.TriggerDefinition(dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
fire_pipeline='test_pipeline'),
|
|
self.debug_manager)
|
|
with self.assertRaises(definition.DefinitionError):
|
|
definition.TriggerDefinition(
|
|
dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')]),
|
|
self.debug_manager)
|
|
tdef = definition.TriggerDefinition(
|
|
dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')],
|
|
match_criteria=[dict(event_type='test.*')]),
|
|
self.debug_manager)
|
|
self.assertEqual(len(tdef.distinguished_by), 0)
|
|
self.assertEqual(len(tdef.fire_criteria), 1)
|
|
self.assertIsInstance(tdef.fire_criteria[0], definition.Criteria)
|
|
self.assertEqual(len(tdef.match_criteria), 1)
|
|
self.assertIsInstance(tdef.match_criteria[0], definition.Criteria)
|
|
self.assertEqual(tdef.fire_delay, 0)
|
|
self.assertEqual(len(tdef.load_criteria), 0)
|
|
|
|
def test_match_for_criteria(self):
|
|
config = dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')],
|
|
match_criteria=[dict(event_type='test.*')])
|
|
tdef = definition.TriggerDefinition(config, self.debug_manager)
|
|
event1 = dict(event_type='test.thing')
|
|
event2 = dict(event_type='other.thing')
|
|
self.assertTrue(tdef.match(event1))
|
|
self.assertFalse(tdef.match(event2))
|
|
config = dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')],
|
|
match_criteria=[dict(event_type='test.*'),
|
|
dict(event_type='other.*')])
|
|
tdef = definition.TriggerDefinition(config, self.debug_manager)
|
|
self.assertTrue(tdef.match(event1))
|
|
self.assertTrue(tdef.match(event2))
|
|
|
|
def test_match_for_distinguished_traits(self):
|
|
config = dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
distinguished_by=['instance_id'],
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')],
|
|
match_criteria=[dict(event_type='test.*')])
|
|
tdef = definition.TriggerDefinition(config, self.debug_manager)
|
|
event1 = dict(event_type='test.thing', instance_id='foo')
|
|
event2 = dict(event_type='test.thing')
|
|
self.assertTrue(tdef.match(event1))
|
|
self.assertFalse(tdef.match(event2))
|
|
|
|
def test_get_distinguished_traits(self):
|
|
config = dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
distinguished_by=['instance_id'],
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')],
|
|
match_criteria=[dict(event_type='test.*')])
|
|
event1 = dict(event_type='test.thing', instance_id='foo')
|
|
tdef = definition.TriggerDefinition(config, self.debug_manager)
|
|
mcriteria = tdef.match(event1)
|
|
dt = tdef.get_distinguishing_traits(event1, mcriteria)
|
|
self.assertEqual(len(dt), 1)
|
|
self.assertIn('instance_id', dt)
|
|
self.assertEqual(dt['instance_id'], 'foo')
|
|
|
|
def test_get_distinguished_traits_with_timeexpression(self):
|
|
config = dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
distinguished_by=['instance_id', dict(timestamp='day')],
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')],
|
|
match_criteria=[dict(event_type='test.*')])
|
|
event1 = dict(event_type='test.thing', instance_id='foo',
|
|
timestamp=datetime.datetime(2014, 8, 1, 20, 4, 23, 444))
|
|
tdef = definition.TriggerDefinition(config, self.debug_manager)
|
|
mcriteria = tdef.match(event1)
|
|
dt = tdef.get_distinguishing_traits(event1, mcriteria)
|
|
self.assertEqual(len(dt), 2)
|
|
self.assertIn('instance_id', dt)
|
|
self.assertEqual(dt['instance_id'], 'foo')
|
|
timerange = timex.TimeRange(datetime.datetime(2014, 8, 1, 0, 0, 0, 0),
|
|
datetime.datetime(2014, 8, 2, 0, 0, 0, 0))
|
|
self.assertIn('timestamp', dt)
|
|
self.assertIsInstance(dt['timestamp'], timex.TimeRange)
|
|
self.assertEqual(dt['timestamp'].begin, timerange.begin)
|
|
self.assertEqual(dt['timestamp'].end, timerange.end)
|
|
|
|
def test_get_distinguished_traits_with_map(self):
|
|
config = dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
distinguished_by=['instance_id'],
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')],
|
|
match_criteria=[dict(event_type='test.*',
|
|
map_distinguished_by=dict(
|
|
instance_id='other_id'))])
|
|
event1 = dict(event_type='test.thing', instance_id='foo',
|
|
other_id='bar')
|
|
tdef = definition.TriggerDefinition(config, self.debug_manager)
|
|
mcriteria = tdef.match(event1)
|
|
dt = tdef.get_distinguishing_traits(event1, mcriteria)
|
|
self.assertEqual(len(dt), 1)
|
|
self.assertIn('instance_id', dt)
|
|
self.assertEqual(dt['instance_id'], 'bar')
|
|
|
|
def test_get_fire_timestamp(self):
|
|
config = dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
distinguished_by=['instance_id'],
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')],
|
|
match_criteria=[dict(event_type='test.*')])
|
|
tdef = definition.TriggerDefinition(config, self.debug_manager)
|
|
test_time = datetime.datetime(2014, 8, 1, 20, 4, 23, 444)
|
|
test_time_plus_1hr = datetime.datetime(2014, 8, 1, 21, 4, 23, 444)
|
|
ft = tdef.get_fire_timestamp(test_time)
|
|
self.assertEqual(ft, test_time)
|
|
config = dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
fire_delay=3600,
|
|
distinguished_by=['instance_id'],
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')],
|
|
match_criteria=[dict(event_type='test.*')])
|
|
tdef = definition.TriggerDefinition(config, self.debug_manager)
|
|
ft = tdef.get_fire_timestamp(test_time)
|
|
self.assertEqual(ft, test_time_plus_1hr)
|
|
|
|
def test_should_fire(self):
|
|
config = dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
distinguished_by=['instance_id'],
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing')],
|
|
match_criteria=[dict(event_type='test.*')])
|
|
tdef = definition.TriggerDefinition(config, self.debug_manager)
|
|
events1 = [dict(event_type='test.foobar'),
|
|
dict(event_type='test.thing'),
|
|
dict(event_type='test.thing')]
|
|
events2 = [dict(event_type='test.foobar'),
|
|
dict(event_type='test.thing')]
|
|
events3 = [dict(event_type='test.foobar'),
|
|
dict(event_type='test.whatsit')]
|
|
self.assertTrue(tdef.should_fire(events1))
|
|
self.assertTrue(tdef.should_fire(events2))
|
|
self.assertFalse(tdef.should_fire(events3))
|
|
config = dict(name='test_trigger',
|
|
expiration='$last + 1d',
|
|
distinguished_by=['instance_id'],
|
|
fire_pipeline='test_pipeline',
|
|
fire_criteria=[dict(event_type='test.thing', number=2)],
|
|
match_criteria=[dict(event_type='test.*')])
|
|
tdef = definition.TriggerDefinition(config, self.debug_manager)
|
|
self.assertTrue(tdef.should_fire(events1))
|
|
self.assertFalse(tdef.should_fire(events2))
|
|
self.assertFalse(tdef.should_fire(events3))
|