source: client/shared/bin/runtest @ 1d1e06d

Last change on this file since 1d1e06d was 1b9eec2, checked in by ramon <ramongomez@…>, 14 years ago

Rama version1.0: runtest soporta comandos y funciones con parámetros en pruebas para BASH.
Modificado #345.

git-svn-id: https://opengnsys.es/svn/branches/version1.0@1602 a21b9725-9963-47de-94b9-378ad31fedc9

  • Property mode set to 100755
File size: 7.7 KB
RevLine 
[a895e47]1#!/usr/bin/env python
2from __future__ import print_function
3
4import os
5import subprocess
6import doctest
7import re
8
9FIRST_SCRIPT = 'prepare'
10LAST_SCRIPT = 'cleanup'
11
12PRE_EXTENSION = '.pre'
13POST_EXTENSION = '.post'
14
15PYTHON_TEST_EXTENSION = '.pytest'
16BASH_TEST_EXTENSION = '.shtest'
17
18
19class RunTest:
20    '''Runs the tests'''
21
22    def __init__(self):
23        self.path = os.path.abspath('.')
24
25        # Only no-hide files
26        self.all_files = [filename for filename in os.listdir(self.path)
27                if filename[0] != '.' and os.path.isfile(filename)]
28
29        self.all_files = sorted(self.all_files)
30
31        self.python_tests = []
32        self.bash_tests = []
33        self.script_tests = []
34        self.first_script = ''
35        self.last_script = ''
36        self.pre_scripts = []
37        self.post_scripts = []
38
39        for filename in self.all_files:
40            if filename.endswith(PYTHON_TEST_EXTENSION):
41                self.python_tests.append(filename)
42
43            elif filename.endswith(BASH_TEST_EXTENSION):
44                self.bash_tests.append(filename)
45
46            elif os.access(filename, os.X_OK):
47                basename, extension = os.path.splitext(filename)
48                if basename == FIRST_SCRIPT:
49                    if self.first_script:
50                        raise MoreThanOneFirstScript()
51                    self.first_script = filename
52                elif basename == LAST_SCRIPT:
53                    if self.last_script:
54                        raise MoreThanOneLastScript()
55                    self.last_script = filename
56                elif extension == PRE_EXTENSION:
57                    self.pre_scripts.append(filename)
58                elif extension == POST_EXTENSION:
59                    self.post_scripts.append(filename)
60                else:
61                    self.script_tests.append(filename)
62
63        self.fails = 0
64
65    def run_script(self, script):
66        '''Run a script test'''
67        path_script = os.path.join(self.path, script)
68        proc = subprocess.Popen((path_script), shell=True, stdout=subprocess.PIPE,
69                stderr=subprocess.PIPE)
70        return_value = proc.wait()
71        if return_value != 0:
72            self.fails += 1
73            stdout, stderr = proc.communicate()
74            print("*******************************************************")
75            print("Error %d in %s:" % (return_value, script))
76            print(stdout.decode(), end='')
77            print(stderr.decode(), end='')
78
79        return return_value
80
81    def run_bash_test(self, script):
82        '''Run bash test'''
83        #import pdb; pdb.set_trace()
84        path_script = os.path.join(self.path, script)
85        errors = 0
86        test_no = 0
87
88        for command, result, line in read_bash_tests(path_script):
89            test_no += 1
90            try:
[1b9eec2]91                proc = subprocess.Popen(('/bin/bash', '-c', command),
92                        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
[a895e47]93                stdout = proc.communicate()[0]
94            except OSError as exc:
95                print('File "%s" line %d:' % (script, line))
96                print('Failed example:')
97                print('    ' + command)
98                print("Exception was raised:")
99                print("    ", end="")
100                print(exc)
101                print("*******************************************************")
102                errors += 1
103
104            else:
105                if result != stdout.decode():
106                    print('File "%s" line %d:' % (script, line))
107                    print('Failed example:')
108                    print('    ' + command)
109                    print("Expected:")
110                    for l in result.split('\n')[:-1]:
111                        print('    ' + l)
112                    print("Got:")
113                    for l in stdout.decode().split('\n')[:-1]:
114                        print('    ' + l)
115                    errors += 1
116                    print("*******************************************************")
117
118        if errors != 0:
119            print("%d items had failures:" % errors)
120            print("    %d of %d in %s" % (errors, test_no, script))
121            print("***Test failed***")
122        else:
123            print("%3d tests PASSED in %s" % (test_no, script))
124
125        return errors
126
127
128    def run_pre_test(self, test):
129        '''Run the pre-test of a test'''
130        pre_test = test + PRE_EXTENSION
131        return_value = 0
132        if pre_test in self.pre_scripts:
133            return_value = self.run_script(pre_test)
134            if return_value:
135                print("No running: %s %s" % (test, test + POST_EXTENSION))
136
137        return return_value
138
139    def run_post_test(self, test):
140        '''Run the post-test of a test'''
141        post_test = test + POST_EXTENSION
142        if post_test in self.post_scripts:
143            return self.run_script(post_test)
144
145    def run_tests(self):
146        '''Run the tests in the correct order'''
147        if self.first_script:
148            if self.run_script(self.first_script) != 0:
149                print('*Error in prepare script. Aborting.*')
150                return self.show_errors()
151
152        all_tests = sorted(self.script_tests + self.python_tests + self.bash_tests)
153        for test in all_tests:
154            if self.run_pre_test(test) != 0:
155                continue
156
157            if test in self.script_tests:
158                self.run_script(test)
159            elif test in self.bash_tests:
160                fails = self.run_bash_test(test)
161                self.fails += fails
162            elif test in self.python_tests:
163                fails, n_tests = doctest.testfile(test, module_relative=False)
164                self.fails += fails
165
166            self.run_post_test(test)
167
168        if self.last_script:
169            self.run_script(self.last_script)
170
171        return self.show_errors()
172
173    def show_errors(self):
174        '''Show the total errors'''
175        if self.fails:
176            print("*******************************************************")
177            print("Total errors: %d" % self.fails)
178
179        return self.fails
180
181class MoreThanOneFirstScript(Exception):
182    def __init__(self):
183        super(MoreThanOneFirstScript, self).__init__(
184                "More than one %s script" % FIRST_SCRIPT)
185
186class MoreThanOneLastScript(Exception):
187    def __init__(self):
188        super(MoreThanOneLastScript, self).__init__(
189                "More than one %s script" % LAST_SCRIPT)
190
191
192def read_bash_tests(file_name):
193    '''Iterator that yields the found tests'''
194    fd = open(file_name)
195    command = ''
196    result = ''
197    tests = []
198    line_no = 0
199    command_line = 0
200    command_re = re.compile("^\$ (.*)\n")
201
202    for line in fd.readlines():
203        line_no += 1
204
205        match = command_re.match(line)
206        if match:
207            # Is it a command?
208            if command:
209                # If it is a command but we have a previous command to send
210                yield (command, result, command_line)
211                result = ''
212
213            command = match.group(1)
214            command_line = line_no
215
216        elif command:
217            # If not a command but we have a previous command
218            if line != "\n":
219                # It's a part of the result
220                if line == "<BLANKLINE>\n":
221                    result += '\n'
222                else:
223                    result += line
224               
225            else:
226                # Or it's the end of the result, yielding
227
228                yield (command, result, command_line)
229                command = ''
230                result = ''
231
232
233        else:
234            # This line is a comment
235            pass
236
237    if command:
238        # Cheking if the last command was sent
239        yield (command, result, command_line)
240
241    fd.close()
242
243
244if __name__ == "__main__":
245    r = RunTest()
246    r.run_tests()
Note: See TracBrowser for help on using the repository browser.