1 #!@PYTHON@
2
3 #
4 # This file and its contents are supplied under the terms of the
5 # Common Development and Distribution License ("CDDL"), version 1.0.
6 # You may only use this file in accordance with the terms of version
7 # 1.0 of the CDDL.
8 #
9 # A full copy of the text of the CDDL should have accompanied this
10 # source. A copy of the CDDL is also available via the Internet at
11 # http://www.illumos.org/license/CDDL.
12 #
13
14 #
15 # Copyright (c) 2012, 2016 by Delphix. All rights reserved.
16 # Copyright (c) 2017, Chris Fraire <cfraire@me.com>.
17 # Copyright 2018 Joyent, Inc.
18 #
19
20 import ConfigParser
21 import os
22 import logging
23 import platform
24 from logging.handlers import WatchedFileHandler
25 from datetime import datetime
26 from optparse import OptionParser
27 from pwd import getpwnam
28 from pwd import getpwuid
29 from select import select
30 from subprocess import PIPE
31 from subprocess import Popen
32 from sys import argv
33 from sys import maxint
34 from threading import Timer
35 from time import time
36
37 BASEDIR = '/var/tmp/test_results'
38 KILL = '/usr/bin/kill'
39 TRUE = '/usr/bin/true'
40 SUDO = '/usr/bin/sudo'
41
42 # Custom class to reopen the log file in case it is forcibly closed by a test.
43 class WatchedFileHandlerClosed(WatchedFileHandler):
44 """Watch files, including closed files.
45 Similar to (and inherits from) logging.handler.WatchedFileHandler,
46 except that IOErrors are handled by reopening the stream and retrying.
47 This will be retried up to a configurable number of times before
48 giving up, default 5.
49 """
50
51 def __init__(self, filename, mode='a', encoding=None, delay=0, max_tries=5):
52 self.max_tries = max_tries
53 self.tries = 0
54 WatchedFileHandler.__init__(self, filename, mode, encoding, delay)
55
56 def emit(self, record):
57 while True:
58 try:
59 WatchedFileHandler.emit(self, record)
60 self.tries = 0
61 return
67 self.tries += 1
68
69 class Result(object):
70 total = 0
71 runresults = {'PASS': 0, 'FAIL': 0, 'SKIP': 0, 'KILLED': 0}
72
73 def __init__(self):
74 self.starttime = None
75 self.returncode = None
76 self.runtime = ''
77 self.stdout = []
78 self.stderr = []
79 self.result = ''
80
81 def done(self, proc, killed):
82 """
83 Finalize the results of this Cmd.
84 Report SKIP for return codes 3,4 (NOTINUSE, UNSUPPORTED)
85 as defined in ../stf/include/stf.shlib
86 """
87 Result.total += 1
88 m, s = divmod(time() - self.starttime, 60)
89 self.runtime = '%02d:%02d' % (m, s)
90 self.returncode = proc.returncode
91 if killed:
92 self.result = 'KILLED'
93 Result.runresults['KILLED'] += 1
94 elif self.returncode is 0:
95 self.result = 'PASS'
96 Result.runresults['PASS'] += 1
97 elif self.returncode is 3 or self.returncode is 4:
98 self.result = 'SKIP'
99 Result.runresults['SKIP'] += 1
100 elif self.returncode is not 0:
101 self.result = 'FAIL'
102 Result.runresults['FAIL'] += 1
103
104
105 class Output(object):
106 """
107 This class is a slightly modified version of the 'Stream' class found
108 here: http://goo.gl/aSGfv
109 """
110 def __init__(self, stream):
111 self.stream = stream
112 self._buf = ''
113 self.lines = []
114
115 def fileno(self):
116 return self.stream.fileno()
117
118 def read(self, drain=0):
119 """
120 Read from the file descriptor. If 'drain' set, read until EOF.
121 """
122 while self._read() is not None:
873
874
875 def main():
876 options = parse_args()
877 testrun = TestRun(options)
878
879 if options.cmd is 'runtests':
880 find_tests(testrun, options)
881 elif options.cmd is 'rdconfig':
882 testrun.read(testrun.logger, options)
883 elif options.cmd is 'wrconfig':
884 find_tests(testrun, options)
885 testrun.write(options)
886 exit(0)
887 else:
888 fail('Unknown command specified')
889
890 testrun.complete_outputdirs()
891 testrun.run(options)
892 testrun.summary()
893 exit(0)
894
895
896 if __name__ == '__main__':
897 main()
|
1 #!@PYTHON@
2
3 #
4 # This file and its contents are supplied under the terms of the
5 # Common Development and Distribution License ("CDDL"), version 1.0.
6 # You may only use this file in accordance with the terms of version
7 # 1.0 of the CDDL.
8 #
9 # A full copy of the text of the CDDL should have accompanied this
10 # source. A copy of the CDDL is also available via the Internet at
11 # http://www.illumos.org/license/CDDL.
12 #
13
14 #
15 # Copyright (c) 2012, 2016 by Delphix. All rights reserved.
16 # Copyright (c) 2017, Chris Fraire <cfraire@me.com>.
17 # Copyright 2019 Joyent, Inc.
18 #
19
20 import ConfigParser
21 import os
22 import logging
23 import platform
24 from logging.handlers import WatchedFileHandler
25 from datetime import datetime
26 from optparse import OptionParser
27 from pwd import getpwnam
28 from pwd import getpwuid
29 from select import select
30 from subprocess import PIPE
31 from subprocess import Popen
32 from sys import argv
33 from sys import maxint
34 from threading import Timer
35 from time import time
36
37 BASEDIR = '/var/tmp/test_results'
38 KILL = '/usr/bin/kill'
39 TRUE = '/usr/bin/true'
40 SUDO = '/usr/bin/sudo'
41
42 retcode = 0
43
44 # Custom class to reopen the log file in case it is forcibly closed by a test.
45 class WatchedFileHandlerClosed(WatchedFileHandler):
46 """Watch files, including closed files.
47 Similar to (and inherits from) logging.handler.WatchedFileHandler,
48 except that IOErrors are handled by reopening the stream and retrying.
49 This will be retried up to a configurable number of times before
50 giving up, default 5.
51 """
52
53 def __init__(self, filename, mode='a', encoding=None, delay=0, max_tries=5):
54 self.max_tries = max_tries
55 self.tries = 0
56 WatchedFileHandler.__init__(self, filename, mode, encoding, delay)
57
58 def emit(self, record):
59 while True:
60 try:
61 WatchedFileHandler.emit(self, record)
62 self.tries = 0
63 return
69 self.tries += 1
70
71 class Result(object):
72 total = 0
73 runresults = {'PASS': 0, 'FAIL': 0, 'SKIP': 0, 'KILLED': 0}
74
75 def __init__(self):
76 self.starttime = None
77 self.returncode = None
78 self.runtime = ''
79 self.stdout = []
80 self.stderr = []
81 self.result = ''
82
83 def done(self, proc, killed):
84 """
85 Finalize the results of this Cmd.
86 Report SKIP for return codes 3,4 (NOTINUSE, UNSUPPORTED)
87 as defined in ../stf/include/stf.shlib
88 """
89 global retcode
90
91 Result.total += 1
92 m, s = divmod(time() - self.starttime, 60)
93 self.runtime = '%02d:%02d' % (m, s)
94 self.returncode = proc.returncode
95 if killed:
96 self.result = 'KILLED'
97 Result.runresults['KILLED'] += 1
98 retcode = 2;
99 elif self.returncode is 0:
100 self.result = 'PASS'
101 Result.runresults['PASS'] += 1
102 elif self.returncode is 3 or self.returncode is 4:
103 self.result = 'SKIP'
104 Result.runresults['SKIP'] += 1
105 elif self.returncode is not 0:
106 self.result = 'FAIL'
107 Result.runresults['FAIL'] += 1
108 retcode = 1;
109
110
111 class Output(object):
112 """
113 This class is a slightly modified version of the 'Stream' class found
114 here: http://goo.gl/aSGfv
115 """
116 def __init__(self, stream):
117 self.stream = stream
118 self._buf = ''
119 self.lines = []
120
121 def fileno(self):
122 return self.stream.fileno()
123
124 def read(self, drain=0):
125 """
126 Read from the file descriptor. If 'drain' set, read until EOF.
127 """
128 while self._read() is not None:
879
880
881 def main():
882 options = parse_args()
883 testrun = TestRun(options)
884
885 if options.cmd is 'runtests':
886 find_tests(testrun, options)
887 elif options.cmd is 'rdconfig':
888 testrun.read(testrun.logger, options)
889 elif options.cmd is 'wrconfig':
890 find_tests(testrun, options)
891 testrun.write(options)
892 exit(0)
893 else:
894 fail('Unknown command specified')
895
896 testrun.complete_outputdirs()
897 testrun.run(options)
898 testrun.summary()
899 exit(retcode)
900
901
902 if __name__ == '__main__':
903 main()
|