from __future__ import absolute_import import json import locale import os import tempfile import time import unittest import mock import six import koji import koji.util from .loadkojid import kojid class MyClientSession(koji.ClientSession): def __init__(self, *a, **kw): super(MyClientSession, self).__init__(*a, **kw) self._testcalls = {} def load_calls(self, name): fn = os.path.join(os.path.dirname(__file__), 'data/calls', name,'calls.json') data = koji.load_json(fn) for call in data: key = self._munge([call['method'], call['args'], call['kwargs']]) self._testcalls[key] = call def _callMethod(self, name, args, kwargs=None, retry=True): if self.multicall: raise Exception('multicall not supported') key = self._munge([name, args, kwargs]) if key in self._testcalls: return self._testcalls[key]['result'] else: return mock.MagicMock() def _munge(self, data): def callback(value): if isinstance(value, list): return tuple(value) elif isinstance(value, dict): keys = sorted(value.keys()) return tuple([(k, value[k]) for k in keys]) else: return value walker = koji.util.DataWalker(data, callback) return walker.walk() class TestBuildNotification(unittest.TestCase): def setUp(self): self.maxDiff = None self.original_timezone = os.environ.get('TZ') os.environ['TZ'] = 'US/Eastern' time.tzset() self.tempdir = tempfile.mkdtemp() self.SMTP = mock.patch('smtplib.SMTP').start() self.session = mock.MagicMock() self.options = mock.MagicMock() self.options.topdir = self.tempdir self.options.workdir = self.tempdir def tearDown(self): if self.original_timezone is None: del os.environ['TZ'] else: os.environ['TZ'] = self.original_timezone time.tzset() mock.patch.stopall() def test_build_notification(self): # force locale to compare 'message' value locale.setlocale(locale.LC_ALL, ('en_US', 'UTF-8')) # task_info['id'], method, params, self.session, self.options task_id = 999 fn = os.path.join(os.path.dirname(__file__), 'data/calls', 'build_notif_1', 'params.json') kwargs = koji.load_json(fn) self.session = MyClientSession('https://koji.example.com/kojihub') self.session.load_calls('build_notif_1') self.options.from_addr = "koji@example.com" server = mock.MagicMock() self.SMTP.return_value = server # run it handler = kojid.BuildNotificationTask( task_id, 'buildNotification', koji.encode_args(**kwargs), self.session, self.options) ret = handler.run() self.assertEqual(ret, "sent notification of build 612609 to: user@example.com") # check sendmail args from_addr, recipients, message = server.sendmail.call_args[0] self.assertEqual(from_addr, "koji@example.com") self.assertEqual(recipients, ["user@example.com"]) fn = os.path.join(os.path.dirname(__file__), 'data/calls', 'build_notif_1', 'message.txt') with open(fn, 'rb') as fp: msg_expect = fp.read() if six.PY2: msg_expect = msg_expect.decode() self.assertMultiLineEqual(message.decode(), msg_expect.decode()) locale.resetlocale()