summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/classes/testimage.bbclass6
-rw-r--r--meta/classes/testsdk.bbclass6
-rw-r--r--meta/lib/oeqa/oetest.py197
3 files changed, 103 insertions, 106 deletions
diff --git a/meta/classes/testimage.bbclass b/meta/classes/testimage.bbclass
index 7f9c918273..53c6174ac5 100644
--- a/meta/classes/testimage.bbclass
+++ b/meta/classes/testimage.bbclass
@@ -195,7 +195,7 @@ def testimage_main(d):
195 import oeqa.runtime 195 import oeqa.runtime
196 import time 196 import time
197 import signal 197 import signal
198 from oeqa.oetest import loadTests, runTests, ImageTestContext 198 from oeqa.oetest import ImageTestContext
199 from oeqa.targetcontrol import get_target_controller 199 from oeqa.targetcontrol import get_target_controller
200 from oeqa.utils.dump import get_host_dumper 200 from oeqa.utils.dump import get_host_dumper
201 201
@@ -219,7 +219,7 @@ def testimage_main(d):
219 # we are doing that to find compile errors in the tests themselves 219 # we are doing that to find compile errors in the tests themselves
220 # before booting the image 220 # before booting the image
221 try: 221 try:
222 loadTests(tc) 222 tc.loadTests()
223 except Exception as e: 223 except Exception as e:
224 import traceback 224 import traceback
225 bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) 225 bb.fatal("Loading tests failed:\n%s" % traceback.format_exc())
@@ -233,7 +233,7 @@ def testimage_main(d):
233 try: 233 try:
234 target.start() 234 target.start()
235 starttime = time.time() 235 starttime = time.time()
236 result = runTests(tc) 236 result = tc.runTests()
237 stoptime = time.time() 237 stoptime = time.time()
238 if result.wasSuccessful(): 238 if result.wasSuccessful():
239 bb.plain("%s - Ran %d test%s in %.3fs" % (pn, result.testsRun, result.testsRun != 1 and "s" or "", stoptime - starttime)) 239 bb.plain("%s - Ran %d test%s in %.3fs" % (pn, result.testsRun, result.testsRun != 1 and "s" or "", stoptime - starttime))
diff --git a/meta/classes/testsdk.bbclass b/meta/classes/testsdk.bbclass
index 47bad29096..ba8897e5ea 100644
--- a/meta/classes/testsdk.bbclass
+++ b/meta/classes/testsdk.bbclass
@@ -13,7 +13,7 @@ def testsdk_main(d):
13 import oeqa.sdk 13 import oeqa.sdk
14 import time 14 import time
15 import subprocess 15 import subprocess
16 from oeqa.oetest import loadTests, runTests, SDKTestContext 16 from oeqa.oetest import SDKTestContext
17 17
18 pn = d.getVar("PN", True) 18 pn = d.getVar("PN", True)
19 bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR", True)) 19 bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR", True))
@@ -40,13 +40,13 @@ def testsdk_main(d):
40 # we are doing that to find compile errors in the tests themselves 40 # we are doing that to find compile errors in the tests themselves
41 # before booting the image 41 # before booting the image
42 try: 42 try:
43 loadTests(tc, "sdk") 43 tc.loadTests()
44 except Exception as e: 44 except Exception as e:
45 import traceback 45 import traceback
46 bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) 46 bb.fatal("Loading tests failed:\n%s" % traceback.format_exc())
47 47
48 starttime = time.time() 48 starttime = time.time()
49 result = runTests(tc, "sdk") 49 result = tc.runTests()
50 stoptime = time.time() 50 stoptime = time.time()
51 if result.wasSuccessful(): 51 if result.wasSuccessful():
52 bb.plain("%s SDK(%s):%s - Ran %d test%s in %.3fs" % (pn, os.path.basename(tcname), os.path.basename(sdkenv),result.testsRun, result.testsRun != 1 and "s" or "", stoptime - starttime)) 52 bb.plain("%s SDK(%s):%s - Ran %d test%s in %.3fs" % (pn, os.path.basename(tcname), os.path.basename(sdkenv),result.testsRun, result.testsRun != 1 and "s" or "", stoptime - starttime))
diff --git a/meta/lib/oeqa/oetest.py b/meta/lib/oeqa/oetest.py
index 7f07037a1f..16705cc3fe 100644
--- a/meta/lib/oeqa/oetest.py
+++ b/meta/lib/oeqa/oetest.py
@@ -45,106 +45,6 @@ def filterByTagExp(testsuite, tagexp):
45 caseList.append(filterByTagExp(each, tagexp)) 45 caseList.append(filterByTagExp(each, tagexp))
46 return testsuite.__class__(caseList) 46 return testsuite.__class__(caseList)
47 47
48def loadTests(tc, type="runtime"):
49 if type == "runtime":
50 # set the context object passed from the test class
51 setattr(oeTest, "tc", tc)
52 # set ps command to use
53 setattr(oeRuntimeTest, "pscmd", "ps -ef" if oeTest.hasPackage("procps") else "ps")
54 # prepare test suite, loader and runner
55 suite = unittest.TestSuite()
56 elif type == "sdk":
57 # set the context object passed from the test class
58 setattr(oeTest, "tc", tc)
59 testloader = unittest.TestLoader()
60 testloader.sortTestMethodsUsing = None
61 suites = [testloader.loadTestsFromName(name) for name in tc.testslist]
62 suites = filterByTagExp(suites, getattr(tc, "tagexp", None))
63
64 def getTests(test):
65 '''Return all individual tests executed when running the suite.'''
66 # Unfortunately unittest does not have an API for this, so we have
67 # to rely on implementation details. This only needs to work
68 # for TestSuite containing TestCase.
69 method = getattr(test, '_testMethodName', None)
70 if method:
71 # leaf case: a TestCase
72 yield test
73 else:
74 # Look into TestSuite.
75 tests = getattr(test, '_tests', [])
76 for t1 in tests:
77 for t2 in getTests(t1):
78 yield t2
79
80 # Determine dependencies between suites by looking for @skipUnlessPassed
81 # method annotations. Suite A depends on suite B if any method in A
82 # depends on a method on B.
83 for suite in suites:
84 suite.dependencies = []
85 suite.depth = 0
86 for test in getTests(suite):
87 methodname = getattr(test, '_testMethodName', None)
88 if methodname:
89 method = getattr(test, methodname)
90 depends_on = getattr(method, '_depends_on', None)
91 if depends_on:
92 for dep_suite in suites:
93 if depends_on in [getattr(t, '_testMethodName', None) for t in getTests(dep_suite)]:
94 if dep_suite not in suite.dependencies and \
95 dep_suite is not suite:
96 suite.dependencies.append(dep_suite)
97 break
98 else:
99 logger.warning("Test %s was declared as @skipUnlessPassed('%s') but that test is either not defined or not active. Will run the test anyway." %
100 (test, depends_on))
101 # Use brute-force topological sort to determine ordering. Sort by
102 # depth (higher depth = must run later), with original ordering to
103 # break ties.
104 def set_suite_depth(suite):
105 for dep in suite.dependencies:
106 new_depth = set_suite_depth(dep) + 1
107 if new_depth > suite.depth:
108 suite.depth = new_depth
109 return suite.depth
110 for index, suite in enumerate(suites):
111 set_suite_depth(suite)
112 suite.index = index
113 suites.sort(cmp=lambda a,b: cmp((a.depth, a.index), (b.depth, b.index)))
114 return testloader.suiteClass(suites)
115
116_buffer = ""
117
118def custom_verbose(msg, *args, **kwargs):
119 global _buffer
120 if msg[-1] != "\n":
121 _buffer += msg
122 else:
123 _buffer += msg
124 try:
125 bb.plain(_buffer.rstrip("\n"), *args, **kwargs)
126 except NameError:
127 logger.info(_buffer.rstrip("\n"), *args, **kwargs)
128 _buffer = ""
129
130def runTests(tc, type="runtime"):
131
132 suite = loadTests(tc, type)
133 logger.info("Test modules %s" % tc.testslist)
134 if hasattr(tc, "tagexp") and tc.tagexp:
135 logger.info("Filter test cases by tags: %s" % tc.tagexp)
136 logger.info("Found %s tests" % suite.countTestCases())
137 runner = unittest.TextTestRunner(verbosity=2)
138 try:
139 if bb.msg.loggerDefaultVerbose:
140 runner.stream.write = custom_verbose
141 except NameError:
142 # Not in bb environment?
143 pass
144 result = runner.run(suite)
145
146 return result
147
148@LogResults 48@LogResults
149class oeTest(unittest.TestCase): 49class oeTest(unittest.TestCase):
150 50
@@ -253,6 +153,19 @@ def skipModuleUnless(cond, reason):
253 if not cond: 153 if not cond:
254 skipModule(reason, 3) 154 skipModule(reason, 3)
255 155
156_buffer_logger = ""
157def custom_verbose(msg, *args, **kwargs):
158 global _buffer_logger
159 if msg[-1] != "\n":
160 _buffer_logger += msg
161 else:
162 _buffer_logger += msg
163 try:
164 bb.plain(_buffer_logger.rstrip("\n"), *args, **kwargs)
165 except NameError:
166 logger.info(_buffer_logger.rstrip("\n"), *args, **kwargs)
167 _buffer_logger = ""
168
256class TestContext(object): 169class TestContext(object):
257 def __init__(self, d): 170 def __init__(self, d):
258 self.d = d 171 self.d = d
@@ -324,6 +237,86 @@ class TestContext(object):
324 237
325 return testslist 238 return testslist
326 239
240 def loadTests(self):
241 setattr(oeTest, "tc", self)
242
243 testloader = unittest.TestLoader()
244 testloader.sortTestMethodsUsing = None
245 suites = [testloader.loadTestsFromName(name) for name in self.testslist]
246 suites = filterByTagExp(suites, getattr(self, "tagexp", None))
247
248 def getTests(test):
249 '''Return all individual tests executed when running the suite.'''
250 # Unfortunately unittest does not have an API for this, so we have
251 # to rely on implementation details. This only needs to work
252 # for TestSuite containing TestCase.
253 method = getattr(test, '_testMethodName', None)
254 if method:
255 # leaf case: a TestCase
256 yield test
257 else:
258 # Look into TestSuite.
259 tests = getattr(test, '_tests', [])
260 for t1 in tests:
261 for t2 in getTests(t1):
262 yield t2
263
264 # Determine dependencies between suites by looking for @skipUnlessPassed
265 # method annotations. Suite A depends on suite B if any method in A
266 # depends on a method on B.
267 for suite in suites:
268 suite.dependencies = []
269 suite.depth = 0
270 for test in getTests(suite):
271 methodname = getattr(test, '_testMethodName', None)
272 if methodname:
273 method = getattr(test, methodname)
274 depends_on = getattr(method, '_depends_on', None)
275 if depends_on:
276 for dep_suite in suites:
277 if depends_on in [getattr(t, '_testMethodName', None) for t in getTests(dep_suite)]:
278 if dep_suite not in suite.dependencies and \
279 dep_suite is not suite:
280 suite.dependencies.append(dep_suite)
281 break
282 else:
283 logger.warning("Test %s was declared as @skipUnlessPassed('%s') but that test is either not defined or not active. Will run the test anyway." %
284 (test, depends_on))
285
286 # Use brute-force topological sort to determine ordering. Sort by
287 # depth (higher depth = must run later), with original ordering to
288 # break ties.
289 def set_suite_depth(suite):
290 for dep in suite.dependencies:
291 new_depth = set_suite_depth(dep) + 1
292 if new_depth > suite.depth:
293 suite.depth = new_depth
294 return suite.depth
295
296 for index, suite in enumerate(suites):
297 set_suite_depth(suite)
298 suite.index = index
299 suites.sort(cmp=lambda a,b: cmp((a.depth, a.index), (b.depth, b.index)))
300
301 self.suite = testloader.suiteClass(suites)
302
303 return self.suite
304
305 def runTests(self):
306 logger.info("Test modules %s" % self.testslist)
307 if hasattr(self, "tagexp") and self.tagexp:
308 logger.info("Filter test cases by tags: %s" % self.tagexp)
309 logger.info("Found %s tests" % self.suite.countTestCases())
310 runner = unittest.TextTestRunner(verbosity=2)
311 try:
312 if bb.msg.loggerDefaultVerbose:
313 runner.stream.write = custom_verbose
314 except NameError:
315 # Not in bb environment?
316 pass
317
318 return runner.run(self.suite)
319
327class ImageTestContext(TestContext): 320class ImageTestContext(TestContext):
328 def __init__(self, d, target, host_dumper): 321 def __init__(self, d, target, host_dumper):
329 super(ImageTestContext, self).__init__(d) 322 super(ImageTestContext, self).__init__(d)
@@ -374,6 +367,10 @@ class ImageTestContext(TestContext):
374 def _get_test_suites_required(self): 367 def _get_test_suites_required(self):
375 return [t for t in self.d.getVar("TEST_SUITES", True).split() if t != "auto"] 368 return [t for t in self.d.getVar("TEST_SUITES", True).split() if t != "auto"]
376 369
370 def loadTests(self):
371 super(ImageTestContext, self).loadTests()
372 setattr(oeRuntimeTest, "pscmd", "ps -ef" if oeTest.hasPackage("procps") else "ps")
373
377class SDKTestContext(TestContext): 374class SDKTestContext(TestContext):
378 def __init__(self, d, sdktestdir, sdkenv): 375 def __init__(self, d, sdktestdir, sdkenv):
379 super(SDKTestContext, self).__init__(d) 376 super(SDKTestContext, self).__init__(d)