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

File python3-logfile-6749-3.2.patch, 13.5 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..e35811d 100644
     
    77A rotating, browsable log file.
    88"""
    99
     10from __future__ import division, absolute_import
     11
    1012# System Imports
    1113import os, glob, time, stat
    1214
    class BaseLogFile: 
    6163        """
    6264        self.closed = False
    6365        if os.path.exists(self.path):
    64             self._file = file(self.path, "r+", 1)
     66            self._file = open(self.path, "r+", 1)
    6567            self._file.seek(0, 2)
    6668        else:
    6769            if self.defaultMode is not None:
    6870                # Set the lowest permissions
    69                 oldUmask = os.umask(0777)
     71                oldUmask = os.umask(0o777)
    7072                try:
    71                     self._file = file(self.path, "w+", 1)
     73                    self._file = open(self.path, "w+", 1)
    7274                finally:
    7375                    os.umask(oldUmask)
    7476            else:
    75                 self._file = file(self.path, "w+", 1)
     77                self._file = open(self.path, "w+", 1)
    7678        if self.defaultMode is not None:
    7779            try:
    7880                os.chmod(self.path, self.defaultMode)
    class LogFile(BaseLogFile): 
    178180        """
    179181        filename = "%s.%d" % (self.path, identifier)
    180182        if not os.path.exists(filename):
    181             raise ValueError, "no such logfile exists"
     183            raise ValueError("no such logfile exists")
    182184        return LogReader(filename)
    183185
    184186    def write(self, data):
    class DailyLogFile(BaseLogFile): 
    266268            return self.getCurrentLog()
    267269        filename = "%s.%s" % (self.path, self.suffix(identifier))
    268270        if not os.path.exists(filename):
    269             raise ValueError, "no such logfile exists"
     271            raise ValueError("no such logfile exists")
    270272        return LogReader(filename)
    271273
    272274    def write(self, data):
    class LogReader: 
    304306    """Read from a log file."""
    305307
    306308    def __init__(self, name):
    307         self._file = file(name, "r")
     309        self._file = open(name, "r")
    308310
    309311    def readLines(self, lines=10):
    310312        """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..2b3f210 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)
     40        log.close()
    3041
    3142
    3243    def testWriting(self):
    class LogFileTestCase(unittest.TestCase): 
    118129        self.assertEqual(reader.readLines(), ["abc\n", "def\n"])
    119130        self.assertEqual(reader.readLines(), [])
    120131        reader.close()
     132        log.close()
    121133
    122134    def testModePreservation(self):
    123135        """
    124136        Check rotated files have same permissions as original.
    125137        """
    126138        f = open(self.path, "w").close()
    127         os.chmod(self.path, 0707)
     139        os.chmod(self.path, 0o707)
    128140        mode = os.stat(self.path)[stat.ST_MODE]
    129141        log = logfile.LogFile(self.name, self.dir)
    130142        log.write("abc")
    131143        log.rotate()
    132144        self.assertEqual(mode, os.stat(self.path)[stat.ST_MODE])
     145        log.close()
    133146
    134147
    135148    def test_noPermission(self):
    class LogFileTestCase(unittest.TestCase): 
    140153        log.write("abc")
    141154
    142155        # change permissions so rotation would fail
    143         os.chmod(self.dir, 0555)
     156        os.chmod(self.dir, 0o555)
    144157
    145158        # if this succeeds, chmod doesn't restrict us, so we can't
    146159        # do the test
    class LogFileTestCase(unittest.TestCase): 
    180193
    181194        log.write("4" * 11)
    182195        self.failUnless(os.path.exists("%s.3" % self.path))
    183         self.assertEqual(file("%s.3" % self.path).read(), "1" * 11)
     196        with open("%s.3" % self.path) as fp:
     197            self.assertEqual(fp.read(), "1" * 11)
    184198
    185199        log.write("5" * 11)
    186         self.assertEqual(file("%s.3" % self.path).read(), "2" * 11)
     200        with open("%s.3" % self.path) as fp:
     201            self.assertEqual(fp.read(), "2" * 11)
    187202        self.failUnless(not os.path.exists("%s.4" % self.path))
     203        log.close()
    188204
    189205    def test_fromFullPath(self):
    190206        """
    191207        Test the fromFullPath method.
    192208        """
    193         log1 = logfile.LogFile(self.name, self.dir, 10, defaultMode=0777)
    194         log2 = logfile.LogFile.fromFullPath(self.path, 10, defaultMode=0777)
     209        log1 = logfile.LogFile(self.name, self.dir, 10, defaultMode=0o777)
     210        log2 = logfile.LogFile.fromFullPath(self.path, 10, defaultMode=0o777)
    195211        self.assertEqual(log1.name, log2.name)
    196212        self.assertEqual(os.path.abspath(log1.path), log2.path)
    197213        self.assertEqual(log1.rotateLength, log2.rotateLength)
    198214        self.assertEqual(log1.defaultMode, log2.defaultMode)
     215        log1.close()
     216        log2.close()
    199217
    200218    def test_defaultPermissions(self):
    201219        """
    202220        Test the default permission of the log file: if the file exist, it
    203221        should keep the permission.
    204222        """
    205         f = file(self.path, "w")
    206         os.chmod(self.path, 0707)
     223        f = open(self.path, "w")
     224        os.chmod(self.path, 0o707)
    207225        currentMode = stat.S_IMODE(os.stat(self.path)[stat.ST_MODE])
    208226        f.close()
    209227        log1 = logfile.LogFile(self.name, self.dir)
    210228        self.assertEqual(stat.S_IMODE(os.stat(self.path)[stat.ST_MODE]),
    211229                          currentMode)
     230        log1.close()
    212231
    213232
    214233    def test_specifiedPermissions(self):
    215234        """
    216235        Test specifying the permissions used on the log file.
    217236        """
    218         log1 = logfile.LogFile(self.name, self.dir, defaultMode=0066)
     237        log1 = logfile.LogFile(self.name, self.dir, defaultMode=0o066)
    219238        mode = stat.S_IMODE(os.stat(self.path)[stat.ST_MODE])
    220239        if runtime.platform.isWindows():
    221240            # The only thing we can get here is global read-only
    222             self.assertEqual(mode, 0444)
     241            self.assertEqual(mode, 0o444)
    223242        else:
    224             self.assertEqual(mode, 0066)
     243            self.assertEqual(mode, 0o066)
     244        log1.close()
    225245
    226246
    227247    def test_reopen(self):
    class LogFileTestCase(unittest.TestCase): 
    257277        self.assertEqual(e.errno, errno.ENOENT)
    258278
    259279
     280    def test_persistence(self):
     281        """
     282        L{LogFile} objects can be pickled and unpickled, which preserves all the
     283        various attributes of the log file.
     284        """
     285        rotateLength = 12345
     286        defaultMode = 0o642
     287        maxRotatedFiles = 42
     288
     289        log = logfile.LogFile(self.name, self.dir,
     290                              rotateLength, defaultMode,
     291                              maxRotatedFiles)
     292        log.write("123")
     293        log.close()
     294
     295        copy = pickle.loads(pickle.dumps(log))
     296
     297        # Check that the unpickled log is the same as the original one.
     298        self.assertEqual(self.name, copy.name)
     299        self.assertEqual(self.dir, copy.directory)
     300        self.assertEqual(self.path, copy.path)
     301        self.assertEqual(rotateLength, copy.rotateLength)
     302        self.assertEqual(defaultMode, copy.defaultMode)
     303        self.assertEqual(maxRotatedFiles, copy.maxRotatedFiles)
     304        self.assertEqual(log.size, copy.size)
     305        copy.close()
     306
     307
     308    def test_cantChangeFileMode(self):
     309        """
     310        Opening a L{LogFile} which can be read and write but whose mode can't
     311        be changed doesn't trigger an error.
     312        """
     313        log = logfile.LogFile("null", "/dev", defaultMode=0o555)
     314
     315        self.assertEqual(log.path, "/dev/null")
     316        self.assertEqual(log.defaultMode, 0o555)
     317        log.close()
     318
     319
     320    def test_listLogsWithBadlyNamedFiles(self):
     321        """
     322        L{LogFile.listLogs} doesn't choke if it encounters a file with an
     323        unexpected name.
     324        """
     325        log = logfile.LogFile(self.name, self.dir)
     326
     327        with open("%s.1" % log.path, "w") as fp:
     328            fp.write("123")
     329        with open("%s.bad-file" % log.path, "w") as fp:
     330            fp.write("123")
     331
     332        self.assertEqual([1], log.listLogs())
     333        log.close()
     334
    260335
    261336class RiggedDailyLogFile(logfile.DailyLogFile):
    262337    _clock = 0.0
    class DailyLogFileTestCase(unittest.TestCase): 
    317392        log._clock = 259199 # 1970/01/03 23:59.59
    318393        log.write("3")
    319394        self.assert_(not os.path.exists(days[2]))
     395        log.close()
     396
     397    def test_getLog(self):
     398        """
     399        Test retrieving log files with L{DailyLogFile.getLog}.
     400        """
     401        data = ["1\n", "2\n", "3\n"]
     402        log = RiggedDailyLogFile(self.name, self.dir)
     403        for d in data:
     404            log.write(d)
     405
     406        # This returns the current log file.
     407        r = log.getLog(0.0)
     408        self.assertEqual(data, r.readLines())
     409
     410        # We can't get this log, it doesn't exist yet.
     411        self.assertRaises(ValueError, log.getLog, 86400)
    320412
     413        log._clock = 86401 # New day
     414        log.rotate()
     415        r.close()
     416        r = log.getLog(0) # We get the previous log
     417        self.assertEqual(data, r.readLines())
     418        log.close()
     419        r.close()
     420
     421
     422    def test_rotateAlreadyExists(self):
     423        """
     424        L{DailyLogFile.rotate} doesn't do anything if they new log file already
     425        exists on the disk.
     426        """
     427        log = RiggedDailyLogFile(self.name, self.dir)
     428        # Build a new file with the same name as the file which would be created
     429        # if the log file is to be rotated.
     430        with open("%s.%s" % (log.path, log.suffix(log.lastDate)), "w") as fp:
     431            fp.write("123")
     432        previous_file = log._file
     433        log.rotate()
     434        self.assertEqual(previous_file, log._file)
     435        log.close()
     436
     437
     438    def test_rotatePermissionDirectoryNotOk(self):
     439        """
     440        L{DailyLogFile.rotate} doesn't do anything if the directory containing
     441        the log files can't be written to.
     442        """
     443        log = logfile.DailyLogFile(self.name, self.dir)
     444        os.chmod(log.directory, 0o444)
     445        # Restore permissions so tests can be cleaned up.
     446        self.addCleanup(os.chmod, log.directory, 0o755)
     447        previous_file = log._file
     448        log.rotate()
     449        self.assertEqual(previous_file, log._file)
     450        log.close()
     451
     452
     453    def test_rotatePermissionFileNotOk(self):
     454        """
     455        L{DailyLogFile.rotate} doesn't do anything if the log file can't be
     456        written to.
     457        """
     458        log = logfile.DailyLogFile(self.name, self.dir)
     459        os.chmod(log.path, 0o444)
     460        previous_file = log._file
     461        log.rotate()
     462        self.assertEqual(previous_file, log._file)
     463        log.close()
     464
     465
     466    def test_toDate(self):
     467        """
     468        Test that L{DailyLogFile.toDate} converts its timestamp argument to a
     469        time tuple (year, month, day).
     470        """
     471        log = logfile.DailyLogFile(self.name, self.dir)
     472
     473        timestamp = time.mktime((2000, 1, 1, 0, 0, 0, 0, 0, 0))
     474        self.assertEqual((2000, 1, 1), log.toDate(timestamp))
     475        log.close()
     476
     477
     478    def test_toDateDefaultToday(self):
     479        """
     480        Test that L{DailyLogFile.toDate} returns today's date by default.
     481        """
     482        log = logfile.DailyLogFile(self.name, self.dir)
     483
     484        # XXX: this might break if by chance, current's date changes between the
     485        # two functions runs.
     486        today = datetime.date.today()
     487        log_date = log.toDate()
     488
     489        self.assertEqual(today.timetuple()[:3], log_date)
     490        log.close()
     491
     492
     493    def test_persistence(self):
     494        """
     495        L{DailyLogFile} objects can be pickled and unpickled, which preserves
     496        all the various attributes of the log file.
     497        """
     498        defaultMode = 0o642
     499
     500        log = logfile.DailyLogFile(self.name, self.dir,
     501                                   defaultMode)
     502        log.write("123")
     503
     504        # Check that the unpickled log is the same as the original one.
     505        copy = pickle.loads(pickle.dumps(log))
     506
     507        self.assertEqual(self.name, copy.name)
     508        self.assertEqual(self.dir, copy.directory)
     509        self.assertEqual(self.path, copy.path)
     510        self.assertEqual(defaultMode, copy.defaultMode)
     511        self.assertEqual(log.lastDate, copy.lastDate)
     512        log.close()
     513        copy.close()