1from PyObjCTools.TestSupport import * 2from CoreFoundation import * 3import errno, time, os, socket, sys 4 5from test_cfsocket import onTheNetwork 6 7 8class TestStream (TestCase): 9 def testTypes(self): 10 self.assertIsCFType(CFReadStreamRef) 11 self.assertIsCFType(CFWriteStreamRef) 12 13 def testConstants(self): 14 self.assertEqual(kCFStreamStatusNotOpen , 0) 15 self.assertEqual(kCFStreamStatusOpening , 1) 16 self.assertEqual(kCFStreamStatusOpen , 2) 17 self.assertEqual(kCFStreamStatusReading , 3) 18 self.assertEqual(kCFStreamStatusWriting , 4) 19 self.assertEqual(kCFStreamStatusAtEnd , 5) 20 self.assertEqual(kCFStreamStatusClosed , 6) 21 self.assertEqual(kCFStreamStatusError , 7) 22 self.assertEqual(kCFStreamEventNone , 0) 23 self.assertEqual(kCFStreamEventOpenCompleted , 1) 24 self.assertEqual(kCFStreamEventHasBytesAvailable , 2) 25 self.assertEqual(kCFStreamEventCanAcceptBytes , 4) 26 self.assertEqual(kCFStreamEventErrorOccurred , 8) 27 self.assertEqual(kCFStreamEventEndEncountered , 16) 28 self.assertEqual(kCFStreamErrorDomainCustom , -1) 29 self.assertEqual(kCFStreamErrorDomainPOSIX , 1) 30 self.assertEqual(kCFStreamErrorDomainMacOSStatus , 2) 31 self.assertIsInstance(kCFStreamPropertyDataWritten, unicode) 32 self.assertIsInstance(kCFStreamPropertyAppendToFile, unicode) 33 self.assertIsInstance(kCFStreamPropertyFileCurrentOffset, unicode) 34 self.assertIsInstance(kCFStreamPropertySocketNativeHandle, unicode) 35 self.assertIsInstance(kCFStreamPropertySocketRemoteHostName, unicode) 36 self.assertIsInstance(kCFStreamPropertySocketRemotePortNumber, unicode) 37 38 def testStructs(self): 39 o = CFStreamError() 40 self.assertHasAttr(o, 'domain') 41 self.assertHasAttr(o, 'error') 42 43 def testGetTypeID(self): 44 v = CFReadStreamGetTypeID() 45 self.assertIsInstance(v, (int, long)) 46 v = CFWriteStreamGetTypeID() 47 self.assertIsInstance(v, (int, long)) 48 49 def testReadStream(self): 50 strval = b"hello world" 51 self.assertArgHasType(CFReadStreamCreateWithBytesNoCopy, 1, b'n^v') 52 self.assertArgSizeInArg(CFReadStreamCreateWithBytesNoCopy, 1, 2) 53 stream = CFReadStreamCreateWithBytesNoCopy(None, 54 strval, len(strval), kCFAllocatorNull) 55 self.assertIsInstance(stream, CFReadStreamRef) 56 r, buf = CFReadStreamRead(stream, None, 10) 57 self.assertEqual(r, -1) 58 self.assertEqual(buf, b'') 59 60 self.assertResultIsCFRetained(CFReadStreamCopyError) 61 err = CFReadStreamCopyError(stream) 62 if err is not None: 63 self.assertIsInstance(err, CFErrorRef) 64 status = CFReadStreamGetStatus(stream) 65 self.assertIsInstance(status, (int, long)) 66 self.assertEqual(status, kCFStreamStatusNotOpen) 67 68 self.assertResultIsBOOL(CFReadStreamOpen) 69 r = CFReadStreamOpen(stream) 70 self.assertIs(r, True) 71 status = CFReadStreamGetStatus(stream) 72 self.assertIsInstance(status, (int, long)) 73 self.assertEqual(status, kCFStreamStatusOpen) 74 75 self.assertResultIsBOOL(CFReadStreamHasBytesAvailable) 76 r = CFReadStreamHasBytesAvailable(stream) 77 self.assertIs(r, True) 78 self.assertArgHasType(CFReadStreamRead, 1, b'o^v') 79 self.assertArgSizeInArg(CFReadStreamRead, 1, 2) 80 self.assertArgSizeInResult(CFReadStreamRead, 1) 81 r, buf = CFReadStreamRead(stream, None, 5) 82 self.assertEqual(r, 5) 83 self.assertEqual(buf, b"hello") 84 85 r, buf = CFReadStreamRead(stream, None, 10) 86 self.assertEqual(r, 6) 87 self.assertEqual(buf, b" world") 88 89 r = CFReadStreamHasBytesAvailable(stream) 90 self.assertIs(r, False) 91 r = CFReadStreamClose(stream) 92 self.assertIs(r, None) 93 status = CFReadStreamGetStatus(stream) 94 self.assertIsInstance(status, (int, long)) 95 self.assertEqual(status, kCFStreamStatusClosed) 96 97 98 del stream 99 100 self.assertResultIsCFRetained(CFReadStreamCreateWithFile) 101 stream = CFReadStreamCreateWithFile(None, 102 CFURLCreateWithString(None, u"file:///etc/shells", None)) 103 self.assertIsInstance(stream, CFReadStreamRef) 104 r = CFReadStreamOpen(stream) 105 self.assertIs(r, True) 106 status = CFReadStreamGetStatus(stream) 107 self.assertIsInstance(status, (int, long)) 108 self.assertEqual(status, kCFStreamStatusOpen) 109 110 r, buf = CFReadStreamRead(stream, None, 5) 111 self.assertEqual(r, 5) 112 self.assertIsInstance(buf, bytes) 113 self.assertResultSizeInArg(CFReadStreamGetBuffer, 2) 114 self.assertResultHasType(CFReadStreamGetBuffer, b'^v') 115 self.assertArgIsOut(CFReadStreamGetBuffer, 2) 116 buf, numBytes = CFReadStreamGetBuffer(stream, 20, None) 117 if buf is objc.NULL: 118 self.assertEqual(numBytes, 0) 119 else: 120 self.assertIsInstance(buf, str) 121 self.assertEqual(numBytes, len(buf)) 122 123 val = CFReadStreamCopyProperty(stream, kCFStreamPropertyFileCurrentOffset) 124 self.assertEqual(val, 5) 125 126 r = CFReadStreamSetProperty(stream, kCFStreamPropertyFileCurrentOffset, 10) 127 self.assertIs(r, True) 128 val = CFReadStreamCopyProperty(stream, kCFStreamPropertyFileCurrentOffset) 129 self.assertEqual(val, 10) 130 131 err = CFReadStreamGetError(stream) 132 self.assertIsInstance(err, CFStreamError) 133 self.assertEqual(err.domain , 0) 134 self.assertEqual(err.error , 0) 135 def testWriteStream(self): 136 import array 137 a = array.array('b', b" "*20) 138 139 # XXX: cannot express the actual type as metadata :-( 140 self.assertArgHasType(CFWriteStreamCreateWithBuffer, 1, b'n^v') 141 self.assertArgSizeInArg(CFWriteStreamCreateWithBuffer, 1, 2) 142 stream = CFWriteStreamCreateWithBuffer(None, a, 20) 143 self.assertIsInstance(stream, CFWriteStreamRef) 144 self.assertResultIsBOOL(CFWriteStreamOpen) 145 r = CFWriteStreamOpen(stream) 146 self.assertIs(r, True) 147 status = CFWriteStreamGetStatus(stream) 148 self.assertIsInstance(status, (int, long)) 149 self.assertEqual(status, kCFStreamStatusOpen) 150 151 self.assertResultIsBOOL(CFWriteStreamCanAcceptBytes) 152 b = CFWriteStreamCanAcceptBytes(stream) 153 self.assertIs(b, True) 154 self.assertArgHasType(CFWriteStreamWrite, 1, b'n^v') 155 self.assertArgSizeInArg(CFWriteStreamWrite, 1, 2) 156 n = CFWriteStreamWrite(stream, b"0123456789ABCDE", 15) 157 self.assertEqual(n, 15) 158 159 if sys.version_info[0] == 3: 160 self.assertEqual(bytes(a[0:1]), b'0') 161 self.assertEqual(bytes(a[1:2]), b'1') 162 self.assertEqual(bytes(a[9:10]), b'9') 163 else: 164 self.assertEqual((a[0]), ord('0')) 165 self.assertEqual((a[1]), ord('1')) 166 self.assertEqual((a[9]), ord('9')) 167 168 n = CFWriteStreamWrite(stream, b"0123456789ABCDE", 15) 169 self.assertEqual(n, -1) 170 171 err = CFWriteStreamCopyError(stream) 172 self.assertIsInstance(err, CFErrorRef) 173 err = CFWriteStreamGetError(stream) 174 self.assertIsInstance(err, CFStreamError) 175 self.assertEqual(err.domain , kCFStreamErrorDomainPOSIX) 176 self.assertEqual(err.error , errno.ENOMEM) 177 status = CFWriteStreamGetStatus(stream) 178 self.assertIsInstance(status, (int, long)) 179 self.assertEqual(status, kCFStreamStatusError) 180 181 182 del stream 183 184 185 self.assertResultIsCFRetained(CFWriteStreamCreateWithAllocatedBuffers) 186 stream = CFWriteStreamCreateWithAllocatedBuffers(None, None) 187 self.assertIsInstance(stream, CFWriteStreamRef) 188 r = CFWriteStreamOpen(stream) 189 self.assertIs(r, True) 190 n = CFWriteStreamWrite(stream, b"0123456789ABCDE", 15) 191 self.assertEqual(n, 15) 192 193 self.assertResultIsCFRetained(CFWriteStreamCopyProperty) 194 buf = CFWriteStreamCopyProperty(stream, kCFStreamPropertyDataWritten) 195 self.assertIsInstance(buf, CFDataRef) 196 buf = CFDataGetBytes(buf, (0, CFDataGetLength(buf)), None) 197 self.assertIsInstance(buf, bytes) 198 self.assertEqual(buf, b'0123456789ABCDE') 199 200 CFWriteStreamClose(stream) 201 status = CFWriteStreamGetStatus(stream) 202 self.assertIsInstance(status, (int, long)) 203 self.assertEqual(status, kCFStreamStatusClosed) 204 205 del stream 206 207 208 stream = CFWriteStreamCreateWithFile(None, 209 CFURLCreateWithString(None, u"file:///tmp/pyobjc.test.txt", None)) 210 self.assertIsInstance(stream, CFWriteStreamRef) 211 r = CFWriteStreamOpen(stream) 212 self.assertIs(r, True) 213 n = CFWriteStreamWrite(stream, b"0123456789ABCDE", 15) 214 self.assertEqual(n, 15) 215 216 self.assertResultIsCFRetained(CFReadStreamCopyProperty) 217 val = CFReadStreamCopyProperty(stream, kCFStreamPropertyFileCurrentOffset) 218 self.assertEqual(val, 15) 219 220 self.assertResultIsBOOL(CFReadStreamSetProperty) 221 r = CFReadStreamSetProperty(stream, kCFStreamPropertyFileCurrentOffset, 10) 222 self.assertIs(r, True) 223 val = CFReadStreamCopyProperty(stream, kCFStreamPropertyFileCurrentOffset) 224 self.assertEqual(val, 10) 225 226 CFWriteStreamClose(stream) 227 status = CFWriteStreamGetStatus(stream) 228 self.assertIsInstance(status, (int, long)) 229 self.assertEqual(status, kCFStreamStatusClosed) 230 231 self.assertResultIsBOOL(CFWriteStreamSetProperty) 232 CFWriteStreamSetProperty(stream, kCFStreamPropertyFileCurrentOffset, 0) 233 234 data = open('/tmp/pyobjc.test.txt', 'rb').read() 235 self.assertEqual(data, b'0123456789ABCDE') 236 os.unlink('/tmp/pyobjc.test.txt') 237 238 def testStreamPair(self): 239 240 self.assertArgIsOut(CFStreamCreateBoundPair, 1) 241 self.assertArgIsOut(CFStreamCreateBoundPair, 2) 242 readStream, writeStream = CFStreamCreateBoundPair(None, None, None, 1024*1024) 243 self.assertIsInstance(readStream, CFReadStreamRef) 244 self.assertIsInstance(writeStream, CFWriteStreamRef) 245 # Make sure we actually have streams instead of random pointers. 246 status = CFReadStreamGetStatus(readStream) 247 self.assertIsInstance(status, (int, long)) 248 self.assertEqual(status, kCFStreamStatusNotOpen) 249 250 status = CFWriteStreamGetStatus(writeStream) 251 self.assertIsInstance(status, (int, long)) 252 self.assertEqual(status, kCFStreamStatusNotOpen) 253 254 del readStream, writeStream 255 256 @onlyIf(onTheNetwork) 257 def testSockets(self): 258 sd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 259 sd.connect(('www.apple.com', 80)) 260 261 self.assertArgIsOut(CFStreamCreatePairWithSocket, 2) 262 self.assertArgIsOut(CFStreamCreatePairWithSocket, 3) 263 readStream, writeStream = CFStreamCreatePairWithSocket(None, 264 sd.fileno(), None, None) 265 266 status = CFReadStreamGetStatus(readStream) 267 self.assertIsInstance(status, (int, long)) 268 self.assertEqual(status, kCFStreamStatusNotOpen) 269 270 status = CFWriteStreamGetStatus(writeStream) 271 self.assertIsInstance(status, (int, long)) 272 self.assertEqual(status, kCFStreamStatusNotOpen) 273 274 del readStream, writeStream, sd 275 276 self.assertArgIsOut(CFStreamCreatePairWithSocketToHost, 3) 277 self.assertArgIsOut(CFStreamCreatePairWithSocketToHost, 4) 278 readStream, writeStream = CFStreamCreatePairWithSocketToHost(None, 279 "www.apple.com", 80, None, None) 280 281 status = CFReadStreamGetStatus(readStream) 282 self.assertIsInstance(status, (int, long)) 283 self.assertEqual(status, kCFStreamStatusNotOpen) 284 285 status = CFWriteStreamGetStatus(writeStream) 286 self.assertIsInstance(status, (int, long)) 287 self.assertEqual(status, kCFStreamStatusNotOpen) 288 289 del readStream, writeStream 290 291 292 # Note: I don't expect anyone to actually use this api, building 293 # struct sockaddr buffers by hand is madness in python. 294 ip = socket.gethostbyname('www.apple.com') 295 ip = map(int, ip.split('.')) 296 297 import struct 298 sockaddr = struct.pack('>BBHBBBB', 16, socket.AF_INET, 80, *ip) 299 300 if sys.version_info[0] == 3: 301 sockaddr_buffer = sockaddr 302 else: 303 sockaddr_buffer = buffer(sockaddr) 304 305 signature = CFSocketSignature( 306 protocolFamily=socket.AF_INET, 307 socketType=socket.SOCK_STREAM, 308 protocol=0, 309 address=sockaddr_buffer) 310 311 self.assertArgIsOut(CFStreamCreatePairWithPeerSocketSignature, 2) 312 self.assertArgIsOut(CFStreamCreatePairWithPeerSocketSignature, 3) 313 readStream, writeStream = CFStreamCreatePairWithPeerSocketSignature( 314 None, signature, None, None) 315 316 self.assertResultIsCFRetained(CFWriteStreamCopyError) 317 status = CFReadStreamGetStatus(readStream) 318 self.assertIsInstance(status, (int, long)) 319 self.assertEqual(status, kCFStreamStatusNotOpen) 320 321 status = CFWriteStreamGetStatus(writeStream) 322 self.assertIsInstance(status, (int, long)) 323 self.assertEqual(status, kCFStreamStatusNotOpen) 324 325 def testReadSocketASync(self): 326 rl = CFRunLoopGetCurrent() 327 328 strval = b"hello world" 329 readStream = CFReadStreamCreateWithBytesNoCopy(None, 330 strval, len(strval), kCFAllocatorNull) 331 self.assertIsInstance(readStream, CFReadStreamRef) 332 data = {} 333 334 state = [] 335 def callback(stream, kind, info): 336 state.append((stream, kind, info)) 337 338 status = CFReadStreamGetStatus(readStream) 339 self.assertIsInstance(status, (int, long)) 340 self.assertEqual(status, kCFStreamStatusNotOpen) 341 342 CFReadStreamOpen(readStream) 343 344 ok = CFReadStreamSetClient(readStream, 345 kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, 346 callback, data) 347 self.assertTrue(ok) 348 349 CFReadStreamScheduleWithRunLoop(readStream, rl, kCFRunLoopDefaultMode) 350 try: 351 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, True) 352 CFRunLoopWakeUp(rl) 353 finally: 354 CFReadStreamClose(readStream) 355 CFReadStreamUnscheduleFromRunLoop(readStream, rl, kCFRunLoopDefaultMode) 356 ok = CFReadStreamSetClient(readStream, 357 kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, 358 callback, objc.NULL) 359 self.assertTrue(ok) 360 361 self.assertEqual(len(state) , 1) 362 self.assertIs(state[0][0], readStream) 363 self.assertIs(state[0][2], data) 364 self.assertEqual(state[0][1], kCFStreamEventHasBytesAvailable) 365 366 367 def testWriteSocketAsync(self): 368 rl = CFRunLoopGetCurrent() 369 370 import array 371 a = array.array('b', b" "*20) 372 373 writeStream = CFWriteStreamCreateWithBuffer(None, a, 20) 374 self.assertIsInstance(writeStream, CFWriteStreamRef) 375 r = CFWriteStreamOpen(writeStream) 376 self.assertIs(r, True) 377 data = {} 378 state = [] 379 def callback(stream, kind, info): 380 state.append((stream, kind, info)) 381 382 ok = CFWriteStreamSetClient(writeStream, 383 kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, 384 callback, data) 385 self.assertTrue(ok) 386 387 CFWriteStreamScheduleWithRunLoop(writeStream, rl, kCFRunLoopDefaultMode) 388 try: 389 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, True) 390 CFRunLoopWakeUp(rl) 391 finally: 392 CFWriteStreamClose(writeStream) 393 CFWriteStreamUnscheduleFromRunLoop(writeStream, rl, kCFRunLoopDefaultMode) 394 ok = CFWriteStreamSetClient(writeStream, 395 kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, 396 callback, objc.NULL) 397 self.assertTrue(ok) 398 399 self.assertEqual(len(state) , 1) 400 self.assertIs(state[0][0], writeStream) 401 self.assertIs(state[0][2], data) 402 self.assertEqual(state[0][1], kCFStreamEventCanAcceptBytes) 403 404if __name__ == "__main__": 405 main() 406