1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 """Module containing information about the host-driven tests."""
11 from pylib
.host_driven
import tests_annotations
13 from pylib
import constants
16 os
.path
.join(constants
.DIR_SOURCE_ROOT
,
17 'build', 'util', 'lib', 'common'))
19 import unittest_util
# pylint: disable=F0401
21 class TestInfo(object):
22 """An object containing and representing a test function, plus metadata."""
24 def __init__(self
, runnable
, set_up
=None, tear_down
=None):
25 # The actual test function/method.
26 self
.runnable
= runnable
27 # Qualified name of test function/method (e.g. FooModule.testBar).
28 self
.qualified_name
= self
._GetQualifiedName
(runnable
)
29 # setUp and teardown functions, if any.
31 self
.tear_down
= tear_down
34 def _GetQualifiedName(runnable
):
35 """Helper method to infer a runnable's name and module name.
37 Many filters and lists presuppose a format of module_name.testMethodName.
38 To make this easy on everyone, we use some reflection magic to infer this
42 runnable: the test method to get the qualified name for
45 qualified name for this runnable, incl. module name and method name.
47 runnable_name
= runnable
.__name
__
48 # See also tests_annotations.
49 module_name
= os
.path
.splitext(
50 os
.path
.basename(runnable
.__globals
__['__file__']))[0]
51 return '.'.join([module_name
, runnable_name
])
54 return self
.qualified_name
57 class TestInfoCollection(object):
58 """A collection of TestInfo objects which facilitates filtering."""
61 """Initialize a new TestInfoCollection."""
62 # Master list of all valid tests.
65 def AddTests(self
, test_infos
):
66 """Adds a set of tests to this collection.
68 The user may then retrieve them, optionally according to criteria, via
72 test_infos: a list of TestInfos representing test functions/methods.
74 self
.all_tests
= test_infos
76 def GetAvailableTests(self
, annotations
, exclude_annotations
, name_filter
):
77 """Get a collection of TestInfos which match the supplied criteria.
80 annotations: List of annotations. Each test in the returned list is
81 annotated with atleast one of these annotations.
82 exclude_annotations: List of annotations. The tests in the returned
83 list are not annotated with any of these annotations.
84 name_filter: name filter which tests must match, if any
87 List of available tests.
89 available_tests
= self
.all_tests
91 # Filter out tests which match neither the requested annotation, nor the
92 # requested name filter, if any.
93 available_tests
= [t
for t
in available_tests
if
94 self
._AnnotationIncludesTest
(t
, annotations
)]
95 if annotations
and len(annotations
) == 1 and annotations
[0] == 'SmallTest':
96 tests_without_annotation
= [
97 t
for t
in self
.all_tests
if
98 not tests_annotations
.AnnotatedFunctions
.GetTestAnnotations(
100 test_names
= [t
.qualified_name
for t
in tests_without_annotation
]
101 logging
.warning('The following tests do not contain any annotation. '
102 'Assuming "SmallTest":\n%s',
103 '\n'.join(test_names
))
104 available_tests
+= tests_without_annotation
105 if exclude_annotations
:
106 excluded_tests
= [t
for t
in available_tests
if
107 self
._AnnotationIncludesTest
(t
, exclude_annotations
)]
108 available_tests
= list(set(available_tests
) - set(excluded_tests
))
111 available_test_names
= unittest_util
.FilterTestNames(
112 [t
.qualified_name
for t
in available_tests
], name_filter
)
114 t
for t
in available_tests
if
115 t
.qualified_name
in available_test_names
]
116 return available_tests
119 def _AnnotationIncludesTest(test_info
, annotation_filter_list
):
120 """Checks whether a given test represented by test_info matches annotation.
123 test_info: TestInfo object representing the test
124 annotation_filter_list: list of annotation filters to match (e.g. Smoke)
127 True if no annotation was supplied or the test matches; false otherwise.
129 if not annotation_filter_list
:
131 for annotation_filter
in annotation_filter_list
:
132 filters
= annotation_filter
.split('=')
133 if len(filters
) == 2:
135 value_list
= filters
[1].split(',')
136 for value
in value_list
:
137 if tests_annotations
.AnnotatedFunctions
.IsAnnotated(
138 key
+ ':' + value
, test_info
.qualified_name
):
140 elif tests_annotations
.AnnotatedFunctions
.IsAnnotated(
141 annotation_filter
, test_info
.qualified_name
):