def testTruncatedDecode(self): """Test that we signal not-enough on truncated decodes.""" for cmd, args in sample_msgs: r = codec.encode_msg(cmd, **args) r = r[:-1] self.assertRaises(codec.MilterIncomplete, codec.decode_msg, r)
def testMessageEncode(self): """Can we encode every sample message to a non-zero message that has the cmd code as its fifth character?""" for cmd, args in sample_msgs: r = codec.encode_msg(cmd, **args) self.assertNotEqual(len(r), 0) self.assertTrue(len(r) >= 5) self.assertEqual(r[4], cmd) if not args: self.assertEqual(len(r), 5)
def recv(self, nbytes): self._verify_conv(READ) # nbytes should be at least as large as what we are # scheduled to send. _, obj = self.conv[self.cindex] self.cindex += 1 if isinstance(obj, (list, tuple)): obj = codec.encode_msg(obj[0], **obj[1]) if (len(obj) > nbytes): raise ConvError("short read") return obj
def testBrokenCommands(self): """Sleazily test that we signal errors on malformed packets.""" # Encode something that has no arguments. r = codec.encode_msg('A') # Break the command byte to something that doesn't exist. r = r[:4] + '!' self.assertRaises(codec.MilterDecodeError, codec.decode_msg, r) # Break the command byte to something that requires arguments. r = r[:4] + 'D' self.assertRaises(codec.MilterDecodeError, codec.decode_msg, r)
def testExtraLength(self): """Sleazily test that messages with extra packet data fail to decode.""" for cmd, args in sample_msgs: # We can't shorten or grow SMFIC_BODY or # SMFIR_REPLYBODY messages. if cmd in (SMFIC_BODY, SMFIR_REPLBODY): continue r = codec.encode_msg(cmd, **args) # remember: we've got to supply the actual extra # data, or we just get a 'message incomplete' note. r = self._changelen(r, +10) + ("*" * 10) self.assertRaises(codec.MilterDecodeError, codec.decode_msg, r)
def testMessageDecode(self): """Test that encoded messages decode back to something that is identical to what we started with.""" suffix = "\nabc" for cmd, args in sample_msgs: r = codec.encode_msg(cmd, **args) dcmd, dargs, rest = codec.decode_msg(r) self.assertEqual(cmd, dcmd) self.assertEqual(args, dargs) self.assertEqual(rest, '') # As a bonus, test that decoding with more data works # right for all messages. dcmd, dargs, rest = codec.decode_msg(r + suffix) self.assertEqual(rest, suffix)
def testShortReads(self): """Test that we correctly read multiple times to reassemble a short message, and that we get the right answer.""" ams = SMFIC_CONNECT adict = { 'hostname': 'localhost', 'family': '4', 'port': 1678, 'address': '127.10.10.1' } msg = codec.encode_msg(ams, **adict) msg1, msg2 = msg[:10], msg[10:] s = FakeSocket() s.addRead(msg1); s.addRead(msg2) mbuf = convo.BufferedMilter(s) rcmd, rdict = mbuf.get_msg() self.assertEqual(ams, rcmd) self.assertEqual(adict, rdict) self.assertTrue(s.isEmpty())
def testBrokenLength(self): """Sleazily test for a too-short version of every message.""" minlen = struct.pack("!L", 1) for cmd, args in sample_msgs: # We can't shorten a message that has no arguments. if not args: continue # We can't shorten or grow SMFIC_BODY or # SMFIR_REPLYBODY messages. if cmd in (SMFIC_BODY, SMFIR_REPLBODY): continue r = codec.encode_msg(cmd, **args) r = self._changelen(r, -1) self.assertRaises(codec.MilterDecodeError, codec.decode_msg, r) # See what happens with a minimum-length message. r = minlen + r[4:] self.assertRaises(codec.MilterDecodeError, codec.decode_msg, r)
def send(self, cmd, **args): """Send an encoded milter message. The arguments are the same arguments that codec.encode_msg() takes.""" self.sock.sendall(codec.encode_msg(cmd, **args))
def addReadMsg(self, cmd, **args): """Add a message to be read; arguments are as per encode_msg.""" self._add(READ, codec.encode_msg(cmd, **args))