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