##// END OF EJS Templates
Added test_send_raw() for issue #4839, see pull request 4840
Doug Blank -
Show More
@@ -1,289 +1,315 b''
1 """test building messages with streamsession"""
1 """test building messages with streamsession"""
2
2
3 #-------------------------------------------------------------------------------
3 #-------------------------------------------------------------------------------
4 # Copyright (C) 2011 The IPython Development Team
4 # Copyright (C) 2011 The IPython Development Team
5 #
5 #
6 # Distributed under the terms of the BSD License. The full license is in
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
7 # the file COPYING, distributed as part of this software.
8 #-------------------------------------------------------------------------------
8 #-------------------------------------------------------------------------------
9
9
10 #-------------------------------------------------------------------------------
10 #-------------------------------------------------------------------------------
11 # Imports
11 # Imports
12 #-------------------------------------------------------------------------------
12 #-------------------------------------------------------------------------------
13
13
14 import os
14 import os
15 import uuid
15 import uuid
16 from datetime import datetime
16 from datetime import datetime
17
17
18 import zmq
18 import zmq
19
19
20 from zmq.tests import BaseZMQTestCase
20 from zmq.tests import BaseZMQTestCase
21 from zmq.eventloop.zmqstream import ZMQStream
21 from zmq.eventloop.zmqstream import ZMQStream
22
22
23 from IPython.kernel.zmq import session as ss
23 from IPython.kernel.zmq import session as ss
24
24
25 from IPython.testing.decorators import skipif, module_not_available
25 from IPython.testing.decorators import skipif, module_not_available
26 from IPython.utils.py3compat import string_types
26 from IPython.utils.py3compat import string_types
27 from IPython.utils import jsonutil
27 from IPython.utils import jsonutil
28
28
29 def _bad_packer(obj):
29 def _bad_packer(obj):
30 raise TypeError("I don't work")
30 raise TypeError("I don't work")
31
31
32 def _bad_unpacker(bytes):
32 def _bad_unpacker(bytes):
33 raise TypeError("I don't work either")
33 raise TypeError("I don't work either")
34
34
35 class SessionTestCase(BaseZMQTestCase):
35 class SessionTestCase(BaseZMQTestCase):
36
36
37 def setUp(self):
37 def setUp(self):
38 BaseZMQTestCase.setUp(self)
38 BaseZMQTestCase.setUp(self)
39 self.session = ss.Session()
39 self.session = ss.Session()
40
40
41
41
42 class TestSession(SessionTestCase):
42 class TestSession(SessionTestCase):
43
43
44 def test_msg(self):
44 def test_msg(self):
45 """message format"""
45 """message format"""
46 msg = self.session.msg('execute')
46 msg = self.session.msg('execute')
47 thekeys = set('header parent_header metadata content msg_type msg_id'.split())
47 thekeys = set('header parent_header metadata content msg_type msg_id'.split())
48 s = set(msg.keys())
48 s = set(msg.keys())
49 self.assertEqual(s, thekeys)
49 self.assertEqual(s, thekeys)
50 self.assertTrue(isinstance(msg['content'],dict))
50 self.assertTrue(isinstance(msg['content'],dict))
51 self.assertTrue(isinstance(msg['metadata'],dict))
51 self.assertTrue(isinstance(msg['metadata'],dict))
52 self.assertTrue(isinstance(msg['header'],dict))
52 self.assertTrue(isinstance(msg['header'],dict))
53 self.assertTrue(isinstance(msg['parent_header'],dict))
53 self.assertTrue(isinstance(msg['parent_header'],dict))
54 self.assertTrue(isinstance(msg['msg_id'],str))
54 self.assertTrue(isinstance(msg['msg_id'],str))
55 self.assertTrue(isinstance(msg['msg_type'],str))
55 self.assertTrue(isinstance(msg['msg_type'],str))
56 self.assertEqual(msg['header']['msg_type'], 'execute')
56 self.assertEqual(msg['header']['msg_type'], 'execute')
57 self.assertEqual(msg['msg_type'], 'execute')
57 self.assertEqual(msg['msg_type'], 'execute')
58
58
59 def test_serialize(self):
59 def test_serialize(self):
60 msg = self.session.msg('execute', content=dict(a=10, b=1.1))
60 msg = self.session.msg('execute', content=dict(a=10, b=1.1))
61 msg_list = self.session.serialize(msg, ident=b'foo')
61 msg_list = self.session.serialize(msg, ident=b'foo')
62 ident, msg_list = self.session.feed_identities(msg_list)
62 ident, msg_list = self.session.feed_identities(msg_list)
63 new_msg = self.session.unserialize(msg_list)
63 new_msg = self.session.unserialize(msg_list)
64 self.assertEqual(ident[0], b'foo')
64 self.assertEqual(ident[0], b'foo')
65 self.assertEqual(new_msg['msg_id'],msg['msg_id'])
65 self.assertEqual(new_msg['msg_id'],msg['msg_id'])
66 self.assertEqual(new_msg['msg_type'],msg['msg_type'])
66 self.assertEqual(new_msg['msg_type'],msg['msg_type'])
67 self.assertEqual(new_msg['header'],msg['header'])
67 self.assertEqual(new_msg['header'],msg['header'])
68 self.assertEqual(new_msg['content'],msg['content'])
68 self.assertEqual(new_msg['content'],msg['content'])
69 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
69 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
70 self.assertEqual(new_msg['metadata'],msg['metadata'])
70 self.assertEqual(new_msg['metadata'],msg['metadata'])
71 # ensure floats don't come out as Decimal:
71 # ensure floats don't come out as Decimal:
72 self.assertEqual(type(new_msg['content']['b']),type(new_msg['content']['b']))
72 self.assertEqual(type(new_msg['content']['b']),type(new_msg['content']['b']))
73
73
74 def test_send(self):
74 def test_send(self):
75 ctx = zmq.Context.instance()
75 ctx = zmq.Context.instance()
76 A = ctx.socket(zmq.PAIR)
76 A = ctx.socket(zmq.PAIR)
77 B = ctx.socket(zmq.PAIR)
77 B = ctx.socket(zmq.PAIR)
78 A.bind("inproc://test")
78 A.bind("inproc://test")
79 B.connect("inproc://test")
79 B.connect("inproc://test")
80
80
81 msg = self.session.msg('execute', content=dict(a=10))
81 msg = self.session.msg('execute', content=dict(a=10))
82 self.session.send(A, msg, ident=b'foo', buffers=[b'bar'])
82 self.session.send(A, msg, ident=b'foo', buffers=[b'bar'])
83
83
84 ident, msg_list = self.session.feed_identities(B.recv_multipart())
84 ident, msg_list = self.session.feed_identities(B.recv_multipart())
85 new_msg = self.session.unserialize(msg_list)
85 new_msg = self.session.unserialize(msg_list)
86 self.assertEqual(ident[0], b'foo')
86 self.assertEqual(ident[0], b'foo')
87 self.assertEqual(new_msg['msg_id'],msg['msg_id'])
87 self.assertEqual(new_msg['msg_id'],msg['msg_id'])
88 self.assertEqual(new_msg['msg_type'],msg['msg_type'])
88 self.assertEqual(new_msg['msg_type'],msg['msg_type'])
89 self.assertEqual(new_msg['header'],msg['header'])
89 self.assertEqual(new_msg['header'],msg['header'])
90 self.assertEqual(new_msg['content'],msg['content'])
90 self.assertEqual(new_msg['content'],msg['content'])
91 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
91 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
92 self.assertEqual(new_msg['metadata'],msg['metadata'])
92 self.assertEqual(new_msg['metadata'],msg['metadata'])
93 self.assertEqual(new_msg['buffers'],[b'bar'])
93 self.assertEqual(new_msg['buffers'],[b'bar'])
94
94
95 content = msg['content']
95 content = msg['content']
96 header = msg['header']
96 header = msg['header']
97 parent = msg['parent_header']
97 parent = msg['parent_header']
98 metadata = msg['metadata']
98 metadata = msg['metadata']
99 msg_type = header['msg_type']
99 msg_type = header['msg_type']
100 self.session.send(A, None, content=content, parent=parent,
100 self.session.send(A, None, content=content, parent=parent,
101 header=header, metadata=metadata, ident=b'foo', buffers=[b'bar'])
101 header=header, metadata=metadata, ident=b'foo', buffers=[b'bar'])
102 ident, msg_list = self.session.feed_identities(B.recv_multipart())
102 ident, msg_list = self.session.feed_identities(B.recv_multipart())
103 new_msg = self.session.unserialize(msg_list)
103 new_msg = self.session.unserialize(msg_list)
104 self.assertEqual(ident[0], b'foo')
104 self.assertEqual(ident[0], b'foo')
105 self.assertEqual(new_msg['msg_id'],msg['msg_id'])
105 self.assertEqual(new_msg['msg_id'],msg['msg_id'])
106 self.assertEqual(new_msg['msg_type'],msg['msg_type'])
106 self.assertEqual(new_msg['msg_type'],msg['msg_type'])
107 self.assertEqual(new_msg['header'],msg['header'])
107 self.assertEqual(new_msg['header'],msg['header'])
108 self.assertEqual(new_msg['content'],msg['content'])
108 self.assertEqual(new_msg['content'],msg['content'])
109 self.assertEqual(new_msg['metadata'],msg['metadata'])
109 self.assertEqual(new_msg['metadata'],msg['metadata'])
110 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
110 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
111 self.assertEqual(new_msg['buffers'],[b'bar'])
111 self.assertEqual(new_msg['buffers'],[b'bar'])
112
112
113 self.session.send(A, msg, ident=b'foo', buffers=[b'bar'])
113 self.session.send(A, msg, ident=b'foo', buffers=[b'bar'])
114 ident, new_msg = self.session.recv(B)
114 ident, new_msg = self.session.recv(B)
115 self.assertEqual(ident[0], b'foo')
115 self.assertEqual(ident[0], b'foo')
116 self.assertEqual(new_msg['msg_id'],msg['msg_id'])
116 self.assertEqual(new_msg['msg_id'],msg['msg_id'])
117 self.assertEqual(new_msg['msg_type'],msg['msg_type'])
117 self.assertEqual(new_msg['msg_type'],msg['msg_type'])
118 self.assertEqual(new_msg['header'],msg['header'])
118 self.assertEqual(new_msg['header'],msg['header'])
119 self.assertEqual(new_msg['content'],msg['content'])
119 self.assertEqual(new_msg['content'],msg['content'])
120 self.assertEqual(new_msg['metadata'],msg['metadata'])
120 self.assertEqual(new_msg['metadata'],msg['metadata'])
121 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
121 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
122 self.assertEqual(new_msg['buffers'],[b'bar'])
122 self.assertEqual(new_msg['buffers'],[b'bar'])
123
123
124 A.close()
124 A.close()
125 B.close()
125 B.close()
126 ctx.term()
126 ctx.term()
127
127
128 def test_args(self):
128 def test_args(self):
129 """initialization arguments for Session"""
129 """initialization arguments for Session"""
130 s = self.session
130 s = self.session
131 self.assertTrue(s.pack is ss.default_packer)
131 self.assertTrue(s.pack is ss.default_packer)
132 self.assertTrue(s.unpack is ss.default_unpacker)
132 self.assertTrue(s.unpack is ss.default_unpacker)
133 self.assertEqual(s.username, os.environ.get('USER', u'username'))
133 self.assertEqual(s.username, os.environ.get('USER', u'username'))
134
134
135 s = ss.Session()
135 s = ss.Session()
136 self.assertEqual(s.username, os.environ.get('USER', u'username'))
136 self.assertEqual(s.username, os.environ.get('USER', u'username'))
137
137
138 self.assertRaises(TypeError, ss.Session, pack='hi')
138 self.assertRaises(TypeError, ss.Session, pack='hi')
139 self.assertRaises(TypeError, ss.Session, unpack='hi')
139 self.assertRaises(TypeError, ss.Session, unpack='hi')
140 u = str(uuid.uuid4())
140 u = str(uuid.uuid4())
141 s = ss.Session(username=u'carrot', session=u)
141 s = ss.Session(username=u'carrot', session=u)
142 self.assertEqual(s.session, u)
142 self.assertEqual(s.session, u)
143 self.assertEqual(s.username, u'carrot')
143 self.assertEqual(s.username, u'carrot')
144
144
145 def test_tracking(self):
145 def test_tracking(self):
146 """test tracking messages"""
146 """test tracking messages"""
147 a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR)
147 a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR)
148 s = self.session
148 s = self.session
149 s.copy_threshold = 1
149 s.copy_threshold = 1
150 stream = ZMQStream(a)
150 stream = ZMQStream(a)
151 msg = s.send(a, 'hello', track=False)
151 msg = s.send(a, 'hello', track=False)
152 self.assertTrue(msg['tracker'] is ss.DONE)
152 self.assertTrue(msg['tracker'] is ss.DONE)
153 msg = s.send(a, 'hello', track=True)
153 msg = s.send(a, 'hello', track=True)
154 self.assertTrue(isinstance(msg['tracker'], zmq.MessageTracker))
154 self.assertTrue(isinstance(msg['tracker'], zmq.MessageTracker))
155 M = zmq.Message(b'hi there', track=True)
155 M = zmq.Message(b'hi there', track=True)
156 msg = s.send(a, 'hello', buffers=[M], track=True)
156 msg = s.send(a, 'hello', buffers=[M], track=True)
157 t = msg['tracker']
157 t = msg['tracker']
158 self.assertTrue(isinstance(t, zmq.MessageTracker))
158 self.assertTrue(isinstance(t, zmq.MessageTracker))
159 self.assertRaises(zmq.NotDone, t.wait, .1)
159 self.assertRaises(zmq.NotDone, t.wait, .1)
160 del M
160 del M
161 t.wait(1) # this will raise
161 t.wait(1) # this will raise
162
162
163
163
164 def test_unique_msg_ids(self):
164 def test_unique_msg_ids(self):
165 """test that messages receive unique ids"""
165 """test that messages receive unique ids"""
166 ids = set()
166 ids = set()
167 for i in range(2**12):
167 for i in range(2**12):
168 h = self.session.msg_header('test')
168 h = self.session.msg_header('test')
169 msg_id = h['msg_id']
169 msg_id = h['msg_id']
170 self.assertTrue(msg_id not in ids)
170 self.assertTrue(msg_id not in ids)
171 ids.add(msg_id)
171 ids.add(msg_id)
172
172
173 def test_feed_identities(self):
173 def test_feed_identities(self):
174 """scrub the front for zmq IDENTITIES"""
174 """scrub the front for zmq IDENTITIES"""
175 theids = "engine client other".split()
175 theids = "engine client other".split()
176 content = dict(code='whoda',stuff=object())
176 content = dict(code='whoda',stuff=object())
177 themsg = self.session.msg('execute',content=content)
177 themsg = self.session.msg('execute',content=content)
178 pmsg = theids
178 pmsg = theids
179
179
180 def test_session_id(self):
180 def test_session_id(self):
181 session = ss.Session()
181 session = ss.Session()
182 # get bs before us
182 # get bs before us
183 bs = session.bsession
183 bs = session.bsession
184 us = session.session
184 us = session.session
185 self.assertEqual(us.encode('ascii'), bs)
185 self.assertEqual(us.encode('ascii'), bs)
186 session = ss.Session()
186 session = ss.Session()
187 # get us before bs
187 # get us before bs
188 us = session.session
188 us = session.session
189 bs = session.bsession
189 bs = session.bsession
190 self.assertEqual(us.encode('ascii'), bs)
190 self.assertEqual(us.encode('ascii'), bs)
191 # change propagates:
191 # change propagates:
192 session.session = 'something else'
192 session.session = 'something else'
193 bs = session.bsession
193 bs = session.bsession
194 us = session.session
194 us = session.session
195 self.assertEqual(us.encode('ascii'), bs)
195 self.assertEqual(us.encode('ascii'), bs)
196 session = ss.Session(session='stuff')
196 session = ss.Session(session='stuff')
197 # get us before bs
197 # get us before bs
198 self.assertEqual(session.bsession, session.session.encode('ascii'))
198 self.assertEqual(session.bsession, session.session.encode('ascii'))
199 self.assertEqual(b'stuff', session.bsession)
199 self.assertEqual(b'stuff', session.bsession)
200
200
201 def test_zero_digest_history(self):
201 def test_zero_digest_history(self):
202 session = ss.Session(digest_history_size=0)
202 session = ss.Session(digest_history_size=0)
203 for i in range(11):
203 for i in range(11):
204 session._add_digest(uuid.uuid4().bytes)
204 session._add_digest(uuid.uuid4().bytes)
205 self.assertEqual(len(session.digest_history), 0)
205 self.assertEqual(len(session.digest_history), 0)
206
206
207 def test_cull_digest_history(self):
207 def test_cull_digest_history(self):
208 session = ss.Session(digest_history_size=100)
208 session = ss.Session(digest_history_size=100)
209 for i in range(100):
209 for i in range(100):
210 session._add_digest(uuid.uuid4().bytes)
210 session._add_digest(uuid.uuid4().bytes)
211 self.assertTrue(len(session.digest_history) == 100)
211 self.assertTrue(len(session.digest_history) == 100)
212 session._add_digest(uuid.uuid4().bytes)
212 session._add_digest(uuid.uuid4().bytes)
213 self.assertTrue(len(session.digest_history) == 91)
213 self.assertTrue(len(session.digest_history) == 91)
214 for i in range(9):
214 for i in range(9):
215 session._add_digest(uuid.uuid4().bytes)
215 session._add_digest(uuid.uuid4().bytes)
216 self.assertTrue(len(session.digest_history) == 100)
216 self.assertTrue(len(session.digest_history) == 100)
217 session._add_digest(uuid.uuid4().bytes)
217 session._add_digest(uuid.uuid4().bytes)
218 self.assertTrue(len(session.digest_history) == 91)
218 self.assertTrue(len(session.digest_history) == 91)
219
219
220 def test_bad_pack(self):
220 def test_bad_pack(self):
221 try:
221 try:
222 session = ss.Session(pack=_bad_packer)
222 session = ss.Session(pack=_bad_packer)
223 except ValueError as e:
223 except ValueError as e:
224 self.assertIn("could not serialize", str(e))
224 self.assertIn("could not serialize", str(e))
225 self.assertIn("don't work", str(e))
225 self.assertIn("don't work", str(e))
226 else:
226 else:
227 self.fail("Should have raised ValueError")
227 self.fail("Should have raised ValueError")
228
228
229 def test_bad_unpack(self):
229 def test_bad_unpack(self):
230 try:
230 try:
231 session = ss.Session(unpack=_bad_unpacker)
231 session = ss.Session(unpack=_bad_unpacker)
232 except ValueError as e:
232 except ValueError as e:
233 self.assertIn("could not handle output", str(e))
233 self.assertIn("could not handle output", str(e))
234 self.assertIn("don't work either", str(e))
234 self.assertIn("don't work either", str(e))
235 else:
235 else:
236 self.fail("Should have raised ValueError")
236 self.fail("Should have raised ValueError")
237
237
238 def test_bad_packer(self):
238 def test_bad_packer(self):
239 try:
239 try:
240 session = ss.Session(packer=__name__ + '._bad_packer')
240 session = ss.Session(packer=__name__ + '._bad_packer')
241 except ValueError as e:
241 except ValueError as e:
242 self.assertIn("could not serialize", str(e))
242 self.assertIn("could not serialize", str(e))
243 self.assertIn("don't work", str(e))
243 self.assertIn("don't work", str(e))
244 else:
244 else:
245 self.fail("Should have raised ValueError")
245 self.fail("Should have raised ValueError")
246
246
247 def test_bad_unpacker(self):
247 def test_bad_unpacker(self):
248 try:
248 try:
249 session = ss.Session(unpacker=__name__ + '._bad_unpacker')
249 session = ss.Session(unpacker=__name__ + '._bad_unpacker')
250 except ValueError as e:
250 except ValueError as e:
251 self.assertIn("could not handle output", str(e))
251 self.assertIn("could not handle output", str(e))
252 self.assertIn("don't work either", str(e))
252 self.assertIn("don't work either", str(e))
253 else:
253 else:
254 self.fail("Should have raised ValueError")
254 self.fail("Should have raised ValueError")
255
255
256 def test_bad_roundtrip(self):
256 def test_bad_roundtrip(self):
257 with self.assertRaises(ValueError):
257 with self.assertRaises(ValueError):
258 session = ss.Session(unpack=lambda b: 5)
258 session = ss.Session(unpack=lambda b: 5)
259
259
260 def _datetime_test(self, session):
260 def _datetime_test(self, session):
261 content = dict(t=datetime.now())
261 content = dict(t=datetime.now())
262 metadata = dict(t=datetime.now())
262 metadata = dict(t=datetime.now())
263 p = session.msg('msg')
263 p = session.msg('msg')
264 msg = session.msg('msg', content=content, metadata=metadata, parent=p['header'])
264 msg = session.msg('msg', content=content, metadata=metadata, parent=p['header'])
265 smsg = session.serialize(msg)
265 smsg = session.serialize(msg)
266 msg2 = session.unserialize(session.feed_identities(smsg)[1])
266 msg2 = session.unserialize(session.feed_identities(smsg)[1])
267 assert isinstance(msg2['header']['date'], datetime)
267 assert isinstance(msg2['header']['date'], datetime)
268 self.assertEqual(msg['header'], msg2['header'])
268 self.assertEqual(msg['header'], msg2['header'])
269 self.assertEqual(msg['parent_header'], msg2['parent_header'])
269 self.assertEqual(msg['parent_header'], msg2['parent_header'])
270 self.assertEqual(msg['parent_header'], msg2['parent_header'])
270 self.assertEqual(msg['parent_header'], msg2['parent_header'])
271 assert isinstance(msg['content']['t'], datetime)
271 assert isinstance(msg['content']['t'], datetime)
272 assert isinstance(msg['metadata']['t'], datetime)
272 assert isinstance(msg['metadata']['t'], datetime)
273 assert isinstance(msg2['content']['t'], string_types)
273 assert isinstance(msg2['content']['t'], string_types)
274 assert isinstance(msg2['metadata']['t'], string_types)
274 assert isinstance(msg2['metadata']['t'], string_types)
275 self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content']))
275 self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content']))
276 self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content']))
276 self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content']))
277
277
278 def test_datetimes(self):
278 def test_datetimes(self):
279 self._datetime_test(self.session)
279 self._datetime_test(self.session)
280
280
281 def test_datetimes_pickle(self):
281 def test_datetimes_pickle(self):
282 session = ss.Session(packer='pickle')
282 session = ss.Session(packer='pickle')
283 self._datetime_test(session)
283 self._datetime_test(session)
284
284
285 @skipif(module_not_available('msgpack'))
285 @skipif(module_not_available('msgpack'))
286 def test_datetimes_msgpack(self):
286 def test_datetimes_msgpack(self):
287 session = ss.Session(packer='msgpack.packb', unpacker='msgpack.unpackb')
287 session = ss.Session(packer='msgpack.packb', unpacker='msgpack.unpackb')
288 self._datetime_test(session)
288 self._datetime_test(session)
289
289
290 def test_send_raw(self):
291 ctx = zmq.Context.instance()
292 A = ctx.socket(zmq.PAIR)
293 B = ctx.socket(zmq.PAIR)
294 A.bind("inproc://test")
295 B.connect("inproc://test")
296
297 msg = self.session.msg('execute', content=dict(a=10))
298 msg_list = [self.session.pack(msg[part]) for part in
299 ['header', 'parent_header', 'metadata', 'content']]
300 print("old:", msg_list)
301 self.session.send_raw(A, msg_list, ident=b'foo')
302
303 ident, new_msg_list = self.session.feed_identities(B.recv_multipart())
304 print("new:", new_msg_list)
305 new_msg = self.session.unserialize(new_msg_list)
306 self.assertEqual(ident[0], b'foo')
307 self.assertEqual(new_msg['msg_type'],msg['msg_type'])
308 self.assertEqual(new_msg['header'],msg['header'])
309 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
310 self.assertEqual(new_msg['content'],msg['content'])
311 self.assertEqual(new_msg['metadata'],msg['metadata'])
312
313 A.close()
314 B.close()
315 ctx.term()
General Comments 0
You need to be logged in to leave comments. Login now