Home | History | Annotate | Download | only in test
      1 """Test program for the fcntl C module.
      2 
      3 OS/2+EMX doesn't support the file locking operations.
      4 
      5 """
      6 import os
      7 import struct
      8 import sys
      9 import _testcapi
     10 import unittest
     11 from test.test_support import (verbose, TESTFN, unlink, run_unittest,
     12     import_module)
     13 
     14 # Skip test if no fnctl module.
     15 fcntl = import_module('fcntl')
     16 
     17 
     18 # TODO - Write tests for flock() and lockf().
     19 
     20 def get_lockdata():
     21     if sys.platform.startswith('atheos'):
     22         start_len = "qq"
     23     else:
     24         try:
     25             os.O_LARGEFILE
     26         except AttributeError:
     27             start_len = "ll"
     28         else:
     29             start_len = "qq"
     30 
     31     if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd', 'bsdos'))
     32         or sys.platform == 'darwin'):
     33         if struct.calcsize('l') == 8:
     34             off_t = 'l'
     35             pid_t = 'i'
     36         else:
     37             off_t = 'lxxxx'
     38             pid_t = 'l'
     39         lockdata = struct.pack(off_t + off_t + pid_t + 'hh', 0, 0, 0,
     40                                fcntl.F_WRLCK, 0)
     41     elif sys.platform in ['aix3', 'aix4', 'hp-uxB', 'unixware7']:
     42         lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0)
     43     elif sys.platform in ['os2emx']:
     44         lockdata = None
     45     else:
     46         lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
     47     if lockdata:
     48         if verbose:
     49             print 'struct.pack: ', repr(lockdata)
     50     return lockdata
     51 
     52 lockdata = get_lockdata()
     53 
     54 
     55 class TestFcntl(unittest.TestCase):
     56 
     57     def setUp(self):
     58         self.f = None
     59 
     60     def tearDown(self):
     61         if self.f and not self.f.closed:
     62             self.f.close()
     63         unlink(TESTFN)
     64 
     65     def test_fcntl_fileno(self):
     66         # the example from the library docs
     67         self.f = open(TESTFN, 'w')
     68         rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
     69         if verbose:
     70             print 'Status from fcntl with O_NONBLOCK: ', rv
     71         if sys.platform not in ['os2emx']:
     72             rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETLKW, lockdata)
     73             if verbose:
     74                 print 'String from fcntl with F_SETLKW: ', repr(rv)
     75         self.f.close()
     76 
     77     def test_fcntl_file_descriptor(self):
     78         # again, but pass the file rather than numeric descriptor
     79         self.f = open(TESTFN, 'w')
     80         rv = fcntl.fcntl(self.f, fcntl.F_SETFL, os.O_NONBLOCK)
     81         if sys.platform not in ['os2emx']:
     82             rv = fcntl.fcntl(self.f, fcntl.F_SETLKW, lockdata)
     83         self.f.close()
     84 
     85     def test_fcntl_bad_file(self):
     86         class F:
     87             def __init__(self, fn):
     88                 self.fn = fn
     89             def fileno(self):
     90                 return self.fn
     91         self.assertRaises(ValueError, fcntl.fcntl, -1, fcntl.F_SETFL, os.O_NONBLOCK)
     92         self.assertRaises(ValueError, fcntl.fcntl, F(-1), fcntl.F_SETFL, os.O_NONBLOCK)
     93         self.assertRaises(TypeError, fcntl.fcntl, 'spam', fcntl.F_SETFL, os.O_NONBLOCK)
     94         self.assertRaises(TypeError, fcntl.fcntl, F('spam'), fcntl.F_SETFL, os.O_NONBLOCK)
     95         # Issue 15989
     96         self.assertRaises(ValueError, fcntl.fcntl, _testcapi.INT_MAX + 1,
     97                                                    fcntl.F_SETFL, os.O_NONBLOCK)
     98         self.assertRaises(ValueError, fcntl.fcntl, F(_testcapi.INT_MAX + 1),
     99                                                    fcntl.F_SETFL, os.O_NONBLOCK)
    100         self.assertRaises(ValueError, fcntl.fcntl, _testcapi.INT_MIN - 1,
    101                                                    fcntl.F_SETFL, os.O_NONBLOCK)
    102         self.assertRaises(ValueError, fcntl.fcntl, F(_testcapi.INT_MIN - 1),
    103                                                    fcntl.F_SETFL, os.O_NONBLOCK)
    104 
    105     def test_fcntl_64_bit(self):
    106         # Issue #1309352: fcntl shouldn't fail when the third arg fits in a
    107         # C 'long' but not in a C 'int'.
    108         try:
    109             cmd = fcntl.F_NOTIFY
    110             # This flag is larger than 2**31 in 64-bit builds
    111             flags = fcntl.DN_MULTISHOT
    112         except AttributeError:
    113             self.skipTest("F_NOTIFY or DN_MULTISHOT unavailable")
    114         fd = os.open(os.path.dirname(os.path.abspath(TESTFN)), os.O_RDONLY)
    115         try:
    116             fcntl.fcntl(fd, cmd, flags)
    117         finally:
    118             os.close(fd)
    119 
    120 
    121 def test_main():
    122     run_unittest(TestFcntl)
    123 
    124 if __name__ == '__main__':
    125     test_main()
    126