Ticket #6749: python3-logfile-6749-2.patch

File python3-logfile-6749-2.patch, 12.7 KB (added by multani, 3 years ago)
  • setup3.py

    diff --git setup3.py setup3.py
    index ca27cbe..505c3e6 100644
    modules = [ 
    7676    "twisted.python.filepath",
    7777    "twisted.python.lockfile",
    7878    "twisted.python.log",
     79    "twisted.python.logfile",
    7980    "twisted.python.monkey",
    8081    "twisted.python.randbytes",
    8182    "twisted.python._reflectpy3",
    testModules = [ 
    168169    "twisted.test.test_iutils",
    169170    "twisted.test.test_lockfile",
    170171    "twisted.test.test_log",
     172    "twisted.test.test_logfile",
    171173    "twisted.test.test_loopback",
    172174    "twisted.test.test_monkey",
    173175    "twisted.test.test_paths",
  • twisted/python/logfile.py

    diff --git twisted/python/logfile.py twisted/python/logfile.py
    index f652271..1c9a633 100644
    class BaseLogFile: 
    3939            self.defaultMode = defaultMode
    4040        self._openFile()
    4141
     42    def __del__(self):
     43        try:
     44            self.close()
     45        except: # File might be already closed
     46            pass
     47
    4248    def fromFullPath(cls, filename, *args, **kwargs):
    4349        """
    4450        Construct a log file from a full file path.
    class BaseLogFile: 
    6167        """
    6268        self.closed = False
    6369        if os.path.exists(self.path):
    64             self._file = file(self.path, "r+", 1)
     70            self._file = open(self.path, "r+", 1)
    6571            self._file.seek(0, 2)
    6672        else:
    6773            if self.defaultMode is not None:
    6874                # Set the lowest permissions
    69                 oldUmask = os.umask(0777)
     75                oldUmask = os.umask(0o777)
    7076                try:
    71                     self._file = file(self.path, "w+", 1)
     77                    self._file = open(self.path, "w+", 1)
    7278                finally:
    7379                    os.umask(oldUmask)
    7480            else:
    75                 self._file = file(self.path, "w+", 1)
     81                self._file = open(self.path, "w+", 1)
    7682        if self.defaultMode is not None:
    7783            try:
    7884                os.chmod(self.path, self.defaultMode)
    class LogFile(BaseLogFile): 
    178184        """
    179185        filename = "%s.%d" % (self.path, identifier)
    180186        if not os.path.exists(filename):
    181             raise ValueError, "no such logfile exists"
     187            raise ValueError("no such logfile exists")
    182188        return LogReader(filename)
    183189
    184190    def write(self, data):
    class DailyLogFile(BaseLogFile): 
    266272            return self.getCurrentLog()
    267273        filename = "%s.%s" % (self.path, self.suffix(identifier))
    268274        if not os.path.exists(filename):
    269             raise ValueError, "no such logfile exists"
     275            raise ValueError("no such logfile exists")
    270276        return LogReader(filename)
    271277
    272278    def write(self, data):
    class LogReader: 
    304310    """Read from a log file."""
    305311
    306312    def __init__(self, name):
    307         self._file = file(name, "r")
     313        self._file = open(name, "r")
     314
     315    def __del__(self):
     316        self.close()
    308317
    309318    def readLines(self, lines=10):
    310319        """Read a list of lines from the log file.
  • twisted/test/test_logfile.py

    diff --git twisted/test/test_logfile.py twisted/test/test_logfile.py
    index e7db238..94eb123 100644
     
    11# Copyright (c) Twisted Matrix Laboratories.
    22# See LICENSE for details.
    33
    4 import os, time, stat, errno
     4import datetime
     5import os, time, stat, errno, pickle
    56
    67from twisted.trial import unittest
    78from twisted.python import logfile, runtime
    class LogFileTestCase(unittest.TestCase): 
    2425        Restore back write rights on created paths: if tests modified the
    2526        rights, that will allow the paths to be removed easily afterwards.
    2627        """
    27         os.chmod(self.dir, 0777)
     28        os.chmod(self.dir, 0o777)
    2829        if os.path.exists(self.path):
    29             os.chmod(self.path, 0777)
     30            os.chmod(self.path, 0o777)
     31
     32
     33    def test_abstractShouldRotate(self):
     34        """
     35        L{BaseLogFile.shouldRotate} is abstract and must be implemented by
     36        subclass.
     37        """
     38        log = logfile.BaseLogFile(self.name, self.dir)
     39        self.assertRaises(NotImplementedError, log.shouldRotate)
    3040
    3141
    3242    def testWriting(self):
    class LogFileTestCase(unittest.TestCase): 
    124134        Check rotated files have same permissions as original.
    125135        """
    126136        f = open(self.path, "w").close()
    127         os.chmod(self.path, 0707)
     137        os.chmod(self.path, 0o707)
    128138        mode = os.stat(self.path)[stat.ST_MODE]
    129139        log = logfile.LogFile(self.name, self.dir)
    130140        log.write("abc")
    class LogFileTestCase(unittest.TestCase): 
    140150        log.write("abc")
    141151
    142152        # change permissions so rotation would fail
    143         os.chmod(self.dir, 0555)
     153        os.chmod(self.dir, 0o555)
    144154
    145155        # if this succeeds, chmod doesn't restrict us, so we can't
    146156        # do the test
    class LogFileTestCase(unittest.TestCase): 
    180190
    181191        log.write("4" * 11)
    182192        self.failUnless(os.path.exists("%s.3" % self.path))
    183         self.assertEqual(file("%s.3" % self.path).read(), "1" * 11)
     193        with open("%s.3" % self.path) as fp:
     194            self.assertEqual(fp.read(), "1" * 11)
    184195
    185196        log.write("5" * 11)
    186         self.assertEqual(file("%s.3" % self.path).read(), "2" * 11)
     197        with open("%s.3" % self.path) as fp:
     198            self.assertEqual(fp.read(), "2" * 11)
    187199        self.failUnless(not os.path.exists("%s.4" % self.path))
    188200
    189201    def test_fromFullPath(self):
    190202        """
    191203        Test the fromFullPath method.
    192204        """
    193         log1 = logfile.LogFile(self.name, self.dir, 10, defaultMode=0777)
    194         log2 = logfile.LogFile.fromFullPath(self.path, 10, defaultMode=0777)
     205        log1 = logfile.LogFile(self.name, self.dir, 10, defaultMode=0o777)
     206        log2 = logfile.LogFile.fromFullPath(self.path, 10, defaultMode=0o777)
    195207        self.assertEqual(log1.name, log2.name)
    196208        self.assertEqual(os.path.abspath(log1.path), log2.path)
    197209        self.assertEqual(log1.rotateLength, log2.rotateLength)
    class LogFileTestCase(unittest.TestCase): 
    202214        Test the default permission of the log file: if the file exist, it
    203215        should keep the permission.
    204216        """
    205         f = file(self.path, "w")
    206         os.chmod(self.path, 0707)
     217        f = open(self.path, "w")
     218        os.chmod(self.path, 0o707)
    207219        currentMode = stat.S_IMODE(os.stat(self.path)[stat.ST_MODE])
    208220        f.close()
    209221        log1 = logfile.LogFile(self.name, self.dir)
    class LogFileTestCase(unittest.TestCase): 
    215227        """
    216228        Test specifying the permissions used on the log file.
    217229        """
    218         log1 = logfile.LogFile(self.name, self.dir, defaultMode=0066)
     230        log1 = logfile.LogFile(self.name, self.dir, defaultMode=0o066)
    219231        mode = stat.S_IMODE(os.stat(self.path)[stat.ST_MODE])
    220232        if runtime.platform.isWindows():
    221233            # The only thing we can get here is global read-only
    222             self.assertEqual(mode, 0444)
     234            self.assertEqual(mode, 0o444)
    223235        else:
    224             self.assertEqual(mode, 0066)
     236            self.assertEqual(mode, 0o066)
    225237
    226238
    227239    def test_reopen(self):
    class LogFileTestCase(unittest.TestCase): 
    257269        self.assertEqual(e.errno, errno.ENOENT)
    258270
    259271
     272    def test_persistence(self):
     273        """
     274        L{LogFile} objects can be pickled and unpickled, which preserves all the
     275        various attributes of the log file.
     276        """
     277        rotateLength = 12345
     278        defaultMode = 0o642
     279        maxRotatedFiles = 42
     280
     281        log = logfile.LogFile(self.name, self.dir,
     282                              rotateLength, defaultMode,
     283                              maxRotatedFiles)
     284        log.write("123")
     285        log.close()
     286
     287        copy = pickle.loads(pickle.dumps(log))
     288
     289        # Check that the unpickled log is the same as the original one.
     290        self.assertEqual(self.name, copy.name)
     291        self.assertEqual(self.dir, copy.directory)
     292        self.assertEqual(self.path, copy.path)
     293        self.assertEqual(rotateLength, copy.rotateLength)
     294        self.assertEqual(defaultMode, copy.defaultMode)
     295        self.assertEqual(maxRotatedFiles, copy.maxRotatedFiles)
     296        self.assertEqual(log.size, copy.size)
     297
     298
     299    def test_cantChangeFileMode(self):
     300        """
     301        Opening a L{LogFile} which can be read and write but whose mode can't
     302        be changed doesn't trigger an error.
     303        """
     304        log = logfile.LogFile("null", "/dev", defaultMode=0o555)
     305
     306        self.assertEqual(log.path, "/dev/null")
     307        self.assertEqual(log.defaultMode, 0o555)
     308
     309
     310    def test_listLogsWithBadlyNamedFiles(self):
     311        """
     312        L{LogFile.listLogs} doesn't choke if it encounters a file with an
     313        unexpected name.
     314        """
     315        log = logfile.LogFile(self.name, self.dir)
     316
     317        with open("%s.1" % log.path, "w") as fp:
     318            fp.write("123")
     319        with open("%s.bad-file" % log.path, "w") as fp:
     320            fp.write("123")
     321
     322        self.assertEqual([1], log.listLogs())
     323
    260324
    261325class RiggedDailyLogFile(logfile.DailyLogFile):
    262326    _clock = 0.0
    class DailyLogFileTestCase(unittest.TestCase): 
    318382        log.write("3")
    319383        self.assert_(not os.path.exists(days[2]))
    320384
     385    def test_getLog(self):
     386        """
     387        Test retrieving log files with L{DailyLogFile.getLog}.
     388        """
     389        data = ["1\n", "2\n", "3\n"]
     390        log = RiggedDailyLogFile(self.name, self.dir)
     391        for d in data:
     392            log.write(d)
     393
     394        # This returns the current log file.
     395        r = log.getLog(0.0)
     396        self.assertEqual(data, r.readLines())
     397
     398        # We can't get this log, it doesn't exist yet.
     399        self.assertRaises(ValueError, log.getLog, 86400)
     400
     401        log._clock = 86401 # New day
     402        log.rotate()
     403        r = log.getLog(0) # We get the previous log
     404        self.assertEqual(data, r.readLines())
     405
     406
     407    def test_rotateAlreadyExists(self):
     408        """
     409        L{DailyLogFile.rotate} doesn't do anything if they new log file already
     410        exists on the disk.
     411        """
     412        log = RiggedDailyLogFile(self.name, self.dir)
     413        # Build a new file with the same name as the file which would be created
     414        # if the log file is to be rotated.
     415        with open("%s.%s" % (log.path, log.suffix(log.lastDate)), "w") as fp:
     416            fp.write("123")
     417        previous_file = log._file
     418        log.rotate()
     419        self.assertEqual(previous_file, log._file)
     420
     421
     422    def test_rotatePermissionDirectoryNotOk(self):
     423        """
     424        L{DailyLogFile.rotate} doesn't do anything if the directory containing
     425        the log files can't be written to.
     426        """
     427        log = logfile.DailyLogFile(self.name, self.dir)
     428        os.chmod(log.directory, 0o444)
     429        # Restore permissions so tests can be cleaned up.
     430        self.addCleanup(os.chmod, log.directory, 0o755)
     431        previous_file = log._file
     432        log.rotate()
     433        self.assertEqual(previous_file, log._file)
     434
     435
     436    def test_rotatePermissionFileNotOk(self):
     437        """
     438        L{DailyLogFile.rotate} doesn't do anything if the log file can't be
     439        written to.
     440        """
     441        log = logfile.DailyLogFile(self.name, self.dir)
     442        os.chmod(log.path, 0o444)
     443        previous_file = log._file
     444        log.rotate()
     445        self.assertEqual(previous_file, log._file)
     446
     447
     448    def test_toDate(self):
     449        """
     450        Test that L{DailyLogFile.toDate} converts its timestamp argument to a
     451        time tuple (year, month, day).
     452        """
     453        log = logfile.DailyLogFile(self.name, self.dir)
     454
     455        timestamp = time.mktime((2000, 1, 1, 0, 0, 0, 0, 0, 0))
     456        self.assertEqual((2000, 1, 1), log.toDate(timestamp))
     457
     458
     459    def test_toDateDefaultToday(self):
     460        """
     461        Test that L{DailyLogFile.toDate} returns today's date by default.
     462        """
     463        log = logfile.DailyLogFile(self.name, self.dir)
     464
     465        # XXX: this might break if by chance, current's date changes between the
     466        # two functions runs.
     467        today = datetime.date.today()
     468        log_date = log.toDate()
     469
     470        self.assertEqual(today.timetuple()[:3], log_date)
     471
     472
     473    def test_persistence(self):
     474        """
     475        L{DailyLogFile} objects can be pickled and unpickled, which preserves
     476        all the various attributes of the log file.
     477        """
     478        defaultMode = 0o642
     479
     480        log = logfile.DailyLogFile(self.name, self.dir,
     481                                   defaultMode)
     482        log.write("123")
     483
     484        # Check that the unpickled log is the same as the original one.
     485        copy = pickle.loads(pickle.dumps(log))
     486
     487        self.assertEqual(self.name, copy.name)
     488        self.assertEqual(self.dir, copy.directory)
     489        self.assertEqual(self.path, copy.path)
     490        self.assertEqual(defaultMode, copy.defaultMode)
     491        self.assertEqual(log.lastDate, copy.lastDate)