Merge lp:~ltrager/maas/stress_ng_tests into lp:~maas-committers/maas/trunk
- stress_ng_tests
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Lee Trager |
Approved revision: | no longer in the source branch. |
Merged at revision: | 5878 |
Proposed branch: | lp:~ltrager/maas/stress_ng_tests |
Merge into: | lp:~maas-committers/maas/trunk |
Diff against target: |
617 lines (+217/-51) 20 files modified
src/maasserver/api/scripts.py (+4/-1) src/maasserver/api/tests/test_scripts.py (+14/-0) src/maasserver/forms/script.py (+5/-0) src/maasserver/forms/tests/test_script.py (+24/-0) src/metadataserver/builtin_scripts/__init__.py (+32/-10) src/metadataserver/builtin_scripts/internet_connectivity.sh (+5/-4) src/metadataserver/builtin_scripts/memtester.sh (+4/-3) src/metadataserver/builtin_scripts/ntp.sh (+4/-4) src/metadataserver/builtin_scripts/stress-ng-cpu-long.sh (+6/-6) src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh (+32/-0) src/metadataserver/builtin_scripts/stress-ng-memory-long.sh (+16/-6) src/metadataserver/builtin_scripts/stress-ng-memory-short.sh (+36/-0) src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py (+15/-3) src/metadataserver/user_data/templates/base_user_data.sh (+1/-1) src/metadataserver/user_data/templates/snippets/maas_enlist.sh (+1/-1) src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py (+6/-0) src/provisioningserver/refresh/node_info_scripts.py (+6/-6) src/provisioningserver/refresh/tests/test_node_info_scripts.py (+1/-1) src/provisioningserver/refresh/tests/test_refresh.py (+2/-2) src/provisioningserver/rpc/tests/test_clusterservice.py (+3/-3) |
To merge this branch: | bzr merge lp:~ltrager/maas/stress_ng_tests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mike Pontillo (community) | Approve | ||
Review via email:
|
Commit message
Add stress-ng short cpu and memory tests and fix stress_
Description of the change
Add stress-ng short cpu and memory tests. These tests run by default during commissioning and testing. This adds 10 minutes to commissioning time.
While testing I discovered the stress_ng_cpu_long fails due to using too much RAM. I've reworked it so while the OOM killer is tripped on a few stress-ng threads it still passes. I also fixed a bug where the script form was resetting any value that wasn't specified on update and new default scripts weren't being added in certain cases.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Gavin Panella (allenap) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Lee Trager (ltrager) wrote : | # |
Fully agree and implemented. I've been using /bin/sh because only because the existing commissioning script use it.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Gavin Panella (allenap) wrote : | # |
Sorry, I wasn't clear. Despite the similarities between sh and bash a change from one to the other may introduce bugs, and we're close to release. I wanted your feedback on whether you thought a policy like that would be okay with you. I guess that's a yes! You may want to revert r5860 and keep it for another day. And sorry again: rereading my comment makes it clear to me now that it was unclear when I wrote it.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Lee Trager (ltrager) wrote : | # |
I took a look how MAAS is using bash. Its used in simple commissioning and testing scripts, as part of unit tests, or in the user_data scripts. The commissioning and user_data scripts are tested pretty well by CI and bash is a superset of shell so it should be compatible even for more advanced scripts. I think its safe to switch, the riskiest would be the user_data scripts. If we really want to be cautious but move towards a bash world we could switch everywhere but the user data scripts for now.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mike Pontillo (mpontillo) wrote : | # |
The code looks good. I'll test it out a bit before I approve.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mike Pontillo (mpontillo) wrote : | # |
Oh, and please change 'sudo' to 'sudo -n' everywhere. I know the risk is small for scripts like these which run in the ephemeral environment, but I'd rather err on the safe side.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mike Pontillo (mpontillo) wrote : | # |
Saw this on a machine with 64 GB of RAM (4 cores, 8 with hyperthreading, if it matters).
Value 8262470656 is out of range for vm-bytes, allowed: 4096 .. 4294967296
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Lee Trager (ltrager) wrote : | # |
Thanks for running the tests! I've added -n to all test scripts which use sudo. The failure you saw was because stress-ng only allows 4GB of testing memory per thread. None of my test systems have more then 4GB total so I never ran into it. I've modified the stress-ng-memory tests to use enough threads so that no thread uses more then 4GB of RAM.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mike Pontillo (mpontillo) wrote : | # |
Thanks for the fix. Re-tested and it's looking good.
Preview Diff
1 | === modified file 'src/maasserver/api/scripts.py' | |||
2 | --- src/maasserver/api/scripts.py 2017-03-23 18:20:00 +0000 | |||
3 | +++ src/maasserver/api/scripts.py 2017-03-29 23:42:47 +0000 | |||
4 | @@ -259,7 +259,8 @@ | |||
5 | 259 | def download(self, request, name): | 259 | def download(self, request, name): |
6 | 260 | """Download a script. | 260 | """Download a script. |
7 | 261 | 261 | ||
9 | 262 | :param revision: What revision to download, latest by default. | 262 | :param revision: What revision to download, latest by default. Can use |
10 | 263 | rev as a shortcut. | ||
11 | 263 | :type revision: integer | 264 | :type revision: integer |
12 | 264 | """ | 265 | """ |
13 | 265 | if name.isdigit(): | 266 | if name.isdigit(): |
14 | @@ -267,6 +268,8 @@ | |||
15 | 267 | else: | 268 | else: |
16 | 268 | script = get_object_or_404(Script, name=name) | 269 | script = get_object_or_404(Script, name=name) |
17 | 269 | revision = get_optional_param(request.GET, 'revision', None, Int) | 270 | revision = get_optional_param(request.GET, 'revision', None, Int) |
18 | 271 | if revision is None: | ||
19 | 272 | revision = get_optional_param(request.GET, 'rev', None, Int) | ||
20 | 270 | if revision is not None: | 273 | if revision is not None: |
21 | 271 | for rev in script.script.previous_versions(): | 274 | for rev in script.script.previous_versions(): |
22 | 272 | if rev.id == revision: | 275 | if rev.id == revision: |
23 | 273 | 276 | ||
24 | === modified file 'src/maasserver/api/tests/test_scripts.py' | |||
25 | --- src/maasserver/api/tests/test_scripts.py 2017-03-23 18:20:00 +0000 | |||
26 | +++ src/maasserver/api/tests/test_scripts.py 2017-03-29 23:42:47 +0000 | |||
27 | @@ -356,6 +356,20 @@ | |||
28 | 356 | self.assertEquals( | 356 | self.assertEquals( |
29 | 357 | script.script.previous_version.data, response.content.decode()) | 357 | script.script.previous_version.data, response.content.decode()) |
30 | 358 | 358 | ||
31 | 359 | def test_download_gets_previous_rev(self): | ||
32 | 360 | script = factory.make_Script() | ||
33 | 361 | script.script = script.script.update(factory.make_string()) | ||
34 | 362 | script.save() | ||
35 | 363 | response = self.client.get( | ||
36 | 364 | self.get_script_uri(script), | ||
37 | 365 | { | ||
38 | 366 | 'op': 'download', | ||
39 | 367 | 'rev': script.script.previous_version.id, | ||
40 | 368 | }) | ||
41 | 369 | self.assertThat(response, HasStatusCode(http.client.OK)) | ||
42 | 370 | self.assertEquals( | ||
43 | 371 | script.script.previous_version.data, response.content.decode()) | ||
44 | 372 | |||
45 | 359 | def test_download_errors_on_unknown_revision(self): | 373 | def test_download_errors_on_unknown_revision(self): |
46 | 360 | script = factory.make_Script() | 374 | script = factory.make_Script() |
47 | 361 | response = self.client.get( | 375 | response = self.client.get( |
48 | 362 | 376 | ||
49 | === modified file 'src/maasserver/forms/script.py' | |||
50 | --- src/maasserver/forms/script.py 2017-03-10 09:15:31 +0000 | |||
51 | +++ src/maasserver/forms/script.py 2017-03-29 23:42:47 +0000 | |||
52 | @@ -83,6 +83,11 @@ | |||
53 | 83 | self, 'script_type', | 83 | self, 'script_type', |
54 | 84 | 'Must be %d, test, testing, %d, commission, or commissioning.' | 84 | 'Must be %d, test, testing, %d, commission, or commissioning.' |
55 | 85 | % (SCRIPT_TYPE.TESTING, SCRIPT_TYPE.COMMISSIONING)) | 85 | % (SCRIPT_TYPE.TESTING, SCRIPT_TYPE.COMMISSIONING)) |
56 | 86 | # If a field wasn't passed in keep the old values when updating. | ||
57 | 87 | if self.instance.id is not None: | ||
58 | 88 | for field in self._meta.fields: | ||
59 | 89 | if field not in self.data: | ||
60 | 90 | cleaned_data[field] = getattr(self.instance, field) | ||
61 | 86 | return cleaned_data | 91 | return cleaned_data |
62 | 87 | 92 | ||
63 | 88 | def is_valid(self): | 93 | def is_valid(self): |
64 | 89 | 94 | ||
65 | === modified file 'src/maasserver/forms/tests/test_script.py' | |||
66 | --- src/maasserver/forms/tests/test_script.py 2017-03-10 09:15:31 +0000 | |||
67 | +++ src/maasserver/forms/tests/test_script.py 2017-03-29 23:42:47 +0000 | |||
68 | @@ -193,6 +193,30 @@ | |||
69 | 193 | ] | 193 | ] |
70 | 194 | }, form.errors) | 194 | }, form.errors) |
71 | 195 | 195 | ||
72 | 196 | def test__update_script_doesnt_effect_other_fields(self): | ||
73 | 197 | script = factory.make_Script() | ||
74 | 198 | script_content = factory.make_string() | ||
75 | 199 | name = script.name | ||
76 | 200 | title = script.title | ||
77 | 201 | description = script.description | ||
78 | 202 | tags = script.tags | ||
79 | 203 | script_type = script.script_type | ||
80 | 204 | timeout = script.timeout | ||
81 | 205 | destructive = script.destructive | ||
82 | 206 | |||
83 | 207 | form = ScriptForm(data={'script': script_content}, instance=script) | ||
84 | 208 | self.assertTrue(form.is_valid(), form.errors) | ||
85 | 209 | script = form.save() | ||
86 | 210 | |||
87 | 211 | self.assertEquals(name, script.name) | ||
88 | 212 | self.assertEquals(title, script.title) | ||
89 | 213 | self.assertEquals(description, script.description) | ||
90 | 214 | self.assertEquals(tags, script.tags) | ||
91 | 215 | self.assertEquals(script_type, script.script_type) | ||
92 | 216 | self.assertEquals(timeout, script.timeout) | ||
93 | 217 | self.assertEquals(destructive, script.destructive) | ||
94 | 218 | self.assertFalse(script.default) | ||
95 | 219 | |||
96 | 196 | def test__can_use_script_type_name(self): | 220 | def test__can_use_script_type_name(self): |
97 | 197 | script_type_name = random.choice([ | 221 | script_type_name = random.choice([ |
98 | 198 | 'test', 'testing', | 222 | 'test', 'testing', |
99 | 199 | 223 | ||
100 | === modified file 'src/metadataserver/builtin_scripts/__init__.py' | |||
101 | --- src/metadataserver/builtin_scripts/__init__.py 2017-03-29 21:13:51 +0000 | |||
102 | +++ src/metadataserver/builtin_scripts/__init__.py 2017-03-29 23:42:47 +0000 | |||
103 | @@ -7,6 +7,7 @@ | |||
104 | 7 | 'load_builtin_scripts', | 7 | 'load_builtin_scripts', |
105 | 8 | ] | 8 | ] |
106 | 9 | 9 | ||
107 | 10 | from datetime import timedelta | ||
108 | 10 | import os | 11 | import os |
109 | 11 | 12 | ||
110 | 12 | import attr | 13 | import attr |
111 | @@ -48,7 +49,8 @@ | |||
112 | 48 | tags = attr.ib(default=None, validator=instance_of(list)) | 49 | tags = attr.ib(default=None, validator=instance_of(list)) |
113 | 49 | script_type = attr.ib( | 50 | script_type = attr.ib( |
114 | 50 | default=SCRIPT_TYPE.TESTING, validator=instance_of(int)) | 51 | default=SCRIPT_TYPE.TESTING, validator=instance_of(int)) |
116 | 51 | timeout = attr.ib(default=0, validator=instance_of(int)) | 52 | timeout = attr.ib( |
117 | 53 | default=timedelta(seconds=0), validator=instance_of(timedelta)) | ||
118 | 52 | destructive = attr.ib(default=False, validator=instance_of(bool)) | 54 | destructive = attr.ib(default=False, validator=instance_of(bool)) |
119 | 53 | filename = attr.ib(default=None, validator=instance_of(str)) | 55 | filename = attr.ib(default=None, validator=instance_of(str)) |
120 | 54 | 56 | ||
121 | @@ -63,7 +65,7 @@ | |||
122 | 63 | title='Storage status', | 65 | title='Storage status', |
123 | 64 | description='Validate SMART health for all drives in parallel.', | 66 | description='Validate SMART health for all drives in parallel.', |
124 | 65 | tags=['storage', 'commissioning'], | 67 | tags=['storage', 'commissioning'], |
126 | 66 | timeout=60 * 5, | 68 | timeout=timedelta(minutes=5), |
127 | 67 | filename='smartctl.py', | 69 | filename='smartctl.py', |
128 | 68 | ), | 70 | ), |
129 | 69 | BuiltinScript( | 71 | BuiltinScript( |
130 | @@ -73,7 +75,7 @@ | |||
131 | 73 | 'Run the short SMART self-test and validate SMART health on all ' | 75 | 'Run the short SMART self-test and validate SMART health on all ' |
132 | 74 | 'drives in parallel'), | 76 | 'drives in parallel'), |
133 | 75 | tags=['storage'], | 77 | tags=['storage'], |
135 | 76 | timeout=60 * 10, | 78 | timeout=timedelta(minutes=10), |
136 | 77 | filename='smartctl.py', | 79 | filename='smartctl.py', |
137 | 78 | ), | 80 | ), |
138 | 79 | BuiltinScript( | 81 | BuiltinScript( |
139 | @@ -106,7 +108,7 @@ | |||
140 | 106 | title='Network validation', | 108 | title='Network validation', |
141 | 107 | description='Download a file from images.maas.io.', | 109 | description='Download a file from images.maas.io.', |
142 | 108 | tags=['network', 'internet'], | 110 | tags=['network', 'internet'], |
144 | 109 | timeout=60 * 5, | 111 | timeout=timedelta(minutes=5), |
145 | 110 | filename='internet_connectivity.sh', | 112 | filename='internet_connectivity.sh', |
146 | 111 | ), | 113 | ), |
147 | 112 | BuiltinScript( | 114 | BuiltinScript( |
148 | @@ -114,23 +116,39 @@ | |||
149 | 114 | title='CPU validation', | 116 | title='CPU validation', |
150 | 115 | description='Run the stress-ng CPU tests over 12 hours.', | 117 | description='Run the stress-ng CPU tests over 12 hours.', |
151 | 116 | tags=['cpu'], | 118 | tags=['cpu'], |
154 | 117 | timeout=60 * 60 * 12, | 119 | timeout=timedelta(hours=12), |
155 | 118 | filename='stress_ng_cpu_long.sh', | 120 | filename='stress-ng-cpu-long.sh', |
156 | 121 | ), | ||
157 | 122 | BuiltinScript( | ||
158 | 123 | name='stress-ng-cpu-short', | ||
159 | 124 | title='CPU validation', | ||
160 | 125 | description='Stress test the CPU for 5 minutes.', | ||
161 | 126 | tags=['cpu'], | ||
162 | 127 | timeout=timedelta(minutes=5), | ||
163 | 128 | filename='stress-ng-cpu-short.sh', | ||
164 | 119 | ), | 129 | ), |
165 | 120 | BuiltinScript( | 130 | BuiltinScript( |
166 | 121 | name='stress-ng-memory-long', | 131 | name='stress-ng-memory-long', |
167 | 122 | title='Memory integrity', | 132 | title='Memory integrity', |
168 | 123 | description='Run the stress-ng memory tests over 12 hours.', | 133 | description='Run the stress-ng memory tests over 12 hours.', |
169 | 124 | tags=['memory'], | 134 | tags=['memory'], |
172 | 125 | timeout=60 * 60 * 12, | 135 | timeout=timedelta(hours=12), |
173 | 126 | filename='stress_ng_memory_long.sh', | 136 | filename='stress-ng-memory-long.sh', |
174 | 137 | ), | ||
175 | 138 | BuiltinScript( | ||
176 | 139 | name='stress-ng-memory-short', | ||
177 | 140 | title='Memory validation', | ||
178 | 141 | description='Stress test memory for 5 minutes.', | ||
179 | 142 | tags=['memory'], | ||
180 | 143 | timeout=timedelta(minutes=5), | ||
181 | 144 | filename='stress-ng-memory-short.sh', | ||
182 | 127 | ), | 145 | ), |
183 | 128 | BuiltinScript( | 146 | BuiltinScript( |
184 | 129 | name='ntp', | 147 | name='ntp', |
185 | 130 | title='NTP validation', | 148 | title='NTP validation', |
186 | 131 | description='Run ntp clock set to verify NTP connectivity.', | 149 | description='Run ntp clock set to verify NTP connectivity.', |
187 | 132 | tags=['network', 'ntp'], | 150 | tags=['network', 'ntp'], |
189 | 133 | timeout=60, | 151 | timeout=timedelta(minutes=1), |
190 | 134 | filename='ntp.sh', | 152 | filename='ntp.sh', |
191 | 135 | ), | 153 | ), |
192 | 136 | ] | 154 | ] |
193 | @@ -161,11 +179,15 @@ | |||
194 | 161 | # Don't add back old versions of a script. This prevents two | 179 | # Don't add back old versions of a script. This prevents two |
195 | 162 | # connected regions with different versions of a script from | 180 | # connected regions with different versions of a script from |
196 | 163 | # fighting with eachother. | 181 | # fighting with eachother. |
197 | 182 | no_update = False | ||
198 | 164 | for vtf in script_in_db.script.previous_versions(): | 183 | for vtf in script_in_db.script.previous_versions(): |
199 | 165 | if vtf.data == script_content: | 184 | if vtf.data == script_content: |
200 | 166 | # Don't update anything if we detect we have an old | 185 | # Don't update anything if we detect we have an old |
201 | 167 | # version of the builtin scripts | 186 | # version of the builtin scripts |
203 | 168 | return | 187 | no_update = True |
204 | 188 | break | ||
205 | 189 | if no_update: | ||
206 | 190 | continue | ||
207 | 169 | script_in_db.script = script_in_db.script.update( | 191 | script_in_db.script = script_in_db.script.update( |
208 | 170 | script_content, | 192 | script_content, |
209 | 171 | "Updated by maas-%s" % get_maas_package_version()) | 193 | "Updated by maas-%s" % get_maas_package_version()) |
210 | 172 | 194 | ||
211 | === modified file 'src/metadataserver/builtin_scripts/internet_connectivity.sh' | |||
212 | --- src/metadataserver/builtin_scripts/internet_connectivity.sh 2017-03-10 16:34:33 +0000 | |||
213 | +++ src/metadataserver/builtin_scripts/internet_connectivity.sh 2017-03-29 23:42:47 +0000 | |||
214 | @@ -1,4 +1,4 @@ | |||
216 | 1 | #!/bin/sh -e | 1 | #!/bin/bash -e |
217 | 2 | # | 2 | # |
218 | 3 | # internet_connectivity - Check if the system has access to the Internet. | 3 | # internet_connectivity - Check if the system has access to the Internet. |
219 | 4 | # | 4 | # |
220 | @@ -20,6 +20,7 @@ | |||
221 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
222 | 21 | 21 | ||
223 | 22 | # Download the index.sjson file used by MAAS to download images to validate | 22 | # Download the index.sjson file used by MAAS to download images to validate |
227 | 23 | # internet connectivity. Close stderr so we don't get the progress from curl. | 23 | # internet connectivity. |
228 | 24 | curl -I -A maas_internet_connectivity_test \ | 24 | URL="https://images.maas.io/ephemeral-v3/daily/streams/v1/index.sjson" |
229 | 25 | https://images.maas.io/ephemeral-v3/daily/streams/v1/index.sjson | 25 | echo "Attempting to retrieve: $URL" |
230 | 26 | curl -ILSsv -A maas_internet_connectivity_test $URL | ||
231 | 26 | 27 | ||
232 | === modified file 'src/metadataserver/builtin_scripts/memtester.sh' | |||
233 | --- src/metadataserver/builtin_scripts/memtester.sh 2017-03-23 18:20:00 +0000 | |||
234 | +++ src/metadataserver/builtin_scripts/memtester.sh 2017-03-29 23:42:47 +0000 | |||
235 | @@ -1,4 +1,4 @@ | |||
237 | 1 | #!/bin/sh -e | 1 | #!/bin/bash -e |
238 | 2 | # | 2 | # |
239 | 3 | # memtester - Run memtester against all available userspace memory. | 3 | # memtester - Run memtester against all available userspace memory. |
240 | 4 | # | 4 | # |
241 | @@ -19,10 +19,11 @@ | |||
242 | 19 | # You should have received a copy of the GNU Affero General Public License | 19 | # You should have received a copy of the GNU Affero General Public License |
243 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
244 | 21 | 21 | ||
246 | 22 | sudo apt-get install -q -y memtester | 22 | sudo -n apt-get install -q -y memtester |
247 | 23 | echo | ||
248 | 23 | 24 | ||
249 | 24 | # Memtester can only test memory available to userspace. Reserve 32M so the | 25 | # Memtester can only test memory available to userspace. Reserve 32M so the |
250 | 25 | # test doesn't fail due to the OOM killer. Only run memtester against available | 26 | # test doesn't fail due to the OOM killer. Only run memtester against available |
251 | 26 | # RAM once. | 27 | # RAM once. |
253 | 27 | sudo memtester \ | 28 | sudo -n memtester \ |
254 | 28 | $(awk '/MemAvailable/ { print ($2 - 32768) "K"}' /proc/meminfo) 1 | 29 | $(awk '/MemAvailable/ { print ($2 - 32768) "K"}' /proc/meminfo) 1 |
255 | 29 | 30 | ||
256 | === modified file 'src/metadataserver/builtin_scripts/ntp.sh' | |||
257 | --- src/metadataserver/builtin_scripts/ntp.sh 2017-03-23 18:20:00 +0000 | |||
258 | +++ src/metadataserver/builtin_scripts/ntp.sh 2017-03-29 23:42:47 +0000 | |||
259 | @@ -1,4 +1,4 @@ | |||
261 | 1 | #!/bin/sh -e | 1 | #!/bin/bash -e |
262 | 2 | # | 2 | # |
263 | 3 | # ntp - Run ntp clock set to verify NTP connectivity. | 3 | # ntp - Run ntp clock set to verify NTP connectivity. |
264 | 4 | # | 4 | # |
265 | @@ -24,7 +24,7 @@ | |||
266 | 24 | # the configured NTP server is accessible. | 24 | # the configured NTP server is accessible. |
267 | 25 | e=0 | 25 | e=0 |
268 | 26 | ntpq -np | 26 | ntpq -np |
272 | 27 | sudo systemctl stop ntp.service | 27 | sudo -n systemctl stop ntp.service |
273 | 28 | sudo timeout 10 ntpd -gq || e=$? | 28 | sudo -n timeout 10 ntpd -gq || e=$? |
274 | 29 | sudo systemctl start ntp.service | 29 | sudo -n systemctl start ntp.service |
275 | 30 | exit $e | 30 | exit $e |
276 | 31 | 31 | ||
277 | === renamed file 'src/metadataserver/builtin_scripts/stress_ng_cpu_long.sh' => 'src/metadataserver/builtin_scripts/stress-ng-cpu-long.sh' | |||
278 | --- src/metadataserver/builtin_scripts/stress_ng_cpu_long.sh 2017-03-23 18:20:00 +0000 | |||
279 | +++ src/metadataserver/builtin_scripts/stress-ng-cpu-long.sh 2017-03-29 23:42:47 +0000 | |||
280 | @@ -1,6 +1,6 @@ | |||
282 | 1 | #!/bin/sh -e | 1 | #!/bin/bash -e |
283 | 2 | # | 2 | # |
285 | 3 | # stress_ng_cpu_long - Run stress-ng memory tests over 12 hours. | 3 | # stress-ng-cpu-long - Run stress-ng memory tests over 12 hours. |
286 | 4 | # | 4 | # |
287 | 5 | # Author: Lee Trager <lee.trager@canonical.com> | 5 | # Author: Lee Trager <lee.trager@canonical.com> |
288 | 6 | # | 6 | # |
289 | @@ -19,8 +19,8 @@ | |||
290 | 19 | # You should have received a copy of the GNU Affero General Public License | 19 | # You should have received a copy of the GNU Affero General Public License |
291 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
292 | 21 | 21 | ||
294 | 22 | sudo apt-get install -q -y stress-ng | 22 | sudo -n apt-get install -q -y stress-ng |
295 | 23 | echo | ||
296 | 23 | 24 | ||
300 | 24 | sudo stress-ng \ | 25 | sudo -n stress-ng --aggressive -a 0 --class cpu,cpu-cache --ignite-cpu \ |
301 | 25 | --aggressive -a 0 --class cpu,cpu-cache --ignite-cpu --log-brief \ | 26 | --log-brief --metrics-brief --times --tz --verify --timeout 12h |
299 | 26 | --metrics --times --tz --verify --timeout 12h | ||
302 | 27 | 27 | ||
303 | === added file 'src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh' | |||
304 | --- src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh 1970-01-01 00:00:00 +0000 | |||
305 | +++ src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh 2017-03-29 23:42:47 +0000 | |||
306 | @@ -0,0 +1,32 @@ | |||
307 | 1 | #!/bin/bash -e | ||
308 | 2 | # | ||
309 | 3 | # stress-ng-cpu-short - Stress test the CPU for 5 minutes. | ||
310 | 4 | # | ||
311 | 5 | # Author: Lee Trager <lee.trager@canonical.com> | ||
312 | 6 | # | ||
313 | 7 | # Copyright (C) 2017 Canonical | ||
314 | 8 | # | ||
315 | 9 | # This program is free software: you can redistribute it and/or modify | ||
316 | 10 | # it under the terms of the GNU Affero General Public License as | ||
317 | 11 | # published by the Free Software Foundation, either version 3 of the | ||
318 | 12 | # License, or (at your option) any later version. | ||
319 | 13 | # | ||
320 | 14 | # This program is distributed in the hope that it will be useful, | ||
321 | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
322 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
323 | 17 | # GNU Affero General Public License for more details. | ||
324 | 18 | # | ||
325 | 19 | # You should have received a copy of the GNU Affero General Public License | ||
326 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
327 | 21 | |||
328 | 22 | sudo -n apt-get install -q -y stress-ng | ||
329 | 23 | echo | ||
330 | 24 | |||
331 | 25 | sudo -n stress-ng --matrix 0 --ignite-cpu --log-brief --metrics-brief --times \ | ||
332 | 26 | --tz --verify --timeout 2m | ||
333 | 27 | echo | ||
334 | 28 | sudo -n stress-ng --cache 0 --ignite-cpu --log-brief --metrics-brief --times \ | ||
335 | 29 | --tz --verify --timeout 1m | ||
336 | 30 | echo | ||
337 | 31 | sudo -n stress-ng --cpu 0 --ignite-cpu --log-brief --metrics-brief --times --tz \ | ||
338 | 32 | --verify --timeout 2m | ||
339 | 0 | 33 | ||
340 | === renamed file 'src/metadataserver/builtin_scripts/stress_ng_memory_long.sh' => 'src/metadataserver/builtin_scripts/stress-ng-memory-long.sh' | |||
341 | --- src/metadataserver/builtin_scripts/stress_ng_memory_long.sh 2017-03-23 18:20:00 +0000 | |||
342 | +++ src/metadataserver/builtin_scripts/stress-ng-memory-long.sh 2017-03-29 23:42:47 +0000 | |||
343 | @@ -1,4 +1,4 @@ | |||
345 | 1 | #!/bin/sh -e | 1 | #!/bin/bash -e |
346 | 2 | # | 2 | # |
347 | 3 | # stress_ng_memory_long - Run stress-ng memory tests over 12 hours. | 3 | # stress_ng_memory_long - Run stress-ng memory tests over 12 hours. |
348 | 4 | # | 4 | # |
349 | @@ -19,8 +19,18 @@ | |||
350 | 19 | # You should have received a copy of the GNU Affero General Public License | 19 | # You should have received a copy of the GNU Affero General Public License |
351 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
352 | 21 | 21 | ||
358 | 22 | sudo apt-get install -q -y stress-ng | 22 | sudo -n apt-get install -q -y stress-ng |
359 | 23 | 23 | echo | |
360 | 24 | sudo stress-ng \ | 24 | |
361 | 25 | --aggressive -a 0 --class memory --ignite-cpu --log-brief --metrics \ | 25 | # Reserve 64M so the test doesn't fail due to the OOM killer. |
362 | 26 | --times --tz --verify --timeout 12h | 26 | total_memory=$(awk '/MemAvailable/ { print ($2 - 65536) }' /proc/meminfo) |
363 | 27 | threads=$(lscpu --all --parse | grep -v '#' | wc -l) | ||
364 | 28 | memory_per_thread=$(($total_memory / $threads)) | ||
365 | 29 | # stress-ng only allows 4GB of memory per thread. | ||
366 | 30 | if [ $memory_per_thread -ge 4194304 ]; then | ||
367 | 31 | threads=$(($total_memory / 4194304 + 1)) | ||
368 | 32 | memory_per_thread=$(($total_memory / $threads)) | ||
369 | 33 | fi | ||
370 | 34 | |||
371 | 35 | stress-ng --vm $threads --vm-bytes ${memory_per_thread}k --page-in \ | ||
372 | 36 | --log-brief --metrics-brief --times --tz --verify --timeout 12h | ||
373 | 27 | 37 | ||
374 | === added file 'src/metadataserver/builtin_scripts/stress-ng-memory-short.sh' | |||
375 | --- src/metadataserver/builtin_scripts/stress-ng-memory-short.sh 1970-01-01 00:00:00 +0000 | |||
376 | +++ src/metadataserver/builtin_scripts/stress-ng-memory-short.sh 2017-03-29 23:42:47 +0000 | |||
377 | @@ -0,0 +1,36 @@ | |||
378 | 1 | #!/bin/bash -e | ||
379 | 2 | # | ||
380 | 3 | # stress-ng-memory-short - Stress test memory for 5 minutes. | ||
381 | 4 | # | ||
382 | 5 | # Author: Lee Trager <lee.trager@canonical.com> | ||
383 | 6 | # | ||
384 | 7 | # Copyright (C) 2017 Canonical | ||
385 | 8 | # | ||
386 | 9 | # This program is free software: you can redistribute it and/or modify | ||
387 | 10 | # it under the terms of the GNU Affero General Public License as | ||
388 | 11 | # published by the Free Software Foundation, either version 3 of the | ||
389 | 12 | # License, or (at your option) any later version. | ||
390 | 13 | # | ||
391 | 14 | # This program is distributed in the hope that it will be useful, | ||
392 | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
393 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
394 | 17 | # GNU Affero General Public License for more details. | ||
395 | 18 | # | ||
396 | 19 | # You should have received a copy of the GNU Affero General Public License | ||
397 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
398 | 21 | |||
399 | 22 | sudo -n apt-get install -q -y stress-ng | ||
400 | 23 | echo | ||
401 | 24 | |||
402 | 25 | # Reserve 64M so the test doesn't fail due to the OOM killer. | ||
403 | 26 | total_memory=$(awk '/MemAvailable/ { print ($2 - 65536) }' /proc/meminfo) | ||
404 | 27 | threads=$(lscpu --all --parse | grep -v '#' | wc -l) | ||
405 | 28 | memory_per_thread=$(($total_memory / $threads)) | ||
406 | 29 | # stress-ng only allows 4GB of memory per thread. | ||
407 | 30 | if [ $memory_per_thread -ge 4194304 ]; then | ||
408 | 31 | threads=$(($total_memory / 4194304 + 1)) | ||
409 | 32 | memory_per_thread=$(($total_memory / $threads)) | ||
410 | 33 | fi | ||
411 | 34 | |||
412 | 35 | stress-ng --vm $threads --vm-bytes ${memory_per_thread}k --page-in \ | ||
413 | 36 | --log-brief --metrics-brief --times --tz --verify --timeout 5m | ||
414 | 0 | 37 | ||
415 | === modified file 'src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py' | |||
416 | --- src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py 2017-03-23 18:20:00 +0000 | |||
417 | +++ src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py 2017-03-29 23:42:47 +0000 | |||
418 | @@ -34,8 +34,7 @@ | |||
419 | 34 | script_in_db.script.comment) | 34 | script_in_db.script.comment) |
420 | 35 | self.assertItemsEqual(script.tags, script_in_db.tags) | 35 | self.assertItemsEqual(script.tags, script_in_db.tags) |
421 | 36 | self.assertEquals(script.script_type, script_in_db.script_type) | 36 | self.assertEquals(script.script_type, script_in_db.script_type) |
424 | 37 | self.assertEquals( | 37 | self.assertEquals(script.timeout, script_in_db.timeout) |
423 | 38 | timedelta(seconds=script.timeout), script_in_db.timeout) | ||
425 | 39 | self.assertEquals(script.destructive, script_in_db.destructive) | 38 | self.assertEquals(script.destructive, script_in_db.destructive) |
426 | 40 | self.assertTrue(script_in_db.default) | 39 | self.assertTrue(script_in_db.default) |
427 | 41 | 40 | ||
428 | @@ -79,7 +78,8 @@ | |||
429 | 79 | 78 | ||
430 | 80 | def test_update_doesnt_revert_script(self): | 79 | def test_update_doesnt_revert_script(self): |
431 | 81 | load_builtin_scripts() | 80 | load_builtin_scripts() |
433 | 82 | update_script_values = random.choice(BUILTIN_SCRIPTS) | 81 | update_script_index = random.randint(0, len(BUILTIN_SCRIPTS) - 2) |
434 | 82 | update_script_values = BUILTIN_SCRIPTS[update_script_index] | ||
435 | 83 | script = Script.objects.get(name=update_script_values.name) | 83 | script = Script.objects.get(name=update_script_values.name) |
436 | 84 | # Put fake new data in to simulate another MAAS region updating | 84 | # Put fake new data in to simulate another MAAS region updating |
437 | 85 | # to a newer version. | 85 | # to a newer version. |
438 | @@ -99,6 +99,14 @@ | |||
439 | 99 | script.timeout = user_timeout | 99 | script.timeout = user_timeout |
440 | 100 | script.save() | 100 | script.save() |
441 | 101 | 101 | ||
442 | 102 | # Test that subsequent scripts still get updated | ||
443 | 103 | second_update_script_values = BUILTIN_SCRIPTS[update_script_index + 1] | ||
444 | 104 | second_script = Script.objects.get( | ||
445 | 105 | name=second_update_script_values.name) | ||
446 | 106 | # Put fake old data in to simulate updating a script. | ||
447 | 107 | second_script.title = factory.make_string() | ||
448 | 108 | second_script.save() | ||
449 | 109 | |||
450 | 102 | load_builtin_scripts() | 110 | load_builtin_scripts() |
451 | 103 | script = reload_object(script) | 111 | script = reload_object(script) |
452 | 104 | 112 | ||
453 | @@ -111,3 +119,7 @@ | |||
454 | 111 | self.assertEquals(user_tags, script.tags) | 119 | self.assertEquals(user_tags, script.tags) |
455 | 112 | self.assertEquals(user_timeout, script.timeout) | 120 | self.assertEquals(user_timeout, script.timeout) |
456 | 113 | self.assertTrue(script.default) | 121 | self.assertTrue(script.default) |
457 | 122 | |||
458 | 123 | second_script = reload_object(second_script) | ||
459 | 124 | self.assertEquals( | ||
460 | 125 | second_update_script_values.title, second_script.title) | ||
461 | 114 | 126 | ||
462 | === modified file 'src/metadataserver/user_data/templates/base_user_data.sh' | |||
463 | --- src/metadataserver/user_data/templates/base_user_data.sh 2017-02-16 00:27:35 +0000 | |||
464 | +++ src/metadataserver/user_data/templates/base_user_data.sh 2017-03-29 23:42:47 +0000 | |||
465 | @@ -1,4 +1,4 @@ | |||
467 | 1 | #!/bin/sh | 1 | #!/bin/bash |
468 | 2 | # | 2 | # |
469 | 3 | # This script carries inside it multiple files. When executed, it creates | 3 | # This script carries inside it multiple files. When executed, it creates |
470 | 4 | # the files into a temporary directory and uses them to execute commands | 4 | # the files into a temporary directory and uses them to execute commands |
471 | 5 | 5 | ||
472 | === modified file 'src/metadataserver/user_data/templates/snippets/maas_enlist.sh' | |||
473 | --- src/metadataserver/user_data/templates/snippets/maas_enlist.sh 2017-03-08 10:10:12 +0000 | |||
474 | +++ src/metadataserver/user_data/templates/snippets/maas_enlist.sh 2017-03-29 23:42:47 +0000 | |||
475 | @@ -1,4 +1,4 @@ | |||
477 | 1 | #!/bin/sh | 1 | #!/bin/bash |
478 | 2 | # | 2 | # |
479 | 3 | # maas-enlist: MAAS Enlistment Tool | 3 | # maas-enlist: MAAS Enlistment Tool |
480 | 4 | # | 4 | # |
481 | 5 | 5 | ||
482 | === modified file 'src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py' | |||
483 | --- src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py 2017-03-03 00:50:43 +0000 | |||
484 | +++ src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py 2017-03-29 23:42:47 +0000 | |||
485 | @@ -233,6 +233,12 @@ | |||
486 | 233 | fail("URL must be provided either in --url or in config\n") | 233 | fail("URL must be provided either in --url or in config\n") |
487 | 234 | url = "%s/%s/" % (url, args.apiver) | 234 | url = "%s/%s/" % (url, args.apiver) |
488 | 235 | 235 | ||
489 | 236 | # Disable the OOM killer on the runner process, the OOM killer will still | ||
490 | 237 | # go after any tests spawned. | ||
491 | 238 | oom_score_adj_path = os.path.join( | ||
492 | 239 | '/proc', str(os.getpid()), 'oom_score_adj') | ||
493 | 240 | open(oom_score_adj_path, 'w').write('-1000') | ||
494 | 241 | |||
495 | 236 | heart_beat = HeartBeat(url, creds) | 242 | heart_beat = HeartBeat(url, creds) |
496 | 237 | heart_beat.start() | 243 | heart_beat.start() |
497 | 238 | 244 | ||
498 | 239 | 245 | ||
499 | === modified file 'src/provisioningserver/refresh/node_info_scripts.py' | |||
500 | --- src/provisioningserver/refresh/node_info_scripts.py 2017-03-29 21:13:51 +0000 | |||
501 | +++ src/provisioningserver/refresh/node_info_scripts.py 2017-03-29 23:42:47 +0000 | |||
502 | @@ -60,19 +60,19 @@ | |||
503 | 60 | 60 | ||
504 | 61 | # Built-in script to run lshw. | 61 | # Built-in script to run lshw. |
505 | 62 | LSHW_SCRIPT = dedent("""\ | 62 | LSHW_SCRIPT = dedent("""\ |
507 | 63 | #!/bin/sh | 63 | #!/bin/bash |
508 | 64 | sudo -n /usr/bin/lshw -xml | 64 | sudo -n /usr/bin/lshw -xml |
509 | 65 | """) | 65 | """) |
510 | 66 | 66 | ||
511 | 67 | # Built-in script to run `ip addr` | 67 | # Built-in script to run `ip addr` |
512 | 68 | IPADDR_SCRIPT = dedent("""\ | 68 | IPADDR_SCRIPT = dedent("""\ |
514 | 69 | #!/bin/sh | 69 | #!/bin/bash |
515 | 70 | ip addr | 70 | ip addr |
516 | 71 | """) | 71 | """) |
517 | 72 | 72 | ||
518 | 73 | # Built-in script to detect virtual instances. | 73 | # Built-in script to detect virtual instances. |
519 | 74 | VIRTUALITY_SCRIPT = dedent("""\ | 74 | VIRTUALITY_SCRIPT = dedent("""\ |
521 | 75 | #!/bin/sh | 75 | #!/bin/bash |
522 | 76 | # In Bourne Shell `type -p` does not work; `which` is closest. | 76 | # In Bourne Shell `type -p` does not work; `which` is closest. |
523 | 77 | if which systemd-detect-virt > /dev/null; then | 77 | if which systemd-detect-virt > /dev/null; then |
524 | 78 | # systemd-detect-virt prints "none" and returns nonzero if | 78 | # systemd-detect-virt prints "none" and returns nonzero if |
525 | @@ -90,7 +90,7 @@ | |||
526 | 90 | """) | 90 | """) |
527 | 91 | 91 | ||
528 | 92 | CPUINFO_SCRIPT = dedent("""\ | 92 | CPUINFO_SCRIPT = dedent("""\ |
530 | 93 | #!/bin/sh | 93 | #!/bin/bash |
531 | 94 | # Gather the standard output as it has some extra info | 94 | # Gather the standard output as it has some extra info |
532 | 95 | lscpu | 95 | lscpu |
533 | 96 | # Gather the machine readable output for processing | 96 | # Gather the machine readable output for processing |
534 | @@ -108,7 +108,7 @@ | |||
535 | 108 | """) | 108 | """) |
536 | 109 | 109 | ||
537 | 110 | SRIOV_SCRIPT = dedent("""\ | 110 | SRIOV_SCRIPT = dedent("""\ |
539 | 111 | #!/bin/sh | 111 | #!/bin/bash |
540 | 112 | for file in $(find /sys/devices/ -name sriov_numvfs); do | 112 | for file in $(find /sys/devices/ -name sriov_numvfs); do |
541 | 113 | dir=$(dirname "$file") | 113 | dir=$(dirname "$file") |
542 | 114 | for eth in $(ls "$dir/net/"); do | 114 | for eth in $(ls "$dir/net/"); do |
543 | @@ -388,7 +388,7 @@ | |||
544 | 388 | 388 | ||
545 | 389 | LIST_MODALIASES_OUTPUT_NAME = '00-maas-04-list-modaliases' | 389 | LIST_MODALIASES_OUTPUT_NAME = '00-maas-04-list-modaliases' |
546 | 390 | LIST_MODALIASES_SCRIPT = dedent("""\ | 390 | LIST_MODALIASES_SCRIPT = dedent("""\ |
548 | 391 | #!/bin/sh | 391 | #!/bin/bash |
549 | 392 | find /sys -name modalias -print0 | xargs -0 cat | sort -u | 392 | find /sys -name modalias -print0 | xargs -0 cat | sort -u |
550 | 393 | """) | 393 | """) |
551 | 394 | 394 | ||
552 | 395 | 395 | ||
553 | === modified file 'src/provisioningserver/refresh/tests/test_node_info_scripts.py' | |||
554 | --- src/provisioningserver/refresh/tests/test_node_info_scripts.py 2017-03-23 18:20:00 +0000 | |||
555 | +++ src/provisioningserver/refresh/tests/test_node_info_scripts.py 2017-03-29 23:42:47 +0000 | |||
556 | @@ -944,7 +944,7 @@ | |||
557 | 944 | self.sysdv.unlink() | 944 | self.sysdv.unlink() |
558 | 945 | sysdv_name = factory.make_name("virt") | 945 | sysdv_name = factory.make_name("virt") |
559 | 946 | with self.sysdv.open("w") as fd: | 946 | with self.sysdv.open("w") as fd: |
561 | 947 | fd.write("#!/bin/sh\n") | 947 | fd.write("#!/bin/bash\n") |
562 | 948 | fd.write("echo %s\n" % sysdv_name) | 948 | fd.write("echo %s\n" % sysdv_name) |
563 | 949 | fd.write("exit 1\n") | 949 | fd.write("exit 1\n") |
564 | 950 | self.sysdv.chmod(0o700) | 950 | self.sysdv.chmod(0o700) |
565 | 951 | 951 | ||
566 | === modified file 'src/provisioningserver/refresh/tests/test_refresh.py' | |||
567 | --- src/provisioningserver/refresh/tests/test_refresh.py 2017-03-03 00:50:43 +0000 | |||
568 | +++ src/provisioningserver/refresh/tests/test_refresh.py 2017-03-29 23:42:47 +0000 | |||
569 | @@ -137,7 +137,7 @@ | |||
570 | 137 | if script_name is None: | 137 | if script_name is None: |
571 | 138 | script_name = factory.make_name('script_name') | 138 | script_name = factory.make_name('script_name') |
572 | 139 | TEST_SCRIPT = dedent("""\ | 139 | TEST_SCRIPT = dedent("""\ |
574 | 140 | #!/bin/sh | 140 | #!/bin/bash |
575 | 141 | echo 'test script' | 141 | echo 'test script' |
576 | 142 | """) | 142 | """) |
577 | 143 | refresh.NODE_INFO_SCRIPTS = OrderedDict([ | 143 | refresh.NODE_INFO_SCRIPTS = OrderedDict([ |
578 | @@ -151,7 +151,7 @@ | |||
579 | 151 | if script_name is None: | 151 | if script_name is None: |
580 | 152 | script_name = factory.make_name('script_name') | 152 | script_name = factory.make_name('script_name') |
581 | 153 | TEST_SCRIPT = dedent("""\ | 153 | TEST_SCRIPT = dedent("""\ |
583 | 154 | #!/bin/sh | 154 | #!/bin/bash |
584 | 155 | echo 'test failed' | 155 | echo 'test failed' |
585 | 156 | exit 1 | 156 | exit 1 |
586 | 157 | """) | 157 | """) |
587 | 158 | 158 | ||
588 | === modified file 'src/provisioningserver/rpc/tests/test_clusterservice.py' | |||
589 | --- src/provisioningserver/rpc/tests/test_clusterservice.py 2017-03-27 14:35:23 +0000 | |||
590 | +++ src/provisioningserver/rpc/tests/test_clusterservice.py 2017-03-29 23:42:47 +0000 | |||
591 | @@ -2479,7 +2479,7 @@ | |||
592 | 2479 | @inlineCallbacks | 2479 | @inlineCallbacks |
593 | 2480 | def test_spawnProcessAndNullifyStdout_nullifies_stdout(self): | 2480 | def test_spawnProcessAndNullifyStdout_nullifies_stdout(self): |
594 | 2481 | done, protocol = makeDeferredWithProcessProtocol() | 2481 | done, protocol = makeDeferredWithProcessProtocol() |
596 | 2482 | args = [b"/bin/sh", b'-c', b"echo foo"] | 2482 | args = [b"/bin/bash", b'-c', b"echo foo"] |
597 | 2483 | outReceived = Mock() | 2483 | outReceived = Mock() |
598 | 2484 | protocol.outReceived = outReceived | 2484 | protocol.outReceived = outReceived |
599 | 2485 | spawnProcessAndNullifyStdout(protocol, args) | 2485 | spawnProcessAndNullifyStdout(protocol, args) |
600 | @@ -2489,7 +2489,7 @@ | |||
601 | 2489 | @inlineCallbacks | 2489 | @inlineCallbacks |
602 | 2490 | def test_spawnProcessAndNullifyStdout_captures_stderr(self): | 2490 | def test_spawnProcessAndNullifyStdout_captures_stderr(self): |
603 | 2491 | done, protocol = makeDeferredWithProcessProtocol() | 2491 | done, protocol = makeDeferredWithProcessProtocol() |
605 | 2492 | args = [b"/bin/sh", b'-c', b"echo foo >&2"] | 2492 | args = [b"/bin/bash", b'-c', b"echo foo >&2"] |
606 | 2493 | errReceived = Mock() | 2493 | errReceived = Mock() |
607 | 2494 | protocol.errReceived = errReceived | 2494 | protocol.errReceived = errReceived |
608 | 2495 | spawnProcessAndNullifyStdout(protocol, args) | 2495 | spawnProcessAndNullifyStdout(protocol, args) |
609 | @@ -2500,7 +2500,7 @@ | |||
610 | 2500 | def test_executeScanNetworksSubprocess(self): | 2500 | def test_executeScanNetworksSubprocess(self): |
611 | 2501 | mock_scan_args = self.patch( | 2501 | mock_scan_args = self.patch( |
612 | 2502 | clusterservice, 'get_scan_all_networks_args') | 2502 | clusterservice, 'get_scan_all_networks_args') |
614 | 2503 | mock_scan_args.return_value = [b"/bin/sh", b'-c', b"echo -n foo >&2"] | 2503 | mock_scan_args.return_value = [b"/bin/bash", b'-c', b"echo -n foo >&2"] |
615 | 2504 | mock_log_msg = self.patch(clusterservice.log, 'msg') | 2504 | mock_log_msg = self.patch(clusterservice.log, 'msg') |
616 | 2505 | d = executeScanNetworksSubprocess() | 2505 | d = executeScanNetworksSubprocess() |
617 | 2506 | yield d | 2506 | yield d |
I haven't reviewed the rest of this branch, but I'd like to suggest a policy: all shell scripts should be run with bash. Bash is fairly unpleasant for anything non-trivial, but /bin/sh in all its forms is hostile to sanity and happiness. Shell scripts are a blight, but if we must write them then let's at least stick to the least insane of the ubiquitous ones.