Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1029)

Side by Side Diff: third_party/twisted_8_1/twisted/conch/test/test_connection.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2007 Twisted Matrix Laboratories.
2 # See LICENSE for details
3
4 """
5 This module tests twisted.conch.ssh.connection.
6 """
7 import struct
8 from twisted.conch import error
9 from twisted.conch.ssh import channel, common, connection
10 from twisted.trial import unittest
11 from twisted.conch.test import test_userauth
12
13 class TestChannel(channel.SSHChannel):
14 """
15 A mocked-up version of twisted.conch.ssh.channel.SSHChannel.
16
17 @ivar gotOpen: True if channelOpen has been called.
18 @type gotOpen: C{bool}
19 @ivar specificData: the specific channel open data passed to channelOpen.
20 @type specificData: C{str}
21 @ivar openFailureReason: the reason passed to openFailed.
22 @type openFailed: C{error.ConchError}
23 @ivar inBuffer: a C{list} of strings received by the channel.
24 @type inBuffer: C{list}
25 @ivar extBuffer: a C{list} of 2-tuples (type, extended data) of received by
26 the channel.
27 @type extBuffer: C{list}
28 @ivar numberRequests: the number of requests that have been made to this
29 channel.
30 @type numberRequests: C{int}
31 @ivar gotEOF: True if the other side sent EOF.
32 @type gotEOF: C{bool}
33 @ivar gotOneClose: True if the other side closed the connection.
34 @type gotOneClose: C{bool}
35 @ivar gotClosed: True if the channel is closed.
36 @type gotClosed: C{bool}
37 """
38 name = "TestChannel"
39 gotOpen = False
40
41 def logPrefix(self):
42 return "TestChannel %i" % self.id
43
44 def channelOpen(self, specificData):
45 """
46 The channel is open. Set up the instance variables.
47 """
48 self.gotOpen = True
49 self.specificData = specificData
50 self.inBuffer = []
51 self.extBuffer = []
52 self.numberRequests = 0
53 self.gotEOF = False
54 self.gotOneClose = False
55 self.gotClosed = False
56
57 def openFailed(self, reason):
58 """
59 Opening the channel failed. Store the reason why.
60 """
61 self.openFailureReason = reason
62
63 def request_test(self, data):
64 """
65 A test request. Return True if data is 'data'.
66
67 @type data: C{str}
68 """
69 self.numberRequests += 1
70 return data == 'data'
71
72 def dataReceived(self, data):
73 """
74 Data was received. Store it in the buffer.
75 """
76 self.inBuffer.append(data)
77
78 def extReceived(self, code, data):
79 """
80 Extended data was received. Store it in the buffer.
81 """
82 self.extBuffer.append((code, data))
83
84 def eofReceived(self):
85 """
86 EOF was received. Remember it.
87 """
88 self.gotEOF = True
89
90 def closeReceived(self):
91 """
92 Close was received. Remember it.
93 """
94 self.gotOneClose = True
95
96 def closed(self):
97 """
98 The channel is closed. Rembember it.
99 """
100 self.gotClosed = True
101
102 class TestAvatar:
103 """
104 A mocked-up version of twisted.conch.avatar.ConchUser
105 """
106
107 def lookupChannel(self, channelType, windowSize, maxPacket, data):
108 """
109 The server wants us to return a channel. If the requested channel is
110 our TestChannel, return it, otherwise return None.
111 """
112 if channelType == TestChannel.name:
113 return TestChannel(remoteWindow=windowSize,
114 remoteMaxPacket=maxPacket,
115 data=data, avatar=self)
116
117 def gotGlobalRequest(self, requestType, data):
118 """
119 The client has made a global request. If the global request is
120 'TestGlobal', return True. If the global request is 'TestData',
121 return True and the request-specific data we received. Otherwise,
122 return False.
123 """
124 if requestType == 'TestGlobal':
125 return True
126 elif requestType == 'TestData':
127 return True, data
128 else:
129 return False
130
131 class TestConnection(connection.SSHConnection):
132 """
133 A subclass of SSHConnection for testing.
134
135 @ivar channel: the current channel.
136 @type channel. C{TestChannel}
137 """
138
139 def logPrefix(self):
140 return "TestConnection"
141
142 def global_TestGlobal(self, data):
143 """
144 The other side made the 'TestGlobal' global request. Return True.
145 """
146 return True
147
148 def global_Test_Data(self, data):
149 """
150 The other side made the 'Test-Data' global request. Return True and
151 the data we received.
152 """
153 return True, data
154
155 def channel_TestChannel(self, windowSize, maxPacket, data):
156 """
157 The other side is requesting the TestChannel. Create a C{TestChannel}
158 instance, store it, and return it.
159 """
160 self.channel = TestChannel(remoteWindow=windowSize,
161 remoteMaxPacket=maxPacket, data=data)
162 return self.channel
163
164 def channel_ErrorChannel(self, windowSize, maxPacket, data):
165 """
166 The other side is requesting the ErrorChannel. Raise an exception.
167 """
168 raise AssertionError('no such thing')
169
170 class ConnectionTestCase(unittest.TestCase):
171
172 def setUp(self):
173 self.transport = test_userauth.FakeTransport(None)
174 self.transport.avatar = TestAvatar()
175 self.conn = TestConnection()
176 self.conn.transport = self.transport
177 self.conn.serviceStarted()
178
179 def _openChannel(self, channel):
180 """
181 Open the channel with the default connection.
182 """
183 self.conn.openChannel(channel)
184 self.transport.packets = self.transport.packets[:-1]
185 self.conn.ssh_CHANNEL_OPEN_CONFIRMATION(struct.pack('>2L',
186 channel.id, 255) + '\x00\x02\x00\x00\x00\x00\x80\x00')
187
188 def tearDown(self):
189 self.conn.serviceStopped()
190
191 def test_linkAvatar(self):
192 """
193 Test that the connection links itself to the avatar in the
194 transport.
195 """
196 self.assertIdentical(self.transport.avatar.conn, self.conn)
197
198 def test_serviceStopped(self):
199 """
200 Test that serviceStopped() closes any open channels.
201 """
202 channel1 = TestChannel()
203 channel2 = TestChannel()
204 self.conn.openChannel(channel1)
205 self.conn.openChannel(channel2)
206 self.conn.ssh_CHANNEL_OPEN_CONFIRMATION('\x00\x00\x00\x00' * 4)
207 self.assertTrue(channel1.gotOpen)
208 self.assertFalse(channel2.gotOpen)
209 self.conn.serviceStopped()
210 self.assertTrue(channel1.gotClosed)
211
212 def test_GLOBAL_REQUEST(self):
213 """
214 Test that global request packets are dispatched to the global_*
215 methods and the return values are translated into success or failure
216 messages.
217 """
218 self.conn.ssh_GLOBAL_REQUEST(common.NS('TestGlobal') + '\xff')
219 self.assertEquals(self.transport.packets,
220 [(connection.MSG_REQUEST_SUCCESS, '')])
221 self.transport.packets = []
222 self.conn.ssh_GLOBAL_REQUEST(common.NS('TestData') + '\xff' +
223 'test data')
224 self.assertEquals(self.transport.packets,
225 [(connection.MSG_REQUEST_SUCCESS, 'test data')])
226 self.transport.packets = []
227 self.conn.ssh_GLOBAL_REQUEST(common.NS('TestBad') + '\xff')
228 self.assertEquals(self.transport.packets,
229 [(connection.MSG_REQUEST_FAILURE, '')])
230 self.transport.packets = []
231 self.conn.ssh_GLOBAL_REQUEST(common.NS('TestGlobal') + '\x00')
232 self.assertEquals(self.transport.packets, [])
233
234 def test_REQUEST_SUCCESS(self):
235 """
236 Test that global request success packets cause the Deferred to be
237 called back.
238 """
239 d = self.conn.sendGlobalRequest('request', 'data', True)
240 self.conn.ssh_REQUEST_SUCCESS('data')
241 def check(data):
242 self.assertEquals(data, 'data')
243 d.addCallback(check)
244 d.addErrback(self.fail)
245 return d
246
247 def test_REQUEST_FAILURE(self):
248 """
249 Test that global request failure packets cause the Deferred to be
250 erred back.
251 """
252 d = self.conn.sendGlobalRequest('request', 'data', True)
253 self.conn.ssh_REQUEST_FAILURE('data')
254 def check(f):
255 self.assertEquals(f.value.data, 'data')
256 d.addCallback(self.fail)
257 d.addErrback(check)
258 return d
259
260 def test_CHANNEL_OPEN(self):
261 """
262 Test that open channel packets cause a channel to be created and
263 opened or a failure message to be returned.
264 """
265 del self.transport.avatar
266 self.conn.ssh_CHANNEL_OPEN(common.NS('TestChannel') +
267 '\x00\x00\x00\x01' * 4)
268 self.assertTrue(self.conn.channel.gotOpen)
269 self.assertEquals(self.conn.channel.conn, self.conn)
270 self.assertEquals(self.conn.channel.data, '\x00\x00\x00\x01')
271 self.assertEquals(self.conn.channel.specificData, '\x00\x00\x00\x01')
272 self.assertEquals(self.conn.channel.remoteWindowLeft, 1)
273 self.assertEquals(self.conn.channel.remoteMaxPacket, 1)
274 self.assertEquals(self.transport.packets,
275 [(connection.MSG_CHANNEL_OPEN_CONFIRMATION,
276 '\x00\x00\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00'
277 '\x00\x00\x80\x00')])
278 self.transport.packets = []
279 self.conn.ssh_CHANNEL_OPEN(common.NS('BadChannel') +
280 '\x00\x00\x00\x02' * 4)
281 self.flushLoggedErrors()
282 self.assertEquals(self.transport.packets,
283 [(connection.MSG_CHANNEL_OPEN_FAILURE,
284 '\x00\x00\x00\x02\x00\x00\x00\x03' + common.NS(
285 'unknown channel') + common.NS(''))])
286 self.transport.packets = []
287 self.conn.ssh_CHANNEL_OPEN(common.NS('ErrorChannel') +
288 '\x00\x00\x00\x02' * 4)
289 self.flushLoggedErrors()
290 self.assertEquals(self.transport.packets,
291 [(connection.MSG_CHANNEL_OPEN_FAILURE,
292 '\x00\x00\x00\x02\x00\x00\x00\x02' + common.NS(
293 'unknown failure') + common.NS(''))])
294
295 def test_CHANNEL_OPEN_CONFIRMATION(self):
296 """
297 Test that channel open confirmation packets cause the channel to be
298 notified that it's open.
299 """
300 channel = TestChannel()
301 self.conn.openChannel(channel)
302 self.conn.ssh_CHANNEL_OPEN_CONFIRMATION('\x00\x00\x00\x00'*5)
303 self.assertEquals(channel.remoteWindowLeft, 0)
304 self.assertEquals(channel.remoteMaxPacket, 0)
305 self.assertEquals(channel.specificData, '\x00\x00\x00\x00')
306 self.assertEquals(self.conn.channelsToRemoteChannel[channel],
307 0)
308 self.assertEquals(self.conn.localToRemoteChannel[0], 0)
309
310 def test_CHANNEL_OPEN_FAILURE(self):
311 """
312 Test that channel open failure packets cause the channel to be
313 notified that its opening failed.
314 """
315 channel = TestChannel()
316 self.conn.openChannel(channel)
317 self.conn.ssh_CHANNEL_OPEN_FAILURE('\x00\x00\x00\x00\x00\x00\x00'
318 '\x01' + common.NS('failure!'))
319 self.assertEquals(channel.openFailureReason.args, ('failure!', 1))
320 self.assertEquals(self.conn.channels.get(channel), None)
321
322
323 def test_CHANNEL_WINDOW_ADJUST(self):
324 """
325 Test that channel window adjust messages add bytes to the channel
326 window.
327 """
328 channel = TestChannel()
329 self._openChannel(channel)
330 oldWindowSize = channel.remoteWindowLeft
331 self.conn.ssh_CHANNEL_WINDOW_ADJUST('\x00\x00\x00\x00\x00\x00\x00'
332 '\x01')
333 self.assertEquals(channel.remoteWindowLeft, oldWindowSize + 1)
334
335 def test_CHANNEL_DATA(self):
336 """
337 Test that channel data messages are passed up to the channel, or
338 cause the channel to be closed if the data is too large.
339 """
340 channel = TestChannel(localWindow=6, localMaxPacket=5)
341 self._openChannel(channel)
342 self.conn.ssh_CHANNEL_DATA('\x00\x00\x00\x00' + common.NS('data'))
343 self.assertEquals(channel.inBuffer, ['data'])
344 self.assertEquals(self.transport.packets,
345 [(connection.MSG_CHANNEL_WINDOW_ADJUST, '\x00\x00\x00\xff'
346 '\x00\x00\x00\x04')])
347 self.transport.packets = []
348 longData = 'a' * (channel.localWindowLeft + 1)
349 self.conn.ssh_CHANNEL_DATA('\x00\x00\x00\x00' + common.NS(longData))
350 self.assertEquals(channel.inBuffer, ['data'])
351 self.assertEquals(self.transport.packets,
352 [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
353 channel = TestChannel()
354 self._openChannel(channel)
355 bigData = 'a' * (channel.localMaxPacket + 1)
356 self.transport.packets = []
357 self.conn.ssh_CHANNEL_DATA('\x00\x00\x00\x01' + common.NS(bigData))
358 self.assertEquals(channel.inBuffer, [])
359 self.assertEquals(self.transport.packets,
360 [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
361
362 def test_CHANNEL_EXTENDED_DATA(self):
363 """
364 Test that channel extended data messages are passed up to the channel,
365 or cause the channel to be closed if they're too big.
366 """
367 channel = TestChannel(localWindow=6, localMaxPacket=5)
368 self._openChannel(channel)
369 self.conn.ssh_CHANNEL_EXTENDED_DATA('\x00\x00\x00\x00\x00\x00\x00'
370 '\x00' + common.NS('data'))
371 self.assertEquals(channel.extBuffer, [(0, 'data')])
372 self.assertEquals(self.transport.packets,
373 [(connection.MSG_CHANNEL_WINDOW_ADJUST, '\x00\x00\x00\xff'
374 '\x00\x00\x00\x04')])
375 self.transport.packets = []
376 longData = 'a' * (channel.localWindowLeft + 1)
377 self.conn.ssh_CHANNEL_EXTENDED_DATA('\x00\x00\x00\x00\x00\x00\x00'
378 '\x00' + common.NS(longData))
379 self.assertEquals(channel.extBuffer, [(0, 'data')])
380 self.assertEquals(self.transport.packets,
381 [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
382 channel = TestChannel()
383 self._openChannel(channel)
384 bigData = 'a' * (channel.localMaxPacket + 1)
385 self.transport.packets = []
386 self.conn.ssh_CHANNEL_EXTENDED_DATA('\x00\x00\x00\x01\x00\x00\x00'
387 '\x00' + common.NS(bigData))
388 self.assertEquals(channel.extBuffer, [])
389 self.assertEquals(self.transport.packets,
390 [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
391
392 def test_CHANNEL_EOF(self):
393 """
394 Test that channel eof messages are passed up to the channel.
395 """
396 channel = TestChannel()
397 self._openChannel(channel)
398 self.conn.ssh_CHANNEL_EOF('\x00\x00\x00\x00')
399 self.assertTrue(channel.gotEOF)
400
401 def test_CHANNEL_CLOSE(self):
402 """
403 Test that channel close messages are passed up to the channel. Also,
404 test that channel.close() is called if both sides are closed when this
405 message is received.
406 """
407 channel = TestChannel()
408 self._openChannel(channel)
409 self.conn.sendClose(channel)
410 self.conn.ssh_CHANNEL_CLOSE('\x00\x00\x00\x00')
411 self.assertTrue(channel.gotOneClose)
412 self.assertTrue(channel.gotClosed)
413
414 def test_CHANNEL_REQUEST_success(self):
415 """
416 Test that channel requests that succeed send MSG_CHANNEL_SUCCESS.
417 """
418 channel = TestChannel()
419 self._openChannel(channel)
420 self.conn.ssh_CHANNEL_REQUEST('\x00\x00\x00\x00' + common.NS('test')
421 + '\x00')
422 self.assertEquals(channel.numberRequests, 1)
423 d = self.conn.ssh_CHANNEL_REQUEST('\x00\x00\x00\x00' + common.NS(
424 'test') + '\xff' + 'data')
425 def check(result):
426 self.assertEquals(self.transport.packets,
427 [(connection.MSG_CHANNEL_SUCCESS, '\x00\x00\x00\xff')])
428 d.addCallback(check)
429 return d
430
431 def test_CHANNEL_REQUEST_failure(self):
432 """
433 Test that channel requests that fail send MSG_CHANNEL_FAILURE.
434 """
435 channel = TestChannel()
436 self._openChannel(channel)
437 d = self.conn.ssh_CHANNEL_REQUEST('\x00\x00\x00\x00' + common.NS(
438 'test') + '\xff')
439 def check(result):
440 self.assertEquals(self.transport.packets,
441 [(connection.MSG_CHANNEL_FAILURE, '\x00\x00\x00\xff'
442 )])
443 d.addCallback(self.fail)
444 d.addErrback(check)
445 return d
446
447 def test_CHANNEL_REQUEST_SUCCESS(self):
448 """
449 Test that channel request success messages cause the Deferred to be
450 called back.
451 """
452 channel = TestChannel()
453 self._openChannel(channel)
454 d = self.conn.sendRequest(channel, 'test', 'data', True)
455 self.conn.ssh_CHANNEL_SUCCESS('\x00\x00\x00\x00')
456 def check(result):
457 self.assertTrue(result)
458 return d
459
460 def test_CHANNEL_REQUEST_FAILURE(self):
461 """
462 Test that channel request failure messages cause the Deferred to be
463 erred back.
464 """
465 channel = TestChannel()
466 self._openChannel(channel)
467 d = self.conn.sendRequest(channel, 'test', '', True)
468 self.conn.ssh_CHANNEL_FAILURE('\x00\x00\x00\x00')
469 def check(result):
470 self.assertEquals(result.value.value, 'channel request failed')
471 d.addCallback(self.fail)
472 d.addErrback(check)
473 return d
474
475 def test_sendGlobalRequest(self):
476 """
477 Test that global request messages are sent in the right format.
478 """
479 d = self.conn.sendGlobalRequest('wantReply', 'data', True)
480 self.conn.sendGlobalRequest('noReply', '', False)
481 self.assertEquals(self.transport.packets,
482 [(connection.MSG_GLOBAL_REQUEST, common.NS('wantReply') +
483 '\xffdata'),
484 (connection.MSG_GLOBAL_REQUEST, common.NS('noReply') +
485 '\x00')])
486 self.assertEquals(self.conn.deferreds, {'global':[d]})
487
488 def test_openChannel(self):
489 """
490 Test that open channel messages are sent in the right format.
491 """
492 channel = TestChannel()
493 self.conn.openChannel(channel, 'aaaa')
494 self.assertEquals(self.transport.packets,
495 [(connection.MSG_CHANNEL_OPEN, common.NS('TestChannel') +
496 '\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x80\x00aaaa')])
497 self.assertEquals(channel.id, 0)
498 self.assertEquals(self.conn.localChannelID, 1)
499
500 def test_sendRequest(self):
501 """
502 Test that channel request messages are sent in the right format.
503 """
504 channel = TestChannel()
505 self._openChannel(channel)
506 d = self.conn.sendRequest(channel, 'test', 'test', True)
507 self.conn.sendRequest(channel, 'test2', '', False)
508 channel.localClosed = True # emulate sending a close message
509 self.conn.sendRequest(channel, 'test3', '', True)
510 self.assertEquals(self.transport.packets,
511 [(connection.MSG_CHANNEL_REQUEST, '\x00\x00\x00\xff' +
512 common.NS('test') + '\x01test'),
513 (connection.MSG_CHANNEL_REQUEST, '\x00\x00\x00\xff' +
514 common.NS('test2') + '\x00')])
515 self.assertEquals(self.conn.deferreds, {0:[d]})
516
517 def test_adjustWindow(self):
518 """
519 Test that channel window adjust messages cause bytes to be added
520 to the window.
521 """
522 channel = TestChannel(localWindow=5)
523 self._openChannel(channel)
524 channel.localWindowLeft = 0
525 self.conn.adjustWindow(channel, 1)
526 self.assertEquals(channel.localWindowLeft, 1)
527 channel.localClosed = True
528 self.conn.adjustWindow(channel, 2)
529 self.assertEquals(channel.localWindowLeft, 1)
530 self.assertEquals(self.transport.packets,
531 [(connection.MSG_CHANNEL_WINDOW_ADJUST, '\x00\x00\x00\xff'
532 '\x00\x00\x00\x01')])
533
534 def test_sendData(self):
535 """
536 Test that channel data messages are sent in the right format.
537 """
538 channel = TestChannel()
539 self._openChannel(channel)
540 self.conn.sendData(channel, 'a')
541 channel.localClosed = True
542 self.conn.sendData(channel, 'b')
543 self.assertEquals(self.transport.packets,
544 [(connection.MSG_CHANNEL_DATA, '\x00\x00\x00\xff' +
545 common.NS('a'))])
546
547 def test_sendExtendedData(self):
548 """
549 Test that channel extended data messages are sent in the right format.
550 """
551 channel = TestChannel()
552 self._openChannel(channel)
553 self.conn.sendExtendedData(channel, 1, 'test')
554 channel.localClosed = True
555 self.conn.sendExtendedData(channel, 2, 'test2')
556 self.assertEquals(self.transport.packets,
557 [(connection.MSG_CHANNEL_EXTENDED_DATA, '\x00\x00\x00\xff' +
558 '\x00\x00\x00\x01' + common.NS('test'))])
559
560 def test_sendEOF(self):
561 """
562 Test that channel EOF messages are sent in the right format.
563 """
564 channel = TestChannel()
565 self._openChannel(channel)
566 self.conn.sendEOF(channel)
567 self.assertEquals(self.transport.packets,
568 [(connection.MSG_CHANNEL_EOF, '\x00\x00\x00\xff')])
569 channel.localClosed = True
570 self.conn.sendEOF(channel)
571 self.assertEquals(self.transport.packets,
572 [(connection.MSG_CHANNEL_EOF, '\x00\x00\x00\xff')])
573
574 def test_sendClose(self):
575 """
576 Test that channel close messages are sent in the right format.
577 """
578 channel = TestChannel()
579 self._openChannel(channel)
580 self.conn.sendClose(channel)
581 self.assertTrue(channel.localClosed)
582 self.assertEquals(self.transport.packets,
583 [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
584 self.conn.sendClose(channel)
585 self.assertEquals(self.transport.packets,
586 [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')])
587
588 channel2 = TestChannel()
589 self._openChannel(channel2)
590 channel2.remoteClosed = True
591 self.conn.sendClose(channel2)
592 self.assertTrue(channel2.gotClosed)
593
594 def test_getChannelWithAvatar(self):
595 """
596 Test that getChannel dispatches to the avatar when an avatar is
597 present. Correct functioning without the avatar is verified in
598 test_CHANNEL_OPEN.
599 """
600 channel = self.conn.getChannel('TestChannel', 50, 30, 'data')
601 self.assertEquals(channel.data, 'data')
602 self.assertEquals(channel.remoteWindowLeft, 50)
603 self.assertEquals(channel.remoteMaxPacket, 30)
604 self.assertRaises(error.ConchError, self.conn.getChannel,
605 'BadChannel', 50, 30, 'data')
606
607 def test_gotGlobalRequestWithoutAvatar(self):
608 """
609 Test that gotGlobalRequests dispatches to global_* without an avatar.
610 """
611 del self.transport.avatar
612 self.assertTrue(self.conn.gotGlobalRequest('TestGlobal', 'data'))
613 self.assertEquals(self.conn.gotGlobalRequest('Test-Data', 'data'),
614 (True, 'data'))
615 self.assertFalse(self.conn.gotGlobalRequest('BadGlobal', 'data'))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698