Merge lp:~kalebral-deactivatedaccount/drizzle-automation/report-sqlbench into lp:drizzle-automation
- report-sqlbench
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~kalebral-deactivatedaccount/drizzle-automation/report-sqlbench |
Merge into: | lp:drizzle-automation |
Diff against target: |
570 lines (+294/-114) 9 files modified
drizzle/automation/drizzleslap/run.py (+2/-0) drizzle/automation/lib/options.py (+0/-9) drizzle/automation/lib/util.py (+31/-0) drizzle/automation/reports/drizzleslap.py (+10/-7) drizzle/automation/reports/run.py (+70/-26) drizzle/automation/reports/sqlbench.py (+175/-43) drizzle/automation/reports/sysbench.py (+0/-27) drizzle/automation/sqlbench/run.py (+3/-1) drizzle/automation/sysbench/run.py (+3/-1) |
To merge this branch: | bzr merge lp:~kalebral-deactivatedaccount/drizzle-automation/report-sqlbench |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jay Pipes | Pending | ||
Review via email: mp+15046@code.launchpad.net |
This proposal supersedes a proposal from 2009-11-17.
This proposal has been superseded by a proposal from 2009-11-19.
Commit message
Description of the change
Lee Bieber (kalebral-deactivatedaccount) wrote : Posted in a previous version of this proposal | # |
Jay Pipes (jaypipes) wrote : Posted in a previous version of this proposal | # |
Hi!
Mostly good stuff, but there's a few things I'd like to clean up. :)
1)
+ if working_dir != "None":
In Python, you use None, not "None" to designate a NULL object. So, I believe the above is an error. In fact, for the REPORT command, I don't believe there is a need for the working_dir variable or os.chdir() command at all.
The reason that the working_dir variable and os.chdir() call was made in, for instance, sysbench/run.py is to output the BZR information for that specific run:
bzr log -r-1 -n0 --line
However, when you re-run a report, the above may be misleading, as the above command gets the *last* revision of the current directory. For a re-run report, the last revision may actually not be the revision to which the report refers. :)
So, I would recommend removing the BZR commit output from the drizzleslap and sqlbench report command output like I have done in the sysbench re-run report output.
2) You've added a new function to reports/run.py:
88 +def getLastRunId(
This is exactly the same as a function in reports/
Cheers!
jay
Lee Bieber (kalebral-deactivatedaccount) wrote : Posted in a previous version of this proposal | # |
Hi Jay
For #1 I wanted to pass "None" so that I could reuse the existing function and not have to duplicate a lot of code. When the report sees "None" is just prints "N/A" in the output. I was trying to avoid lots of duplication of code. Should I be passing something else?
For #2 I had pulled out the function from reports/sysbench.py so that everyone can use this function. Do you still want me to put it in a separate file?
Jay Pipes (jaypipes) wrote : Posted in a previous version of this proposal | # |
> Hi Jay
> For #1 I wanted to pass "None" so that I could reuse the existing function and
> not have to duplicate a lot of code. When the report sees "None" is just
> prints "N/A" in the output. I was trying to avoid lots of duplication of code.
> Should I be passing something else?
OK. Just pass None then, not "None", since it can be confusing. :)
> For #2 I had pulled out the function from reports/sysbench.py so that everyone
> can use this function. Do you still want me to put it in a separate file?
Let's put it in lib/util.py along with some of the other common queries.
Thanks!
Jay
- 111. By lbieber <lbieber@orisndriz05>
-
move the error logging from lib/util.py to report/run.py for when run_id cannot be found
Unmerged revisions
Preview Diff
1 | === modified file 'drizzle/automation/drizzleslap/run.py' |
2 | --- drizzle/automation/drizzleslap/run.py 2009-11-13 23:17:05 +0000 |
3 | +++ drizzle/automation/drizzleslap/run.py 2009-11-19 22:35:18 +0000 |
4 | @@ -232,6 +232,8 @@ |
5 | import drizzle.automation.reports.drizzleslap as reports |
6 | email_text= reports.getDrizzleslapReport(working_dir, config_name, run_id, run_date, server_name, variables['bzr_branch'], int(variables['bzr_revision'])) |
7 | logging.info("Sending email...") |
8 | + # bug https://bugs.launchpad.net/launchpad/+bug/419562 - need to use registered launchpad name for from |
9 | + #from_string= ('%s <drizzle-benchmark@lists.launchpad.net>' % socket.gethostname()) |
10 | from_string= ('%s <eday@oddments.org>' % socket.gethostname()) |
11 | util.mail(from_string, variables['drizzleslap']['report_email'], "Drizzleslap Report - %s" % server_version, email_text) |
12 | |
13 | |
14 | === modified file 'drizzle/automation/lib/options.py' |
15 | --- drizzle/automation/lib/options.py 2009-11-17 01:28:37 +0000 |
16 | +++ drizzle/automation/lib/options.py 2009-11-19 22:35:18 +0000 |
17 | @@ -385,15 +385,6 @@ |
18 | else: |
19 | variables['report_name']= report_name |
20 | |
21 | - # Check to ensure we have a sysbench_config value... |
22 | - bench_config= supplied.sysbench_config |
23 | - if bench_config is None: |
24 | - logging.error("The --sysbench-config CLI option is required when running the BENCH command. Exiting.") |
25 | - sys.exit(1) |
26 | - else: |
27 | - variables['sysbench_config']= bench_config |
28 | - |
29 | - |
30 | return variables |
31 | |
32 | options= RuntimeOptions() |
33 | |
34 | === modified file 'drizzle/automation/lib/util.py' |
35 | --- drizzle/automation/lib/util.py 2009-10-14 22:35:50 +0000 |
36 | +++ drizzle/automation/lib/util.py 2009-11-19 22:35:18 +0000 |
37 | @@ -29,6 +29,7 @@ |
38 | import textwrap |
39 | import types |
40 | from drizzle.automation.lib import logging |
41 | +from drizzle.automation.lib import db |
42 | |
43 | def pretty_print_configuration(configuration, key=None, indent_level= 0): |
44 | """Prints configuration variables for the run.""" |
45 | @@ -121,3 +122,33 @@ |
46 | new_run_id= int(result[0][0]) + 1 |
47 | |
48 | return new_run_id |
49 | + |
50 | +# Find the specific last run_id which corresponds to the revision and branch ... |
51 | +def getLastRunId(config_name, server_name, bzr_branch, bzr_revision): |
52 | + |
53 | + version= bzr_branch + '-' + str(bzr_revision) |
54 | + |
55 | + sql= """ |
56 | +SELECT |
57 | + run_id |
58 | +FROM sysbench_config c |
59 | +NATURAL JOIN sysbench_runs r |
60 | +WHERE c.name = '%s' |
61 | +AND r.server = '%s' |
62 | +AND r.version LIKE '%s%%' |
63 | +ORDER BY run_id DESC |
64 | +LIMIT 1 |
65 | +""" % ( |
66 | + config_name |
67 | + , server_name |
68 | + , version |
69 | + ) |
70 | + results= db.get_select(sql) |
71 | + |
72 | + if len(results) == 1: |
73 | + return int(results[0][0]) |
74 | + else: |
75 | + return False |
76 | + |
77 | + return True |
78 | + |
79 | |
80 | === modified file 'drizzle/automation/reports/drizzleslap.py' |
81 | --- drizzle/automation/reports/drizzleslap.py 2009-11-16 05:11:43 +0000 |
82 | +++ drizzle/automation/reports/drizzleslap.py 2009-11-19 22:35:18 +0000 |
83 | @@ -95,13 +95,13 @@ |
84 | |
85 | return report_text |
86 | |
87 | - |
88 | def getDrizzleslapReport(working_dir, drizzleslap_config_name, run_id, run_date, server_name, bzr_branch, bzr_revision): |
89 | """Returns a textual report of the results over a series of runs""" |
90 | |
91 | # Find the revision comment from BZR |
92 | - os.chdir(working_dir) |
93 | - (retcode, rev_comment_output)= commands.getstatusoutput("bzr log -r-1 -n0 --line") |
94 | + if working_dir != None: |
95 | + os.chdir(working_dir) |
96 | + (retcode, rev_comment_output)= commands.getstatusoutput("bzr log -r-1 -n0 --line") |
97 | |
98 | # Output from above command looks like this: |
99 | # jpipes@serialcoder:~/repos/drizzle/trunk-sysbench-r1046$ bzr log -r-1 -n0 --line |
100 | @@ -115,11 +115,14 @@ |
101 | # 1039.2.3: Jay Pipes 2009-05-31 Phase 3 of refactoring JOIN |
102 | # 1039.2.2: Jay Pipes 2009-05-31 Phase 2 of JOIN refactoring. |
103 | |
104 | - comment_lines= rev_comment_output.split("\n") |
105 | - rev_comment= comment_lines[0] |
106 | - if len(comment_lines) > 1: |
107 | - full_commentary= "\n".join(comment_lines[1:]) |
108 | + comment_lines= rev_comment_output.split("\n") |
109 | + rev_comment= comment_lines[0] |
110 | + if len(comment_lines) > 1: |
111 | + full_commentary= "\n".join(comment_lines[1:]) |
112 | + else: |
113 | + full_commentary= None |
114 | else: |
115 | + rev_comment= "N/A" |
116 | full_commentary= None |
117 | |
118 | sql= """ |
119 | |
120 | === modified file 'drizzle/automation/reports/run.py' |
121 | --- drizzle/automation/reports/run.py 2009-11-16 21:25:20 +0000 |
122 | +++ drizzle/automation/reports/run.py 2009-11-19 22:35:18 +0000 |
123 | @@ -31,48 +31,92 @@ |
124 | import os.path |
125 | from drizzle.automation.lib import logging |
126 | from drizzle.automation.lib import util |
127 | +from drizzle.automation.lib import db |
128 | import commands |
129 | import re |
130 | import time |
131 | import datetime |
132 | |
133 | +# Email or display the report |
134 | +def email_or_display_report(email_flag, email_string, report_string, report_text, bzr_revision, run_id): |
135 | + if email_flag is True: |
136 | + # bug https://bugs.launchpad.net/launchpad/+bug/419562 - need to use registered launchpad name for from |
137 | + #from_string= ('%s <drizzle-benchmark@lists.launchpad.net>' % socket.gethostname()) |
138 | + from_string= ('%s <eday@oddments.org>' % socket.gethostname()) |
139 | + util.mail(from_string, email_string, "%s Report for Build %d and Run ID %d" % (report_string, int(bzr_revision), int(run_id)), report_text) |
140 | + else: |
141 | + print report_text |
142 | + |
143 | def execute(report_name, variables): |
144 | # Verify configuration variables and run the requested report |
145 | |
146 | + # We need a server, a revision, and a branch |
147 | + try: |
148 | + bzr_revision= variables['bzr_revision'] |
149 | + bzr_branch= variables['bzr_branch'] |
150 | + except KeyError: |
151 | + logging.error("The report option requires the --bzr-revision, --bzr-branch CLI options to be supplied. Exiting.") |
152 | + return False |
153 | + |
154 | if report_name == 'sysbench': |
155 | - # We need a config file, a server, a revision, and a branch |
156 | + # For sysbench We need a config file, a server, a revision, and a branch |
157 | try: |
158 | sysbench_config= variables['sysbench_config'] |
159 | - bzr_revision= variables['bzr_revision'] |
160 | - bzr_branch= variables['bzr_branch'] |
161 | except KeyError: |
162 | logging.error("The sysbench report requires the --sysbench-config, --bzr-revision, --bzr-branch CLI options to be supplied. Exiting.") |
163 | return False |
164 | |
165 | - try: |
166 | - server_name= variables['server'] |
167 | - except KeyError: |
168 | - server_name= 'drizzled' |
169 | + try: |
170 | + server_name= variables['server'] |
171 | + except KeyError: |
172 | + server_name= 'drizzled' |
173 | |
174 | + if report_name == 'sysbench': |
175 | import drizzle.automation.reports.sysbench as reports |
176 | - |
177 | - # OK, now we need to find the specific last run_id which |
178 | - # corresponds to the revision and branch ... |
179 | - run_id= reports.getLastRunId(sysbench_config, server_name, variables['bzr_branch'], int(variables['bzr_revision'])) |
180 | - |
181 | + run_id= util.getLastRunId(variables['sysbench_config'], server_name, variables['bzr_branch'], int(variables['bzr_revision'])) |
182 | if run_id is None: |
183 | - logging.error("Could not find the last run ID for config %s, server %s, branch %s at revision %s. Exiting." % (sysbench_config, |
184 | - server_name, |
185 | - variables['bzr_branch'], |
186 | - variables['bzr_revision'])) |
187 | - return False |
188 | - |
189 | + logging.error("Could not find the last run ID for config %s, server %s, branch %s at revision %s. Exiting." |
190 | + % ( |
191 | + sysbench_config_name |
192 | + , server_name |
193 | + , variables['bzr_branch'] |
194 | + , variables['bzr_revision'] |
195 | + )) |
196 | + sys.exit(1) |
197 | report_text= reports.getSysbenchRegressionReportForRunId(run_id, sysbench_config, server_name, variables['bzr_branch'], int(variables['bzr_revision'])) |
198 | - |
199 | - if variables['with_email_report'] is True: |
200 | - from_string= ('%s <drizzle-benchmark@lists.launchpad.net>' % socket.gethostname()) |
201 | - util.mail(from_string, variables['sysbench']['report_email'], "SYSBENCH Regression Report for Run ID %d" % int(run_id), report_text) |
202 | - else: |
203 | - print report_text |
204 | - |
205 | - return True |
206 | + email_or_display_report(variables['with_email_report'], variables['sysbench']['report_email'], 'SYSBENCH', report_text, bzr_revision, run_id) |
207 | + |
208 | + elif report_name == 'sqlbench': |
209 | + import drizzle.automation.reports.sqlbench as reports |
210 | + run_id= util.getLastRunId(variables['sqlbench']['sqlbench_config_name'], server_name, variables['bzr_branch'], int(variables['bzr_revision'])) |
211 | + if run_id is None: |
212 | + logging.error("Could not find the last run ID for config %s, server %s, branch %s at revision %s. Exiting." |
213 | + % ( |
214 | + variables['sysbench']['sysbench_config_name'] |
215 | + , server_name |
216 | + , variables['bzr_branch'] |
217 | + , variables['bzr_revision'] |
218 | + )) |
219 | + sys.exit(1) |
220 | + report_text= reports.getSqlbenchReport(None, variables['sqlbench']['sqlbench_config_name'], run_id, 'N/A', server_name, variables['bzr_branch'], int(variables['bzr_revision']), variables['engine']) |
221 | + email_or_display_report(variables['with_email_report'], variables['sysbench']['report_email'], 'SQLBENCH', report_text, bzr_revision, run_id) |
222 | + |
223 | + elif report_name == 'drizzleslap': |
224 | + import drizzle.automation.reports.drizzleslap as reports |
225 | + run_id= util.getLastRunId(variables['drizzleslap']['drizzleslap_config_name'], server_name, variables['bzr_branch'], int(variables['bzr_revision'])) |
226 | + if run_id is None: |
227 | + logging.error("Could not find the last run ID for config %s, server %s, branch %s at revision %s. Exiting." |
228 | + % ( |
229 | + variables['drizzleslap']['drizzleslap_config_name'] |
230 | + , server_name |
231 | + , variables['bzr_branch'] |
232 | + , variables['bzr_revision'] |
233 | + )) |
234 | + sys.exit(1) |
235 | + report_text= reports.getDrizzleslapReport(None, variables['drizzleslap']['drizzleslap_config_name'], run_id, 'N/A', server_name, variables['bzr_branch'], int(variables['bzr_revision'])) |
236 | + email_or_display_report(variables['with_email_report'], variables['sysbench']['report_email'], 'DRIZZLESLAP', report_text, bzr_revision, run_id) |
237 | + else: |
238 | + logging.error("Invalid report option %s. Must be drizzleslap, sqlbench or sysbench", report_name) |
239 | + return False |
240 | + |
241 | + return True |
242 | |
243 | === modified file 'drizzle/automation/reports/sqlbench.py' |
244 | --- drizzle/automation/reports/sqlbench.py 2009-11-16 05:11:43 +0000 |
245 | +++ drizzle/automation/reports/sqlbench.py 2009-11-19 22:35:18 +0000 |
246 | @@ -31,12 +31,80 @@ |
247 | import socket |
248 | import commands |
249 | |
250 | -def getSysbenchRegressionReport(working_dir, run_id, run_date, server_name, bzr_branch, bzr_revision,storage_engine): |
251 | + |
252 | +def sqlQueryString(last_revs, run_id): |
253 | + sql= """ |
254 | +SELECT |
255 | + i.engine |
256 | +, i.operation_name |
257 | +, ROUND(AVG(i.seconds),2) AS seconds |
258 | +, IF (AVG(i.seconds) >= agg.avg_seconds |
259 | + , CONCAT('+', ROUND(((AVG(i.seconds) - agg.avg_seconds) / agg.avg_seconds) * 100, 2), '%%') |
260 | + , CONCAT('-', ROUND(((agg.avg_seconds- AVG(i.seconds)) / agg.avg_seconds) * 100, 2), '%%') |
261 | + ) as pct_diff_from_avg |
262 | +, ROUND((AVG(i.seconds) - agg.avg_seconds), 2) AS diff_from_avg |
263 | +, IF(ABS(AVG(i.seconds) - agg.avg_seconds) <= agg.stddev_seconds |
264 | + , 'within norms' |
265 | + , 'outside norms' |
266 | + ) as is_normal |
267 | +, ROUND(agg.min_seconds,2) AS min_seconds |
268 | +, ROUND(agg.max_seconds,2) AS max_seconds |
269 | +, ROUND(agg.avg_seconds,2) AS avg_seconds |
270 | +, ROUND(agg.stddev_seconds,2) AS stddev_seconds |
271 | +FROM sysbench_config c |
272 | +NATURAL JOIN sysbench_runs r |
273 | +NATURAL JOIN sqlbench_run_iterations i |
274 | +INNER JOIN ( |
275 | + SELECT |
276 | + operation_name |
277 | + , MIN(seconds) as min_seconds |
278 | + , MAX(seconds) as max_seconds |
279 | + , AVG(seconds) as avg_seconds |
280 | + , STDDEV(seconds) as stddev_seconds |
281 | + FROM sqlbench_run_iterations iter |
282 | + WHERE run_id IN (%s) |
283 | + GROUP BY engine, operation_name |
284 | +) AS agg |
285 | + ON i.operation_name = agg.operation_name |
286 | +WHERE r.run_id = %d |
287 | +GROUP BY i.engine, i.operation_name |
288 | +ORDER BY i.engine, i.operation_name |
289 | + """ % ( |
290 | + ",".join(last_revs) |
291 | + , run_id |
292 | + ) |
293 | + |
294 | + return db.get_select(sql) |
295 | + |
296 | +def printResults(results, report_text): |
297 | + """ Print out the sql results for a query """ |
298 | + |
299 | + for result in results: |
300 | + if result[1] != "TOTALS": |
301 | + report_text= report_text + "%-7s %-33s %8s %12s %10s %14s %7s %7s %7s %7s\n" % tuple(result) |
302 | + return report_text |
303 | + |
304 | +# Returns header information for each section |
305 | +def printHeader(string, report_text): |
306 | + report_text= report_text + """ |
307 | +========================================================================================================================= |
308 | +TRENDING OVER %s |
309 | +""" % (string) |
310 | + |
311 | + report_text= report_text + "%-7s %-36s %-6s %-17s %-10s %-11s %-7s %-7s %-7s %-7s" % ("Engine","Test","Time","% Diff from Avg","Diff","Norm?","Min","Max","Avg","STD") |
312 | + |
313 | + report_text= report_text + """ |
314 | +========================================================================================================================= |
315 | +""" |
316 | + return report_text |
317 | + |
318 | +def getSqlbenchReport(working_dir, sqlbench_config_name, run_id, run_date, server_name, bzr_branch, bzr_revision,storage_engine): |
319 | """Returns a textual report of the regression over a series of runs""" |
320 | |
321 | # Find the revision comment from BZR |
322 | - os.chdir(working_dir) |
323 | - (retcode, rev_comment_output)= commands.getstatusoutput("bzr log -r-1 -n0 --line") |
324 | + if working_dir != None: |
325 | + os.chdir(working_dir) |
326 | + (retcode, rev_comment_output)= commands.getstatusoutput("bzr log -r-1 -n0 --line") |
327 | |
328 | # Output from above command looks like this: |
329 | # jpipes@serialcoder:~/repos/drizzle/trunk-sysbench-r1046$ bzr log -r-1 -n0 --line |
330 | @@ -45,67 +113,131 @@ |
331 | # 1039.2.8: Jay Pipes 2009-05-31 Yet more indentation and style cleanup |
332 | # 1039.2.7: Jay Pipes 2009-05-31 Yet more style and indentation cleanups. |
333 | # 1039.2.6: Jay Pipes 2009-05-31 No code changes...only indentation and style cleanup. |
334 | - # 1039.2.5: Jay Pipes 2009-05-31 Style cleanups and moves JOIN_TAB definition out into its own header. |
335 | - # 1039.2.4: Jay Pipes 2009-05-31 Tiny indentation cleanup. |
336 | - # 1039.2.3: Jay Pipes 2009-05-31 Phase 3 of refactoring JOIN |
337 | - # 1039.2.2: Jay Pipes 2009-05-31 Phase 2 of JOIN refactoring. |
338 | |
339 | - comment_lines= rev_comment_output.split("\n") |
340 | - rev_comment= comment_lines[0] |
341 | - if len(comment_lines) > 1: |
342 | - full_commentary= "\n".join(comment_lines[1:]) |
343 | + comment_lines= rev_comment_output.split("\n") |
344 | + rev_comment= comment_lines[0] |
345 | + if len(comment_lines) > 1: |
346 | + full_commentary= "\n".join(comment_lines[1:]) |
347 | + else: |
348 | + full_commentary= None |
349 | else: |
350 | - full_commentary= None |
351 | - |
352 | - rev_range= range(int(bzr_revision) - 3, int(bzr_revision) + 1) |
353 | - revision_versions= "" |
354 | - for rev in rev_range: |
355 | - revision_versions= revision_versions + "'" + bzr_branch + '-' + str(rev) + "'," |
356 | - # Cut off the last comma... |
357 | - revision_versions= revision_versions[0:-1] |
358 | - |
359 | - sql= """SELECT r.version, r.run_id, r.run_date, i.operation_name, i.seconds, i.usr, i.sys, i.cpu |
360 | - FROM sysbench_config c |
361 | - NATURAL JOIN sysbench_runs r |
362 | - NATURAL JOIN sqlbench_run_iterations i |
363 | - WHERE r.server = '%s' |
364 | - AND i.engine = '%s' |
365 | - AND r.version IN (%s) |
366 | - GROUP BY i.operation_name, r.version |
367 | - ORDER BY i.operation_name, r.version |
368 | - """ % ( |
369 | - server_name |
370 | - , storage_engine |
371 | - , revision_versions |
372 | + rev_comment= "N/A" |
373 | + full_commentary= None |
374 | + |
375 | + sql= """ |
376 | +SELECT |
377 | + run_id |
378 | +FROM sysbench_config c |
379 | +NATURAL JOIN sysbench_runs r |
380 | +WHERE c.name = '%s' |
381 | +AND r.server = '%s' |
382 | +AND r.version LIKE '%s%%' |
383 | +AND r.run_id <= %d |
384 | +ORDER BY run_id DESC |
385 | +LIMIT 20 |
386 | +""" % ( |
387 | + sqlbench_config_name |
388 | + , server_name |
389 | + , bzr_branch |
390 | + , run_id |
391 | ) |
392 | - |
393 | - report_text= """================================================================== |
394 | -SQLBENCH REGRESSION REPORT |
395 | -================================================================== |
396 | + results= db.get_select(sql) |
397 | + |
398 | + last_5_revs= [] |
399 | + last_20_revs= [] |
400 | + x= 0 |
401 | + for result in results: |
402 | + cur_run_id= int(result[0]) |
403 | + if x < 5: |
404 | + last_5_revs.append(str(cur_run_id)) |
405 | + last_20_revs.append(str(cur_run_id)) |
406 | + x= x + 1 |
407 | + |
408 | + report_text= """======================================================================================= |
409 | +SQLBENCH REPORT |
410 | +======================================================================================= |
411 | ENGINE: %s |
412 | MACHINE: %s |
413 | RUN ID: %d |
414 | RUN DATE: %s |
415 | +SERVER: %s |
416 | VERSION: %s |
417 | REVISION: %d |
418 | COMMENT: %s |
419 | -================================================================== |
420 | -Version\t\tRun ID\tDate\t\t\tTest\t\tSeconds\tUsr\tSys\tCPU |
421 | -================================================================== |
422 | """ % ( |
423 | storage_engine |
424 | , socket.gethostname() |
425 | , run_id |
426 | , run_date |
427 | + , server_name |
428 | , bzr_branch |
429 | , int(bzr_revision) |
430 | , rev_comment |
431 | ) |
432 | |
433 | + report_text= printHeader('LAST 5 runs', report_text) |
434 | + results= sqlQueryString(last_5_revs, run_id) |
435 | + report_text= printResults(results, report_text) |
436 | + |
437 | + report_text= printHeader('LAST 20 runs', report_text) |
438 | + results= sqlQueryString(last_20_revs, run_id) |
439 | + report_text= printResults(results, report_text) |
440 | + |
441 | + report_text= printHeader('ALL runs', report_text) |
442 | + |
443 | + sql= """ |
444 | +SELECT |
445 | + i.engine |
446 | +, i.operation_name |
447 | +, ROUND(AVG(i.seconds),2) AS seconds |
448 | +, IF (AVG(i.seconds) >= agg.avg_seconds |
449 | + , CONCAT('+', ROUND(((AVG(i.seconds) - agg.avg_seconds) / agg.avg_seconds) * 100, 2), '%%') |
450 | + , CONCAT('-', ROUND(((agg.avg_seconds- AVG(i.seconds)) / agg.avg_seconds) * 100, 2), '%%') |
451 | + ) as pct_diff_from_avg |
452 | +, ROUND((AVG(i.seconds) - agg.avg_seconds), 2) AS diff_from_avg |
453 | +, IF(ABS(AVG(i.seconds) - agg.avg_seconds) <= agg.stddev_seconds |
454 | + , 'within norms' |
455 | + , 'outside norms' |
456 | + ) as is_normal |
457 | +, ROUND(agg.min_seconds,2) AS min_seconds |
458 | +, ROUND(agg.max_seconds,2) AS max_seconds |
459 | +, ROUND(agg.avg_seconds,2) AS avg_seconds |
460 | +, ROUND(agg.stddev_seconds,2) AS stddev_seconds |
461 | +FROM sysbench_config c |
462 | +NATURAL JOIN sysbench_runs r |
463 | +NATURAL JOIN sqlbench_run_iterations i |
464 | +INNER JOIN ( |
465 | + SELECT |
466 | + iter.operation_name |
467 | + , MIN(seconds) as min_seconds |
468 | + , MAX(seconds) as max_seconds |
469 | + , AVG(seconds) as avg_seconds |
470 | + , STDDEV(seconds) as stddev_seconds |
471 | + FROM sysbench_config conf |
472 | + NATURAL JOIN sysbench_runs runs |
473 | + NATURAL JOIN sqlbench_run_iterations iter |
474 | + WHERE conf.name = '%s' |
475 | + AND runs.server = '%s' |
476 | + AND runs.version LIKE '%s%%' |
477 | + GROUP BY iter.engine, iter.operation_name |
478 | +) AS agg |
479 | + ON i.operation_name= agg.operation_name |
480 | +WHERE r.run_id = %d |
481 | +GROUP BY i.engine, i.operation_name |
482 | +ORDER BY i.engine, i.operation_name |
483 | + """ % ( |
484 | + sqlbench_config_name |
485 | + , server_name |
486 | + , bzr_branch |
487 | + , run_id |
488 | + ) |
489 | + |
490 | results= db.get_select(sql) |
491 | - for result in results: |
492 | - report_text= report_text + "\t".join(result) + "\n" |
493 | - report_text= report_text + "==================================================================" |
494 | + |
495 | + report_text= printResults(results, report_text) |
496 | + report_text= report_text + """ |
497 | +=========================================================================================================================""" |
498 | + |
499 | if full_commentary: |
500 | report_text= report_text + """ |
501 | FULL REVISION COMMENTARY: |
502 | |
503 | === modified file 'drizzle/automation/reports/sysbench.py' |
504 | --- drizzle/automation/reports/sysbench.py 2009-11-16 21:25:20 +0000 |
505 | +++ drizzle/automation/reports/sysbench.py 2009-11-19 22:35:18 +0000 |
506 | @@ -30,33 +30,6 @@ |
507 | import socket |
508 | import commands |
509 | |
510 | -def getLastRunId(sysbench_config, server_name, bzr_branch, bzr_revision): |
511 | - """Returns the last Run ID given the supplied config, server, branch and revision""" |
512 | - |
513 | - version= bzr_branch + '-' + str(bzr_revision) |
514 | - |
515 | - sql= """ |
516 | -SELECT |
517 | - run_id |
518 | -FROM sysbench_config c |
519 | -NATURAL JOIN sysbench_runs r |
520 | -WHERE c.name = '%s' |
521 | -AND r.server = '%s' |
522 | -AND r.version LIKE '%s%%' |
523 | -ORDER BY run_id DESC |
524 | -LIMIT 1 |
525 | -""" % ( |
526 | - sysbench_config |
527 | - , server_name |
528 | - , version |
529 | - ) |
530 | - results= db.get_select(sql) |
531 | - |
532 | - if len(results) == 1: |
533 | - return int(results[0][0]) |
534 | - else: |
535 | - return None |
536 | - |
537 | def get5and20RevisionRanges(sysbench_config, server_name, bzr_branch, run_id): |
538 | """Return a tuple with 2 ranges of run_id values for the last 5 and 20 runs""" |
539 | sql= """ |
540 | |
541 | === modified file 'drizzle/automation/sqlbench/run.py' |
542 | --- drizzle/automation/sqlbench/run.py 2009-11-07 17:39:19 +0000 |
543 | +++ drizzle/automation/sqlbench/run.py 2009-11-19 22:35:18 +0000 |
544 | @@ -197,8 +197,10 @@ |
545 | # send email report |
546 | if variables['with_email_report'] is True: |
547 | import drizzle.automation.reports.sqlbench as reports |
548 | - email_text= reports.getSysbenchRegressionReport(working_dir, run_id, run_date, server_name, variables['bzr_branch'], int(variables['bzr_revision']),storage_engine) |
549 | + email_text= reports.getSqlbenchReport(working_dir, sqlbench_config_name, run_id, run_date, server_name, variables['bzr_branch'], int(variables['bzr_revision']),storage_engine) |
550 | logging.info("Sending email...") |
551 | + # bug https://bugs.launchpad.net/launchpad/+bug/419562 - need to use registered launchpad name for from |
552 | + #from_string= ('%s <drizzle-benchmark@lists.launchpad.net>' % socket.gethostname()) |
553 | from_string= ('%s <eday@oddments.org>' % socket.gethostname()) |
554 | util.mail(from_string, variables['sysbench']['report_email'], "SQLBENCH Regression Report - %s" % server_version, email_text) |
555 | |
556 | |
557 | === modified file 'drizzle/automation/sysbench/run.py' |
558 | --- drizzle/automation/sysbench/run.py 2009-10-16 15:40:17 +0000 |
559 | +++ drizzle/automation/sysbench/run.py 2009-11-19 22:35:18 +0000 |
560 | @@ -444,7 +444,9 @@ |
561 | if variables['with_email_report'] is True: |
562 | import drizzle.automation.reports.sysbench as reports |
563 | email_text= reports.getSysbenchRegressionReport(working_dir, sysbench_config, run_id, run_date, server_name, variables['bzr_branch'], int(variables['bzr_revision'])) |
564 | - from_string= ('%s <drizzle-benchmark@lists.launchpad.net>' % socket.gethostname()) |
565 | + # bug https://bugs.launchpad.net/launchpad/+bug/419562 - need to use registered launchpad name for from |
566 | + #from_string= ('%s <drizzle-benchmark@lists.launchpad.net>' % socket.gethostname()) |
567 | + from_string= ('%s <eday@oddments.org>' % socket.gethostname()) |
568 | util.mail(from_string, variables['sysbench']['report_email'], "SYSBENCH Regression Report - %s" % server_version, email_text) |
569 | |
570 | return True |
add report ability for sqlbench and drizzleslap, still more work to on drizzleslap to pretty print output