From 407a6d9267e3af7de3408e3ca5d54ee09d5bdf51 Mon Sep 17 00:00:00 2001 From: Alexander Maretskiy Date: Wed, 28 Dec 2016 13:07:51 +0200 Subject: [PATCH] Set of small fixes --- notify/api/v1/api.py | 4 +- notify/config.py | 27 +++---- notify/driver.py | 10 +-- .../200/notify_backends.json | 7 +- raml/schemas/post/notify_backends.json | 5 +- test-requirements.txt | 2 +- .../{post_notify_dummy.sh => notify_dummy.sh} | 2 +- tests/unit/drivers/__init__.py | 0 tests/unit/drivers/test_dummy.py | 70 +++++++++++++++++++ tests/unit/test.py | 2 +- 10 files changed, 90 insertions(+), 39 deletions(-) rename tests/tools/{post_notify_dummy.sh => notify_dummy.sh} (76%) create mode 100644 tests/unit/drivers/__init__.py create mode 100644 tests/unit/drivers/test_dummy.py diff --git a/notify/api/v1/api.py b/notify/api/v1/api.py index 06b127a..6d06d32 100644 --- a/notify/api/v1/api.py +++ b/notify/api/v1/api.py @@ -91,8 +91,8 @@ def send_notification(backends): result["result"][backend][drv_name] = {"error": str(e)} result["errors"] += 1 except Exception as e: - LOG.error(("Backend '{}' driver '{}' " - "error: {}").format(backend, drv_name, e)) + LOG.error("Backend '{}' driver '{}': {}: {}".format( + backend, drv_name, type(e), e)) error = "Something has went wrong!" result["result"][backend][drv_name] = {"error": error} result["errors"] += 1 diff --git a/notify/config.py b/notify/config.py index f61b4c0..5254c36 100644 --- a/notify/config.py +++ b/notify/config.py @@ -32,7 +32,8 @@ "type": "elastic", "connection": [{"host": "127.0.0.1", "port": 9200}] }, - "notify_backends": {} + "notify_backends": {}, + "logging": {"level": "INFO"} } CONF_SCHEMA = { @@ -69,23 +70,13 @@ "notify_backends": { "type": "object", "properties": { - "*": { - "type": "object", - "properties": { - "salesforce": { - "type": "object", - "properties": { - "atuh_url": {"type": "string"}, - "username": {"type": "string"}, - "password": {"type": "string"}, - "environment": {"type": "string"}, - "client_id": {"type": "string"}, - "client_secret": {"type": "string"}, - "organization_id": {"type": "string"} - } - } - } - } + "*": {"type": "object"} + } + }, + "logging": { + "type": "object", + "properties": { + "level": {"type": "string"} } } }, diff --git a/notify/driver.py b/notify/driver.py index 4d326e0..d019af3 100644 --- a/notify/driver.py +++ b/notify/driver.py @@ -68,10 +68,7 @@ class Driver(object): "severity": { "enum": ["OK", "INFO", "UNKNOWN", "WARNING", "CRITICAL", "DOWN"]}, - "who": {"type": "array", - "items": {"type": "string"}, - "minItems": 1, - "uniqueItems": True}, + "who": {"type": "string"}, "what": {"type": "string"}, "affected_hosts": {"type": "array"} }, @@ -112,12 +109,11 @@ def __init__(self, config): self.config = config def notify(self, payload): - """Send notification alert. + """Send notification payload. This method must be overriden by specific driver implementation. - :param payload: alert data - :type payload: dict, validated api.PAYLOAD_SCHEMA + :param payload: payload dict, valid for PAYLOAD_SCHEMA :returns: status whether notification is successful :rtype: bool """ diff --git a/raml/response_examples/200/notify_backends.json b/raml/response_examples/200/notify_backends.json index a89edb0..9ff74ba 100644 --- a/raml/response_examples/200/notify_backends.json +++ b/raml/response_examples/200/notify_backends.json @@ -3,14 +3,11 @@ "failed": 1, "passed": 2, "payload": { - "description": "This is a dummy alert, just for testing.", + "description": "This is a dummy payload, just for testing.", "region": "farfaraway", "severity": "INFO", "what": "Hooray!", - "who": [ - "Alice", - "Bob" - ] + "who": "John Doe" }, "result": { "dummy": { diff --git a/raml/schemas/post/notify_backends.json b/raml/schemas/post/notify_backends.json index 31c5f9b..594ee28 100644 --- a/raml/schemas/post/notify_backends.json +++ b/raml/schemas/post/notify_backends.json @@ -8,10 +8,7 @@ "region": {"type": "string"}, "description": {"type": "object"}, "severity": {"enum": ["OK", "INFO", "UNKNOWN", "WARNING", "CRITICAL", "DOWN"]}, - "who": { - "type": "array", - "items": {"type": "string"} - }, + "who": {"type": "string"}, "what": {"type": "string"}, "affected_hosts": {"type": "array"} }, diff --git a/test-requirements.txt b/test-requirements.txt index ceeb3ee..12e9693 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -3,7 +3,7 @@ pytest>=2.7,<=2.9.2 pytest-cov>=2.2.1,<=2.3.0 pytest-html==1.10.1 -coverage>=3.6 +coverage>=3.6,!=4.3.0 ddt>=1.0.1 mock>=2.0 diff --git a/tests/tools/post_notify_dummy.sh b/tests/tools/notify_dummy.sh similarity index 76% rename from tests/tools/post_notify_dummy.sh rename to tests/tools/notify_dummy.sh index fc21877..0c7c4c7 100644 --- a/tests/tools/post_notify_dummy.sh +++ b/tests/tools/notify_dummy.sh @@ -1,7 +1,7 @@ curl -XPOST -H 'Content-Type: application/json' localhost:5000/api/v1/notify/dummy,dummyrand,dummyerr -d ' { "region": "farfaraway", - "description": "This is a dummy alert, just for testing.", + "description": "This is a dummy payload, just for testing.", "severity": "INFO", "who": ["Alice", "Bob"], "what": "Hooray!" diff --git a/tests/unit/drivers/__init__.py b/tests/unit/drivers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/drivers/test_dummy.py b/tests/unit/drivers/test_dummy.py new file mode 100644 index 0000000..f6f9e84 --- /dev/null +++ b/tests/unit/drivers/test_dummy.py @@ -0,0 +1,70 @@ +# Copyright 2016: Mirantis Inc. +# All Rights Reserved. +# +# 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. + +import mock + +from notify import driver +from notify.drivers import dummy_err +from notify.drivers import dummy_err_explained +from notify.drivers import dummy_fail +from notify.drivers import dummy_pass +from notify.drivers import dummy_random +from tests.unit import test + + +class DummyErrDriverTestCase(test.TestCase): + + def test_notify(self): + e = self.assertRaises(ValueError, + dummy_err.Driver({}).notify, self.payload) + self.assertEqual("This error message is for logging only!", str(e)) + + +class DummyErrExplainedDriverTestCase(test.TestCase): + + def test_notify(self): + e = self.assertRaises(driver.ExplainedError, + dummy_err_explained.Driver({}).notify, + self.payload) + self.assertEqual("This error message must appear in API response!", + str(e)) + + +class DummyFailDriverTestCase(test.TestCase): + + def test_notify(self): + self.assertFalse(dummy_fail.Driver({}).notify(self.payload)) + + +class DummyPassDriverTestCase(test.TestCase): + + def test_notify(self): + self.assertTrue(dummy_pass.Driver({}).notify(self.payload)) + + +class DummyRandomDriverTestCase(test.TestCase): + + @mock.patch("notify.drivers.dummy_random.random.random") + def test_notify(self, mock_random): + drv = dummy_random.Driver({}) + + mock_random.return_value = 0.49 + self.assertTrue(drv.notify(self.payload)) + + mock_random.return_value = 0.51 + self.assertFalse(drv.notify(self.payload)) + + drv = dummy_random.Driver({"probability": 0.53}) + self.assertTrue(drv.notify(self.payload)) diff --git a/tests/unit/test.py b/tests/unit/test.py index 0236590..5735431 100644 --- a/tests/unit/test.py +++ b/tests/unit/test.py @@ -31,7 +31,7 @@ def setUp(self): "region": "farfaraway", "severity": "INFO", "what": "Hooray!", - "who": ["Alice", "Bob"]} + "who": "John Doe"} def get(self, *args, **kwargs): rv = self.client.get(*args, **kwargs)