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