Ticket #5596: names-examples-tests-5596.patch

File names-examples-tests-5596.patch, 4.0 KB (added by rwall, 23 months ago)

Some basic tests for these examples

  • 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.tap}. 
     6""" 
     7import os 
     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("Examples (%s) not found - cannot test" % (here.path,)) 
     47        sys.path.append(here.parent().path) 
     48        # Import the example as a module 
     49        moduleName = here.basename().split('.')[0] 
     50        self.example = __import__(moduleName) 
     51        self.examplePath = here 
     52 
     53 
     54    def tearDown(self): 
     55        """ 
     56        Remove the example directory from the path and remove all modules loaded by 
     57        the test from sys.modules. 
     58        """ 
     59        sys.modules.clear() 
     60        sys.modules.update(self.originalModules) 
     61        sys.path[:] = self.originalPath 
     62        sys.stderr = self.originalErr 
     63 
     64 
     65    def test_executable(self): 
     66        """ 
     67        The example scripts should start with the standard shebang 
     68        line and should be executable. 
     69        """ 
     70        self.assertEquals( 
     71            self.examplePath.open().readline().rstrip(), 
     72            '#!/usr/bin/env python') 
     73 
     74        mode = os.stat(self.examplePath.path).st_mode 
     75        self.assertEquals(mode, 33277) 
     76 
     77 
     78    def test_usage(self): 
     79        """ 
     80        The example script prints a usage message to stderr and raises 
     81        SystemExit if it is passed incorrect command line 
     82        arguments. The first line should contain a USAGE summary and 
     83        the last line should contain an ERROR, explaining that 
     84        incorrect arguments were supplied. 
     85        """ 
     86        self.assertRaises(SystemExit, self.example.main, None) 
     87        err = self.fakeErr.getvalue().splitlines() 
     88        self.assertEquals(err[0][:len('USAGE:')], 'USAGE:') 
     89        self.assertEquals(err[-1][:len('ERROR:')], 'ERROR:') 
     90 
     91 
     92class TestDnsTests(ExampleTestBase, TestCase): 
     93    """ 
     94    Tests for the testdns.py example script. 
     95    """ 
     96 
     97    examplePath = 'doc/names/examples/testdns.py'.split('/') 
     98 
     99 
     100class GetHostByNameTests(ExampleTestBase, TestCase): 
     101    """ 
     102    Tests for the gethostbyname.py example script. 
     103    """ 
     104 
     105    examplePath = 'doc/names/examples/gethostbyname.py'.split('/') 
     106 
     107 
     108class DnsServiceTests(ExampleTestBase, TestCase): 
     109    """ 
     110    Tests for the dns-service.py example script. 
     111    """ 
     112 
     113    examplePath = 'doc/names/examples/dns-service.py'.split('/')