1
- #!/usr/bin/python
1
+ #!/usr/bin/env python3
2
2
3
3
"Test Render Script"
4
4
5
- import os , shutil , tempfile , time , sys , math , re
6
- from subprocess import Popen , PIPE , STDOUT , CalledProcessError
7
- from optparse import OptionParser
5
+ import argparse
6
+ import math
7
+ import os
8
+ import re
9
+ import shutil
10
+ import sys
11
+ import tempfile
12
+ import time
13
+ from shlex import split
14
+ from subprocess import PIPE , STDOUT , CalledProcessError , run
8
15
9
16
overviewer_scripts = ['./overviewer.py' , './gmap.py' ]
10
17
11
- def check_call (* args , ** kwargs ):
12
- quiet = False
13
- if "quiet" in kwargs .keys ():
14
- quiet = kwargs ["quiet" ]
15
- del kwargs ["quiet" ]
16
- if quiet :
17
- kwargs ['stdout' ] = PIPE
18
- kwargs ['stderr' ] = STDOUT
19
- p = Popen (* args , ** kwargs )
20
- output = ""
21
- if quiet :
22
- while p .poll () == None :
23
- output += p .communicate ()[0 ]
24
- returncode = p .wait ()
25
- if returncode :
26
- if quiet :
27
- print output
28
- raise CalledProcessError (returncode , args )
29
- return returncode
30
-
31
- def check_output (* args , ** kwargs ):
32
- kwargs ['stdout' ] = PIPE
33
- # will hang for HUGE output... you were warned
34
- p = Popen (* args , ** kwargs )
35
- returncode = p .wait ()
36
- if returncode :
37
- raise CalledProcessError (returncode , args )
38
- return p .communicate ()[0 ]
39
-
40
- def clean_render (overviewerargs , quiet ):
18
+
19
+ def check_call (args , verbose = False ):
20
+ try :
21
+ return run (
22
+ args ,
23
+ check = True ,
24
+ stdout = None if verbose else PIPE ,
25
+ stderr = None if verbose else STDOUT ,
26
+ universal_newlines = True ,
27
+ )
28
+ except CalledProcessError as e :
29
+ if verbose :
30
+ print (e .output )
31
+ raise e
32
+
33
+
34
+ def check_output (args ):
35
+ p = run (
36
+ args ,
37
+ check = True ,
38
+ stdout = PIPE ,
39
+ universal_newlines = True
40
+ )
41
+ return p .stdout
42
+
43
+
44
+ def clean_render (overviewerargs , verbose = False ):
41
45
tempdir = tempfile .mkdtemp ('mc-overviewer-test' )
42
46
overviewer_script = None
43
47
for script in overviewer_scripts :
@@ -47,115 +51,121 @@ def clean_render(overviewerargs, quiet):
47
51
if overviewer_script is None :
48
52
sys .stderr .write ("could not find main overviewer script\n " )
49
53
sys .exit (1 )
50
-
54
+
51
55
try :
52
56
# check_call raises CalledProcessError when overviewer.py exits badly
53
- check_call ([sys .executable , ' setup.py' , ' clean' , ' build' ], quiet = quiet )
57
+ check_call ([sys .executable ] + split ( " setup.py clean build" ), verbose = verbose )
54
58
try :
55
- check_call ([sys .executable , overviewer_script , '-d' ] + overviewerargs , quiet = quiet )
59
+ check_call ([sys .executable , overviewer_script , '-d' ] + overviewerargs , verbose = verbose )
56
60
except CalledProcessError :
57
61
pass
58
62
starttime = time .time ()
59
- check_call ([sys .executable , overviewer_script ,] + overviewerargs + [tempdir ,], quiet = quiet )
63
+ check_call ([sys .executable , overviewer_script ] +
64
+ overviewerargs + [tempdir , ], verbose = verbose )
60
65
endtime = time .time ()
61
-
66
+
62
67
return endtime - starttime
63
68
finally :
64
69
shutil .rmtree (tempdir , True )
65
70
71
+
66
72
def get_stats (timelist ):
67
- stats = {}
68
-
69
- stats [ 'count' ] = len (timelist )
70
- stats [ 'minimum' ] = min ( timelist )
71
- stats [ 'maximum' ] = max (timelist )
72
- stats [ 'average' ] = sum ( timelist ) / float ( len ( timelist ))
73
-
74
- meandiff = map ( lambda x : ( x - stats [ ' average' ]) ** 2 , timelist )
75
- stats [ 'standard deviation' ] = math . sqrt ( sum ( meandiff ) / float ( len ( meandiff )))
76
-
77
- return stats
73
+ average = sum ( timelist ) / float ( len ( timelist ))
74
+ meandiff = [( x - stats [ "average" ]) ** 2 for x in timelist ]
75
+ sd = math . sqrt ( sum ( meandiff ) / len (meandiff ) )
76
+ return {
77
+ "count" : len (timelist ),
78
+ "minimum" : min ( timelist ),
79
+ "maximum" : max ( timelist ),
80
+ "average" : average ,
81
+ "standard deviation" : sd
82
+ }
83
+
78
84
79
85
commitre = re .compile ('^commit ([a-z0-9]{40})$' , re .MULTILINE )
80
86
branchre = re .compile ('^\\ * (.+)$' , re .MULTILINE )
87
+
88
+
81
89
def get_current_commit ():
82
- gittext = check_output ([ 'git' , ' branch'] )
90
+ gittext = check_output (split ( 'git branch' ) )
83
91
match = branchre .search (gittext )
84
92
if match and not ("no branch" in match .group (1 )):
85
93
return match .group (1 )
86
- gittext = check_output ([ 'git' , ' show' , ' HEAD'] )
94
+ gittext = check_output (split ( 'git show HEAD' ) )
87
95
match = commitre .match (gittext )
88
96
if match == None :
89
97
return None
90
98
return match .group (1 )
91
99
100
+
92
101
def get_commits (gitrange ):
93
- gittext = check_output ([ 'git' , ' log' , ' --raw' , ' --reverse', gitrange ])
102
+ gittext = check_output (split ( 'git log --raw --reverse' ) + [ gitrange , ])
94
103
for match in commitre .finditer (gittext ):
95
104
yield match .group (1 )
96
105
106
+
97
107
def set_commit (commit ):
98
- check_call ([ 'git' , ' checkout', commit ], quiet = True )
99
-
100
- parser = OptionParser ( usage = "usage: %prog [options] -- [overviewer options/world]" )
101
- parser . add_option ( "-n" , "--number" , metavar = "N" ,
102
- action = "store" , type = "int" , dest = "number" , default = 3 ,
103
- help = "number of renders per commit [default: 3]" )
104
- parser . add_option ( "-c" , "--commits" , metavar = "RANGE" ,
105
- action = "append" , type = "string" , dest = " commits" , default = [],
106
- help = "the commit (or range of commits) to test [default: current]" )
107
- parser . add_option ( "-v" , "--verbose" ,
108
- action = "store_false" , dest = "quiet" , default = True ,
109
- help = "don't suppress overviewer output" )
110
- parser . add_option ( "-k" , "--keep-going" ,
111
- action = "store_false" , dest = "fatal_errors" , default = True ,
112
- help = "don't stop testing when Overviewer croaks" )
113
- parser . add_option ( "-l" , "--log" , dest = " log" , default = "" , metavar = "FILE" ,
114
- help = "log all test results to a file" )
115
-
116
- ( options , args ) = parser . parse_args ()
117
-
118
- if len ( args ) == 0 :
119
- parser . print_help ( )
120
- sys . exit ( 0 )
121
-
122
- commits = []
123
- for commit in options . commits :
124
- if '..' in commit :
125
- commits = get_commits ( commit )
126
- else :
127
- commits . append ( commit )
128
- if not commits :
129
- commits = [ get_current_commit (),]
130
-
131
- log = None
132
- if options . log != "" :
133
- log = open ( options . log , "w" )
134
-
135
- reset_commit = get_current_commit ( )
136
- try :
137
- for commit in commits :
138
- print "testing commit" , commit
139
- set_commit (commit )
140
- timelist = []
141
- print " -- " ,
142
- try :
143
- for i in range ( options . number ):
144
- sys . stdout . write ( str ( i + 1 ) + " " )
145
- sys . stdout . flush ( )
146
- timelist . append ( clean_render ( args , options . quiet ) )
147
- print "... done"
148
- stats = get_stats ( timelist )
149
- print stats
150
- if log :
151
- log . write ( "%s %s \n " % ( commit , repr ( stats )) )
152
- except CalledProcessError , e :
153
- if options . fatal_errors :
154
- print
155
- print "Overviewer croaked, exiting..."
156
- print "(to avoid this, use --keep-going)"
157
- sys . exit ( 1 )
158
- finally :
159
- set_commit ( reset_commit )
160
- if log :
161
- log . close ( )
108
+ check_call (split ( 'git checkout' ) + [ commit , ] )
109
+
110
+
111
+ def main ( args ):
112
+ commits = []
113
+ for commit in args . commits :
114
+ if '..' in commit :
115
+ commits = get_commits ( commit )
116
+ else :
117
+ commits . append ( commit )
118
+ if not commits :
119
+ commits = [ get_current_commit (), ]
120
+
121
+ log = None
122
+ if args . log :
123
+ log = args . log
124
+
125
+ reset_commit = get_current_commit ()
126
+ try :
127
+ for commit in commits :
128
+ print ( "testing commit" , commit )
129
+ set_commit ( commit )
130
+ timelist = []
131
+ print ( " -- " ),
132
+ try :
133
+ for i in range ( args . number ) :
134
+ sys . stdout . write ( str ( i + 1 ) + " " )
135
+ sys . stdout . flush ( )
136
+ timelist . append ( clean_render ( args . overviewer_args , verbose = args . verbose ))
137
+ print ( "... done" )
138
+ stats = get_stats ( timelist )
139
+ print ( stats )
140
+ if log :
141
+ log . write ( "%s %s \n " % ( commit , repr ( stats )))
142
+ except CalledProcessError as e :
143
+ if args . fatal_errors :
144
+ print ( e )
145
+ print ( "Overviewer croaked, exiting..." )
146
+ print ( "(to avoid this, use --keep-going)" )
147
+ sys . exit ( 1 )
148
+ finally :
149
+ set_commit (reset_commit )
150
+ if log :
151
+ log . close ()
152
+
153
+
154
+ if __name__ == "__main__" :
155
+ parser = argparse . ArgumentParser ( description = __doc__ )
156
+ parser . add_argument ( "overviewer_args" , metavar = "[overviewer options/world]" , nargs = "+" )
157
+ parser . add_argument ( "-n" , "--option" , metavar = "N" , type = int , action = "store" ,
158
+ dest = "number" , default = 3 , help = "number of renders per commit [default: 3]" )
159
+ parser . add_argument ( "-c" , "--commits" , metavar = "RANGE" ,
160
+ action = "append" , type = str , dest = "commits" , default = [],
161
+ help = "the commit (or range of commits) to test [default: current]" )
162
+ parser . add_argument ( "-v" , "--verbose" , action = "store_true" , dest = "verbose" , default = False ,
163
+ help = "don't suppress overviewer output" )
164
+ parser . add_argument ( "-k" , "--keep-going" ,
165
+ action = "store_false" , dest = "fatal_errors" , default = True ,
166
+ help = "don't stop testing when Overviewer croaks" )
167
+ parser . add_argument ( "-l" , "--log" , dest = "log" , type = argparse . FileType ( 'w' ), metavar = "FILE" ,
168
+ help = "log all test results to a file" )
169
+
170
+ args = parser . parse_args ()
171
+ main ( args )
0 commit comments