10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test case for the os.poll() function 20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport os, select, random, unittest 40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport _testcapi 50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom test.test_support import TESTFN, run_unittest 60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitry: 80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi select.poll 90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexcept AttributeError: 100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise unittest.SkipTest, "select.poll not defined -- skipping test_poll" 110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef find_ready_matching(ready, flag): 140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi match = [] 150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for fd, mode in ready: 160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if mode & flag: 170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi match.append(fd) 180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return match 190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass PollTests(unittest.TestCase): 210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_poll1(self): 230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Basic functional test of poll object 240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Create a bunch of pipe and test that poll works with them. 250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = select.poll() 270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi NUM_PIPES = 12 290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi MSG = " This is a test." 300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi MSG_LEN = len(MSG) 310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi readers = [] 320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writers = [] 330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r2w = {} 340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi w2r = {} 350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for i in range(NUM_PIPES): 370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rd, wr = os.pipe() 380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p.register(rd) 390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p.modify(rd, select.POLLIN) 400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p.register(wr, select.POLLOUT) 410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi readers.append(rd) 420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writers.append(wr) 430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r2w[rd] = wr 440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi w2r[wr] = rd 450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi bufs = [] 470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while writers: 490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ready = p.poll() 500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ready_writers = find_ready_matching(ready, select.POLLOUT) 510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not ready_writers: 520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise RuntimeError, "no pipes ready for writing" 530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi wr = random.choice(ready_writers) 540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi os.write(wr, MSG) 550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ready = p.poll() 570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ready_readers = find_ready_matching(ready, select.POLLIN) 580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not ready_readers: 590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise RuntimeError, "no pipes ready for reading" 600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rd = random.choice(ready_readers) 610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi buf = os.read(rd, MSG_LEN) 620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(len(buf), MSG_LEN) 630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi bufs.append(buf) 640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi os.close(r2w[rd]) ; os.close( rd ) 650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p.unregister( r2w[rd] ) 660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p.unregister( rd ) 670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writers.remove(r2w[rd]) 680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(bufs, [MSG] * NUM_PIPES) 700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def poll_unit_tests(self): 720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # returns NVAL for invalid file descriptor 730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi FD = 42 740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi os.close(FD) 760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except OSError: 770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pass 780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = select.poll() 790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p.register(FD) 800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = p.poll() 810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(r[0], (FD, select.POLLNVAL)) 820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f = open(TESTFN, 'w') 840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fd = f.fileno() 850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = select.poll() 860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p.register(f) 870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = p.poll() 880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(r[0][0], fd) 890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f.close() 900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = p.poll() 910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(r[0], (fd, select.POLLNVAL)) 920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi os.unlink(TESTFN) 930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # type error for invalid arguments 950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = select.poll() 960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(TypeError, p.register, p) 970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(TypeError, p.unregister, p) 980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # can't unregister non-existent object 1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = select.poll() 1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(KeyError, p.unregister, 3) 1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test error cases 1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pollster = select.poll() 1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi class Nope: 1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pass 1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi class Almost: 1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def fileno(self): 1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 'fileno' 1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(TypeError, pollster.register, Nope(), 0) 1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(TypeError, pollster.register, Almost(), 0) 1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Another test case for poll(). This is copied from the test case for 1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # select(), modified to use poll() instead. 1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_poll2(self): 1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done' 1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = os.popen(cmd, 'r') 1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pollster = select.poll() 1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pollster.register( p, select.POLLIN ) 1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for tout in (0, 1000, 2000, 4000, 8000, 16000) + (-1,)*10: 1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fdlist = pollster.poll(tout) 1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if (fdlist == []): 1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi continue 1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fd, flags = fdlist[0] 1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if flags & select.POLLHUP: 1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi line = p.readline() 1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if line != "": 1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.fail('error: pipe seems to be closed, but still returns data') 1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi continue 1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif flags & select.POLLIN: 1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi line = p.readline() 1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not line: 1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi continue 1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.fail('Unexpected return value from select.poll: %s' % fdlist) 1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p.close() 1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_poll3(self): 1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # test int overflow 1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pollster = select.poll() 1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pollster.register(1) 1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(OverflowError, pollster.poll, 1L << 64) 1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x = 2 + 3 1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if x != 5: 1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.fail('Overflow must have occurred') 1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pollster = select.poll() 1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Issue 15989 1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(OverflowError, pollster.register, 0, 1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _testcapi.SHRT_MAX + 1) 1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(OverflowError, pollster.register, 0, 1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _testcapi.USHRT_MAX + 1) 1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(OverflowError, pollster.poll, _testcapi.INT_MAX + 1) 1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(OverflowError, pollster.poll, _testcapi.UINT_MAX + 1) 1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef test_main(): 1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi run_unittest(PollTests) 1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif __name__ == '__main__': 1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi test_main() 168