1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """
20 Contains utilities used by test launchers when running, printing, cleaning or making new tests.
21
22 The module includes the L{pysys.launcher.createDescriptors} method which locates test
23 descriptors based upon a given starting location on the file system, the chosen range
24 of test ids, the test type, the specified requirements, and the include and exclude lists.
25
26 Utilities defined in the module can be used by any launchers, either distributed
27 with the framework, or created as an extension to it. Currently the framework
28 distributes the console launcher module only - see L{pysys.launcher.console}. This
29 module uses the current working directory in a command shell as the starting location
30 on the file system, and provides utilities for parsing command line arguments in order
31 to launch operations against a set of tests etc.
32
33 """
34 __all__ = [ "createDescriptors",
35 "console" ]
36
37 import sys, os, os.path, glob, getopt, re, string, logging
38
39
40 try:
41 set
42 except NameError:
43 import sets
44 from sets import Set as set
45
46 from pysys import log
47 from pysys.constants import *
48 from pysys.exceptions import *
49 from pysys.xml.descriptor import XMLDescriptorParser
50
51
53 """Create a list of descriptor objects representing a set of tests to run, returning the list.
54
55 @param testIdSpecs: A list of strings specifying the set of testcase identifiers
56 @param type: The type of the tests to run (manual | auto)
57 @param includes: A list of test groups to include in the returned set
58 @param excludes: A list of test groups to exclude in the returned set
59 @param trace: A list of requirements to indicate tests to include in the returned set
60 @param dir: The parent directory to search for runnable tests
61 @return: List of L{pysys.xml.descriptor.XMLDescriptorContainer} objects
62 @rtype: list
63 @raises Exception: Raised if not testcases can be found or are returned by the requested input parameters
64
65 """
66 descriptors = []
67 descriptorfiles = []
68 ignoreSet = set(OSWALK_IGNORES)
69 descriptorSet =set(DEFAULT_DESCRIPTOR)
70
71 if dir is None: dir = os.getcwd()
72 for root, dirs, files in os.walk(dir):
73 intersection = descriptorSet & set(files)
74 if intersection : descriptorfiles.append(os.path.join(root, intersection.pop()))
75 for ignore in (ignoreSet & set(dirs)): dirs.remove(ignore)
76
77 for descriptorfile in descriptorfiles:
78 try:
79 descriptors.append(XMLDescriptorParser(descriptorfile).getContainer())
80 except Exception, value:
81 print sys.exc_info()[0], sys.exc_info()[1]
82 log.info("Error reading descriptorfile %s" % descriptorfile)
83 descriptors = sorted(descriptors, key=lambda x: x.file)
84
85
86 tests = []
87 if testIdSpecs == []:
88 tests = descriptors
89 else:
90 def idMatch(descriptorId, specId):
91 return specId==descriptorId or (specId.isdigit() and re.match('.+_0*%s$'%specId, descriptorId))
92
93 for t in testIdSpecs:
94 try:
95 if re.search('^[\w_]*$', t):
96 for i in range(0,len(descriptors)):
97 if idMatch(descriptors[i].id, t): index = i
98 tests.extend(descriptors[index:index+1])
99
100 elif re.search('^:[\w_]*', t):
101 for i in range(0,len(descriptors)):
102 if idMatch(descriptors[i].id, string.split(t, ':')[1]): index = i
103 tests.extend(descriptors[:index+1])
104
105 elif re.search('^[\w_]*:$', t):
106 for i in range(0,len(descriptors)):
107 if idMatch(descriptors[i].id, string.split(t, ':')[0]): index = i
108 tests.extend(descriptors[index:])
109
110 elif re.search('^[\w_]*:[\w_]*$', t):
111 for i in range(0,len(descriptors)):
112 if idMatch(descriptors[i].id, string.split(t, ':')[0]): index1 = i
113 if idMatch(descriptors[i].id, string.split(t, ':')[1]): index2 = i
114 tests.extend(descriptors[index1:index2+1])
115
116 else:
117 tests.extend([descriptors[i] for i in range(0,len(descriptors)) if re.search(t, descriptors[i].id)])
118
119 except :
120 raise Exception("Unable to locate requested testcase(s)")
121
122
123 if type:
124 index = 0
125 while index != len(tests):
126 if type != tests[index].type:
127 tests.pop(index)
128 else:
129 index = index + 1
130
131
132 if len(excludes) != 0:
133 index = 0
134 while index != len(tests):
135 remove = False
136
137 for exclude in excludes:
138 if exclude in tests[index].groups:
139 remove = True
140 break
141
142 if remove:
143 tests.pop(index)
144 else:
145 index = index +1
146
147 if includes != []:
148 index = 0
149 while index != len(tests):
150 keep = False
151
152 for include in includes:
153 if include in tests[index].groups:
154 keep = True
155 break
156
157 if not keep:
158 tests.pop(index)
159 else:
160 index = index +1
161
162
163
164 if trace:
165 index = 0
166 while index != len(tests):
167 if trace not in tests[index].traceability :
168 tests.pop(index)
169 else:
170 index = index + 1
171
172 if len(tests) == 0:
173 raise Exception("The supplied options did not result in the selection of any tests")
174 else:
175 return tests
176