Changeset 460:7394f2097327

Show
Ignore:
Timestamp:
08/04/08 13:06:58 (5 months ago)
Author:
"Brian Warner <warner@lothar.com>"
branch:
default
Message:

logging: add test coverage for 'flogtool dump'

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • ChangeLog

    r459 r460  
    112008-08-04  Brian Warner  <warner@lothar.com> 
     2 
     3        * foolscap/test/test_logging.py (Filter): test 'flogtool filter' 
     4        * foolscap/logging/filter.py: control stdout/stderr better 
    25 
    36        * foolscap/test/test_logging.py (Dumper): test 'flogtool dump' 
  • foolscap/logging/filter.py

    r382 r460  
    11 
    22from twisted.python import usage 
    3 import os, pickle, bz2, time 
     3import sys, os, pickle, bz2, time 
    44from foolscap.logging import log 
    55 
    66class FilterOptions(usage.Options): 
     7    stdout = sys.stdout 
     8    stderr = sys.stderr 
    79    synopsis = "Usage: flogtool filter [options] OLDFILE.pickle NEWFILE.pickle" 
    810 
     
    2325        self.newfile = newfile 
    2426        if newfile is None: 
    25             print "modifying event file in place" 
    2627            self.newfile = oldfile 
    2728 
     
    5152 
    5253    def run(self, options): 
     54        stdout = options.stdout 
    5355        newfilename = options.newfile 
    5456        if options.newfile == options.oldfile: 
     57            print >>stdout, "modifying event file in place" 
    5558            newfilename = newfilename + ".tmp" 
    5659        if options.newfile.endswith(".bz2"): 
     
    6063        after = options['after'] 
    6164        if after is not None: 
    62             print " --after: removing events before %s" % time.ctime(after) 
     65            print >>stdout, " --after: removing events before %s" % time.ctime(after) 
    6366        before = options['before'] 
    6467        if before is not None: 
    65             print " --before: removing events after %s" % time.ctime(before) 
     68            print >>stdout, " --before: removing events after %s" % time.ctime(before) 
    6669        above = options['above'] 
    6770        if above: 
    68             print " --above: removing events below level %d" % above 
     71            print >>stdout, " --above: removing events below level %d" % above 
    6972        from_tubid = options['from'] 
    7073        if from_tubid: 
    71             print " --from: retaining events only from tubid prefix %s" % from_tubid 
     74            print >>stdout, " --from: retaining events only from tubid prefix %s" % from_tubid 
    7275        strip_facility = options['strip-facility'] 
    7376        if strip_facility is not None: 
    74             print "--strip-facility: removing events for %s and children" % strip_facility 
     77            print >>stdout, "--strip-facility: removing events for %s and children" % strip_facility 
    7578        total = 0 
    7679        copied = 0 
     
    7881            if options['verbose']: 
    7982                if "d" in e: 
    80                     print e['d']['num'] 
     83                    print >>stdout, e['d']['num'] 
    8184                else: 
    82                     print "HEADER" 
     85                    print >>stdout, "HEADER" 
    8386            total += 1 
    8487            if "d" in e: 
     
    99102        if options.newfile == options.oldfile: 
    100103            os.rename(newfilename, options.newfile) 
    101         print "copied %d of %d events into new file" % (copied, total) 
     104        print >>stdout, "copied %d of %d events into new file" % (copied, total) 
    102105 
    103106    def get_events(self, fn): 
  • foolscap/test/test_logging.py

    r459 r460  
    15281528        self.failUnless("to launch the daemon" in out, out) 
    15291529 
    1530 class Dumper(unittest.TestCase, LogfileReaderMixin): 
    1531     # create a logfile, then dump it, and examine the output to make sure it 
    1532     # worked right. 
     1530class LogfileWriterMixin: 
    15331531 
    15341532    def create_logfile(self): 
     
    15371535        fn = os.path.join(self.basedir, "dump.flog") 
    15381536        l = log.FoolscapLogger() 
    1539         lfo = log.LogFileObserver(fn
     1537        lfo = log.LogFileObserver(fn, level=0
    15401538        l.addObserver(lfo.msg) 
    1541         l.msg("one") 
    1542         l.msg("two") 
     1539        l.msg("one", facility="big.facility") 
     1540        time.sleep(0.2) # give filter --after something to work with 
     1541        l.msg("two", level=log.OPERATIONAL-1) 
    15431542        try: 
    15441543            raise SampleError("whoops1") 
    15451544        except: 
    1546             l.err(
    1547         l.msg("three") 
     1545            l.err(message="three"
     1546        l.msg("four") 
    15481547        d = fireEventually() 
    15491548        def _done(res): 
     
    15541553        d.addCallback(_done) 
    15551554        return d 
     1555 
     1556    def create_incident(self): 
     1557        if not os.path.exists(self.basedir): 
     1558            os.makedirs(self.basedir) 
     1559        l = log.FoolscapLogger() 
     1560        l.setLogDir(self.basedir) 
     1561        l.setIncidentReporterFactory(NoFollowUpReporter) 
     1562 
     1563        d = defer.Deferred() 
     1564        def _done(name, trigger): 
     1565            d.callback( (name,trigger) ) 
     1566        l.addImmediateIncidentObserver(_done) 
     1567 
     1568        l.msg("one") 
     1569        l.msg("two") 
     1570        l.msg("boom", level=log.WEIRD) 
     1571        l.msg("four") 
     1572 
     1573        d.addCallback(lambda (name,trigger): 
     1574                      os.path.join(self.basedir, name+".flog.bz2")) 
     1575 
     1576        return d 
     1577 
     1578class Dumper(unittest.TestCase, LogfileWriterMixin, LogfileReaderMixin): 
     1579    # create a logfile, then dump it, and examine the output to make sure it 
     1580    # worked right. 
    15561581 
    15571582    def test_dump(self): 
     
    15941619                     d.format_time(events[1]["d"]["time"])) 
    15951620            self.failUnlessEqual(lines[0].strip(), line0) 
    1596             self.failUnless(lines[-1].strip().endswith(" three")) 
     1621            self.failUnless(lines[-1].strip().endswith(" four")) 
    15971622 
    15981623            argv = ["flogtool", "dump", "--verbose", fn] 
     
    16021627            self.failUnless("'message': 'one'" in lines[0]) 
    16031628            self.failUnless("'level': 20" in lines[0]) 
    1604             self.failUnless(": three: {" in lines[-1]) 
     1629            self.failUnless(": four: {" in lines[-1]) 
    16051630 
    16061631        d.addCallback(_check) 
    1607         return d 
    1608  
    1609     def create_incident(self): 
    1610         if not os.path.exists(self.basedir): 
    1611             os.makedirs(self.basedir) 
    1612         l = log.FoolscapLogger() 
    1613         l.setLogDir(self.basedir) 
    1614         l.setIncidentReporterFactory(NoFollowUpReporter) 
    1615  
    1616         d = defer.Deferred() 
    1617         def _done(name, trigger): 
    1618             d.callback( (name,trigger) ) 
    1619         l.addImmediateIncidentObserver(_done) 
    1620  
    1621         l.msg("one") 
    1622         l.msg("two") 
    1623         l.msg("boom", level=log.WEIRD) 
    1624         l.msg("four") 
    1625  
    1626         d.addCallback(lambda (name,trigger): 
    1627                       os.path.join(self.basedir, name+".flog.bz2")) 
    1628  
    16291632        return d 
    16301633 
     
    16491652        d.addCallback(_check) 
    16501653        return d 
     1654 
     1655class Filter(unittest.TestCase, LogfileWriterMixin, LogfileReaderMixin): 
     1656 
     1657    def compare_events(self, a, b): 
     1658        # cmp(a,b) won't quite work, because two instances of CopiedFailure 
     1659        # loaded from the same pickle don't compare as equal 
     1660        self.failUnlessEqual(len(a), len(b)) 
     1661        for i in range(len(a)): 
     1662            a1,b1 = a[i],b[i] 
     1663            self.failUnlessEqual(set(a1.keys()), set(b1.keys())) 
     1664            for k in a1: 
     1665                if k == "d": 
     1666                    self.failUnlessEqual(set(a1["d"].keys()), 
     1667                                         set(b1["d"].keys())) 
     1668                    for k2 in a1["d"]: 
     1669                        if k2 == "failure": 
     1670                            f1 = a1["d"][k2] 
     1671                            f2 = b1["d"][k2] 
     1672                            self.failUnlessEqual(f1.value, f2.value) 
     1673                            self.failUnlessEqual(f1.getTraceback(), 
     1674                                                 f2.getTraceback()) 
     1675                        else: 
     1676                            self.failUnlessEqual(a1["d"][k2], b1["d"][k2]) 
     1677                else: 
     1678                    self.failUnlessEqual(a1[k], b1[k]) 
     1679                 
     1680 
     1681    def test_basic(self): 
     1682        self.basedir = "logging/Filter/basic" 
     1683        d = self.create_logfile() 
     1684        def _check(fn): 
     1685            events = self._read_logfile(fn) 
     1686            count = len(events) 
     1687            assert count == 5 
     1688 
     1689            dirname,filename = os.path.split(fn) 
     1690            fn2 = os.path.join(dirname, "filtered-" + filename) 
     1691 
     1692            # pass-through 
     1693            argv = ["flogtool", "filter", fn, fn2] 
     1694            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1695            self.failUnless("copied 5 of 5 events into new file" in out, out) 
     1696            self.compare_events(events, self._read_logfile(fn2)) 
     1697 
     1698            # convert to .bz2 while we're at it 
     1699            fn2bz2 = fn2 + ".bz2" 
     1700            argv = ["flogtool", "filter", fn, fn2bz2] 
     1701            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1702            self.failUnless("copied 5 of 5 events into new file" in out, out) 
     1703            self.compare_events(events, self._read_logfile(fn2bz2)) 
     1704 
     1705            # modify the file in place 
     1706            argv = ["flogtool", "filter", "--above", "20", fn2] 
     1707            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1708            self.failUnless("modifying event file in place" in out, out) 
     1709            self.failUnless("--above: removing events below level 20" in out, out) 
     1710            self.failUnless("copied 4 of 5 events into new file" in out, out) 
     1711            self.compare_events([events[0], events[1], events[3], events[4]], 
     1712                                self._read_logfile(fn2)) 
     1713 
     1714            # modify the file in place, two-argument version 
     1715            argv = ["flogtool", "filter", fn2, fn2] 
     1716            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1717            self.failUnless("modifying event file in place" in out, out) 
     1718            self.failUnless("copied 4 of 4 events into new file" in out, out) 
     1719            self.compare_events([events[0], events[1], events[3], events[4]], 
     1720                                self._read_logfile(fn2)) 
     1721 
     1722            # --above with a string argument 
     1723            argv = ["flogtool", "filter", "--above", "OPERATIONAL", fn, fn2] 
     1724            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1725            self.failUnless("--above: removing events below level 20" in out, out) 
     1726            self.failUnless("copied 4 of 5 events into new file" in out, out) 
     1727            self.compare_events([events[0], events[1], events[3], events[4]], 
     1728                                self._read_logfile(fn2)) 
     1729 
     1730            t_one = events[1]["d"]["time"] 
     1731            # we can only pass integers into --before and --after, so we'll 
     1732            # just test that we get all or nothing 
     1733            argv = ["flogtool", "filter", "--before", str(int(t_one - 10)), 
     1734                    fn, fn2] 
     1735            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1736            self.failUnless("copied 1 of 5 events into new file" in out, out) 
     1737            # we always get the header, so it's 1 instead of 0 
     1738            self.compare_events(events[:1], self._read_logfile(fn2)) 
     1739 
     1740            argv = ["flogtool", "filter", "--after", str(int(t_one + 10)), 
     1741                    fn, fn2] 
     1742            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1743            self.failUnless("copied 1 of 5 events into new file" in out, out) 
     1744            self.compare_events(events[:1], self._read_logfile(fn2)) 
     1745 
     1746            # --facility 
     1747            argv = ["flogtool", "filter", "--strip-facility", "big", fn, fn2] 
     1748            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1749            self.failUnless("--strip-facility: removing events for big and children" in out, out) 
     1750            self.failUnless("copied 4 of 5 events into new file" in out, out) 
     1751            self.compare_events([events[0],events[2],events[3],events[4]], 
     1752                                self._read_logfile(fn2)) 
     1753 
     1754            # pass-through, --verbose, read from .bz2 
     1755            argv = ["flogtool", "filter", "--verbose", fn2bz2, fn2] 
     1756            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1757            self.failUnless("copied 5 of 5 events into new file" in out, out) 
     1758            lines = [l.strip() for l in StringIO(out).readlines()] 
     1759            self.failUnlessEqual(lines, 
     1760                                 ["HEADER", "0", "1", "2", "3", 
     1761                                  "copied 5 of 5 events into new file"]) 
     1762            self.compare_events(events, self._read_logfile(fn2)) 
     1763 
     1764            # --from . This normally takes a base32 tubid prefix, but the 
     1765            # things we've logged all say ["from"]="local". So just test 
     1766            # all-or-nothing. 
     1767            argv = ["flogtool", "filter", "--from", "local", fn, fn2] 
     1768            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1769            self.failUnless("--from: retaining events only from tubid prefix local" in out, out) 
     1770            self.failUnless("copied 5 of 5 events into new file" in out, out) 
     1771            self.compare_events(events, self._read_logfile(fn2)) 
     1772 
     1773            argv = ["flogtool", "filter", "--from", "NOTlocal", fn, fn2] 
     1774            (out,err) = cli.run_flogtool(argv[1:], run_by_human=False) 
     1775            self.failUnless("--from: retaining events only from tubid prefix NOTlocal" in out, out) 
     1776            self.failUnless("copied 1 of 5 events into new file" in out, out) 
     1777            self.compare_events(events[:1], self._read_logfile(fn2)) 
     1778 
     1779 
     1780        d.addCallback(_check) 
     1781        return d 
     1782 
     1783 
    16511784 
    16521785class Web(unittest.TestCase):