source: orange/Orange/testing/regression/xtest.py @ 10067:ade7a1b97bd0

Revision 10067:ade7a1b97bd0, 10.3 KB checked in by Miha Stajdohar <miha.stajdohar@…>, 2 years ago (diff)

Multiplatform test results fixed.

Line 
1#! usr/bin/env python
2
3import os, re, sys, time, subprocess
4import getopt
5from Orange.misc import environ
6
7regtestdir = os.getcwd().replace("\\", "/")
8re_israndom = re.compile(r"#\s*xtest\s*:\s*RANDOM")
9
10date = "%2.2i-%2.2i-%2.2i" % time.localtime()[:3]
11
12platform = sys.platform
13pyversion = sys.version[:3]
14states = ["OK", "timedout", "changed", "random", "error", "crash"]
15
16def file_name_match(name, patterns):
17    """Is any of the string in patterns a substring of name?"""
18    for p in patterns:
19        if p in name:
20            return True
21    return False
22
23def test_scripts(complete, just_print, module="orange", root_directory=".",
24                test_files=None, directories=None, timeout=5):
25    """Test the scripts in the given directory."""
26    global error_status
27    if sys.platform == "win32" and sys.executable[-6:].upper() != "_D.EXE":
28        import win32process, win32api
29        win32process.SetPriorityClass(win32api.GetCurrentProcess(), 64)
30
31    caller_directory = os.getcwd()
32    os.chdir(root_directory) # directory to start the testing in
33    for dirname, dir in directories:
34        dir = os.path.join(root_directory, dir)
35        os.chdir(dir)
36        #if module <> dirname:
37        #    outputsdir = "%s/results/%s/%s" % (regtestdir, module, dirname)
38        #else:
39        #    outputsdir = "%s/results/%s" % (regtestdir, module)
40
41        outputsdir = "%s/results_%s" % (regtestdir, dirname)
42
43        print "DIR %s (%s)" % (dirname, dir)
44        if not os.path.exists(outputsdir):
45            os.mkdir(outputsdir)
46
47        if os.path.exists("exclude-from-regression.txt"):
48            dont_test = [x.strip() for x in file("exclude-from-regression.txt").readlines()]
49        else:
50            dont_test = []
51        test_set = []
52
53        # file name filtering
54        names = [name for name in os.listdir('.') if name[-3:] == ".py"]
55        if test_files:
56            names = [name for name in names if file_name_match(name, test_files)]
57        names = [name for name in names if name not in dont_test]
58        names.sort()
59
60        if names or True:
61            if just_print == "report-html":
62                print "<h2>Directory '%s'</h2>" % dir
63                print '<table class="xtest_report">'
64            elif just_print:
65                print "-" * 79
66                print "Directory '%s'" % dir
67                print
68
69        # test_set includes all the scripts (file, status) to be tested
70        for name in names:
71            if not os.path.exists("%s/%s.txt" % (outputsdir, name)):
72                # past result not available
73                test_set.append((name, "new"))
74            else:
75                # past result available
76                for state in states:
77                    if os.path.exists("%s/%s.%s.%s.%s.txt" % \
78                                      (outputsdir, name, platform, pyversion, state)):
79                        test_set.append((name, state))
80                        # current result already on disk
81                        break
82                else:
83                    if os.path.exists("%s/%s.%s.%s.random1.txt" % \
84                                      (outputsdir, name, platform, pyversion)):
85                        test_set.append((name, "random"))
86                    elif complete or just_print:
87                        test_set.append((name, "OK"))
88                    else:
89                        dont_test.append(name)
90
91        if just_print == "report-html":
92            for name, lastResult in test_set:
93                if lastResult == "OK":
94                    result = "results/%s/%s/%s.txt" % (module, dirname, name)
95                    print '''  <tr><td><a href="http://orange.biolab.si/trac/browser/trunk/orange/doc/%(dir)s/%(name)s">%(name)s</a></td>
96    <td><a href="%(result)s">%(lastResult)s</a></td>
97  </tr>''' % {"dir":dir, "name":name, "lastResult":lastResult, "result":result}
98
99#                    print '  <tr><td><a href="results/%s/%s/%s.txt">%s</a></td><td>%s</td></tr>' % (module, dirname, name, name, lastResult)
100                elif lastResult in ["changed", "crash", "random"]:
101#                else:
102                    if lastResult == "random":
103                        result = "results/%s/%s/%s.%s.%s.%s.txt" % \
104                        (module, dirname, name, platform, pyversion, lastResult + "1")
105                    else:
106                        result = "results/%s/%s/%s.%s.%s.%s.txt" % (module, dirname, name, platform, pyversion, lastResult)
107                    original = "results/%s/%s/%s.txt" % (module, dirname, name)
108                    print '''  <tr><td><a href="http://orange.biolab.si/trac/browser/trunk/orange/doc/%(dir)s/%(name)s">%(name)s</a>
109    </td><td><a href="%(result)s">%(lastResult)s</a></td>
110    <td><a href="%(original)s">original</a></td>
111  </tr>''' % {"dir":dir, "name":name, "lastResult":lastResult, "result":result, "original":original}
112
113            print "</table>"
114        elif just_print:
115            for name, lastResult in test_set:
116                print "%-30s %s" % (name, lastResult)
117
118        else:
119            if dont_test:
120                print "Skipped: %s\n" % ", ".join(dont_test)
121
122            for name, lastResult in test_set:
123                print "%s (%s): " % (name, lastResult == "new" and lastResult \
124                                     or ("last: %s" % lastResult)),
125                sys.stdout.flush()
126
127                for state in states:
128                    remname = "%s/%s.%s.%s.%s.txt" % \
129                              (outputsdir, name, platform, pyversion, state)
130                    if os.path.exists(remname):
131                        os.remove(remname)
132
133                titerations = re_israndom.search(open(name, "rt").read()) and 1 or iterations
134                #os.spawnl(os.P_WAIT, sys.executable, "-c", regtestdir + "/xtest_one.py", name, str(titerations), outputsdir)
135                p = subprocess.Popen([sys.executable, regtestdir + "/xtest_one.py", \
136                                      name, str(titerations), outputsdir])
137
138                passed_time = 0
139                while passed_time < timeout:
140                    time.sleep(0.01)
141                    passed_time += 0.01
142
143                    if p.poll() is not None:
144                        break
145
146                if p.poll() is None:
147                    p.kill()
148                    result2 = "timedout"
149                    print "timedout (use: --timeout #)"
150                    # remove output file and change it for *.timedout.*
151                    for state in states:
152                        remname = "%s/%s.%s.%s.%s.txt" % \
153                                  (outputsdir, name, platform, pyversion, state)
154                        if os.path.exists(remname):
155                            os.remove(remname)
156
157                    timeoutname = "%s/%s.%s.%s.%s.txt" % \
158                                    (outputsdir, name, sys.platform, \
159                                     sys.version[:3], "timedout")
160                    open(timeoutname, "wt").close()
161                    result = "timedout"
162                else:
163                    stdout, stderr = p.communicate()
164                    result = open("xtest1_report", "rt").readline().rstrip() or "crash"
165
166                error_status = max(error_status, states.index(result))
167                os.remove("xtest1_report")
168
169        os.chdir("..")
170
171    os.chdir(caller_directory)
172
173iterations = 1
174directories = []
175error_status = 0
176
177def usage():
178    """Print out help."""
179    print "%s [test|update|report|report-html|errors] -[h|s] [--single|--module=[all|orange|docs]|--timeout=<#>|--dir=<dir>|] <files>" % sys.argv[0]
180    print "  test:   regression tests on all scripts (default)"
181    print "  update: regression tests on all previously failed scripts"
182    print "  report: report on testing results"
183    print "  errors: report on errors from regression tests"
184    print
185    print "-s, --single: runs a single test on each script"
186    print "--module=<module>: defines a module to test"
187    print "--timeout=<#seconds>: defines max. execution time"
188    print "--dir=<dir>: a comma-separated list of names where any should match the directory to be tested"
189    print "<files>: space separated list of string matching the file names to be tested"
190
191
192def main(argv):
193    """Process the argument list and run the regression test."""
194    global iterations
195
196    command = "test"
197    if argv:
198        if argv[0] in ["update", "test", "report", "report-html", "errors", "help"]:
199            command = argv[0]
200            del argv[0]
201
202    try:
203        opts, test_files = getopt.getopt(argv, "hs", ["single", "module=", "timeout=", "help", "files=", "verbose="])
204    except getopt.GetoptError:
205        print "Warning: Wrong argument"
206        usage()
207        sys.exit(1)
208    opts = dict(opts) if opts else {}
209    if "--single" in opts or "-s" in opts:
210        iterations = 1
211    if "--help" in opts or '-h' in opts:
212        usage()
213        sys.exit(0)
214
215    module = opts.get("--module", "all")
216    if module == "all":
217        root = "%s/.." % environ.install_dir
218        module = "orange"
219        dirs = [("tests", "Orange/testing/regression/tests"),
220                ("tests_20", "Orange/testing/regression/tests_20"),
221                ("tutorial", "docs/tutorial/rst/code"),
222                ("reference", "docs/reference/rst/code")]
223    elif module == "orange":
224        root = "%s" % environ.install_dir
225        module = "orange"
226        dirs = [("tests", "testing/regression/tests"),
227                ("tests_20", "testing/regression/tests_20")]
228    elif module == "docs":
229        root = "%s/.." % environ.install_dir
230        module = "orange"
231        dirs = [("tutorial", "docs/tutorial/rst/code"),
232                ("reference", "docs/reference/rst/code")]
233    else:
234        print "Error: %s is wrong name of the module, should be in [orange|docs]" % module
235        sys.exit(1)
236
237    timeout = 5
238    try:
239        _t = opts.get("--timeout", "5")
240        timeout = int(_t)
241        if timeout <= 0 or timeout > 300:
242            raise AttributeError()
243    except AttributeError:
244        print "Error: timeout out of range (0 < # < 300)"
245        sys.exit(1)
246    except:
247        print "Error: %s wrong timeout" % opts.get("--timeout", "5")
248        sys.exit(1)
249
250    test_scripts(command == "test", command == "report" or (command == "report-html" and command or False),
251                 module=module, root_directory=root,
252                 test_files=test_files, directories=dirs, timeout=timeout)
253    # sys.exit(error_status)
254
255main(sys.argv[1:])
Note: See TracBrowser for help on using the repository browser.