From 260a68fd9a3271b7b1e4bfc616fd57de27331e41 Mon Sep 17 00:00:00 2001 From: Michael Krotscheck Date: Mon, 11 May 2015 09:16:16 -0700 Subject: [PATCH] Revert "Email Send Cron Worker" This reverts commit 264d6f82883ef51f94186fde7044a1ec24ed2699. Change-Id: I2bd4a7ef0b6d18e600c9270fcd4a2b5291163f84 --- setup.cfg | 1 - storyboard/plugin/email/workers.py | 78 ---------- storyboard/tests/plugin/email/test_workers.py | 143 ------------------ 3 files changed, 222 deletions(-) delete mode 100644 storyboard/plugin/email/workers.py delete mode 100644 storyboard/tests/plugin/email/test_workers.py diff --git a/setup.cfg b/setup.cfg index 538de1bf..70ae06e8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,7 +40,6 @@ storyboard.plugin.user_preferences = email = storyboard.plugin.email.preferences:EmailPreferences storyboard.plugin.scheduler = token-cleaner = storyboard.plugin.token_cleaner.cleaner:TokenCleaner - email-sender = storyboard.plugin.email.workers:EmailSender [build_sphinx] source-dir = doc/source diff --git a/storyboard/plugin/email/workers.py b/storyboard/plugin/email/workers.py deleted file mode 100644 index a826548f..00000000 --- a/storyboard/plugin/email/workers.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright (c) 2015 Hewlett-Packard Development Company, L.P. -# -# 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 pytz -import smtplib - -from apscheduler.triggers.interval import IntervalTrigger -from oslo_log import log - -from storyboard.plugin.email.base import EmailPluginBase -from storyboard.plugin.email.outbox import get_outbox -from storyboard.plugin.email.smtp_client import get_smtp_client -from storyboard.plugin.scheduler.base import SchedulerPluginBase - -LOG = log.getLogger(__name__) - - -class EmailSender(SchedulerPluginBase, EmailPluginBase): - """A Cron Plugin which goes through all email messages that have been - written to the outbox in its provided time interval, and sends them using - the email sender. - """ - - def trigger(self): - """This plugin executes every minute. APScheduler will collate the - executions of this plugin, so there will be no overlap between - executions. - """ - return IntervalTrigger(minutes=1, timezone=pytz.utc) - - def run(self): - """Send all the messages between the given timestamps. If a message - cannot be sent, or if the sender is not retrievable, - then discard all messages - we don't want to build up a massive - backlog and then spam people. - """ - - # Try to send email. - try: - with get_outbox() as outbox: - with get_smtp_client() as smtp_client: - for key, message in outbox.iteritems(): - from_addr = message.get('From') - to_addrs = message.get('To') - - try: - smtp_client.sendmail(from_addr=from_addr, - to_addrs=to_addrs, - msg=message.as_string()) - except smtplib.SMTPException as e: - LOG.error( - 'Cannot send email, discarding: %s' % (e,)) - finally: - outbox.discard(key) - except Exception as e: - LOG.error("Error while trying to send email.") - LOG.error(e) - - # After everything's said and done, clear out anything that hasn't - # been handled. - try: - with get_outbox() as outbox: - for key, message in outbox.iteritems(): - outbox.discard(key) - except Exception as e: - LOG.error("Unable to flush remaining emails.", e) diff --git a/storyboard/tests/plugin/email/test_workers.py b/storyboard/tests/plugin/email/test_workers.py deleted file mode 100644 index 0ed4931c..00000000 --- a/storyboard/tests/plugin/email/test_workers.py +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright (c) 2015 Hewlett-Packard Development Company, L.P. -# -# 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 email -from mock import patch -from random import random -import smtplib - -from oslo_config import cfg - -from storyboard.plugin.email.factory import EmailFactory -from storyboard.plugin.email.outbox import Outbox -from storyboard.plugin.email.workers import EmailSender -from storyboard.tests import base - - -CONF = cfg.CONF - - -class TestEmailSender(base.WorkingDirTestCase): - """Test the email sender plugin. Makes use of the dummy smtp sender.""" - - def setUp(self): - """Add messages to the outbox. Note that the outbox directory will be - deleted when the working directory is cleared in the parent test class. - """ - super(TestEmailSender, self).setUp() - - # Build a test outbox. - outbox = Outbox() - self.assertIsNotNone(outbox) - - factory = EmailFactory('test@example.org', - 'test_subject', - 'test.txt', - 'plugin.email') - # Generate 25 emails that are now-ish - for i in range(0, 25): - recipient = 'test_%s@example.com' % (i,) - message = factory.build(recipient, test_parameter=i) - outbox.add(message) - - # Generate 25 emails that are in the 0-60 timeframe. - for i in range(0, 25): - recipient = 'test_%s@example.com' % (i,) - message = factory.build(recipient, test_parameter=i) - - # Override the date header with our actual date + some random - # seconds, so that all timestamps fall between 1 and 59 - message.replace_header('Date', - email.utils.formatdate(1 + (random() * 58))) - outbox.add(message) - outbox.flush() - - def test_trigger(self): - """Assert that the this plugin runs every minute.""" - plugin = EmailSender(CONF) - trigger = plugin.trigger() - - self.assertEqual(60, trigger.interval_length) - - @patch('storyboard.plugin.email.workers.get_smtp_client') - def test_failing_sender_causes_flush(self, get_smtp_client): - """Assert that running against a failing sender causes no errors, - and discards all messages, so we don't build up a massive send queue. - """ - - # Raise an exception when this is called. - get_smtp_client.side_effect = smtplib.SMTPException - - # Run the plugin. - plugin = EmailSender(CONF) - plugin.run() - - # Read the outbox, making sure there's no messages left. - outbox = Outbox() - self.assertEqual(0, len(outbox)) - - @patch('mock_smtp.DummySMTP.sendmail') - def test_successful_run(self, mock_sendmail): - """Assert that running with a valid sender and outbox sends all the - messages in the provided time frame, and leaves other messages alone. - """ - - # Run the plugin. - plugin = EmailSender(CONF) - plugin.run() - - # The outbox should be clean. - outbox = Outbox() - self.assertEqual(0, len(outbox)) - - # The dummy SMTP library should have received 50 messages. - self.assertEqual(50, mock_sendmail.call_count) - - @patch('mock_smtp.DummySMTP.sendmail') - def test_badly_formatted_email_causes_flush(self, mock_sendmail): - """Assert that a message that would otherwise cause a send exceptoin - creates no side_effect, and flushes the message from the queue. - """ - - # Create a sideffect - mock_sendmail.side_effect = smtplib.SMTPException - - # Run the plugin. - plugin = EmailSender(CONF) - plugin.run() - - # Read the outbox, making sure that all messages have been flushed. - outbox = Outbox() - self.assertEqual(0, len(outbox)) - - # Assert that the sendmail message was called 50 times. - self.assertEqual(50, mock_sendmail.call_count) - - @patch('storyboard.plugin.email.workers.get_outbox') - def test_failing_outbox_causes_no_side_effects(self, mock_get_outbox): - """Assert that running with a valid sender but invalid outbox does - nothing, since we can't get at any messages. - """ - - # Raise an exception when this is called. - mock_get_outbox.side_effect = OSError - - # Run the plugin. - plugin = EmailSender(CONF) - plugin.run() - - # Read the outbox, making sure we still have 50 messages (since the - # outbox was never accessible via the context handler. - outbox = Outbox() - self.assertEqual(50, len(outbox))