blob: bdfeb676eb94994eb89b61505aca18135cbb452a [file] [log] [blame]
Yuexi Ma27d5c6b2016-11-29 10:07:00 -08001#
2# Copyright (C) 2016 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
Hsin-Yi Chenf0c22e32017-06-30 12:44:32 +080017import os
Yuexi Ma27d5c6b2016-11-29 10:07:00 -080018import re
Yuexi Ma27d5c6b2016-11-29 10:07:00 -080019import logging
20
Hsin-Yi Chen2a6e4be2017-03-24 15:13:42 +080021from vts.utils.python.os import path_utils
22
Yuexi Ma27d5c6b2016-11-29 10:07:00 -080023from vts.testcases.kernel.ltp import ltp_enums
24from vts.testcases.kernel.ltp import ltp_configs
25
26
27class TestCase(object):
28 """Stores name, path, and param information for each test case.
29
30 All class initiation inputs are assumed to be already validated by
31 test case parser.
32
33 Attributes:
34 testsuite: string, name of testsuite to which the testcase belongs
35 testname: string, name of the test case
36 command: string, the command to run the test case
37 _args: list of string, test case command line arguments
38 requirement_state: RequirementState, enum representing requirement
39 check results
40 note: string, a place to store additional note for the test case
41 such as what environment requirement did not satisfy.
42 is_staging: bool, whether test case is a staging test
43 is_filtered: bool, whether test case is excluded by filter
44 """
45
46 def __init__(self, testsuite, testname, command):
47 self.testsuite = testsuite
48 self.testname = testname
49 self._command = command
50 self.requirement_state = ltp_enums.RequirementState.UNCHECKED
51 self.note = ""
52 self.is_staging = False
Steve Mucklec93a0892019-01-02 17:56:41 -080053 self.is_mandatory = False
Yuexi Ma27d5c6b2016-11-29 10:07:00 -080054 self.is_filtered = False
55
56 @property
57 def note(self):
58 """Get the note"""
59 return self._note
60
61 @note.setter
62 def note(self, note):
63 """Set the note"""
64 self._note = note
65
66 @property
67 def requirement_state(self):
68 """Get the requirement state"""
69 return self._requirement_state
70
71 @requirement_state.setter
72 def requirement_state(self, requirement_state):
73 """Set the requirement state"""
74 self._requirement_state = requirement_state
75
76 @property
77 def testsuite(self):
78 """Get the test suite's name."""
79 return self._testsuite
80
81 @testsuite.setter
82 def testsuite(self, testsuite):
83 """Set the test suite's name."""
84 self._testsuite = testsuite
85
86 @property
87 def testname(self):
88 """Get the test case's name."""
89 return self._testname
90
91 @testname.setter
92 def testname(self, testname):
93 """Set the test case's name."""
94 self._testname = testname
95
Hsin-Yi Chen5c2c7682017-08-04 11:44:22 +080096 @property
97 def command(self):
98 """Get the test case's command."""
99 return self._command
Yuexi Ma27d5c6b2016-11-29 10:07:00 -0800100
101 def InternalGetExecutableNames(self):
102 """Get a generator of all required executable file names"""
103 executables = (command.strip().split()[0]
104 for command in self._command.split('&&'))
105
Sandeep Patil5adf5ab2017-09-18 16:38:24 -0700106 # Adjust for simple command substitutions like
107 # TMPDIR=`mktemp ...` && test $TMPDIR
108 pattern = re.compile('[\`]')
Yuexi Ma27d5c6b2016-11-29 10:07:00 -0800109 return (pattern.sub('', executable.split('=')[1])
110 if executable.find('=') > 0 else executable
111 for executable in executables)
112
Hsin-Yi Chenf0c22e32017-06-30 12:44:32 +0800113 def GetRequiredExecutablePaths(self, ltp_bin_host_path):
114 """Get required executables' paths on host.
Yuexi Ma27d5c6b2016-11-29 10:07:00 -0800115
116 Returns:
117 A list of all executables' paths that will be needed
118 by its command. For LTP's executables, absolute path will be
119 returned. For binaries in system's PATH, only the name will be
120 returned.
121 """
Hsin-Yi Chenf0c22e32017-06-30 12:44:32 +0800122 return [os.path.join(ltp_bin_host_path, executable)
Yuexi Ma27d5c6b2016-11-29 10:07:00 -0800123 if executable not in ltp_configs.INTERNAL_BINS else executable
124 for executable in self.InternalGetExecutableNames()
125 if executable not in ltp_configs.INTERNAL_SHELL_COMMANDS]
126
127 @property
128 def fullname(self):
129 """Return full test name in <testsuite-testname> format"""
130 return "%s.%s" % (self.testsuite, self.testname)
131
132 def __str__(self):
133 return self.fullname
134
135 @property
136 def is_staging(self):
137 '''Whether this test is a staging test.'''
138 return self._is_staging
139
140 @is_staging.setter
141 def is_staging(self, is_staging):
142 '''Set whether this test is a staging test.'''
143 self._is_staging = is_staging
144
145 @property
Steve Mucklec93a0892019-01-02 17:56:41 -0800146 def is_mandatory(self):
147 '''Whether this test is a mandatory test.'''
148 return self._is_mandatory
149
150 @is_mandatory.setter
151 def is_mandatory(self, is_mandatory):
152 '''Set whether this test is a mandatory test.'''
153 self._is_mandatory = is_mandatory
154
155 @property
Yuexi Ma27d5c6b2016-11-29 10:07:00 -0800156 def is_filtered(self):
157 '''Whether this test has been filtered out.'''
158 return self._is_filtered
159
160 @is_filtered.setter
161 def is_filtered(self, is_filtered):
162 '''Set whether this test has been filtered out.'''
163 self._is_filtered = is_filtered