Merge lp:~stub/charms/precise/postgresql/pgtune into lp:charms/postgresql
- Precise Pangolin (12.04)
- pgtune
- Merge into trunk
Proposed by
Stuart Bishop
Status: | Merged |
---|---|
Merged at revision: | 93 |
Proposed branch: | lp:~stub/charms/precise/postgresql/pgtune |
Merge into: | lp:charms/postgresql |
Prerequisite: | lp:~stub/charms/precise/postgresql/tests |
Diff against target: |
523 lines (+189/-138) 7 files modified
Makefile (+10/-0) config.yaml (+21/-12) hooks/hooks.py (+41/-18) hooks/test_hooks.py (+73/-83) test.py (+4/-0) testing/jujufixture.py (+38/-24) tests/00_setup.test (+2/-1) |
To merge this branch: | bzr merge lp:~stub/charms/precise/postgresql/pgtune |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marco Ceppi (community) | Approve | ||
Review via email: mp+213640@code.launchpad.net |
Commit message
Description of the change
Tune the database using the pgtune tool, rather than attempt to reproduce its logic ourselves.
To post a comment you must log in.
Revision history for this message
Stuart Bishop (stub) wrote : | # |
- 132. By Stuart Bishop
-
delint
- 133. By Stuart Bishop
-
Merged tests into pgtune.
- 134. By Stuart Bishop
-
Remove dead code, fix another test wait race
- 135. By Stuart Bishop
-
Fix tests and config documentation
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Makefile' |
2 | --- Makefile 2014-01-27 12:59:00 +0000 |
3 | +++ Makefile 2014-04-04 12:07:49 +0000 |
4 | @@ -1,6 +1,16 @@ |
5 | CHARM_DIR := $(shell pwd) |
6 | TEST_TIMEOUT := 900 |
7 | |
8 | +default: |
9 | + @echo "One of:" |
10 | + @echo " make lint" |
11 | + @echo " make test" |
12 | + @echo " make unit_test" |
13 | + @echo " make integration_test" |
14 | + @echo " make integration_test_91" |
15 | + @echo " make integration_test_92" |
16 | + @echo " make integration_test_93" |
17 | + |
18 | test: lint unit_test integration_test |
19 | |
20 | unit_test: |
21 | |
22 | === modified file 'config.yaml' |
23 | --- config.yaml 2014-04-04 12:07:49 +0000 |
24 | +++ config.yaml 2014-04-04 12:07:49 +0000 |
25 | @@ -225,21 +225,25 @@ |
26 | work_mem: |
27 | default: "1MB" |
28 | type: string |
29 | - description: Working Memory |
30 | + description: | |
31 | + Working Memory. |
32 | + Ignored unless 'performance_tuning' is set to 'manual'. |
33 | maintenance_work_mem: |
34 | default: "1MB" |
35 | type: string |
36 | - description: Maintenance working memory |
37 | + description: | |
38 | + Maintenance working memory. |
39 | + Ignored unless 'performance_tuning' is set to 'manual'. |
40 | performance_tuning: |
41 | - default: "auto" |
42 | + default: "Mixed" |
43 | type: string |
44 | description: | |
45 | - Possible values here are "auto" or "manual". If we set "auto" then the |
46 | - charm will attempt to automatically tune all the performance parameters |
47 | - for kernel_shmall, kernel_shmmax, shared_buffers and |
48 | - effective_cache_size below, unless those config values are explicitly |
49 | - set. If manual, then it will use the defaults below unless set. |
50 | - "auto" gathers information about the node on which you are deployed and |
51 | + Possible values here are "manual", "DW" (data warehouse), |
52 | + "OLTP" (online transaction processing), "Web" (web application), |
53 | + "Desktop" or "Mixed". When this is set to a value other than |
54 | + "manual", the charm invokes the pgtune tool to tune a number |
55 | + of performance parameters based on the specified load type. |
56 | + pgtune gathers information about the node on which you are deployed and |
57 | tries to make intelligent guesses about what tuning parameters to set |
58 | based on available RAM and CPU under the assumption that it's the only |
59 | significant service running on this node. |
60 | @@ -257,13 +261,15 @@ |
61 | description: | |
62 | The amount of memory the database server uses for shared memory |
63 | buffers. This string should be of the format '###MB'. |
64 | + Ignored unless 'performance_tuning' is set to 'manual'. |
65 | effective_cache_size: |
66 | default: "" |
67 | type: string |
68 | description: | |
69 | Effective cache size is an estimate of how much memory is available for |
70 | disk caching within the database. (50% to 75% of system memory). This |
71 | - string should be of the format '###MB'. |
72 | + string should be of the format '###MB'. Ignored unless |
73 | + 'performance_tuning' is set to 'manual'. |
74 | temp_buffers: |
75 | default: "1MB" |
76 | type: string |
77 | @@ -273,11 +279,14 @@ |
78 | default: "-1" |
79 | type: string |
80 | description: | |
81 | - min 32kB, -1 sets based on shared_buffers (change requires restart) |
82 | + min 32kB, -1 sets based on shared_buffers (change requires restart). |
83 | + Ignored unless 'performance_tuning' is set to 'manual'. |
84 | checkpoint_segments: |
85 | default: 3 |
86 | type: int |
87 | - description: in logfile segments, min 1, 16MB each |
88 | + description: | |
89 | + in logfile segments, min 1, 16MB each. |
90 | + Ignored unless 'performance_tuning' is set to 'manual'. |
91 | random_page_cost: |
92 | default: 4.0 |
93 | type: float |
94 | |
95 | === modified file 'hooks/hooks.py' |
96 | --- hooks/hooks.py 2014-04-04 12:07:49 +0000 |
97 | +++ hooks/hooks.py 2014-04-04 12:07:49 +0000 |
98 | @@ -437,27 +437,18 @@ |
99 | return int(run("getconf PAGE_SIZE")) # frequently 4096 |
100 | |
101 | |
102 | +def _run_sysctl(postgresql_sysctl): |
103 | + """sysctl -p postgresql_sysctl, helper for easy test mocking.""" |
104 | + return run("sysctl -p {}".format(postgresql_sysctl)) |
105 | + |
106 | + |
107 | def create_postgresql_config(config_file): |
108 | '''Create the postgresql.conf file''' |
109 | config_data = hookenv.config() |
110 | if not config_data.get('listen_port', None): |
111 | config_data['listen_port'] = get_service_port() |
112 | - if config_data["performance_tuning"] == "auto": |
113 | - # Taken from: |
114 | - # http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server |
115 | - # num_cpus is not being used ... commenting it out ... negronjl |
116 | - #num_cpus = run("cat /proc/cpuinfo | grep processor | wc -l") |
117 | + if config_data["performance_tuning"].lower() != "manual": |
118 | total_ram = _get_system_ram() |
119 | - if not config_data["effective_cache_size"]: |
120 | - config_data["effective_cache_size"] = \ |
121 | - "%sMB" % (int(int(total_ram) * 0.75),) |
122 | - if not config_data["shared_buffers"]: |
123 | - if total_ram > 1023: |
124 | - config_data["shared_buffers"] = \ |
125 | - "%sMB" % (int(int(total_ram) * 0.25),) |
126 | - else: |
127 | - config_data["shared_buffers"] = \ |
128 | - "%sMB" % (int(int(total_ram) * 0.15),) |
129 | config_data["kernel_shmmax"] = (int(total_ram) * 1024 * 1024) + 1024 |
130 | config_data["kernel_shmall"] = config_data["kernel_shmmax"] |
131 | |
132 | @@ -473,7 +464,7 @@ |
133 | if config_data["kernel_shmmax"] > 0: |
134 | lines.append("kernel.shmmax = %s\n" % config_data["kernel_shmmax"]) |
135 | host.write_file(postgresql_sysctl, ''.join(lines), perms=0600) |
136 | - run("sysctl -p {}".format(postgresql_sysctl)) |
137 | + _run_sysctl(postgresql_sysctl) |
138 | |
139 | # If we are replicating, some settings may need to be overridden to |
140 | # certain minimum levels. |
141 | @@ -504,10 +495,29 @@ |
142 | # Create or update files included from postgresql.conf. |
143 | configure_log_destination(os.path.dirname(config_file)) |
144 | |
145 | + tune_postgresql_config(config_file) |
146 | + |
147 | local_state['saved_config'] = config_data |
148 | local_state.save() |
149 | |
150 | |
151 | +def tune_postgresql_config(config_file): |
152 | + tune_workload = hookenv.config('performance_tuning').lower() |
153 | + if tune_workload == "manual": |
154 | + return # Requested no autotuning. |
155 | + |
156 | + if tune_workload == "auto": |
157 | + tune_workload = "mixed" # Pre-pgtune backwards compatibility. |
158 | + |
159 | + with NamedTemporaryFile() as tmp_config: |
160 | + run(['pgtune', '-i', config_file, '-o', tmp_config.name, |
161 | + '-T', tune_workload, |
162 | + '-c', str(hookenv.config('max_connections'))]) |
163 | + host.write_file( |
164 | + config_file, open(tmp_config.name, 'r').read(), |
165 | + owner='postgres', group='postgres', perms=0o600) |
166 | + |
167 | + |
168 | def create_postgresql_ident(output_file): |
169 | '''Create the pg_ident.conf file.''' |
170 | ident_data = {} |
171 | @@ -834,6 +844,17 @@ |
172 | log("listen_ip values other than '*' do not work per LP:1271837", |
173 | CRITICAL) |
174 | |
175 | + valid_workloads = [ |
176 | + 'dw', 'oltp', 'web', 'mixed', 'desktop', 'manual', 'auto'] |
177 | + requested_workload = config_data['performance_tuning'].lower() |
178 | + if requested_workload not in valid_workloads: |
179 | + valid = False |
180 | + log('Invalid performance_tuning setting {}'.format(requested_workload), |
181 | + CRITICAL) |
182 | + if requested_workload == 'auto': |
183 | + log("'auto' performance_tuning deprecated. Using 'mixed' tuning", |
184 | + WARNING) |
185 | + |
186 | unchangeable_config = [ |
187 | 'locale', 'encoding', 'version', 'cluster_name', 'pgdg'] |
188 | |
189 | @@ -1554,11 +1575,13 @@ |
190 | "postgresql-{}".format(version), |
191 | "postgresql-contrib-{}".format(version), |
192 | "postgresql-plpython-{}".format(version), |
193 | - "python-jinja2", "syslinux", "python-psycopg2"] |
194 | + "python-jinja2", "python-psycopg2"] |
195 | # PGDG currently doesn't have debversion for 9.3. Put this back when |
196 | # it does. |
197 | if not (hookenv.config('pgdg') and version == '9.3'): |
198 | - "postgresql-{}-debversion".format(version) |
199 | + packages.append("postgresql-{}-debversion".format(version)) |
200 | + if hookenv.config('performance_tuning').lower() != 'manual': |
201 | + packages.append('pgtune') |
202 | packages.extend((hookenv.config('extra-packages') or '').split()) |
203 | packages = fetch.filter_installed_packages(packages) |
204 | fetch.apt_install(packages, fatal=True) |
205 | |
206 | === modified file 'hooks/test_hooks.py' |
207 | --- hooks/test_hooks.py 2014-01-08 08:55:50 +0000 |
208 | +++ hooks/test_hooks.py 2014-04-04 12:07:49 +0000 |
209 | @@ -159,11 +159,11 @@ |
210 | def log(self, *args, **kwargs): |
211 | pass |
212 | |
213 | - def config_get(self, scope=None): |
214 | + def config(self, scope=None): |
215 | if scope is None: |
216 | - return self.config |
217 | + return dict(self._config) |
218 | else: |
219 | - return self.config[scope] |
220 | + return self._config[scope] |
221 | |
222 | def relation_get(self, scope=None, unit_name=None, relation_id=None): |
223 | pass |
224 | @@ -175,14 +175,13 @@ |
225 | hooks.hookenv = TestJuju() |
226 | hooks.host = TestJujuHost() |
227 | hooks.juju_log_dir = self.makeDir() |
228 | - hooks.hookenv.config = lambda: hooks.hookenv._config |
229 | - #hooks.hookenv.localunit = lambda: "localhost" |
230 | hooks.os.environ["JUJU_UNIT_NAME"] = "landscape/1" |
231 | hooks.os.environ["CHARM_DIR"] = os.path.abspath( |
232 | os.path.join(os.path.dirname(__file__), os.pardir)) |
233 | hooks.postgresql_sysctl = self.makeFile() |
234 | hooks._get_system_ram = lambda: 1024 # MB |
235 | hooks._get_page_size = lambda: 1024 * 1024 # bytes |
236 | + hooks._run_sysctl = lambda x: "" |
237 | self.maxDiff = None |
238 | |
239 | def assertFileContains(self, filename, lines): |
240 | @@ -216,8 +215,8 @@ |
241 | C{replication} relations, default wal settings will be present. |
242 | """ |
243 | config_outfile = self.makeFile() |
244 | - run = self.mocker.replace(hooks.run) |
245 | - run("sysctl -p %s" % hooks.postgresql_sysctl) |
246 | + _run_sysctl = self.mocker.replace(hooks._run_sysctl) |
247 | + _run_sysctl(hooks.postgresql_sysctl) |
248 | self.mocker.result(True) |
249 | self.mocker.replay() |
250 | hooks.create_postgresql_config(config_outfile) |
251 | @@ -240,8 +239,8 @@ |
252 | hooks.hookenv._relation_ids = { |
253 | "replication/0": "db-admin:5", "replication/1": "db-admin:6"} |
254 | config_outfile = self.makeFile() |
255 | - run = self.mocker.replace(hooks.run) |
256 | - run("sysctl -p %s" % hooks.postgresql_sysctl) |
257 | + _run_sysctl = self.mocker.replace(hooks._run_sysctl) |
258 | + _run_sysctl(hooks.postgresql_sysctl) |
259 | self.mocker.result(True) |
260 | self.mocker.replay() |
261 | hooks.create_postgresql_config(config_outfile) |
262 | @@ -269,8 +268,8 @@ |
263 | hooks.hookenv._config["wal_keep_segments"] = 1000 |
264 | hooks.hookenv._config["replicated_wal_keep_segments"] = 999 |
265 | config_outfile = self.makeFile() |
266 | - run = self.mocker.replace(hooks.run) |
267 | - run("sysctl -p %s" % hooks.postgresql_sysctl) |
268 | + _run_sysctl = self.mocker.replace(hooks._run_sysctl) |
269 | + _run_sysctl(hooks.postgresql_sysctl) |
270 | self.mocker.result(True) |
271 | self.mocker.replay() |
272 | hooks.create_postgresql_config(config_outfile) |
273 | @@ -279,79 +278,70 @@ |
274 | ["hot_standby = True", "wal_level = hot_standby", |
275 | "max_wal_senders = 3", "wal_keep_segments = 1000"]) |
276 | |
277 | - def test_create_postgresql_config_performance_tune_auto_large_ram(self): |
278 | - """ |
279 | - When configuration attribute C{performance_tune} is set to C{auto} and |
280 | - total RAM on a system is > 1023MB. It will automatically calculate |
281 | - values for the following attributes if these attributes were left as |
282 | - default values: |
283 | - - C{effective_cache_size} set to 75% of total RAM in MegaBytes |
284 | - - C{shared_buffers} set to 25% of total RAM in MegaBytes |
285 | - - C{kernel_shmmax} set to total RAM in bytes |
286 | - - C{kernel_shmall} equal to kernel_shmmax in pages |
287 | - """ |
288 | - config_outfile = self.makeFile() |
289 | - run = self.mocker.replace(hooks.run) |
290 | - run("sysctl -p %s" % hooks.postgresql_sysctl) |
291 | - self.mocker.result(True) |
292 | - self.mocker.replay() |
293 | - hooks.create_postgresql_config(config_outfile) |
294 | - self.assertFileContains( |
295 | - config_outfile, |
296 | - ["shared_buffers = 256MB", "effective_cache_size = 768MB"]) |
297 | + def test_auto_tuned_postgresql_config(self): |
298 | + """ |
299 | + When automatic performance tuning is specified, pgtune will |
300 | + modify postgresql.conf. Automatic performance tuning is the default. |
301 | + """ |
302 | + config_outfile = self.makeFile() |
303 | + _run_sysctl = self.mocker.replace(hooks._run_sysctl) |
304 | + _run_sysctl(hooks.postgresql_sysctl) |
305 | + self.mocker.result(True) |
306 | + self.mocker.replay() |
307 | + |
308 | + hooks.create_postgresql_config(config_outfile) |
309 | + |
310 | + raw_config = open(config_outfile, 'r').read() |
311 | + self.assert_('# pgtune wizard' in raw_config) |
312 | + |
313 | + def test_auto_tuned_kernel_settings(self): |
314 | + """ |
315 | + Kernel settings are automatically set to max RAM values |
316 | + """ |
317 | + config_outfile = self.makeFile() |
318 | + _run_sysctl = self.mocker.replace(hooks._run_sysctl) |
319 | + _run_sysctl(hooks.postgresql_sysctl) |
320 | + self.mocker.result(True) |
321 | + self.mocker.replay() |
322 | + |
323 | + hooks.create_postgresql_config(config_outfile) |
324 | + |
325 | self.assertFileContains( |
326 | hooks.postgresql_sysctl, |
327 | ["kernel.shmall = 1025\nkernel.shmmax = 1073742848"]) |
328 | |
329 | - def test_create_postgresql_config_performance_tune_auto_small_ram(self): |
330 | - """ |
331 | - When configuration attribute C{performance_tune} is set to C{auto} and |
332 | - total RAM on a system is <= 1023MB. It will automatically calculate |
333 | - values for the following attributes if these attributes were left as |
334 | - default values: |
335 | - - C{effective_cache_size} set to 75% of total RAM in MegaBytes |
336 | - - C{shared_buffers} set to 15% of total RAM in MegaBytes |
337 | - - C{kernel_shmmax} set to total RAM in bytes |
338 | - - C{kernel_shmall} equal to kernel_shmmax in pages |
339 | - """ |
340 | - hooks._get_system_ram = lambda: 1023 # MB |
341 | - config_outfile = self.makeFile() |
342 | - run = self.mocker.replace(hooks.run) |
343 | - run("sysctl -p %s" % hooks.postgresql_sysctl) |
344 | - self.mocker.result(True) |
345 | - self.mocker.replay() |
346 | - hooks.create_postgresql_config(config_outfile) |
347 | - self.assertFileContains( |
348 | - config_outfile, |
349 | - ["shared_buffers = 153MB", "effective_cache_size = 767MB"]) |
350 | - self.assertFileContains( |
351 | - hooks.postgresql_sysctl, |
352 | - ["kernel.shmall = 1024\nkernel.shmmax = 1072694272"]) |
353 | - |
354 | - def test_create_postgresql_config_performance_tune_auto_overridden(self): |
355 | - """ |
356 | - When configuration attribute C{performance_tune} is set to C{auto} any |
357 | - non-default values for the configuration parameters below will be used |
358 | - instead of the automatically calculated values. |
359 | - - C{effective_cache_size} |
360 | - - C{shared_buffers} |
361 | - - C{kernel_shmmax} |
362 | - - C{kernel_shmall} |
363 | - """ |
364 | - hooks.hookenv._config["effective_cache_size"] = "999MB" |
365 | - hooks.hookenv._config["shared_buffers"] = "101MB" |
366 | - hooks.hookenv._config["kernel_shmmax"] = 50000 |
367 | - hooks.hookenv._config["kernel_shmall"] = 500 |
368 | - hooks._get_system_ram = lambda: 1023 # MB |
369 | - config_outfile = self.makeFile() |
370 | - run = self.mocker.replace(hooks.run) |
371 | - run("sysctl -p %s" % hooks.postgresql_sysctl) |
372 | - self.mocker.result(True) |
373 | - self.mocker.replay() |
374 | - hooks.create_postgresql_config(config_outfile) |
375 | - self.assertFileContains( |
376 | - config_outfile, |
377 | - ["shared_buffers = 101MB", "effective_cache_size = 999MB"]) |
378 | - self.assertFileContains( |
379 | - hooks.postgresql_sysctl, |
380 | - ["kernel.shmall = 1024\nkernel.shmmax = 1072694272"]) |
381 | + def test_auto_tuning_preserves_max_connections(self): |
382 | + """ |
383 | + pgtune with choose max_connections unless you tell it not too |
384 | + """ |
385 | + # Note that the charm does not yet make use of automatic |
386 | + # max_connections. We may want to change the default |
387 | + # max_connections to null and autotune then. |
388 | + hooks.hookenv._config["max_connections"] = 42 |
389 | + config_outfile = self.makeFile() |
390 | + _run_sysctl = self.mocker.replace(hooks._run_sysctl) |
391 | + _run_sysctl(hooks.postgresql_sysctl) |
392 | + self.mocker.result(True) |
393 | + self.mocker.replay() |
394 | + |
395 | + hooks.create_postgresql_config(config_outfile) |
396 | + |
397 | + raw_config = open(config_outfile, 'r').read() |
398 | + self.assert_('\nmax_connections = 42\n' in raw_config) |
399 | + |
400 | + def test_manually_tuned_postgresql_config(self): |
401 | + """ |
402 | + When automatic performance tuning is specified, pgtune will |
403 | + modify postgresql.conf. Automatic performance tuning is the default. |
404 | + """ |
405 | + hooks.hookenv._config["performance_tuning"] = "maNual" |
406 | + config_outfile = self.makeFile() |
407 | + _run_sysctl = self.mocker.replace(hooks._run_sysctl) |
408 | + _run_sysctl(hooks.postgresql_sysctl) |
409 | + self.mocker.result(True) |
410 | + self.mocker.replay() |
411 | + |
412 | + hooks.create_postgresql_config(config_outfile) |
413 | + |
414 | + raw_config = open(config_outfile, 'r').read() |
415 | + self.assert_('# pgtune wizard' not in raw_config) |
416 | |
417 | === modified file 'test.py' |
418 | --- test.py 2014-04-04 12:07:49 +0000 |
419 | +++ test.py 2014-04-04 12:07:49 +0000 |
420 | @@ -94,6 +94,10 @@ |
421 | 'database', None) |
422 | num_masters = 0 |
423 | for unit, unit_rel_info in rel_info.items(): |
424 | + if not unit_rel_info: |
425 | + raise NotReady( |
426 | + '{} {} is not setup'.format( |
427 | + unit, rel_id)) |
428 | if not unit.startswith('postgresql/'): |
429 | continue |
430 | if 'user' not in unit_rel_info: |
431 | |
432 | === modified file 'testing/jujufixture.py' |
433 | --- testing/jujufixture.py 2014-04-04 12:07:49 +0000 |
434 | +++ testing/jujufixture.py 2014-04-04 12:07:49 +0000 |
435 | @@ -139,11 +139,18 @@ |
436 | self, juju_run_cmd + [ |
437 | 'relation-list -r {}'.format(rel_id)]).split() |
438 | for rel_unit in relation_units: |
439 | - json_rel_info = run( |
440 | - self, juju_run_cmd + [ |
441 | - 'relation-get --format=json -r {} - {}'.format( |
442 | - rel_id, rel_unit)]) |
443 | - res[rel_name][rel_id][rel_unit] = json.loads(json_rel_info) |
444 | + try: |
445 | + json_rel_info = run( |
446 | + self, juju_run_cmd + [ |
447 | + 'relation-get --format=json -r {} - {}'.format( |
448 | + rel_id, rel_unit)]) |
449 | + res[rel_name][rel_id][rel_unit] = json.loads( |
450 | + json_rel_info) |
451 | + except subprocess.CalledProcessError as x: |
452 | + if x.returncode == 2: |
453 | + res[rel_name][rel_id][rel_unit] = None |
454 | + else: |
455 | + raise |
456 | return res |
457 | |
458 | def wait_until_ready(self, extra=60): |
459 | @@ -238,27 +245,34 @@ |
460 | |
461 | |
462 | def run(detail_collector, cmd, input=''): |
463 | + global _run_seq |
464 | + _run_seq = _run_seq + 1 |
465 | + |
466 | + # This helper primarily exists to capture the subprocess details, |
467 | + # but this is failing. Details are being captured, but those added |
468 | + # inside the actual test (not setup) are not being reported. |
469 | + |
470 | + out, err, returncode = None, None, None |
471 | try: |
472 | proc = subprocess.Popen( |
473 | cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, |
474 | stderr=subprocess.PIPE) |
475 | - except subprocess.CalledProcessError: |
476 | + (out, err) = proc.communicate(input) |
477 | + returncode = proc.returncode |
478 | + if returncode != 0: |
479 | + raise subprocess.CalledProcessError(returncode, cmd, err) |
480 | + return out |
481 | + except subprocess.CalledProcessError as x: |
482 | + returncode = x.returncode |
483 | raise |
484 | - |
485 | - (out, err) = proc.communicate(input) |
486 | - if detail_collector: |
487 | - global _run_seq |
488 | - _run_seq += 1 |
489 | - m = { |
490 | - 'cmd': ' '.join(cmd), |
491 | - 'rc': proc.returncode, |
492 | - 'stdout': out, |
493 | - 'stderr': err, |
494 | - } |
495 | - detail_collector.addDetail( |
496 | - 'run_{}'.format(_run_seq), |
497 | - text_content(yaml.safe_dump(m, default_flow_style=False))) |
498 | - if proc.returncode != 0: |
499 | - raise subprocess.CalledProcessError( |
500 | - proc.returncode, cmd, err) |
501 | - return out |
502 | + finally: |
503 | + if detail_collector is not None: |
504 | + m = { |
505 | + 'cmd': ' '.join(cmd), |
506 | + 'rc': returncode, |
507 | + 'stdout': out, |
508 | + 'stderr': err, |
509 | + } |
510 | + detail_collector.addDetail( |
511 | + 'run_{}'.format(_run_seq), |
512 | + text_content(yaml.safe_dump(m, default_flow_style=False))) |
513 | |
514 | === modified file 'tests/00_setup.test' |
515 | --- tests/00_setup.test 2014-02-07 07:33:23 +0000 |
516 | +++ tests/00_setup.test 2014-04-04 12:07:49 +0000 |
517 | @@ -8,5 +8,6 @@ |
518 | python-psycopg2 \ |
519 | python-testtools \ |
520 | python-twisted-core \ |
521 | - python-yaml |
522 | + python-yaml \ |
523 | + pgtune |
524 |
Note that although I change the default value in config.yaml to 'mixed', we still accept the old 'auto' value so existing environments will not need config changes.
syslinux package seems to be unused and unnecessary, so removing it resolves Bug #1297987.
A bug caused the postgresql- debversion package to not be installed. This has been fixed, which could have confused our redeployments.
The changes in jujufixture.py were me futzing around trying to get test detail reporting working. I'm giving up for now, at least on this branch.