summaryrefslogtreecommitdiffstats
path: root/misc/testsuite/harness.py
blob: d45398b70c9a42290deacf0e004cc1aba49334d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/usr/bin/env python
# encoding: utf-8
"""
link-testsuite/harness/run.py
Run or Generate test suite for link checkers

Created by olivier Thereaux on 2008-01-23.
Copyright (c) 2008 W3C. Licensed under the W3C Software License
http://www.w3.org/Consortium/Legal/copyright-software
"""

import os
import sys
import glob
import getopt
import unittest
import re

basedir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(basedir, "lib"))
from ValidatorsAPIs import W3CValidatorHTTP, W3CValidatorHTTP_test
from TestCase import ValidatorTestCase, ValidatorTestSuite, ValidatorTestCase_UT, ValidatorTestSuite_UT
from Documentation import Documentation
help_message = '''

Run or Generate test suite for markup validator(s)

Usage: harness.py [options] [run|sanity|doc]
    Options: 
        -h, --help: this manual you are reading
        -v, --verbose: verbose output
        -q, --quiet: suppress all output except errors
        --validator_uri: use a specific validator instance
          e.g http://validator.w3.org/check
        --id=collection_id: run a single collection from the test suite
          In run mode only, this filters the test suite and uses only
          a collection identified with id="..." 
          with its children tests and collections
    
    Modes:
        run: run the test suite 
        sanity: check that this code is still working 
            useful after using test cases or modifying code
        list: list the available test collections
        doc: generate an HTML index of the test cases
        (to be saved in ../../htdocs/dev/tests/index.html)
'''

class Usage(Exception):
    def __init__(self, msg):
        self.msg = msg

class TestRun(unittest.TestCase):
    def test_1_1_readTestCase(self):
        """Opening and parsing a Test Case"""
        basedir = getBaseDir()
        test_file = os.path.join(basedir, 'sample', 'collection_1.xml')


def main(argv=None):
    collection_id = None
    checker = None
    check_URI = None
    verbose=1
    if argv is None:
        argv = sys.argv
    try:
        try:
            opts, args = getopt.getopt(argv[1:], "ho:vq", ["help", "verbose", "quiet", "id=", "validator=", "validator_uri="])
            for (opt, value) in opts:
                if opt == "h" or opt == "--help":
                    raise Usage(help_message)
        except getopt.GetoptError as err:
            raise Usage(err)
    
        # option processing
        for option, value in opts:
            if option == "-v" or opt == "--verbose":
                verbose = 2
            if option == "-q" or opt == "--quiet":
                verbose = 0
            if option in ("-h", "--help"):
                raise Usage(help_message)
            if option in ("-o", "--output"):
                output = value
            if option == "--id":
                collection_id = value
            if option == "--validator":
                pass # TODO add selection of different validators
            if option == "--validator_uri":
                check_URI = value

        if len(args) == 0:
            raise Usage(help_message)
    
    except Usage as err:
        sys.stderr.write("%s: %s\n\t for help use --help\n" % \
                             (sys.argv[0].split("/")[-1], str(err.msg)))
        return 2

        
    if args[0] == "run":
        if checker == None:
            checker = W3CValidatorHTTP(check_URI=check_URI)
        else:
            pass # TODO add selection of different validators
        testsuite = buildTestSuite(collection_id=collection_id, checker=checker)
        runTestSuite(testsuite, verbose)
        
    elif args[0] == "sanity":
        suite1 = unittest.TestLoader().loadTestsFromTestCase(ValidatorTestCase_UT)
        suite2 = unittest.TestLoader().loadTestsFromTestCase(ValidatorTestSuite_UT)
        suite3 = unittest.TestLoader().loadTestsFromTestCase(TestRun)
        suite4 = unittest.TestLoader().loadTestsFromTestCase(W3CValidatorHTTP_test)
        suite = unittest.TestSuite([suite1, suite2, suite3, suite4])
        unittest.TextTestRunner(verbosity=verbose).run(suite)

    elif args[0] == "list":
        listCollections()

        
    elif args[0] == "doc":
        generateIndex()

def getBaseDir():
    basedir = os.path.dirname(os.path.abspath(__file__))
    return basedir
        
def buildTestSuite(ts_file=None, collection_id=None, checker=None):
    """read test suite XML file and build it"""
    test_suite = ValidatorTestSuite(checker=checker)
    if ts_file == None:
        basedir = getBaseDir()
        ts_file = os.path.join(basedir, 'catalog.xml')
    parsed_ts = test_suite.readTestSuiteFile(ts_file)
    filtered_ts = parsed_ts
    if collection_id != None:
        for collection in parsed_ts.findall(".//collection"):
            if collection.attrib.has_key("id"):
                if collection.attrib["id"] == collection_id: # this is the one we want, we keep this and its children
                    filtered_ts = collection
    test_suite.readTestCollection(filtered_ts)
    return test_suite

def runTestSuite(testsuite, verbose):
    """Describe each test collection in the test suite and run them"""
    for collection in testsuite.collections:
        print ("*** Running Collection #%s: %s" % (collection.collection_id, collection.title))
        if collection.countTestCases() > 0:
            unittest.TextTestRunner(verbosity=verbose).run(collection)

def listCollections():
    index = Documentation('list')
    test_suite = buildTestSuite()
    index.addTestSuite(test_suite)
    print (index.generate(template_path=os.path.join(basedir, "templates")).encode('utf-8'))


def generateIndex():
    index = Documentation('index')
    test_suite = buildTestSuite()
    index.addTestSuite(test_suite)
    print (index.generate(template_path=os.path.join(basedir, "templates")).encode('utf-8'))



if __name__ == "__main__":
    sys.exit(main())