Merge lp:~spiv/bzr-usertest/network-suite into lp:~bzr/bzr-usertest/trunk-old
- network-suite
- Merge into trunk-old
Status: | Work in progress |
---|---|
Proposed branch: | lp:~spiv/bzr-usertest/network-suite |
Merge into: | lp:~bzr/bzr-usertest/trunk-old |
Diff against target: |
1424 lines (+537/-204) 14 files modified
__init__.py (+21/-7) archiveutil.py (+1/-1) compare.py (+47/-24) datadump.py (+8/-2) dirutil.py (+7/-0) scripts/script_commit.py (+34/-0) scripts/script_common.py (+142/-59) scripts/script_log.py (+45/-45) scripts/script_logplus.py (+6/-6) scripts/script_network.py (+64/-12) statistics.py (+34/-6) suiterunner.py (+66/-14) tests/test_archiveutil.py (+21/-16) userscript.py (+41/-12) |
To merge this branch: | bzr merge lp:~spiv/bzr-usertest/network-suite |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Pool (community) | none | Needs Fixing | |
Bazaar Developers | Pending | ||
Review via email: mp+1335@code.launchpad.net |
Commit message
Description of the change
- 124. By Andrew Bennetts
-
Fix thinko.
Martin Pool (mbp) wrote : | # |
class AnotherBranchTa
+ def __init__(self, branch_
+ self._branch_name = branch_name
+ super(AnotherBr
+
+ def id(self):
+ return super(AnotherBr
+
+ def name(self):
+ return super(AnotherBr
+
def load(self):
cd ..
- $tool clone $repo_read_
- cd ${work_
- """)
- # Go up an extra level for Bazaar to get outside the shared repo
- self.compile_
- cd ..
- cd ..
- $tool clone $repo_read_
- cd ${work_
- """)
+ $tool clone $repo_read_
+ cd ${work_
+ """ % {'branch_name': self._branch_name})
So it looks like you're doing variable substitution into this string through both ${} and %()s. That's not necessarily wrong and it seems syntactically valid, but I do wonder if it's good style. Is there a reason you can't feed the branch name in through the same mechanism that the rest of usertest apparently uses?
Andrew Bennetts (spiv) wrote : | # |
Martin Pool wrote:
> def load(self):
[...]
> + $tool clone $repo_read_
> + cd ${work_
> + """ % {'branch_name': self._branch_name})
>
> So it looks like you're doing variable substitution into this string through both ${} and %()s. That's not necessarily wrong and it seems syntactically valid, but I do wonder if it's good style. Is there a reason you can't feed the branch name in through the same mechanism that the rest of usertest apparently uses?
Yes, they need to happen at different times.
I want to paramaterise branch_name when creating the script, so that I can reuse
this script snippet multiple times in the overall script built by the
script_suite function.
usertest then takes that complete script suite and runs it once for each tool
(and possibly repeats if it has been instructed to do so). work_basename needs
to vary by run.
I could use string.Template for my per-script substitution instead of the %
operator, like per-run substitution, but I think that the double-escaping of
${work_basename} that would require would be no better, and more verbose.
Martin Pool (mbp) wrote : | # |
On Mon, Nov 3, 2008 at 4:33 PM, Andrew Bennetts
<email address hidden> wrote:
> Martin Pool wrote:
>> def load(self):
> [...]
>> + $tool clone $repo_read_
>> + cd ${work_
>> + """ % {'branch_name': self._branch_name})
>>
>> So it looks like you're doing variable substitution into this string through both ${} and %()s. That's not necessarily wrong and it seems syntactically valid, but I do wonder if it's good style. Is there a reason you can't feed the branch name in through the same mechanism that the rest of usertest apparently uses?
>
> Yes, they need to happen at different times. [snip]
OK, maybe a comment here would be worthwhile?
--
Martin <http://
Jelmer Vernooij (jelmer) wrote : | # |
Is this still in progress?
- 125. By Andrew Bennetts
-
Merge trunk.
- 126. By Andrew Bennetts
-
Remove a touch of duplication.
- 127. By Andrew Bennetts
-
Merge fix-tests.
- 128. By Andrew Bennetts
-
Fix handling config var substitution for network suite.
Unmerged revisions
- 128. By Andrew Bennetts
-
Fix handling config var substitution for network suite.
- 127. By Andrew Bennetts
-
Merge fix-tests.
- 126. By Andrew Bennetts
-
Remove a touch of duplication.
- 125. By Andrew Bennetts
-
Merge trunk.
- 124. By Andrew Bennetts
-
Fix thinko.
- 123. By Andrew Bennetts
-
Extend script_network to cover the significant cases from http://
bazaar- vcs.org/ SmartPushAnalys is1.4
Preview Diff
1 | === modified file '__init__.py' |
2 | --- __init__.py 2009-03-27 06:17:04 +0000 |
3 | +++ __init__.py 2011-02-16 06:18:13 +0000 |
4 | @@ -1,4 +1,4 @@ |
5 | -# Copyright (C) 2007 Canonical Ltd |
6 | +# Copyright (C) 2007, 2009 Canonical Ltd |
7 | # |
8 | # This program is free software; you can redistribute it and/or modify |
9 | # it under the terms of the GNU General Public License as published by |
10 | @@ -295,6 +295,7 @@ |
11 | user_params = params_dict |
12 | if config_file is None: |
13 | per_tree_params = None |
14 | + dynamic_user_params = None |
15 | else: |
16 | config = ConfigParser.SafeConfigParser() |
17 | try: |
18 | @@ -304,6 +305,7 @@ |
19 | return 1 |
20 | config.readfp(cfg_fp) |
21 | user_params.update(dict(config.items('DEFAULT'))) |
22 | + dynamic_user_params = dict(config.items('DYNAMIC')) |
23 | per_tree_params = {} |
24 | for tree in trees_list: |
25 | basename = os.path.basename(tree) |
26 | @@ -350,8 +352,8 @@ |
27 | measures_list, data_file, dry_run=dry_run, |
28 | keep_dirs=keep_dirs, verbose=verbose, profiler=prof, |
29 | prof_out_template=prof_out_template, |
30 | - dynamic_params=user_params, per_tree_params=per_tree_params, |
31 | - strict=strict, url=url) |
32 | + user_params=user_params, per_tree_params=per_tree_params, |
33 | + dynamic_user_params=dynamic_user_params, strict=strict, url=url) |
34 | finally: |
35 | data_file.close() |
36 | return result |
37 | @@ -369,13 +371,20 @@ |
38 | trees = dict(config.items('DEFAULT')) |
39 | default_tree = trees.get("default") |
40 | relpath = trees.get(tool_name, default_tree) |
41 | + if relpath is None: |
42 | + raise errors.BzrCommandError( |
43 | + "no archive defined for tool '%s' in lookup file '%s'" |
44 | + % (tool_name,ini_file)) |
45 | tree_path = osutils.pathjoin(basepath, relpath) |
46 | tool_params = {} |
47 | for sect in config.sections(): |
48 | if not sect.startswith("parameter:"): |
49 | continue |
50 | param_name = sect[len('parameter:'):].strip() |
51 | - tool_params[param_name] = config.get(sect, tool_name) |
52 | + try: |
53 | + tool_params[param_name] = config.get(sect, tool_name) |
54 | + except ConfigParser.NoOptionError: |
55 | + tool_params[param_name] = config.get(sect, 'default') |
56 | cfg_fp.close() |
57 | return tree_path, tool_params |
58 | |
59 | @@ -418,9 +427,14 @@ |
60 | class cmd_usertestcompare(Command): |
61 | """Generate a comparison report on csv data produced by userteststats. |
62 | |
63 | - The CSV files must have names of the form $tool-$suite-$scenario.csv |
64 | - (where the components do not contain dashes) and the suite name corresponds |
65 | - to the usertest suite used to generate the data, e.g. "common" or "log". |
66 | + The CSV files must have names of the form $tool-$suite-$scenario.csv: |
67 | + |
68 | + * $tool is the name of the tool used in the run, like "bzr-1.12". It |
69 | + may optionally have a version, separated by a dash. |
70 | + * $suite is the usertest suite used to generate the data, e.g. "common" |
71 | + or "log"; it must not contain a dash. |
72 | + * $scenario is an arbitrary name for the scenario being tested, again |
73 | + containing no dashes. |
74 | """ |
75 | hidden = True |
76 | takes_args = ['csv_files+'] |
77 | |
78 | === modified file 'archiveutil.py' |
79 | --- archiveutil.py 2009-04-02 12:10:24 +0000 |
80 | +++ archiveutil.py 2011-02-16 06:18:13 +0000 |
81 | @@ -81,7 +81,7 @@ |
82 | # need to specially construct a root and ensure all files go in there. |
83 | members.sort() |
84 | if not members[0].isdir(): |
85 | - root_dir == '' |
86 | + root_dir = '' |
87 | shared_root = False |
88 | else: |
89 | root_dir = members[0].name |
90 | |
91 | === modified file 'compare.py' |
92 | --- compare.py 2009-04-02 13:42:24 +0000 |
93 | +++ compare.py 2011-02-16 06:18:13 +0000 |
94 | @@ -78,11 +78,7 @@ |
95 | |
96 | # Collect the additional info for the report: headings, etc. |
97 | hdgs = order * column_count |
98 | - # If we're comparing different tools (e.g. bzr vs hg), then it might be |
99 | - # better to make the descriptions show both commands. For now, assume |
100 | - # we're mostly benching one bzr release vs another so just the first |
101 | - # tool is good enough. |
102 | - action_descriptions = get_action_descriptions(suite, tools[0], labels) |
103 | + action_descriptions = get_action_descriptions(suite, tools, labels) |
104 | |
105 | # Build the cross-file report |
106 | if html: |
107 | @@ -108,24 +104,43 @@ |
108 | return result |
109 | |
110 | |
111 | -def get_action_descriptions(suite_name, tool, labels): |
112 | +def get_action_descriptions(suite_name, tools, labels): |
113 | """Get the dictionary of action descriptions indexed by labels for a suite.""" |
114 | suite = suiterunner.get_suite_by_name(suite_name) |
115 | - essential_params = {} |
116 | descriptions = {} |
117 | for script in suite.iter_scripts(): |
118 | script_id = script.name() |
119 | if script_id .endswith("Task"): |
120 | script_id = script_id[:-4] |
121 | - real_tool = usertool.get_tool_by_fuzzy_name(tool)[0].name |
122 | - cmds_by_labels = script.get_commands_by_label(real_tool, |
123 | - essential_params) |
124 | + cmds_by_labels = _get_cmds_for_labels(script, tools) |
125 | for label in cmds_by_labels: |
126 | compound_name = "%s:%s" % (script_id,label) |
127 | descriptions[compound_name] = cmds_by_labels[label] |
128 | return descriptions |
129 | |
130 | |
131 | +def _get_cmds_for_labels(script, tools): |
132 | + result = {} |
133 | + # Collect the cmds as lists indexed by labels |
134 | + for tool in tools: |
135 | + essential_params = {} |
136 | + real_tool = usertool.get_tool_by_fuzzy_name(tool)[0].name |
137 | + cmds = script.get_commands_by_label(real_tool, essential_params) |
138 | + for label, cmd in cmds.items(): |
139 | + if label in result: |
140 | + result[label].append(cmd) |
141 | + else: |
142 | + result[label] = [cmd] |
143 | + |
144 | + # Now collapse the lists we can |
145 | + for label, cmds in result.items(): |
146 | + # Split out the parameters from the command name |
147 | + params = set([cmd.split(" ", 1)[-1] for cmd in cmds]) |
148 | + if len(params) == 1: |
149 | + result[label] = "$tool %s" % (params.pop(),) |
150 | + return result |
151 | + |
152 | + |
153 | class ReportFormatter(object): |
154 | |
155 | def format(self, hdgs, labels, data, projects, action_descriptions): |
156 | @@ -165,6 +180,8 @@ |
157 | if c.find('.') != -1: |
158 | c = "%.1f" % float(c) |
159 | s += c.rjust(10) |
160 | + if isinstance(desc, list): |
161 | + desc = "; ".join(desc) |
162 | s += " %s" % desc |
163 | return s |
164 | |
165 | @@ -190,7 +207,7 @@ |
166 | return "<tr>" + s + "</tr>" |
167 | |
168 | def _columns(self, label, cols, desc, columns_per_project): |
169 | - s = '<td align="left">%s</td>' % label |
170 | + s = '<td align="left" valign="top">%s</td>' % label |
171 | for i, c in enumerate(cols): |
172 | if i % columns_per_project == 0: |
173 | first = None |
174 | @@ -201,21 +218,26 @@ |
175 | c = "%.1f" % value |
176 | if first is None: |
177 | first = value |
178 | - elif abs(value - first) < 0.1: |
179 | + elif abs(value - first) < 0.15: |
180 | # difference too small to highlight |
181 | pass |
182 | - elif value > first * 1.05: |
183 | - colour = "red" |
184 | - elif value > first: |
185 | - colour = "yellow" |
186 | + elif value > first * 2.00: |
187 | + colour = "OrangeRed" |
188 | + elif value > first * 1.33: |
189 | + colour = "Orange" |
190 | + elif value > first * 1.06: |
191 | + colour = "Yellow" |
192 | elif value < first * 0.50: |
193 | colour = "Cyan" |
194 | elif value < first * 0.75: |
195 | colour = "SkyBlue" |
196 | elif value < first * 0.95: |
197 | colour = "LightGreen" |
198 | - s += '<td align="right" bgcolor="%s">%s</td>' % (colour, c) |
199 | + s += '<td align="right" valign="top" bgcolor="%s">%s</td>' % \ |
200 | + (colour, c) |
201 | if desc is not None: |
202 | + if isinstance(desc, list): |
203 | + desc = "<br>".join(desc) |
204 | s += '<td> </td><td align="left">%s</td>' % desc |
205 | return "<tr>" + s + "</tr>" |
206 | |
207 | @@ -226,19 +248,20 @@ |
208 | print "<html>\n<body>" |
209 | print "<table>" |
210 | print self._heading_columns("Projects:", project_hdgs, "") |
211 | - print self._heading_columns("Action", hdgs, "Description") |
212 | + print self._heading_columns("Action", hdgs, "Commands") |
213 | for label in labels: |
214 | desc = action_descriptions.get(label, "") |
215 | print self._columns(label, data[label], desc, columns_per_project) |
216 | print "</table>" |
217 | print "<p></p>" |
218 | print "<table>" |
219 | - print "<th>Legend:</th>%s%s%s%s%s</tr>" % ( |
220 | - '<td bgcolor="red">slower > 5%</td>', |
221 | - '<td bgcolor="yellow">slower</td>', |
222 | - '<td bgcolor="LightGreen">faster > 5%</td>', |
223 | - '<td bgcolor="SkyBlue">faster > 25%</td>', |
224 | - '<td bgcolor="Cyan">faster > 50%</td>', |
225 | + print "<th>Legend:</th>%s%s%s%s%s%s</tr>" % ( |
226 | + '<td bgcolor="OrangeRed">worse > 2x</td>', |
227 | + '<td bgcolor="Orange">worse > 1.33x</td>', |
228 | + '<td bgcolor="Yellow">worse > 1.06x</td>', |
229 | + '<td bgcolor="LightGreen">better > 5%</td>', |
230 | + '<td bgcolor="SkyBlue">better > 25%</td>', |
231 | + '<td bgcolor="Cyan">better > 50%</td>', |
232 | ) |
233 | print "</table>" |
234 | print "</body>\n</html>" |
235 | |
236 | === modified file 'datadump.py' |
237 | --- datadump.py 2008-02-29 03:33:24 +0000 |
238 | +++ datadump.py 2011-02-16 06:18:13 +0000 |
239 | @@ -75,7 +75,7 @@ |
240 | file_writer = csv.writer(data_file) |
241 | # Dump a header |
242 | time_str = time.asctime() |
243 | - file_count = unpack_stats.get('file_count', '??') |
244 | + file_count = unpack_stats.get('other_count', '??') |
245 | header = "suite %s on tree %s at %s (%s files)" % \ |
246 | (suite, tree, time_str, file_count) |
247 | data_file.write("--run %d: %s\n" % (run_id,header)) |
248 | @@ -85,6 +85,8 @@ |
249 | _nice_time_report(stdout, csv_data) |
250 | # Collect and report the disk space used by each tool |
251 | disk_usage_dict = _get_disk_usage_of_subdirs(work_root) |
252 | + disk_usage_dict[':control-directory:'] = unpack_stats['control_size'] |
253 | + disk_usage_dict[':working-tree:'] = unpack_stats['other_size'] |
254 | disk_usage_data = _dict_to_csv(disk_usage_dict, "Directory", "MB", |
255 | value_formatter=_disk_size_as_str) |
256 | if disk_usage_data is not None: |
257 | @@ -192,7 +194,11 @@ |
258 | stdout.write("%s\t%s\t%s\n" % ("Old:New", "MB", "Directory")) |
259 | for key in keys: |
260 | new_size = disk_usage_dict[key] |
261 | - ratio = new_size * 1.0 / baseline_dir_size |
262 | + if key[0] == ':' and key[-1] == ':': |
263 | + # special statistic |
264 | + ratio = 0 |
265 | + else: |
266 | + ratio = new_size * 1.0 / baseline_dir_size |
267 | size_in_mbytes = _disk_size_as_str(new_size) |
268 | stdout.write("%.3f\t%s\t%s\n" % (ratio,size_in_mbytes,key)) |
269 | |
270 | |
271 | === modified file 'dirutil.py' |
272 | --- dirutil.py 2009-02-23 03:46:54 +0000 |
273 | +++ dirutil.py 2011-02-16 06:18:13 +0000 |
274 | @@ -64,6 +64,13 @@ |
275 | error("%d problems removing %s - manual clean-up may be required" % |
276 | (_cleanup_error_count,path)) |
277 | |
278 | +def dir_count(start): |
279 | + """Get the number of files in a directory tree.""" |
280 | + total = 0L |
281 | + for root, dirs, files in os.walk(start): |
282 | + total += len(dirs) + len(files) |
283 | + return total |
284 | + |
285 | |
286 | def dir_used_size(start): |
287 | "Get bytes used by files in a directory." |
288 | |
289 | === added file 'scripts/script_commit.py' |
290 | --- scripts/script_commit.py 1970-01-01 00:00:00 +0000 |
291 | +++ scripts/script_commit.py 2011-02-16 06:18:13 +0000 |
292 | @@ -0,0 +1,34 @@ |
293 | +# Copyright (C) 2007, 2008 Canonical Ltd |
294 | +# |
295 | +# This program is free software; you can redistribute it and/or modify |
296 | +# it under the terms of the GNU General Public License as published by |
297 | +# the Free Software Foundation; either version 2 of the License, or |
298 | +# (at your option) any later version. |
299 | +# |
300 | +# This program is distributed in the hope that it will be useful, |
301 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
302 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
303 | +# GNU General Public License for more details. |
304 | +# |
305 | +# You should have received a copy of the GNU General Public License |
306 | +# along with this program; if not, write to the Free Software |
307 | +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
308 | + |
309 | +"""Script covering commit operations in Bazaar.""" |
310 | + |
311 | +from bzrlib.plugins.usertest.userscript import ScriptTask, ScriptSuite |
312 | +import script_common |
313 | + |
314 | + |
315 | +## Suite ## |
316 | + |
317 | +def script_suite(): |
318 | + |
319 | + suite = ScriptSuite() |
320 | + # Setup |
321 | + suite.add(script_common.SetupSuite()) |
322 | + # Work |
323 | + suite.add(script_common.AddTask()) |
324 | + suite.add(script_common.ChangeTask()) |
325 | + suite.add(script_common.ChangeFileTask()) |
326 | + return suite |
327 | |
328 | === modified file 'scripts/script_common.py' |
329 | --- scripts/script_common.py 2009-03-25 23:59:10 +0000 |
330 | +++ scripts/script_common.py 2011-02-16 06:18:13 +0000 |
331 | @@ -24,6 +24,12 @@ |
332 | |
333 | * 'additional' tasks are ones that other VCS tools might support |
334 | but we're only interested in their speed on Bazaar. |
335 | + |
336 | +The following variables need to be set before calling this script: |
337 | + |
338 | + * file - the file to use for file-specific logging |
339 | + |
340 | +This variable is used in the log, annotate and cat tasks. |
341 | """ |
342 | |
343 | from bzrlib.plugins.usertest.userscript import ScriptTask, ScriptSuite |
344 | @@ -72,6 +78,10 @@ |
345 | once_only = True |
346 | |
347 | def load(self): |
348 | + # To trigger this, run a script called bzr-current |
349 | + self.compile_for_versions(TOOL_BZR, "current", """ |
350 | + $tool upgrade --1.9 |
351 | + """) |
352 | # To trigger this, run a script called bzr-btree |
353 | self.compile_for_versions(TOOL_BZR, "btree", """ |
354 | $tool upgrade --1.9 |
355 | @@ -80,29 +90,9 @@ |
356 | self.compile_for_versions(TOOL_BZR, "development", """ |
357 | $tool upgrade --development |
358 | """) |
359 | - # To trigger this, run a script called bzr-dev5plain |
360 | - self.compile_for_versions(TOOL_BZR, "dev5plain", """ |
361 | - $tool upgrade --development5 |
362 | - """) |
363 | - # To trigger this, run a script called bzr-dev5h16 |
364 | - self.compile_for_versions(TOOL_BZR, "dev5h16", """ |
365 | - $tool upgrade --development5-hash16 |
366 | - """) |
367 | - # To trigger this, run a script called bzr-dev5h255 |
368 | - self.compile_for_versions(TOOL_BZR, "dev5h255", """ |
369 | - $tool upgrade --development5-hash255 |
370 | - """) |
371 | - # To trigger this, run a script called bzr-gcnrr |
372 | - self.compile_for_versions(TOOL_BZR, "gcnrr", """ |
373 | - $tool upgrade --gc-no-rich-root |
374 | - """) |
375 | - # To trigger this, run a script called bzr-gcchk16 |
376 | - self.compile_for_versions(TOOL_BZR, "gcchk16", """ |
377 | - $tool upgrade --gc-chk16 |
378 | - """) |
379 | - # To trigger this, run a script called bzr-gcchk255 |
380 | - self.compile_for_versions(TOOL_BZR, "gcchk255", """ |
381 | - $tool upgrade --gc-chk255 |
382 | + # To trigger this, run a script called bzr-dev6 |
383 | + self.compile_for_versions(TOOL_BZR, "dev6", """ |
384 | + $tool upgrade --development6-rich-root |
385 | """, exit_codes={'upgrade': [0, 3]}) |
386 | # To trigger this, run a script called bzr-gcchk255 |
387 | self.compile_for_versions(TOOL_BZR, "gcchk255big", """ |
388 | @@ -124,24 +114,36 @@ |
389 | def load(self): |
390 | self.compile_for_tools([TOOL_BZR], """ |
391 | cd .. |
392 | - $tool init-repo repo --${format} |
393 | - $tool branch $work_basename repo/${work_basename} ## unshared |
394 | - cd repo |
395 | - $tool branch $work_basename fix ## shared |
396 | - $tool branch fix fix2 --no-tree ## sharedNoTree |
397 | - cd $work_basename |
398 | - """) |
399 | - self.compile_for_tools([TOOL_GIT, TOOL_HG], """ |
400 | - cd .. |
401 | - $tool clone $work_basename ${work_basename}-branchAndFix ## unshared |
402 | - cd ${work_basename}-branchAndFix |
403 | + $tool init-repo project --${format} |
404 | + $tool branch $work_basename project/trunk ## unshared |
405 | + cd project |
406 | + $tool branch trunk fix ## shared |
407 | + $tool branch fix fix2 --no-tree ## sharedNoTree |
408 | + cd fix |
409 | + """) |
410 | + self.compile_for_tools([TOOL_HG], """ |
411 | + cd .. |
412 | + mkdir project |
413 | + $tool clone --pull $work_basename project/trunk ## unshared |
414 | + cd project |
415 | + $tool clone trunk fix ## shared |
416 | + $tool clone -U fix fix2 ## sharedNoTree |
417 | + cd fix |
418 | + """) |
419 | + self.compile_for_tools([TOOL_GIT], """ |
420 | + cd .. |
421 | + mkdir project |
422 | + $tool clone $work_basename project/trunk ## unshared |
423 | + cd project |
424 | + $tool clone trunk fix ## shared |
425 | + cd fix |
426 | """) |
427 | |
428 | |
429 | class AddTask(ScriptTask): |
430 | |
431 | def load(self): |
432 | - self.compile_default(""" |
433 | + self.compile_for_tools([TOOL_BZR], """ |
434 | mkdir zzzDir |
435 | echo "# junk" > zzzDir/zzzFile |
436 | $tool add |
437 | @@ -149,6 +151,16 @@ |
438 | $tool diff |
439 | $tool commit -m "testing add" |
440 | """, exit_codes={'diff': 1}) |
441 | + # hg is the same except for the diff exit code |
442 | + self.compile_for_tools([TOOL_HG], """ |
443 | + mkdir zzzDir |
444 | + echo "# junk" > zzzDir/zzzFile |
445 | + $tool add |
446 | + $tool status |
447 | + $tool diff |
448 | + $tool commit -m "testing add" |
449 | + """) |
450 | + # git needs an extra option to diff as well |
451 | self.compile_for_tools([TOOL_GIT], """ |
452 | mkdir zzzDir |
453 | echo "# junk" > zzzDir/zzzFile |
454 | @@ -162,12 +174,20 @@ |
455 | class ChangeTask(ScriptTask): |
456 | |
457 | def load(self): |
458 | - self.compile_default(""" |
459 | + self.compile_for_tools([TOOL_BZR], """ |
460 | echo "# more junk" >> zzzDir/zzzFile |
461 | $tool status |
462 | $tool diff |
463 | $tool commit -m "testing change" |
464 | """, exit_codes={'diff': 1}) |
465 | + # hg is the same except for the diff exit code |
466 | + self.compile_for_tools([TOOL_HG], """ |
467 | + echo "# more junk" >> zzzDir/zzzFile |
468 | + $tool status |
469 | + $tool diff |
470 | + $tool commit -m "testing change" |
471 | + """) |
472 | + # git needs an explicit add and different diff cli |
473 | self.compile_for_tools([TOOL_GIT], """ |
474 | echo "# more junk" >> zzzDir/zzzFile |
475 | $tool add |
476 | @@ -177,24 +197,54 @@ |
477 | """) |
478 | |
479 | |
480 | +class ChangeFileTask(ScriptTask): |
481 | + |
482 | + def load(self): |
483 | + self.compile_for_tools([TOOL_BZR], """ |
484 | + echo "# more junk" >> zzzDir/zzzFile |
485 | + $tool status zzzDir/zzzFile |
486 | + $tool diff zzzDir/zzzFile |
487 | + $tool commit -m "testing change file" zzzDir/zzzFile |
488 | + """, exit_codes={'diff': 1}) |
489 | + # hg is the same except for the diff exit code |
490 | + self.compile_for_tools([TOOL_HG], """ |
491 | + echo "# more junk" >> zzzDir/zzzFile |
492 | + $tool status zzzDir/zzzFile |
493 | + $tool diff zzzDir/zzzFile |
494 | + $tool commit -m "testing change file" zzzDir/zzzFile |
495 | + """) |
496 | + # git needs an explicit add and different diff cli |
497 | + self.compile_for_tools([TOOL_GIT], """ |
498 | + echo "# more junk" >> zzzDir/zzzFile |
499 | + $tool add zzzDir/zzzFile |
500 | + $tool status |
501 | + $tool diff --cached |
502 | + $tool commit -m "testing change file" |
503 | + """) |
504 | + |
505 | + |
506 | class BranchAddChangeSuite(ScriptSuite): |
507 | |
508 | def load(self): |
509 | self.add(BranchTask()) |
510 | self.add(AddTask()) |
511 | self.add(ChangeTask()) |
512 | + self.add(ChangeFileTask()) |
513 | |
514 | |
515 | ## Work Scripts - Additional ## |
516 | |
517 | -class BundleTask(ScriptTask): |
518 | +class SendTask(ScriptTask): |
519 | |
520 | def load(self): |
521 | # This can fail if there's no submit branch, which there isn't |
522 | # if we're excluding the BranchTask during a run say |
523 | self.compile_for_tools([TOOL_BZR], """ |
524 | - $tool send -o zzzBundle.path |
525 | + $tool send -o zzzBundle.patch |
526 | """, exit_codes={'send': [0, 3]}) |
527 | + self.compile_for_tools([TOOL_HG], """ |
528 | + $tool bundle zzzBundle.patch ../trunk ## send |
529 | + """) |
530 | |
531 | |
532 | class RemoveTask(ScriptTask): |
533 | @@ -235,8 +285,13 @@ |
534 | class TagTask(ScriptTask): |
535 | |
536 | def load(self): |
537 | - self.compile_default(""" |
538 | - $tool tag BETA-1 |
539 | + self.compile_for_tools([TOOL_BZR, TOOL_HG], """ |
540 | + $tool tag BETA-1 |
541 | + $tool tags |
542 | + """) |
543 | + self.compile_for_tools([TOOL_GIT], """ |
544 | + $tool tag BETA-1 |
545 | + $tool tag ## tags |
546 | """) |
547 | |
548 | |
549 | @@ -287,13 +342,32 @@ |
550 | def load(self): |
551 | self.compile_default(""" |
552 | $tool log |
553 | - $tool log zzzDir/zzzFile ## oneFile |
554 | - """) |
555 | - self.compile_for_tools([TOOL_BZR], """ |
556 | - $tool log |
557 | - $tool log zzzDir/zzzFile ## oneFile |
558 | - $tool log -n1 ## mainline |
559 | - $tool log -n1 zzzDir/zzzFile ## mainlineOneFile |
560 | + """) |
561 | + self.compile_for_tools([TOOL_BZR], """ |
562 | + $tool log |
563 | + $tool log -n0 ## detailed |
564 | + """) |
565 | + self.compile_for_tools([TOOL_HG], """ |
566 | + $tool log |
567 | + $tool log --follow ## detailed |
568 | + """) |
569 | + |
570 | + |
571 | +class LogFileTask(ScriptTask): |
572 | + |
573 | + run_if_defined = ['file'] |
574 | + |
575 | + def load(self): |
576 | + self.compile_default(""" |
577 | + $tool log $file |
578 | + """) |
579 | + self.compile_for_tools([TOOL_BZR], """ |
580 | + $tool log $file |
581 | + $tool log -n0 $file ## detailed |
582 | + """) |
583 | + self.compile_for_tools([TOOL_HG], """ |
584 | + $tool log $file |
585 | + $tool log --follow $file ## detailed |
586 | """) |
587 | |
588 | |
589 | @@ -308,9 +382,11 @@ |
590 | |
591 | class AnnotateTask(ScriptTask): |
592 | |
593 | + run_if_defined = ['file'] |
594 | + |
595 | def load(self): |
596 | self.compile_default(""" |
597 | - $tool annotate zzzDir/zzzFile |
598 | + $tool annotate $file |
599 | """) |
600 | |
601 | |
602 | @@ -355,9 +431,11 @@ |
603 | |
604 | class FileContentTask(ScriptTask): |
605 | |
606 | + run_if_defined = ['file'] |
607 | + |
608 | def load(self): |
609 | self.compile_for_tools([TOOL_BZR], """ |
610 | - $tool cat -r -1 zzzDir/zzzFile |
611 | + $tool cat -r -1 $file |
612 | """) |
613 | |
614 | |
615 | @@ -365,11 +443,20 @@ |
616 | |
617 | def load(self): |
618 | self.compile_for_tools([TOOL_BZR], """ |
619 | - $tool status -r -2..-1 |
620 | - $tool diff -r -2..-1 |
621 | - $tool ls -r -1 --non-recursive ## listRoot |
622 | - $tool ls -r -1 ## listAll |
623 | + $tool log -r -1 |
624 | + $tool status -c -1 |
625 | + $tool diff -c -1 |
626 | + $tool ls -r -1 ## list |
627 | + $tool ls -r -1 --recursive ## listAll |
628 | """, exit_codes={'diff': 1}) |
629 | + # Note: hg locate has no way of limiting recusion down |
630 | + self.compile_for_tools([TOOL_HG], """ |
631 | + $tool tip ## log |
632 | + $tool status -r tip |
633 | + $tool diff -r tip |
634 | + $tool locate -r tip ## list |
635 | + $tool locate -r tip ## listAll |
636 | + """) |
637 | |
638 | |
639 | |
640 | @@ -461,14 +548,10 @@ |
641 | suite.add(SetupSuite()) |
642 | # Work |
643 | suite.add(BranchAddChangeSuite()) |
644 | - suite.add(BundleTask()) # TODO: remove once default script = local |
645 | - # Admin |
646 | - suite.add(TagTask()) |
647 | + suite.add(SendTask()) |
648 | # Info |
649 | - suite.add(HelpTask()) |
650 | - suite.add(ChangeInfoTask()) |
651 | suite.add(LogTask()) |
652 | + suite.add(LogFileTask()) |
653 | suite.add(AnnotateTask()) |
654 | - suite.add(TagsTask()) |
655 | suite.add(HistoryTask()) |
656 | return suite |
657 | |
658 | === modified file 'scripts/script_log.py' |
659 | --- scripts/script_log.py 2009-04-02 13:52:55 +0000 |
660 | +++ scripts/script_log.py 2011-02-16 06:18:13 +0000 |
661 | @@ -64,43 +64,43 @@ |
662 | def load(self): |
663 | # Note: do not add log -v below - it belongs in the logplus suite |
664 | self.compile_for_tools([TOOL_BZR], """ |
665 | - $tool log --short ## mainline |
666 | - $tool log --short $file ## mainline-file |
667 | - $tool log --long ## merges |
668 | - $tool log --long $file ## merges-file |
669 | + $tool log ## mainline |
670 | + $tool log $file ## mainline-file |
671 | + $tool log -n0 ## merges |
672 | + $tool log -n0 $file ## merges-file |
673 | """) |
674 | |
675 | class LogRecentTask(ScriptTask): |
676 | |
677 | def load(self): |
678 | self.compile_for_tools([TOOL_BZR], """ |
679 | - $tool log -r-10.. --short ## mainline |
680 | - $tool log -r-10.. --short --forward ## mainline-forward |
681 | - $tool log -r-10.. --short $file ## mainline-file |
682 | - $tool log -r-10.. --short -v ## mainline-delta |
683 | - $tool log -r-10.. --long ## merges |
684 | - $tool log -r-10.. --long $file ## merges-file |
685 | - $tool log -r-10.. --long -v ## merges-delta |
686 | + $tool log -r-10.. ## mainline |
687 | + $tool log -r-10.. --forward ## mainline-forward |
688 | + $tool log -r-10.. $file ## mainline-file |
689 | + $tool log -r-10.. -v ## mainline-delta |
690 | + $tool log -r-10.. -n0 ## merges |
691 | + $tool log -r-10.. -n0 $file ## merges-file |
692 | + $tool log -r-10.. -n0 -v ## merges-delta |
693 | """) |
694 | |
695 | class LogTipTask(ScriptTask): |
696 | |
697 | def load(self): |
698 | self.compile_for_tools([TOOL_BZR], """ |
699 | - $tool log -r-1 --short ## top |
700 | - $tool log -r-1 --short -v ## top-delta |
701 | - $tool log -r-1 --long ## merges |
702 | - $tool log -r-1 --long -v ## merges-delta |
703 | + $tool log -r-1 ## top |
704 | + $tool log -r-1 -v ## top-delta |
705 | + $tool log -r-1 -n0 ## merges |
706 | + $tool log -r-1 -n0 -v ## merges-delta |
707 | """) |
708 | |
709 | class LogMainlineTask(ScriptTask): |
710 | |
711 | def load(self): |
712 | self.compile_for_tools([TOOL_BZR], """ |
713 | - $tool log -r-10 --short ## top |
714 | - $tool log -r-10 --short -v ## top-delta |
715 | - $tool log -r-10 --long ## merges |
716 | - $tool log -r-10 --long -v ## merges-delta |
717 | + $tool log -r-10 ## top |
718 | + $tool log -r-10 -v ## top-delta |
719 | + $tool log -r-10 -n0 ## merges |
720 | + $tool log -r-10 -n0 -v ## merges-delta |
721 | """) |
722 | |
723 | class LogMergeRevisionTask(ScriptTask): |
724 | @@ -109,30 +109,30 @@ |
725 | |
726 | def load(self): |
727 | self.compile_for_tools([TOOL_BZR], """ |
728 | - $tool log -r$merge_revision --short ## top |
729 | - $tool log -r$merge_revision --short -v ## top-delta |
730 | - $tool log -r$merge_revision --long ## merges |
731 | - $tool log -r$merge_revision --long -v ## merges-delta |
732 | + $tool log -r$merge_revision ## top |
733 | + $tool log -r$merge_revision -v ## top-delta |
734 | + $tool log -r$merge_revision -n0 ## merges |
735 | + $tool log -r$merge_revision -n0 -v ## merges-delta |
736 | """) |
737 | |
738 | class LogInitialTask(ScriptTask): |
739 | |
740 | def load(self): |
741 | self.compile_for_tools([TOOL_BZR], """ |
742 | - $tool log -r1 --short ## top |
743 | - $tool log -r1 --short -v ## top-delta |
744 | - $tool log -r1 --long ## merges |
745 | - $tool log -r1 --long -v ## merges-delta |
746 | + $tool log -r1 ## top |
747 | + $tool log -r1 -v ## top-delta |
748 | + $tool log -r1 -n0 ## merges |
749 | + $tool log -r1 -n0 -v ## merges-delta |
750 | """) |
751 | |
752 | class LogEarlyTask(ScriptTask): |
753 | |
754 | def load(self): |
755 | self.compile_for_tools([TOOL_BZR], """ |
756 | - $tool log -r..10 --short ## mainline |
757 | - $tool log -r..10 --short -v ## mainline-delta |
758 | - $tool log -r..10 --long ## merges |
759 | - $tool log -r..10 --long -v ## merges-delta |
760 | + $tool log -r..10 ## mainline |
761 | + $tool log -r..10 -v ## mainline-delta |
762 | + $tool log -r..10 -n0 ## merges |
763 | + $tool log -r..10 -n0 -v ## merges-delta |
764 | """) |
765 | |
766 | class LogEarlyFileTask(ScriptTask): |
767 | @@ -141,32 +141,32 @@ |
768 | |
769 | def load(self): |
770 | self.compile_for_tools([TOOL_BZR], """ |
771 | - $tool log -r..10 --short $early_file ## mainline-file |
772 | - $tool log -r..10 --long $early_file ## merges-file |
773 | + $tool log -r..10 $early_file ## mainline-file |
774 | + $tool log -r..10 -n0 $early_file ## merges-file |
775 | """) |
776 | |
777 | class LogIncrementalAllTask(ScriptTask): |
778 | |
779 | def load(self): |
780 | self.compile_for_tools([TOOL_BZR], """ |
781 | - $tool log -l5 --short ## mainline |
782 | - $tool log -l5 --short $file ## mainline-file |
783 | - $tool log -l5 --short -v ## mainline-delta |
784 | - $tool log -l5 --long ## merges |
785 | - $tool log -l5 --long $file ## merges-file |
786 | - $tool log -l5 --long -v ## merges-delta |
787 | + $tool log -l5 ## mainline |
788 | + $tool log -l5 $file ## mainline-file |
789 | + $tool log -l5 -v ## mainline-delta |
790 | + $tool log -l5 -n0 ## merges |
791 | + $tool log -l5 -n0 $file ## merges-file |
792 | + $tool log -l5 -n0 -v ## merges-delta |
793 | """) |
794 | |
795 | class LogIncrementalRecentTask(ScriptTask): |
796 | |
797 | def load(self): |
798 | self.compile_for_tools([TOOL_BZR], """ |
799 | - $tool log -l5 -r-10.. --short ## mainline |
800 | - $tool log -l5 -r-10.. --short $file ## mainline-file |
801 | - $tool log -l5 -r-10.. --short -v ## mainline-delta |
802 | - $tool log -l5 -r-10.. --long ## merges |
803 | - $tool log -l5 -r-10.. --long $file ## merges-file |
804 | - $tool log -l5 -r-10.. --long -v ## merges-delta |
805 | + $tool log -l5 -r-10.. ## mainline |
806 | + $tool log -l5 -r-10.. $file ## mainline-file |
807 | + $tool log -l5 -r-10.. -v ## mainline-delta |
808 | + $tool log -l5 -r-10.. -n0 ## merges |
809 | + $tool log -l5 -r-10.. -n0 $file ## merges-file |
810 | + $tool log -l5 -r-10.. -n0 -v ## merges-delta |
811 | """) |
812 | |
813 | |
814 | |
815 | === modified file 'scripts/script_logplus.py' |
816 | --- scripts/script_logplus.py 2009-04-02 07:21:04 +0000 |
817 | +++ scripts/script_logplus.py 2011-02-16 06:18:13 +0000 |
818 | @@ -38,24 +38,24 @@ |
819 | |
820 | def load(self): |
821 | self.compile_for_tools([TOOL_BZR], """ |
822 | - $tool log --short -v ## mainline |
823 | - $tool log --long -v ## merges |
824 | + $tool log -n1 -v ## mainline |
825 | + $tool log -n0 -v ## merges |
826 | """) |
827 | |
828 | class LogPatchesTask(ScriptTask): |
829 | |
830 | def load(self): |
831 | self.compile_for_tools([TOOL_BZR], """ |
832 | - $tool log --short -p ## mainline |
833 | - $tool log --long -p ## merges |
834 | + $tool log -n1 -p ## mainline |
835 | + $tool log -n0 -p ## merges |
836 | """) |
837 | |
838 | class LogDirectoryTask(ScriptTask): |
839 | |
840 | def load(self): |
841 | self.compile_for_tools([TOOL_BZR], """ |
842 | - $tool log --short $dir ## mainline |
843 | - $tool log --long $dir ## merges |
844 | + $tool log -n1 $dir ## mainline |
845 | + $tool log -n0 $dir ## merges |
846 | """) |
847 | |
848 | |
849 | |
850 | === modified file 'scripts/script_network.py' |
851 | --- scripts/script_network.py 2009-02-14 07:17:15 +0000 |
852 | +++ scripts/script_network.py 2011-02-16 06:18:13 +0000 |
853 | @@ -64,6 +64,7 @@ |
854 | ## Scripts ## |
855 | |
856 | class InitialPushTask(ScriptTask): |
857 | + """Push into a new shared repository.""" |
858 | |
859 | def load(self): |
860 | self.compile_for_tools([TOOL_BZR], """ |
861 | @@ -107,48 +108,99 @@ |
862 | |
863 | class AnotherBranchTask(ScriptTask): |
864 | |
865 | + def __init__(self, branch_name='-anotherBranch'): |
866 | + self._branch_name = branch_name |
867 | + super(AnotherBranchTask, self).__init__() |
868 | + |
869 | + def id(self): |
870 | + return super(AnotherBranchTask, self).id() + self._branch_name |
871 | + |
872 | + def name(self): |
873 | + return super(AnotherBranchTask, self).name() + self._branch_name |
874 | + |
875 | def load(self): |
876 | - self.compile_default(""" |
877 | + script = (""" |
878 | cd .. |
879 | - $tool clone $repo_read_url/trunk ${work_basename}-anotherBranch |
880 | - cd ${work_basename}-anotherBranch |
881 | - """) |
882 | + $tool clone $repo_read_url/trunk ${work_basename}%(branch_name)s |
883 | + cd ${work_basename}%(branch_name)s |
884 | + """ % {'branch_name': self._branch_name}) |
885 | + self.compile_default(script) |
886 | # Go up an extra level for Bazaar to get outside the shared repo |
887 | self.compile_for_tools([TOOL_BZR], """ |
888 | - cd .. |
889 | - cd .. |
890 | - $tool clone $repo_read_url/trunk ${work_basename}-anotherBranch |
891 | - cd ${work_basename}-anotherBranch |
892 | - """) |
893 | + cd ..""" + script) |
894 | |
895 | |
896 | class AnotherPushTask(ScriptTask): |
897 | - |
898 | + """Push a branch into an existing shared repository.""" |
899 | + |
900 | + def __init__(self, expect_diverged_error=False, label=''): |
901 | + self._expect_diverged_error = expect_diverged_error |
902 | + self._label = label |
903 | + super(AnotherPushTask, self).__init__() |
904 | + |
905 | + def id(self): |
906 | + return super(AnotherPushTask, self).id() + self._label |
907 | + |
908 | + def name(self): |
909 | + return super(AnotherPushTask, self).name() + self._label |
910 | + |
911 | def load(self): |
912 | + if self._expect_diverged_error: |
913 | + exit_codes = {'bzrpush': 3} |
914 | + else: |
915 | + exit_codes = {} |
916 | self.compile_default(""" |
917 | $tool push $repo_write_url/anotherBranch |
918 | """) |
919 | self.compile_for_tools([TOOL_BZR], """ |
920 | - $tool push --create-prefix $repo_write_url/anotherBranch |
921 | - """) |
922 | + $tool push --create-prefix $repo_write_url/anotherBranch ## bzrpush |
923 | + """, exit_codes=exit_codes) |
924 | # Hg doesn't support push over sftp out of the box |
925 | self.compile_for_tools([TOOL_HG, TOOL_GIT], """ |
926 | scp -r . $repo_server:$repo_dir/anotherBranch |
927 | """) |
928 | |
929 | |
930 | +class PushOverwriteTask(ScriptTask): |
931 | + """Push a branch into an existing shared repository.""" |
932 | + |
933 | + def load(self): |
934 | + self.compile_for_tools([TOOL_BZR], """ |
935 | + $tool push --overwrite $repo_write_url/anotherBranch |
936 | + """) |
937 | + |
938 | + |
939 | +class DivergeTask(ScriptTask): |
940 | + """Make a branch that diverges.""" |
941 | + |
942 | + def load(self): |
943 | + self.compile_default(""" |
944 | + $tool push $repo_write_url/anotherBranch |
945 | + """) |
946 | + |
947 | ## Suite ## |
948 | |
949 | def script_suite(): |
950 | |
951 | suite = ScriptSuite() |
952 | + # Initialise: make standalone 'trunk' locally |
953 | suite.add(script_common.SetupSuite()) |
954 | + # Push branch into empty shared repo |
955 | suite.add(InitialPushTask()) |
956 | + # Push one new revision onto existing remote branch |
957 | suite.add(script_common.BranchTask()) |
958 | suite.add(script_common.AddTask()) |
959 | suite.add(PushChangesTask()) |
960 | + # Pull that one new revision back to local 'trunk' |
961 | suite.add(RefreshMirrorTask()) |
962 | + # Push a new branch to shared repo with one new revision. |
963 | suite.add(AnotherBranchTask()) |
964 | suite.add(script_common.ChangeTask()) |
965 | suite.add(AnotherPushTask()) |
966 | + # Push to a diverged branch, resulting in error. |
967 | + suite.add(AnotherBranchTask(branch_name='-divergedBranch')) |
968 | + suite.add(script_common.ChangeTask()) |
969 | + suite.add(AnotherPushTask(expect_diverged_error=True, label='-diverged')) |
970 | + # Push to diverged branch, with overwrite. |
971 | + suite.add(PushOverwriteTask()) |
972 | return suite |
973 | |
974 | === modified file 'statistics.py' |
975 | --- statistics.py 2009-02-23 03:46:54 +0000 |
976 | +++ statistics.py 2011-02-16 06:18:13 +0000 |
977 | @@ -52,9 +52,12 @@ |
978 | self.slow_counts = {} |
979 | self.vslow_counts = {} |
980 | self.vvslow_counts = {} |
981 | + self.space_originals = {} |
982 | self.space_totals = {} |
983 | self.space_ratios = {} |
984 | self.file_counts = {} |
985 | + self.control_spaces = {} |
986 | + self.working_spaces = {} |
987 | |
988 | |
989 | def get_project_run(report_name): |
990 | @@ -99,8 +102,11 @@ |
991 | vslow_count = 0 |
992 | vvslow_count = 0 |
993 | space_ratio = 0 |
994 | + space_original = 0 |
995 | space_total = 0 |
996 | file_count = 0 |
997 | + control_space = 0 |
998 | + working_space = 0 |
999 | looking_for_times = True |
1000 | found_times = False |
1001 | looking_for_space = False |
1002 | @@ -137,8 +143,15 @@ |
1003 | elif found_space: |
1004 | # accumulate the space usage data if on multiple lines |
1005 | (dir_ratio,dir_total,dir) = line.split() |
1006 | - space_ratio += float(dir_ratio) |
1007 | - space_total += float(dir_total) |
1008 | + if dir.startswith(':control'): |
1009 | + control_space = float(dir_total) |
1010 | + elif dir.startswith(':working'): |
1011 | + working_space = float(dir_total) |
1012 | + else: |
1013 | + space_ratio += float(dir_ratio) |
1014 | + space_total += float(dir_total) |
1015 | + if space_original == 0: |
1016 | + space_original = space_total / space_ratio |
1017 | elif found_times: |
1018 | (seconds,action) = line.split() |
1019 | if not verbose: |
1020 | @@ -173,18 +186,24 @@ |
1021 | stats.slow_counts[project][run] = slow_count |
1022 | stats.vslow_counts[project][run] = vslow_count |
1023 | stats.vvslow_counts[project][run] = vvslow_count |
1024 | + stats.space_originals[project][run] = space_original |
1025 | stats.space_totals[project][run] = space_total |
1026 | stats.space_ratios[project][run] = space_ratio |
1027 | stats.file_counts[project][run] = file_count |
1028 | + stats.control_spaces[project][run] = control_space |
1029 | + stats.working_spaces[project][run] = working_space |
1030 | else: |
1031 | project_runs[project] = {run: total} |
1032 | stats.fast_counts[project] = {run: fast_count} |
1033 | stats.slow_counts[project] = {run: slow_count} |
1034 | stats.vslow_counts[project] = {run: vslow_count} |
1035 | stats.vvslow_counts[project] = {run: vvslow_count} |
1036 | + stats.space_originals[project] = {run: space_original} |
1037 | stats.space_totals[project] = {run: space_total} |
1038 | stats.space_ratios[project] = {run: space_ratio} |
1039 | stats.file_counts[project] = {run: file_count} |
1040 | + stats.control_spaces[project] = {run: control_space} |
1041 | + stats.working_spaces[project] = {run: working_space} |
1042 | |
1043 | return all_actions, times, project_runs, stats |
1044 | |
1045 | @@ -228,6 +247,10 @@ |
1046 | # Prepare statistics |
1047 | files_data = [str(stats.file_counts[p][best_run[p]]) for p in projects] |
1048 | files_label = "File count:" |
1049 | + working_data = [str(stats.working_spaces[p][best_run[p]]) for p in projects] |
1050 | + working_label = "Working space in MB:" |
1051 | + control_data = [str(stats.control_spaces[p][best_run[p]]) for p in projects] |
1052 | + control_label = "Control space in MB:" |
1053 | fast_data = [str(stats.fast_counts[p][best_run[p]]) for p in projects] |
1054 | fast_label = "Actions <= %d seconds:" % SLOW_THRESHHOLD |
1055 | slow_data = [str(stats.slow_counts[p][best_run[p]]) for p in projects] |
1056 | @@ -237,19 +260,24 @@ |
1057 | vvslow_data = [str(stats.vvslow_counts[p][best_run[p]]) for p in projects] |
1058 | vvslow_label = "Actions > %d seconds:" % VVSLOW_THRESHHOLD |
1059 | sp_ratio_data = [str(stats.space_ratios[p][best_run[p]]) for p in projects] |
1060 | - sp_ratio_label = "Used space vs original:" |
1061 | + sp_ratio_label = "Final space vs original:" |
1062 | + sp_original_data = [str(stats.space_originals[p][best_run[p]]) for p in projects] |
1063 | + sp_original_label = "Original space in MB:" |
1064 | sp_total_data = [str(stats.space_totals[p][best_run[p]]) for p in projects] |
1065 | - sp_total_label = "Total space in MB:" |
1066 | + sp_total_label = "Final space in MB:" |
1067 | |
1068 | # Dump the data |
1069 | print "Action," + ",".join(projects) |
1070 | print "%s,%s" % (files_label, ",".join(files_data)) |
1071 | + print "%s,%s" % (working_label, ",".join(working_data)) |
1072 | + print "%s,%s" % (control_label, ",".join(control_data)) |
1073 | + print "%s,%s" % (sp_original_label, ",".join(sp_original_data)) |
1074 | + print "%s,%s" % (sp_total_label, ",".join(sp_total_data)) |
1075 | + print "%s,%s" % (sp_ratio_label, ",".join(sp_ratio_data)) |
1076 | print "%s,%s" % (fast_label, ",".join(fast_data)) |
1077 | print "%s,%s" % (slow_label, ",".join(slow_data)) |
1078 | print "%s,%s" % (vslow_label, ",".join(vslow_data)) |
1079 | print "%s,%s" % (vvslow_label, ",".join(vvslow_data)) |
1080 | - print "%s,%s" % (sp_ratio_label, ",".join(sp_ratio_data)) |
1081 | - print "%s,%s" % (sp_total_label, ",".join(sp_total_data)) |
1082 | for action in actions: |
1083 | data = [str(times.get((p,best_run[p],action), "")) for p in projects] |
1084 | print "%s,%s" % (action, ",".join(data)) |
1085 | |
1086 | === modified file 'suiterunner.py' |
1087 | --- suiterunner.py 2009-04-02 07:21:04 +0000 |
1088 | +++ suiterunner.py 2011-02-16 06:18:13 +0000 |
1089 | @@ -18,13 +18,13 @@ |
1090 | |
1091 | import os |
1092 | import random |
1093 | -import shutil |
1094 | import string |
1095 | import subprocess |
1096 | import sys |
1097 | import time |
1098 | |
1099 | -from bzrlib.trace import info, warning, error |
1100 | +from bzrlib import osutils |
1101 | +from bzrlib.trace import info, log_exception_quietly |
1102 | import archiveutil |
1103 | import datadump |
1104 | import dirutil |
1105 | @@ -36,7 +36,8 @@ |
1106 | |
1107 | def get_suite_names(): |
1108 | # TODO: use reflection to look these up (walk sys.path) |
1109 | - return ['common', 'local', 'network', 'history', 'log', 'logplus', 'mega'] |
1110 | + return ['common', 'local', 'network', 'history', 'log', 'logplus', 'mega', |
1111 | + 'commit'] |
1112 | |
1113 | |
1114 | def get_suite_by_name(name): |
1115 | @@ -58,7 +59,7 @@ |
1116 | try: |
1117 | module = __import__(module_name, globals(), locals()) |
1118 | except ImportError, e: |
1119 | - # TODO: log exception properly |
1120 | + log_exception_quietly() |
1121 | info("failed to find module %s\nerror: %s" % (module_name, e)) |
1122 | return None |
1123 | else: |
1124 | @@ -66,7 +67,7 @@ |
1125 | module = getattr(module, part) |
1126 | fn = getattr(module, 'script_suite', None) |
1127 | if fn is None: |
1128 | - # TODO: log exception properly |
1129 | + log_exception_quietly() |
1130 | info("failed to find script_suite() in %s" % module) |
1131 | return None |
1132 | return fn() |
1133 | @@ -99,9 +100,57 @@ |
1134 | os.mkdir(dest) |
1135 | else: |
1136 | archiveutil.unpack_archive(tree, dest_dirs, verbose, unpack_stats) |
1137 | + sample_tool, sample_dir = dirs_by_tool.items()[0] |
1138 | + control_dir = _control_dir_for(sample_tool) |
1139 | + unpack_stats.update(_collect_archive_stats(sample_dir, control_dir)) |
1140 | return (work_root,already_there,dirs_by_tool,run_id, unpack_stats) |
1141 | |
1142 | |
1143 | +def _control_dir_for(tool): |
1144 | + real_tool, version_id = usertool.get_tool_by_fuzzy_name(tool) |
1145 | + if real_tool is not None: |
1146 | + return "." + real_tool.name |
1147 | + else: |
1148 | + raise AssertionError("unknown control directory for tool %s" % tool) |
1149 | + |
1150 | + |
1151 | +def _collect_archive_stats(work_dir, control_dir): |
1152 | + """Collect statistics from an unpacked archive. |
1153 | + |
1154 | + :param work_dir: name of directory to analyze |
1155 | + :param control_dir: name of control directory, e.g. .bzr, .hg |
1156 | + :return: a dictionary with keys of: |
1157 | + * total_count - the # of files in the work directory |
1158 | + * control_count - the # of files in the control directory |
1159 | + * other_count - the # of files in the other directories |
1160 | + * total_size - the size in bytes of the work directory |
1161 | + * control_size - the size in bytes of the control directory |
1162 | + * other_size - the size in bytes of the other directories |
1163 | + """ |
1164 | + # TODO: It would be nice to work out the repo revision count |
1165 | + # as well, though the logic for that is obviously tool dependent. |
1166 | + result = {} |
1167 | + total_count = dirutil.dir_count(work_dir) |
1168 | + total_size = dirutil.dir_size(work_dir) |
1169 | + control_path = osutils.pathjoin(work_dir, control_dir) |
1170 | + if os.path.isdir(control_path): |
1171 | + control_count = dirutil.dir_count(control_path) |
1172 | + control_size = dirutil.dir_size(control_path) |
1173 | + else: |
1174 | + control_count = 0 |
1175 | + control_size = 0 |
1176 | + result = { |
1177 | + 'total_count': total_count, |
1178 | + 'control_count': control_count, |
1179 | + 'other_count': total_count - control_count, |
1180 | + 'total_size': total_size, |
1181 | + 'control_size': control_size, |
1182 | + 'other_size': total_size - control_size, |
1183 | + } |
1184 | + #info("archive stats are: %s" % (result,)) |
1185 | + return result |
1186 | + |
1187 | + |
1188 | def _run_task_on_dirs(task, dirs_by_tool, measures, initial_params=None, |
1189 | profiler=None, prof_out_template=None, dry_run=False, tools=None, |
1190 | dynamic_params=None, per_tree_params=None, verbose=False, strict=False): |
1191 | @@ -191,8 +240,9 @@ |
1192 | |
1193 | def run_suite(self, suite, trees, tools, measures, data_file, |
1194 | dry_run=False, keep_dirs=False, verbose=False, |
1195 | - profiler=None, prof_out_template=None, dynamic_params=None, |
1196 | - per_tree_params=None, strict=False, url=False): |
1197 | + profiler=None, prof_out_template=None, user_params=None, |
1198 | + per_tree_params=None, dynamic_user_params=None, strict=False, |
1199 | + url=False): |
1200 | if url: |
1201 | tree_label = "url" |
1202 | else: |
1203 | @@ -212,13 +262,13 @@ |
1204 | tree_label: tree, |
1205 | 'tree_id': usertestutil.tree_short_name(tree), |
1206 | } |
1207 | - all_dynamic_params = {} |
1208 | - if dynamic_params: |
1209 | - all_dynamic_params.update(dynamic_params) |
1210 | + if user_params: |
1211 | + initial_params.update(user_params) |
1212 | if per_tree_params: |
1213 | tree_params = per_tree_params.get(tree) |
1214 | if tree_params: |
1215 | - all_dynamic_params.update(tree_params) |
1216 | + initial_params.update(tree_params) |
1217 | + dynamic_params = dynamic_user_params.copy() |
1218 | |
1219 | # Baseline the size of a tree - use last tool to max. cache usage |
1220 | if not dry_run: |
1221 | @@ -238,14 +288,16 @@ |
1222 | if len(top_level_dirs) == 2 and '.bzr' in top_level_dirs: |
1223 | top_level_dirs.remove('.bzr') |
1224 | branch_dir = top_level_dirs[0] |
1225 | - info("found shared repo with branch %s" % branch_dir) |
1226 | - work_dir = os.path.join(work_dir, branch_dir) |
1227 | + if (os.path.isdir(branch_dir) |
1228 | + and '.bzr' in os.listdir(branch_dir)): |
1229 | + info("found shared repo with branch %s" % branch_dir) |
1230 | + work_dir = os.path.join(work_dir, branch_dir) |
1231 | dirs_by_tool[tool] = work_dir |
1232 | temp_dirs = set() |
1233 | temp_dirs.add(work_root) |
1234 | csv_data = self.run_tests(suite, dirs_by_tool, measures, |
1235 | initial_params, profiler, prof_out_template, dry_run, tools, |
1236 | - all_dynamic_params, verbose=verbose, strict=strict) |
1237 | + dynamic_params, verbose=verbose, strict=strict) |
1238 | os.chdir(original_dir) |
1239 | if not dry_run: |
1240 | datadump.dump_summary(data_file, sys.stdout, suite, tree, |
1241 | |
1242 | === modified file 'tests/test_archiveutil.py' |
1243 | --- tests/test_archiveutil.py 2009-03-18 17:24:05 +0000 |
1244 | +++ tests/test_archiveutil.py 2011-02-16 06:18:13 +0000 |
1245 | @@ -37,7 +37,7 @@ |
1246 | class TestEmptyArchive(TestArchive): |
1247 | |
1248 | def _make_tarfile(self): |
1249 | - self.tarname = "tmp%d.tar.gz" % (random.uniform(9000,9999)) |
1250 | + self.tarname = "empty.tar.gz" |
1251 | tar = tarfile.open(self.tarname, "w:gz") |
1252 | tar.close() |
1253 | |
1254 | @@ -49,36 +49,41 @@ |
1255 | class TestArchiveWithOneRoot(TestArchive): |
1256 | |
1257 | def _make_tarfile(self): |
1258 | - self.root_dir = "root%d" % (random.uniform(10,99)) |
1259 | + self.root_dir = "root" |
1260 | os.mkdir(self.root_dir) |
1261 | - self.addCleanup(shutil.rmtree, self.root_dir) |
1262 | - self.tarname = "tmp%d.tar.gz" % (random.uniform(9000,9999)) |
1263 | + self.tarname = "abc-in-root.tar.gz" |
1264 | + for item in ['a', 'b', 'c']: |
1265 | + filename = os.path.join(self.root_dir, item) |
1266 | + f = open(filename, "w") |
1267 | + try: |
1268 | + f.write("%s rocks\n" % item) |
1269 | + finally: |
1270 | + f.close() |
1271 | tar = tarfile.open(self.tarname, "w:gz") |
1272 | try: |
1273 | - for item in ['a', 'b', 'c']: |
1274 | - filename = os.path.join(self.root_dir,item) |
1275 | - f = open(filename, "w") |
1276 | - try: |
1277 | - f.write("%s rocks\n" % item) |
1278 | - finally: |
1279 | - f.close() |
1280 | - tar.add(filename) |
1281 | + tar.add(self.root_dir) |
1282 | finally: |
1283 | tar.close() |
1284 | |
1285 | + def assertPathExists(self, path): |
1286 | + self.assertTrue(os.path.exists(path), "%r does not exist" % (path,)) |
1287 | + |
1288 | + def assertPathExistsInRoot(self, path): |
1289 | + self.assertTrue(os.path.exists(os.path.join(self.root_dir,path)), |
1290 | + "%r does not exist in root_dir %r" % (path, self.root_dir)) |
1291 | + |
1292 | def test_dir_there(self): |
1293 | work_roots = archiveutil.unpack_archive(self.tarname) |
1294 | self.assertEqual([], work_roots) |
1295 | for item in ['a', 'b', 'c']: |
1296 | - self.assertTrue(os.path.exists(os.path.join(self.root_dir,item))) |
1297 | + self.assertPathExistsInRoot(item) |
1298 | |
1299 | def test_dir_not_there(self): |
1300 | shutil.rmtree(self.root_dir) |
1301 | work_roots = archiveutil.unpack_archive(self.tarname) |
1302 | self.assertEqual([self.root_dir], work_roots) |
1303 | for item in ['a', 'b', 'c']: |
1304 | - self.assertTrue(os.path.exists(os.path.join(self.root_dir,item))) |
1305 | - |
1306 | + self.assertPathExistsInRoot(item) |
1307 | |
1308 | def test_multiple_destinations(self): |
1309 | shutil.rmtree(self.root_dir) |
1310 | @@ -87,7 +92,7 @@ |
1311 | self.assertEqual(dests, work_roots) |
1312 | for dest in dests: |
1313 | for item in ['a', 'b', 'c']: |
1314 | - self.assertTrue(os.path.exists(os.path.join(dest,item))) |
1315 | + self.assertPathExists(os.path.join(dest, item)) |
1316 | |
1317 | |
1318 | class TestArchiveWithNoSharedRoot(TestArchive): |
1319 | |
1320 | === modified file 'userscript.py' |
1321 | --- userscript.py 2009-04-02 13:42:24 +0000 |
1322 | +++ userscript.py 2011-02-16 06:18:13 +0000 |
1323 | @@ -23,7 +23,7 @@ |
1324 | import unittest |
1325 | |
1326 | from bzrlib.errors import BzrError |
1327 | -from bzrlib.trace import info |
1328 | +from bzrlib.trace import info, note |
1329 | from bzrlib.tests import TestUtil |
1330 | |
1331 | import usermeasure |
1332 | @@ -73,8 +73,37 @@ |
1333 | self.default_script = None |
1334 | self.scripts_by_tool = {} |
1335 | self.title = None |
1336 | + # Indexed by (tool, version) or tool or 'default', then label |
1337 | self.exit_codes = {} |
1338 | |
1339 | + def _set_exit_codes(self, tool, codes_by_label, version=None): |
1340 | + """Set the map of expected exit codes for a tool and version.""" |
1341 | + if codes_by_label is None: |
1342 | + return |
1343 | + #note("saving exit-codes %s for tool=%s, version=%s" |
1344 | + # % (codes_by_label, tool, version)) |
1345 | + if version is None: |
1346 | + key = tool |
1347 | + else: |
1348 | + key = (tool, version) |
1349 | + if key not in self.exit_codes: |
1350 | + self.exit_codes[key] = codes_by_label |
1351 | + else: |
1352 | + self.exit_codes[key].update(codes_by_label) |
1353 | + |
1354 | + def _expected_exit_code(self, tool, label, version=None): |
1355 | + """Get the expected exit code for a 'command'.""" |
1356 | + # When looking up exit codes, if it's not found for a |
1357 | + # tool+version combination, fall back to the one defined for the tool |
1358 | + tv_key = (tool, version) |
1359 | + if tv_key in self.exit_codes: |
1360 | + return self.exit_codes[tv_key].get(label, 0) |
1361 | + elif tool in self.exit_codes: |
1362 | + return self.exit_codes[tool].get(label, 0) |
1363 | + elif 'default' in self.exit_codes: |
1364 | + return self.exit_codes['default'].get(label, 0) |
1365 | + return 0 |
1366 | + |
1367 | def _compile_template(self, template): |
1368 | if template is None: |
1369 | return None |
1370 | @@ -92,15 +121,13 @@ |
1371 | def compile_default(self, template, exit_codes=None): |
1372 | "Compile the default script to be used." |
1373 | self.default_script = self._compile_template(template) |
1374 | - if exit_codes: |
1375 | - self.exit_codes.update(exit_codes) |
1376 | + self._set_exit_codes('default', exit_codes) |
1377 | |
1378 | def compile_for_tools(self, tools_mask, template, exit_codes=None): |
1379 | "Compile the script to be used for just the tools named." |
1380 | for tool in tools_mask: |
1381 | self.compile_for_versions(tool, None, template) |
1382 | - if exit_codes: |
1383 | - self.exit_codes.update(exit_codes) |
1384 | + self._set_exit_codes(tool, exit_codes) |
1385 | |
1386 | def compile_for_versions(self, tool, version_pattern, template, |
1387 | exit_codes=None): |
1388 | @@ -109,8 +136,7 @@ |
1389 | templates_by_version = self.scripts_by_tool.get(tool, {}) |
1390 | templates_by_version[version_pattern] = compiled_template |
1391 | self.scripts_by_tool[tool] = templates_by_version |
1392 | - if exit_codes: |
1393 | - self.exit_codes.update(exit_codes) |
1394 | + self._set_exit_codes(tool, exit_codes, version_pattern) |
1395 | |
1396 | def _get_raw_script_for(self, tool, params, version=None, |
1397 | missing_params_ok=False): |
1398 | @@ -250,7 +276,7 @@ |
1399 | return actions |
1400 | |
1401 | def get_commands_by_label(self, tool, params={}): |
1402 | - """Get the mapping fron labels to commands.""" |
1403 | + """Get the mapping from labels to commands.""" |
1404 | script, exceptions = self._get_raw_script_for(tool, params, |
1405 | missing_params_ok=True) |
1406 | if script is None: |
1407 | @@ -314,10 +340,13 @@ |
1408 | (sout,serr) = process.communicate() |
1409 | exit_code = process.returncode |
1410 | if strict: |
1411 | - if self.exit_codes: |
1412 | - expected_exit_code = self.exit_codes.get(label, 0) |
1413 | - else: |
1414 | - expected_exit_code = 0 |
1415 | + real_tool,version_id = usertool.get_tool_by_fuzzy_name(tool) |
1416 | + if real_tool is not None: |
1417 | + real_tool = real_tool.name |
1418 | + expected_exit_code = self._expected_exit_code(real_tool, |
1419 | + label, version=version_id) |
1420 | + #note("expected-exit-code is %s for tool=%s, label=%s, version=%s" |
1421 | + # % (expected_exit_code, real_tool, label, version_id)) |
1422 | if (isinstance(expected_exit_code, int) |
1423 | and expected_exit_code != exit_code or |
1424 | isinstance(expected_exit_code, list) |
This adds the most interesting cases from http:// bazaar- vcs.org/ SmartPushAnalys is1.4 to script_network.py.