Ticket #5989: examples-react-5989-2.patch

File examples-react-5989-2.patch, 11.5 KB (added by Richard Wall, 7 years ago)

An updated patch without the tests for executability

  • doc/names/examples/dns-service.py

    === modified file 'doc/names/examples/dns-service.py'
     
    44# See LICENSE for details.
    55
    66"""
    7 Sample app to lookup SRV records in DNS.
    8 To run this script:
    9 $ python dns-service.py <service> <proto> <domain>
    10 where,
    11 service = the symbolic name of the desired service.
    12 proto = the transport protocol of the desired service; this is usually either TCP or UDP.
    13 domain =  the domain name for which this record is valid.
    14 e.g.:
    15 $ python dns-service.py sip udp yahoo.com
    16 $ python dns-service.py xmpp-client tcp gmail.com
     7USAGE: python dns-service.py SERVICE PROTO DOMAINNAME
     8
     9Print the SRV records for a given DOMAINNAME eg
     10
     11 python dns-service.py xmpp-client tcp gmail.com
     12
     13SERVICE: the symbolic name of the desired service.
     14
     15PROTO: the transport protocol of the desired service; this is usually
     16       either TCP or UDP.
     17
     18DOMAINNAME: the domain name for which this record is valid.
    1719"""
    18 
    19 from twisted.names import client
    20 from twisted.internet import reactor
    2120import sys
    2221
    23 def printAnswer((answers, auth, add)):
    24     if not len(answers):
    25         print 'No answers'
     22from twisted.names import client, error
     23from twisted.internet.task import react
     24
     25
     26def printResult(records, domainname):
     27    """
     28    Print the SRV records for the domainname or an error message if no
     29    SRV records were found.
     30    """
     31    answers, authority, additional = records
     32    if answers:
     33        sys.stdout.write(
     34            domainname + ' IN \n ' +
     35            '\n '.join(str(x.payload) for x in answers) +
     36            '\n')
    2637    else:
    27         print '\n'.join([str(x.payload) for x in answers])
    28     reactor.stop()
    29 
    30 def printFailure(arg):
    31     print "error: could not resolve:", arg
    32     reactor.stop()
    33 
    34 try:
    35     service, proto, domain = sys.argv[1:]
    36 except ValueError:
    37     sys.stderr.write('%s: usage:\n' % sys.argv[0] +
    38                      '  %s SERVICE PROTO DOMAIN\n' % sys.argv[0])
    39     sys.exit(1)
    40 
    41 resolver = client.Resolver('/etc/resolv.conf')
    42 d = resolver.lookupService('_%s._%s.%s' % (service, proto, domain), [1])
    43 d.addCallbacks(printAnswer, printFailure)
    44 
    45 reactor.run()
     38        sys.stderr.write(
     39            'ERROR: No SRV records found for name %r\n' % (domainname,))
     40
     41
     42def printError(failure, domainname):
     43    """
     44    Print a friendly error message if the domainname could not be
     45    resolved.
     46    """
     47    failure.trap(error.DNSNameError)
     48    sys.stderr.write('ERROR: domain name not found %r\n' % (domainname,))
     49
     50
     51def main(reactor, *argv):
     52    try:
     53        service, proto, domainname = sys.argv[1:]
     54    except ValueError:
     55        sys.stderr.write(
     56            __doc__.lstrip() + '\n'
     57            'ERROR: incorrect command line arguments\n')
     58        raise SystemExit(1)
     59
     60    resolver = client.Resolver('/etc/resolv.conf')
     61    domainname = '_%s._%s.%s' % (service, proto, domainname)
     62    d = resolver.lookupService(domainname)
     63    d.addCallback(printResult, domainname)
     64    d.addErrback(printError, domainname)
     65    return d
     66
     67if __name__ == '__main__':
     68    react(main, sys.argv[1:])
  • doc/names/examples/index.xhtml

    === modified file 'doc/names/examples/index.xhtml'
     
    1212
    1313    <h2>DNS (Twisted Names)</h2>
    1414    <ul>
    15         <li><a href="testdns.py">testdns.py</a> - Prints the results of an Address record lookup, Mail-Exchanger record lookup, and Nameserver record lookup for the given hostname for a given hostname.</li>
     15        <li><a href="testdns.py">testdns.py</a> - Prints the results of an Address record lookup, Mail-Exchanger record lookup, and Nameserver record lookup for the given domain name.</li>
    1616        <li><a href="dns-service.py">dns-service.py</a> - Searches for SRV records in DNS.</li>
    1717        <li><a href="gethostbyname.py">gethostbyname.py</a> - Returns the IP address for a given hostname.</li>
    1818    </ul>
    1919</body>
    2020</html>
    21 
  • doc/names/examples/testdns.py

    === modified file 'doc/names/examples/testdns.py' (properties changed: -x to +x)
     
    44# See LICENSE for details.
    55
    66"""
    7 Prints the results of an Address record lookup, Mail-Exchanger record
    8 lookup, and Nameserver record lookup for the given hostname for a
    9 given hostname.
    10 
    11 To run this script:
    12 $ python testdns.py <hostname>
    13 e.g.:
    14 $ python testdns.py www.google.com
     7USAGE: python testdns.py DOMAINNAME
     8
     9Print the Address records, Mail-Exchanger records and the Nameserver
     10records for the given domain name. eg
     11
     12 python testdns.py google.com
    1513"""
    1614import sys
    1715
    18 from twisted.names import client
    19 from twisted.internet import defer, reactor
    20 from twisted.names import dns, error
    21 
    22 
    23 r = client.Resolver('/etc/resolv.conf')
    24 
    25 
    26 def formatResult(a, heading):
    27     answer, authority, additional = a
     16from twisted.internet import defer
     17from twisted.internet.task import react
     18from twisted.names import client, dns, error
     19
     20
     21def formatRecords(records, heading):
     22    """
     23    Extract only the answer records and return them as a neatly
     24    formatted string beneath the given heading.
     25    """
     26    answers, authority, additional = records
    2827    lines = ['# ' + heading]
    29     for a in answer:
     28    for a in answers:
    3029        line = [
    3130            a.name,
    3231            dns.QUERY_CLASSES.get(a.cls, 'UNKNOWN (%d)' % (a.cls,)),
     
    3635    return '\n'.join(line for line in lines)
    3736
    3837
    39 def printError(f):
    40     f.trap(defer.FirstError)
    41     f = f.value.subFailure
    42     f.trap(error.DomainError)
    43     print f.value.__class__.__name__, f.value.message.queries
    44 
    45 
    46 def printResults(res):
    47     for r in res:
    48         print r
    49         print
    50 
    51 
    52 if __name__ == '__main__':
    53     domainname = sys.argv[1]
    54 
     38def printResults(results, domainname):
     39    """
     40    Print the formatted results for each DNS record type.
     41    """
     42    sys.stdout.write('# Domain Summary for %r\n' % (domainname,))
     43    sys.stdout.write('\n\n'.join(results) + '\n')
     44
     45
     46def printError(failure, domainname):
     47    """
     48    Print a friendly error message if the hostname could not be
     49    resolved.
     50    """
     51    failure.trap(defer.FirstError)
     52    failure = failure.value.subFailure
     53    failure.trap(error.DNSNameError)
     54    sys.stderr.write('ERROR: domain name not found %r\n' % (domainname,))
     55
     56
     57def main(reactor, *argv):
     58    try:
     59        domainname = argv[0]
     60    except IndexError:
     61        sys.stderr.write(
     62            __doc__.lstrip() + '\n'
     63            'ERROR: missing DOMAINNAME argument\n')
     64        raise SystemExit(1)
     65
     66    r = client.Resolver('/etc/resolv.conf')
    5567    d = defer.gatherResults([
    5668            r.lookupAddress(domainname).addCallback(
    57                 formatResult, 'Addresses'),
     69                formatRecords, 'Addresses'),
    5870            r.lookupMailExchange(domainname).addCallback(
    59                 formatResult, 'Mail Exchangers'),
     71                formatRecords, 'Mail Exchangers'),
    6072            r.lookupNameservers(domainname).addCallback(
    61                 formatResult, 'Nameservers'),
     73                formatRecords, 'Nameservers'),
    6274            ], consumeErrors=True)
    6375
    64     d.addCallbacks(printResults, printError)
    65 
    66     d.addBoth(lambda ign: reactor.stop())
    67 
    68     reactor.run()
     76    d.addCallback(printResults, domainname)
     77    d.addErrback(printError, domainname)
     78    return d
     79
     80
     81if __name__ == '__main__':
     82    react(main, sys.argv[1:])
  • twisted/names/test/test_examples.py

    === added file 'twisted/names/test/test_examples.py'
     
     1# Copyright (c) Twisted Matrix Laboratories.
     2# See LICENSE for details.
     3
     4"""
     5Tests for L{twisted.names} example scripts.
     6"""
     7
     8import sys
     9from StringIO import StringIO
     10
     11from twisted.python.filepath import FilePath
     12from twisted.trial.unittest import SkipTest, TestCase
     13
     14
     15class ExampleTestBase(object):
     16    """
     17    This is a mixin which adds an example to the path, tests it, and then
     18    removes it from the path and unimports the modules which the test loaded.
     19    Test cases which test example code and documentation listings should use
     20    this.
     21
     22    This is done this way so that examples can live in isolated path entries,
     23    next to the documentation, replete with their own plugin packages and
     24    whatever other metadata they need.  Also, example code is a rare instance
     25    of it being valid to have multiple versions of the same code in the
     26    repository at once, rather than relying on version control, because
     27    documentation will often show the progression of a single piece of code as
     28    features are added to it, and we want to test each one.
     29    """
     30
     31    examplePath = None
     32
     33    def setUp(self):
     34        """
     35        Add our example directory to the path and record which modules are
     36        currently loaded.
     37        """
     38        self.fakeErr = StringIO()
     39        self.originalErr, sys.stderr = sys.stderr, self.fakeErr
     40        self.originalPath = sys.path[:]
     41        self.originalModules = sys.modules.copy()
     42        here = FilePath(__file__).parent().parent().parent().parent()
     43        for childName in self.examplePath:
     44            here = here.child(childName)
     45        if not here.exists():
     46            raise SkipTest(
     47                "Examples (%s) not found - cannot test" % (here.path,))
     48        sys.path.append(here.parent().path)
     49        # Import the example as a module
     50        moduleName = here.basename().split('.')[0]
     51        self.example = __import__(moduleName)
     52        self.examplePath = here
     53
     54
     55    def tearDown(self):
     56        """
     57        Remove the example directory from the path and remove all
     58        modules loaded by the test from sys.modules.
     59        """
     60        sys.modules.clear()
     61        sys.modules.update(self.originalModules)
     62        sys.path[:] = self.originalPath
     63        sys.stderr = self.originalErr
     64
     65
     66    def test_shebang(self):
     67        """
     68        The example scripts start with the standard shebang line.
     69        """
     70        self.assertEquals(
     71            self.examplePath.open().readline().rstrip(),
     72            '#!/usr/bin/env python')
     73
     74
     75    def test_usageConsistency(self):
     76        """
     77        The example script prints a usage message to stderr if it is
     78        passed unrecognised command line arguments.
     79
     80        The first line should contain a USAGE summary, explaining the
     81        accepted command arguments.
     82
     83        The last line should contain an ERROR summary, explaining that
     84        incorrect arguments were supplied.
     85        """
     86        self.assertRaises(SystemExit, self.example.main, None)
     87        err = self.fakeErr.getvalue().splitlines()
     88        self.assertTrue(
     89            err[0].startswith('USAGE:'),
     90            'Usage message first line should start with "USAGE:". '
     91            'Actual: %r' % (err[0],))
     92        self.assertTrue(
     93            err[-1].startswith('ERROR:'),
     94            'Usage message last line should start with "ERROR:" '
     95            'Actual: %r' % (err[-1],))
     96
     97
     98
     99class TestDnsTests(ExampleTestBase, TestCase):
     100    """
     101    Test the testdns.py example script.
     102    """
     103
     104    examplePath = 'doc/names/examples/testdns.py'.split('/')
     105
     106
     107class GetHostByNameTests(ExampleTestBase, TestCase):
     108    """
     109    Test the gethostbyname.py example script.
     110    """
     111
     112    examplePath = 'doc/names/examples/gethostbyname.py'.split('/')
     113
     114
     115class DnsServiceTests(ExampleTestBase, TestCase):
     116    """
     117    Test the dns-service.py example script.
     118    """
     119
     120    examplePath = 'doc/names/examples/dns-service.py'.split('/')