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 os
18import re
19import logging
20
21from vts.utils.python.os import path_utils
22
23from 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
53        self.is_mandatory = False
54        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
96    @property
97    def command(self):
98        """Get the test case's command."""
99        return self._command
100
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
106        # Adjust for simple command substitutions like
107        # TMPDIR=`mktemp ...` && test $TMPDIR
108        pattern = re.compile('[\`]')
109        return (pattern.sub('', executable.split('=')[1])
110                if executable.find('=') > 0 else executable
111                for executable in executables)
112
113    def GetRequiredExecutablePaths(self, ltp_bin_host_path):
114        """Get required executables' paths on host.
115
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        """
122        return [os.path.join(ltp_bin_host_path, executable)
123                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
146    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
156    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
164