1# 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 17import re 18import logging 19 20from vts.utils.python.os import path_utils 21 22from vts.testcases.kernel.ltp import ltp_enums 23from vts.testcases.kernel.ltp import ltp_configs 24 25 26class TestCase(object): 27 """Stores name, path, and param information for each test case. 28 29 All class initiation inputs are assumed to be already validated by 30 test case parser. 31 32 Attributes: 33 testsuite: string, name of testsuite to which the testcase belongs 34 testname: string, name of the test case 35 command: string, the command to run the test case 36 _args: list of string, test case command line arguments 37 requirement_state: RequirementState, enum representing requirement 38 check results 39 note: string, a place to store additional note for the test case 40 such as what environment requirement did not satisfy. 41 is_staging: bool, whether test case is a staging test 42 is_filtered: bool, whether test case is excluded by filter 43 """ 44 45 def __init__(self, testsuite, testname, command): 46 self.testsuite = testsuite 47 self.testname = testname 48 self._command = command 49 self.requirement_state = ltp_enums.RequirementState.UNCHECKED 50 self.note = "" 51 self.is_staging = False 52 self.is_filtered = False 53 54 @property 55 def note(self): 56 """Get the note""" 57 return self._note 58 59 @note.setter 60 def note(self, note): 61 """Set the note""" 62 self._note = note 63 64 @property 65 def requirement_state(self): 66 """Get the requirement state""" 67 return self._requirement_state 68 69 @requirement_state.setter 70 def requirement_state(self, requirement_state): 71 """Set the requirement state""" 72 self._requirement_state = requirement_state 73 74 @property 75 def testsuite(self): 76 """Get the test suite's name.""" 77 return self._testsuite 78 79 @testsuite.setter 80 def testsuite(self, testsuite): 81 """Set the test suite's name.""" 82 self._testsuite = testsuite 83 84 @property 85 def testname(self): 86 """Get the test case's name.""" 87 return self._testname 88 89 @testname.setter 90 def testname(self, testname): 91 """Set the test case's name.""" 92 self._testname = testname 93 94 def InternalAddLtpPathToCommand(self, command): 95 """Internal function to change binary in commands to their full path""" 96 tokens = command.strip().split() 97 98 # If not ltp executables: 99 if (tokens[0] in ltp_configs.INTERNAL_BINS or 100 tokens[0] in ltp_configs.INTERNAL_SHELL_COMMANDS or 101 tokens[0].find('=') > 0): 102 return command 103 else: # Is Ltp executable 104 tokens[0] = path_utils.JoinTargetPath(ltp_configs.LTPBINPATH, 105 tokens[0]) 106 return ' '.join(tokens) 107 108 def GetCommand(self): 109 """Get test case's command. 110 111 Get the test case's command where ltp test binary names have been 112 replaced with their full paths 113 """ 114 return '&&'.join((self.InternalAddLtpPathToCommand(command) 115 for command in self._command.split('&&'))) 116 117 def InternalGetExecutableNames(self): 118 """Get a generator of all required executable file names""" 119 executables = (command.strip().split()[0] 120 for command in self._command.split('&&')) 121 122 # In some test definitions there were command starting with 123 # > TDsrc='mktemp ...'. We use regex to remove quotes 124 pattern = re.compile('[\'|\"]') 125 return (pattern.sub('', executable.split('=')[1]) 126 if executable.find('=') > 0 else executable 127 for executable in executables) 128 129 def GetRequiredExecutablePaths(self, ltp_bin_path=ltp_configs.LTPBINPATH): 130 """Get required executables' paths. 131 132 Returns: 133 A list of all executables' paths that will be needed 134 by its command. For LTP's executables, absolute path will be 135 returned. For binaries in system's PATH, only the name will be 136 returned. 137 """ 138 return [path_utils.JoinTargetPath(ltp_bin_path, executable) 139 if executable not in ltp_configs.INTERNAL_BINS else executable 140 for executable in self.InternalGetExecutableNames() 141 if executable not in ltp_configs.INTERNAL_SHELL_COMMANDS] 142 143 @property 144 def fullname(self): 145 """Return full test name in <testsuite-testname> format""" 146 return "%s.%s" % (self.testsuite, self.testname) 147 148 def __str__(self): 149 return self.fullname 150 151 @property 152 def is_staging(self): 153 '''Whether this test is a staging test.''' 154 return self._is_staging 155 156 @is_staging.setter 157 def is_staging(self, is_staging): 158 '''Set whether this test is a staging test.''' 159 self._is_staging = is_staging 160 161 @property 162 def is_filtered(self): 163 '''Whether this test has been filtered out.''' 164 return self._is_filtered 165 166 @is_filtered.setter 167 def is_filtered(self, is_filtered): 168 '''Set whether this test has been filtered out.''' 169 self._is_filtered = is_filtered 170