changeset 88:8ae753a22494

Some refactoring of the BEEP implementation: * Renamed {{{MIMEMessage}}} to {{{Payload}}} * No longer is a subclass of {{{email.Message.Message}}}
author cmlenz
date Thu, 14 Jul 2005 14:20:42 +0000
parents 94b703e2114d
children 7b10a8b2d0c4
files bitten/master.py bitten/slave.py bitten/util/beep.py bitten/util/tests/beep.py
diffstat 4 files changed, 162 insertions(+), 144 deletions(-) [+]
line wrap: on
line diff
--- a/bitten/master.py
+++ b/bitten/master.py
@@ -183,9 +183,9 @@
     def handle_disconnect(self):
         self.master.unregister(self)
 
-    def handle_msg(self, msgno, msg):
-        assert msg.get_content_type() == beep.BEEP_XML
-        elem = xmlio.parse(msg.get_payload())
+    def handle_msg(self, msgno, payload):
+        assert payload.content_type == beep.BEEP_XML
+        elem = xmlio.parse(payload.body)
 
         if elem.name == 'register':
             self.name = elem.attr['name']
@@ -203,27 +203,27 @@
                 xml = xmlio.Element('error', code=550)[
                     'Nothing for you to build here, please move along'
                 ]
-                self.channel.send_err(msgno, beep.MIMEMessage(xml))
+                self.channel.send_err(msgno, beep.Payload(xml))
                 return
 
             xml = xmlio.Element('ok')
-            self.channel.send_rpy(msgno, beep.MIMEMessage(xml))
+            self.channel.send_rpy(msgno, beep.Payload(xml))
 
     def send_initiation(self, build):
         logging.debug('Initiating build of "%s" on slave %s', build.config,
                       self.name)
 
-        def handle_reply(cmd, msgno, ansno, msg):
+        def handle_reply(cmd, msgno, ansno, payload):
             if cmd == 'ERR':
-                if msg.get_content_type() == beep.BEEP_XML:
-                    elem = xmlio.parse(msg.get_payload())
+                if payload.content_type == beep.BEEP_XML:
+                    elem = xmlio.parse(payload.body)
                     if elem.name == 'error':
                         logging.warning('Slave %s refused build request: '
                                         '%s (%d)', self.name, elem.gettext(),
                                         int(elem.attr['code']))
                 return
 
-            elem = xmlio.parse(msg.get_payload())
+            elem = xmlio.parse(payload.body)
             assert elem.name == 'proceed'
             type = encoding = None
             for child in elem.children('accept'):
@@ -238,26 +238,26 @@
                 xml = xmlio.Element('error', code=550)[
                     'None of the accepted archive formats supported'
                 ]
-                self.channel.send_err(beep.MIMEMessage(xml))
+                self.channel.send_err(beep.Payload(xml))
                 return
             self.send_snapshot(build, type, encoding)
 
         xml = xmlio.Element('build', recipe='recipe.xml')
-        self.channel.send_msg(beep.MIMEMessage(xml), handle_reply=handle_reply)
+        self.channel.send_msg(beep.Payload(xml), handle_reply=handle_reply)
 
     def send_snapshot(self, build, type, encoding):
 
-        def handle_reply(cmd, msgno, ansno, msg):
+        def handle_reply(cmd, msgno, ansno, payload):
             if cmd == 'ERR':
-                assert msg.get_content_type() == beep.BEEP_XML
-                elem = xmlio.parse(msg.get_payload())
+                assert payload.content_type == beep.BEEP_XML
+                elem = xmlio.parse(payload.body)
                 if elem.name == 'error':
                     logging.warning('Slave %s did not accept archive: %s (%d)',
                                     self.name, elem.gettext(),
                                     int(elem.attr['code']))
 
             if cmd == 'ANS':
-                elem = xmlio.parse(msg.get_payload())
+                elem = xmlio.parse(payload.body)
 
                 if elem.name == 'started':
                     build.slave = self.name
@@ -308,9 +308,9 @@
         #       asyncore push_with_producer()
         snapshot_path = self.master.get_snapshot(build, type, encoding)
         snapshot_name = os.path.basename(snapshot_path)
-        message = beep.MIMEMessage(file(snapshot_path).read(),
-                                   content_disposition=snapshot_name,
-                                   content_type=type, content_encoding=encoding)
+        message = beep.Payload(file(snapshot_path).read(),
+                               content_disposition=snapshot_name,
+                               content_type=type, content_encoding=encoding)
         self.channel.send_msg(message, handle_reply=handle_reply)
 
 
--- a/bitten/slave.py
+++ b/bitten/slave.py
@@ -55,10 +55,10 @@
         """Register with the build master."""
         self.recipe_path = None
 
-        def handle_reply(cmd, msgno, ansno, msg):
+        def handle_reply(cmd, msgno, ansno, payload):
             if cmd == 'ERR':
-                if msg.get_content_type() == beep.BEEP_XML:
-                    elem = xmlio.parse(msg.get_payload())
+                if payload.content_type == beep.BEEP_XML:
+                    elem = xmlio.parse(payload.body)
                     if elem.name == 'error':
                         logging.error('Slave registration failed: %s (%d)',
                                       elem.gettext(), int(elem.attr['code']))
@@ -75,12 +75,11 @@
             xmlio.Element('platform', processor=processor)[machine],
             xmlio.Element('os', family=os.name, version=release)[system]
         ]
-        self.channel.send_msg(beep.MIMEMessage(xml), handle_reply)
+        self.channel.send_msg(beep.Payload(xml), handle_reply)
 
-    def handle_msg(self, msgno, msg):
-        content_type = msg.get_content_type()
-        if content_type == beep.BEEP_XML:
-            elem = xmlio.parse(msg.get_payload())
+    def handle_msg(self, msgno, payload):
+        if payload.content_type == beep.BEEP_XML:
+            elem = xmlio.parse(payload.body)
             if elem.name == 'build':
                 # Received a build request
                 self.recipe_path = elem.attr['recipe']
@@ -92,26 +91,25 @@
                                   encoding='gzip'),
                     xmlio.Element('accept', type='application/zip')
                 ]
-                self.channel.send_rpy(msgno, beep.MIMEMessage(xml))
+                self.channel.send_rpy(msgno, beep.Payload(xml))
 
-        elif content_type in ('application/tar', 'application/zip'):
+        elif payload.content_type in ('application/tar', 'application/zip'):
             # Received snapshot archive for build
             workdir = tempfile.mkdtemp(prefix='bitten')
 
-            archive_name = msg.get('Content-Disposition')
+            archive_name = payload.content_disposition
             if not archive_name:
-                if content_type == 'application/tar':
-                    encoding = msg.get('Content-Transfer-Encoding')
-                    if encoding == 'gzip':
+                if payload.content_type == 'application/tar':
+                    if payload.content_encoding == 'gzip':
                         archive_name = 'snapshot.tar.gz'
-                    elif encoding == 'bzip2':
+                    elif payload.content_encoding == 'bzip2':
                         archive_name = 'snapshot.tar.bz2'
-                    elif not encoding:
+                    elif not payload.content_encoding:
                         archive_name = 'snapshot.tar'
                 else:
                     archive_name = 'snapshot.zip'
             archive_path = os.path.join(workdir, archive_name)
-            file(archive_path, 'wb').write(msg.get_payload())
+            file(archive_path, 'wb').write(payload.body)
             logging.debug('Received snapshot archive: %s', archive_path)
 
             # Unpack the archive
@@ -135,7 +133,7 @@
             recipe = Recipe(recipe_path, basedir)
 
             xml = xmlio.Element('started', time=datetime.utcnow().isoformat())
-            self.channel.send_ans(msgno, beep.MIMEMessage(xml))
+            self.channel.send_ans(msgno, beep.Payload(xml))
 
             failed = False
             for step in recipe:
@@ -150,7 +148,7 @@
                                         time=started.isoformat(),
                                         duration=duration.seconds)[log]
                     recipe.ctxt._log = []
-                    self.channel.send_ans(msgno, beep.MIMEMessage(xml))
+                    self.channel.send_ans(msgno, beep.Payload(xml))
                 except (BuildError, InvalidRecipeError), e:
                     duration = datetime.utcnow() - started
                     failed = True
@@ -158,24 +156,24 @@
                                         description=step.description,
                                         time=started.isoformat(),
                                         duration=duration.seconds)[e]
-                    self.channel.send_ans(msgno, beep.MIMEMessage(xml))
+                    self.channel.send_ans(msgno, beep.Payload(xml))
 
             logging.info('Build completed')
             recipe.ctxt._log = []
             xml = xmlio.Element('completed', time=datetime.utcnow().isoformat(),
                                 result=['success', 'failure'][failed])
-            self.channel.send_ans(msgno, beep.MIMEMessage(xml))
+            self.channel.send_ans(msgno, beep.Payload(xml))
 
             self.channel.send_nul(msgno)
 
         except InvalidRecipeError, e:
             xml = xmlio.Element('error')[e]
-            self.channel.send_ans(msgno, beep.MIMEMessage(xml))
+            self.channel.send_ans(msgno, beep.Payload(xml))
             self.channel.send_nul(msgno)
 
         except (KeyboardInterrupt, SystemExit), e:
             xml = xmlio.Element('aborted')['Build cancelled']
-            self.channel.send_ans(msgno, beep.MIMEMessage(xml))
+            self.channel.send_ans(msgno, beep.Payload(xml))
             self.channel.send_nul(msgno)
 
             raise beep.TerminateSession, 'Cancelled'
--- a/bitten/util/beep.py
+++ b/bitten/util/beep.py
@@ -31,7 +31,6 @@
 import asyncore
 import bisect
 import email
-from email.Message import Message
 import logging
 import socket
 try:
@@ -43,7 +42,7 @@
 
 from bitten.util import xmlio
 
-__all__ = ['Listener', 'Initiator', 'MIMEMessage', 'ProfileHandler',
+__all__ = ['Listener', 'Initiator', 'Payload', 'ProfileHandler',
            'ProtocolError']
 
 BEEP_XML = 'application/beep+xml'
@@ -450,52 +449,58 @@
         if cmd in ('ERR', 'RPY', 'NUL') and msgno in self.msgnos:
             # Final reply using this message number, so dealloc
             self.msgnos.remove(msgno)
-        message = None
         if payload:
-            message = email.message_from_string(payload)
+            payload = Payload.parse(payload)
+        else:
+            payload = None
 
         if cmd == 'MSG':
-            self.profile.handle_msg(msgno, message)
+            self.profile.handle_msg(msgno, payload)
         else:
             if msgno in self.reply_handlers:
                 try:
-                    self.reply_handlers[msgno](cmd, msgno, ansno, message)
+                    self.reply_handlers[msgno](cmd, msgno, ansno, payload)
                 finally:
                     if cmd != 'ANS':
                         del self.reply_handlers[msgno]
             elif cmd == 'RPY':
-                self.profile.handle_rpy(msgno, message)
+                self.profile.handle_rpy(msgno, payload)
             elif cmd == 'ERR':
-                self.profile.handle_err(msgno, message)
+                self.profile.handle_err(msgno, payload)
             elif cmd == 'ANS':
-                self.profile.handle_ans(msgno, ansno, message)
+                self.profile.handle_ans(msgno, ansno, payload)
             elif cmd == 'NUL':
                 self.profile.handle_nul(msgno)
 
-    def _send(self, cmd, msgno, ansno=None, message=None):
+    def _send(self, cmd, msgno, ansno=None, payload=None):
         """Send a frame to the peer."""
-        payload = ''
-        if message is not None:
-            payload = message.as_string()
+        data = ''
+        if payload is not None:
+            data = payload.as_string()
 
         # If the size of the payload exceeds the current negotiated window size,
         # fragment the message and send in smaller chunks
-        while len(payload) > self.windowsize:
-            window = payload[:self.windowsize]
+        while len(data) > self.windowsize:
+            window = data[:self.windowsize]
             self.session.send_data_frame(cmd, self.channelno, msgno, True,
                                          self.seqno[1].value, payload=window,
                                          ansno=ansno)
             self.seqno[1] += self.windowsize
-            payload = payload[self.windowsize:]
+            data = data[self.windowsize:]
 
         # Send the final frame
         self.session.send_data_frame(cmd, self.channelno, msgno, False,
-                                     self.seqno[1].value, payload=payload,
+                                     self.seqno[1].value, payload=data,
                                      ansno=ansno)
-        self.seqno[1] += len(payload)
+        self.seqno[1] += len(data)
 
-    def send_msg(self, message, handle_reply=None):
-        """Send a MSG frame to the peer."""
+    def send_msg(self, payload, handle_reply=None):
+        """Send a MSG frame to the peer.
+        
+        @param payload: The message payload (a `Payload` instance)
+        @param handle_reply: A function that is called when a reply to this
+                             message is received
+        """
         while True: # Find a unique message number
             msgno = self.msgno.next()
             if msgno not in self.msgnos:
@@ -503,34 +508,34 @@
         self.msgnos.add(msgno) # Flag the chosen message number as in use
         if handle_reply is not None:
             self.reply_handlers[msgno] = handle_reply
-        self._send('MSG', msgno, None, message)
+        self._send('MSG', msgno, None, payload)
         return msgno
 
-    def send_rpy(self, msgno, message):
+    def send_rpy(self, msgno, payload):
         """Send a RPY frame to the peer.
         
         @param msgno: The number of the message this reply is in reference to
-        @param message: The message payload (a `MIMEMessage` instance)
+        @param payload: The message payload (a `Payload` instance)
         """
-        self._send('RPY', msgno, None, message)
+        self._send('RPY', msgno, None, payload)
 
-    def send_err(self, msgno, message):
+    def send_err(self, msgno, payload):
         """Send an ERR frame to the peer.
         
         @param msgno: The number of the message this reply is in reference to
-        @param message: The message payload (a `MIMEMessage` instance)
+        @param payload: The message payload (a `Payload` instance)
         """
-        self._send('ERR', msgno, None, message)
+        self._send('ERR', msgno, None, payload)
 
-    def send_ans(self, msgno, message):
+    def send_ans(self, msgno, payload):
         """Send an ANS frame to the peer.
         
         @param msgno: The number of the message this reply is in reference to
-        @param message: The message payload (a `MIMEMessage` instance)
+        @param payload: The message payload (a `Payload` instance)
         """
         ansnos = self.ansnos.setdefault(msgno, cycle_through(0, 2147483647))
         next_ansno = ansnos.next()
-        self._send('ANS', msgno, next_ansno, message)
+        self._send('ANS', msgno, next_ansno, payload)
         return next_ansno
 
     def send_nul(self, msgno):
@@ -592,12 +597,12 @@
         xml = xmlio.Element('greeting')[
             [xmlio.Element('profile', uri=uri) for uri in profile_uris]
         ]
-        self.channel.send_rpy(0, MIMEMessage(xml))
+        self.channel.send_rpy(0, Payload(xml))
 
     def handle_msg(self, msgno, message):
         """Handle an incoming message."""
-        assert message.get_content_type() == BEEP_XML
-        elem = xmlio.parse(message.get_payload())
+        assert message.content_type == BEEP_XML
+        elem = xmlio.parse(message.body)
 
         if elem.name == 'start':
             channelno = int(elem.attr['number'])
@@ -612,7 +617,7 @@
                                       self.session.profiles[profile.attr['uri']])
                     self.session.channels[channelno] = channel
                     xml = xmlio.Element('profile', uri=profile.attr['uri'])
-                    self.channel.send_rpy(msgno, MIMEMessage(xml))
+                    self.channel.send_rpy(msgno, Payload(xml))
                     return
             self.send_error(msgno, 550,
                             'None of the requested profiles is supported')
@@ -630,14 +635,14 @@
                 self.send_error(msgno, 550, 'Channel waiting for replies')
                 return
             self.session.channels[channelno].close()
-            self.channel.send_rpy(msgno, MIMEMessage(xmlio.Element('ok')))
+            self.channel.send_rpy(msgno, Payload(xmlio.Element('ok')))
             if not self.session.channels:
                 self.session.close()
 
     def handle_rpy(self, msgno, message):
         """Handle a positive reply."""
-        assert message.get_content_type() == BEEP_XML
-        elem = xmlio.parse(message.get_payload())
+        assert message.content_type == BEEP_XML
+        elem = xmlio.parse(message.body)
 
         if elem.name == 'greeting':
             if isinstance(self.session, Initiator):
@@ -652,8 +657,8 @@
         # Probably an error on connect, because other errors should get handled
         # by the corresponding callbacks
         # TODO: Terminate the session, I guess
-        assert message.get_content_type() == BEEP_XML
-        elem = xmlio.parse(message.get_payload())
+        assert message.content_type == BEEP_XML
+        elem = xmlio.parse(message.body)
         assert elem.name == 'error'
         logging.warning('Received error in response to message #%d: %s (%d)',
                         msgno, elem.gettext(), int(elem.attr['code']))
@@ -670,7 +675,7 @@
                 if handle_ok is not None:
                     handle_ok()
             elif cmd == 'ERR':
-                elem = xmlio.parse(message.get_payload())
+                elem = xmlio.parse(message.body)
                 text = elem.gettext()
                 code = int(elem.attr['code'])
                 logging.debug('Peer refused to start channel %d: %s (%d)',
@@ -680,13 +685,13 @@
 
         logging.debug('Requesting closure of channel %d', channelno)
         xml = xmlio.Element('close', number=channelno, code=code)
-        return self.channel.send_msg(MIMEMessage(xml), handle_reply)
+        return self.channel.send_msg(Payload(xml), handle_reply)
 
     def send_error(self, msgno, code, message=''):
         """Send an error reply to the peer."""
         logging.warning('%s (%d)', message, code)
         xml = xmlio.Element('error', code=code)[message]
-        self.channel.send_err(msgno, MIMEMessage(xml))
+        self.channel.send_err(msgno, Payload(xml))
 
     def send_start(self, profiles, handle_ok=None, handle_error=None):
         """Send a request to start a new channel to the peer.
@@ -702,7 +707,7 @@
         channelno = self.session.channelno.next()
         def handle_reply(cmd, msgno, ansno, message):
             if cmd == 'RPY':
-                elem = xmlio.parse(message.get_payload())
+                elem = xmlio.parse(message.body)
                 for cls in [p for p in profiles if p.URI == elem.attr['uri']]:
                     logging.debug('Channel %d started with profile %s',
                                   channelno, elem.attr['uri'])
@@ -712,7 +717,7 @@
                 if handle_ok is not None:
                     handle_ok(channelno, elem.attr['uri'])
             elif cmd == 'ERR':
-                elem = xmlio.parse(message.get_payload())
+                elem = xmlio.parse(message.body)
                 text = elem.gettext()
                 code = int(elem.attr['code'])
                 logging.debug('Peer refused to start channel %d: %s (%d)',
@@ -725,25 +730,40 @@
         xml = xmlio.Element('start', number=channelno)[
             [xmlio.Element('profile', uri=profile.URI) for profile in profiles]
         ]
-        return self.channel.send_msg(MIMEMessage(xml), handle_reply)
+        return self.channel.send_msg(Payload(xml), handle_reply)
 
 
-class MIMEMessage(Message):
-    """Simplified construction of generic MIME messages for transmission as
-    payload with BEEP."""
+class Payload(object):
+    """MIME message for transmission as payload with BEEP."""
 
-    def __init__(self, payload, content_type=BEEP_XML, content_disposition=None,
+    def __init__(self, data, content_type=BEEP_XML, content_disposition=None,
                  content_encoding=None):
-        """Create the MIME message."""
-        Message.__init__(self)
-        if content_type:
-            self.set_type(content_type)
-            del self['MIME-Version']
-        if content_disposition:
-            self['Content-Disposition'] = content_disposition
-        if content_encoding:
-            self['Content-Transfer-Encoding'] = content_encoding
-        self.set_payload(str(payload))
+        """Initialize the payload."""
+        self.content_type = content_type
+        self.content_disposition = content_disposition
+        self.content_encoding = content_encoding
+        self.body = str(data)
+
+    def as_string(self):
+        hdrs = []
+        if self.content_type:
+            hdrs.append('Content-Type: ' + self.content_type)
+        if self.content_disposition:
+            hdrs.append('Content-Disposition: ' + self.content_disposition)
+        if self.content_encoding:
+            hdrs.append('Content-Transfer-Encoding: ' + self.content_encoding)
+        hdrs.append('')
+
+        return '\n'.join(hdrs) + '\n' + self.body
+
+    def parse(cls, string):
+        message = email.message_from_string(string)
+        content_type = message.get('Content-Type')
+        content_disposition = message.get('Content-Disposition')
+        content_encoding = message.get('Content-Transfer-Encoding')
+        return Payload(message.get_payload(), content_type,
+                       content_disposition, content_encoding)
+    parse = classmethod(parse)
 
 
 def cycle_through(start, stop=None, step=1):
--- a/bitten/util/tests/beep.py
+++ b/bitten/util/tests/beep.py
@@ -102,7 +102,7 @@
         corresponding message number (0) is reserved.
         """
         channel = beep.Channel(self.session, 0, MockProfileHandler)
-        msgno = channel.send_msg(beep.MIMEMessage('foo bar', None))
+        msgno = channel.send_msg(beep.Payload('foo bar', None))
         self.assertEqual(('MSG', 0, msgno, False, 0L, None, 'foo bar'),
                          self.session.sent_messages[0])
         assert msgno in channel.msgnos
@@ -113,8 +113,8 @@
         expected.
         """
         channel = beep.Channel(self.session, 0, MockProfileHandler)
-        channel.send_msg(beep.MIMEMessage('foo bar', None))
-        channel.send_rpy(0, beep.MIMEMessage('nil', None))
+        channel.send_msg(beep.Payload('foo bar', None))
+        channel.send_rpy(0, beep.Payload('nil', None))
         self.assertEqual(('MSG', 0, 0, False, 0L, None, 'foo bar'),
                          self.session.sent_messages[0])
         self.assertEqual(('RPY', 0, 0, False, 8L, None, 'nil'),
@@ -126,12 +126,12 @@
         messages.
         """
         channel = beep.Channel(self.session, 0, MockProfileHandler)
-        msgno = channel.send_msg(beep.MIMEMessage('foo bar', None))
+        msgno = channel.send_msg(beep.Payload('foo bar', None))
         assert msgno == 0
         self.assertEqual(('MSG', 0, msgno, False, 0L, None, 'foo bar'),
                          self.session.sent_messages[0])
         assert msgno in channel.msgnos
-        msgno = channel.send_msg(beep.MIMEMessage('foo baz', None))
+        msgno = channel.send_msg(beep.Payload('foo baz', None))
         assert msgno == 1
         self.assertEqual(('MSG', 0, msgno, False, 8L, None, 'foo baz'),
                          self.session.sent_messages[1])
@@ -142,7 +142,7 @@
         Verify that sending an ANS message is processed correctly.
         """
         channel = beep.Channel(self.session, 0, MockProfileHandler)
-        channel.send_rpy(0, beep.MIMEMessage('foo bar', None))
+        channel.send_rpy(0, beep.Payload('foo bar', None))
         self.assertEqual(('RPY', 0, 0, False, 0L, None, 'foo bar'),
                          self.session.sent_messages[0])
 
@@ -152,7 +152,7 @@
         has been received.
         """
         channel = beep.Channel(self.session, 0, MockProfileHandler)
-        msgno = channel.send_msg(beep.MIMEMessage('foo bar', None))
+        msgno = channel.send_msg(beep.Payload('foo bar', None))
         self.assertEqual(('MSG', 0, msgno, False, 0L, None, 'foo bar'),
                          self.session.sent_messages[0])
         assert msgno in channel.msgnos
@@ -167,7 +167,7 @@
         has been received.
         """
         channel = beep.Channel(self.session, 0, MockProfileHandler)
-        msgno = channel.send_msg(beep.MIMEMessage('foo bar', None))
+        msgno = channel.send_msg(beep.Payload('foo bar', None))
         self.assertEqual(('MSG', 0, msgno, False, 0L, None, 'foo bar'),
                          self.session.sent_messages[0])
         assert msgno in channel.msgnos
@@ -182,7 +182,7 @@
         has been received.
         """
         channel = beep.Channel(self.session, 0, MockProfileHandler)
-        msgno = channel.send_msg(beep.MIMEMessage('foo bar', None))
+        msgno = channel.send_msg(beep.Payload('foo bar', None))
         self.assertEqual(('MSG', 0, msgno, False, 0L, None, 'foo bar'),
                          self.session.sent_messages[0])
         assert msgno in channel.msgnos
@@ -200,7 +200,7 @@
         Verify that sending an ERR message is processed correctly.
         """
         channel = beep.Channel(self.session, 0, MockProfileHandler)
-        channel.send_err(0, beep.MIMEMessage('oops', None))
+        channel.send_err(0, beep.Payload('oops', None))
         self.assertEqual(('ERR', 0, 0, False, 0L, None, 'oops'),
                          self.session.sent_messages[0])
 
@@ -209,12 +209,12 @@
         Verify that sending an ANS message is processed correctly.
         """
         channel = beep.Channel(self.session, 0, MockProfileHandler)
-        ansno = channel.send_ans(0, beep.MIMEMessage('foo bar', None))
+        ansno = channel.send_ans(0, beep.Payload('foo bar', None))
         assert ansno == 0
         self.assertEqual(('ANS', 0, 0, False, 0L, ansno, 'foo bar'),
                          self.session.sent_messages[0])
         assert 0 in channel.ansnos
-        ansno = channel.send_ans(0, beep.MIMEMessage('foo baz', None))
+        ansno = channel.send_ans(0, beep.Payload('foo baz', None))
         assert ansno == 1
         self.assertEqual(('ANS', 0, 0, False, 8L, ansno, 'foo baz'),
                          self.session.sent_messages[1])
@@ -240,7 +240,7 @@
         self.profile.handle_connect()
         self.assertEqual(1, len(self.session.sent_messages))
         xml = xmlio.Element('greeting')
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('RPY', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
@@ -255,7 +255,7 @@
         xml = xmlio.Element('greeting')[
             xmlio.Element('profile', uri=MockProfileHandler.URI)
         ]
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('RPY', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
@@ -270,7 +270,7 @@
         greeting_received.called = False
         self.session.greeting_received = greeting_received
         xml = xmlio.Element('greeting')[xmlio.Element('profile', uri='test')]
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.channel.handle_data_frame('RPY', 0, False, 0L, None, message)
         assert greeting_received.called
 
@@ -280,11 +280,11 @@
             xmlio.Element('profile', uri=MockProfileHandler.URI),
             xmlio.Element('profile', uri='http://example.com/bogus')
         ]
-        self.profile.handle_msg(0, beep.MIMEMessage(xml))
+        self.profile.handle_msg(0, beep.Payload(xml))
 
         assert 2 in self.session.channels
         xml = xmlio.Element('profile', uri=MockProfileHandler.URI)
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('RPY', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
@@ -294,13 +294,13 @@
             xmlio.Element('profile', uri='http://example.com/foo'),
             xmlio.Element('profile', uri='http://example.com/bar')
         ]
-        self.profile.handle_msg(0, beep.MIMEMessage(xml))
+        self.profile.handle_msg(0, beep.Payload(xml))
 
         assert 2 not in self.session.channels
         xml = xmlio.Element('error', code=550)[
             'None of the requested profiles is supported'
         ]
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('ERR', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
@@ -312,11 +312,11 @@
         xml = xmlio.Element('start', number=2)[
             xmlio.Element('profile', uri=MockProfileHandler.URI)
         ]
-        self.profile.handle_msg(0, beep.MIMEMessage(xml))
+        self.profile.handle_msg(0, beep.Payload(xml))
 
         assert self.session.channels[2].profile is orig_profile
         xml = xmlio.Element('error', code=550)['Channel already in use']
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('ERR', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
@@ -324,45 +324,45 @@
         self.session.channels[1] = beep.Channel(self.session, 1,
                                                 MockProfileHandler)
         xml = xmlio.Element('close', number=1, code=200)
-        self.profile.handle_msg(0, beep.MIMEMessage(xml))
+        self.profile.handle_msg(0, beep.Payload(xml))
 
         assert 1 not in self.session.channels
         xml = xmlio.Element('ok')
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('RPY', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
     def test_handle_close_session(self):
         xml = xmlio.Element('close', number=0, code=200)
-        self.profile.handle_msg(0, beep.MIMEMessage(xml))
+        self.profile.handle_msg(0, beep.Payload(xml))
 
         assert 1 not in self.session.channels
         xml = xmlio.Element('ok')
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('RPY', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
         assert self.session.closed
 
     def test_handle_close_channel_not_open(self):
         xml = xmlio.Element('close', number=1, code=200)
-        self.profile.handle_msg(0, beep.MIMEMessage(xml))
+        self.profile.handle_msg(0, beep.Payload(xml))
 
         xml = xmlio.Element('error', code=550)['Channel not open']
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('ERR', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
     def test_handle_close_channel_busy(self):
         self.session.channels[1] = beep.Channel(self.session, 1,
                                                 MockProfileHandler)
-        self.session.channels[1].send_msg(beep.MIMEMessage('test'))
+        self.session.channels[1].send_msg(beep.Payload('test'))
         assert self.session.channels[1].msgnos
 
         xml = xmlio.Element('close', number=1, code=200)
-        self.profile.handle_msg(0, beep.MIMEMessage(xml))
+        self.profile.handle_msg(0, beep.Payload(xml))
 
         xml = xmlio.Element('error', code=550)['Channel waiting for replies']
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('ERR', 0, 0, False, 0, None, message),
                          self.session.sent_messages[1])
 
@@ -371,10 +371,10 @@
                                                 MockProfileHandler)
 
         xml = xmlio.Element('close', number=0, code=200)
-        self.profile.handle_msg(0, beep.MIMEMessage(xml))
+        self.profile.handle_msg(0, beep.Payload(xml))
 
         xml = xmlio.Element('error', code=550)['Other channels still open']
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('ERR', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
@@ -384,7 +384,7 @@
         """
         self.profile.send_error(0, 521, 'ouch')
         xml = xmlio.Element('error', code=521)['ouch']
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('ERR', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
@@ -396,7 +396,7 @@
         xml = xmlio.Element('start', number="1")[
             xmlio.Element('profile', uri=MockProfileHandler.URI)
         ]
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('MSG', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
@@ -407,7 +407,7 @@
         """
         self.profile.send_start([MockProfileHandler])
         xml = xmlio.Element('profile', uri=MockProfileHandler.URI)
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.channel.handle_data_frame('RPY', 0, False, 0L, None, message)
         assert isinstance(self.session.channels[1].profile, MockProfileHandler)
 
@@ -418,7 +418,7 @@
         """
         self.profile.send_start([MockProfileHandler])
         xml = xmlio.Element('error', code=500)['ouch']
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.channel.handle_data_frame('ERR', 0, False, 0L, None, message)
         assert 1 not in self.session.channels
 
@@ -439,7 +439,7 @@
                                 handle_error=handle_error)
 
         xml = xmlio.Element('profile', uri=MockProfileHandler.URI)
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.channel.handle_data_frame('RPY', 0, False, 0L, None, message)
         assert isinstance(self.session.channels[1].profile, MockProfileHandler)
         assert handle_ok.called
@@ -462,7 +462,7 @@
                                 handle_error=handle_error)
 
         xml = xmlio.Element('error', code=500)['ouch']
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.channel.handle_data_frame('ERR', 0, False, 0L, None, message)
         assert 1 not in self.session.channels
         assert not handle_ok.called
@@ -474,7 +474,7 @@
         """
         self.profile.send_close(1, code=200)
         xml = xmlio.Element('close', number=1, code=200)
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.assertEqual(('MSG', 0, 0, False, 0, None, message),
                          self.session.sent_messages[0])
 
@@ -488,7 +488,7 @@
         self.profile.send_close(1, code=200)
 
         xml = xmlio.Element('ok')
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.channel.handle_data_frame('RPY', 0, False, 0L, None, message)
         assert 1 not in self.session.channels
 
@@ -500,7 +500,7 @@
         self.profile.send_close(0, code=200)
 
         xml = xmlio.Element('ok')
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.channel.handle_data_frame('RPY', 0, False, 0L, None, message)
         assert 0 not in self.session.channels
         assert self.session.closed
@@ -515,7 +515,7 @@
         self.profile.send_close(1, code=200)
 
         xml = xmlio.Element('error', code=500)['ouch']
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.channel.handle_data_frame('ERR', 0, False, 0L, None, message)
         assert 1 in self.session.channels
 
@@ -536,7 +536,7 @@
                                 handle_error=handle_error)
 
         xml = xmlio.Element('profile', uri=MockProfileHandler.URI)
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.channel.handle_data_frame('RPY', 0, False, 0L, None, message)
         assert 1 not in self.session.channels
         assert handle_ok.called
@@ -561,7 +561,7 @@
                                 handle_error=handle_error)
 
         xml = xmlio.Element('error', code=500)['ouch']
-        message = beep.MIMEMessage(xml).as_string()
+        message = beep.Payload(xml).as_string()
         self.channel.handle_data_frame('ERR', 0, False, 0L, None, message)
         assert 1 in self.session.channels
         assert not handle_ok.called
Copyright (C) 2012-2017 Edgewall Software