Merge lp:~ltrager/maas/stress_ng_tests into lp:~maas-committers/maas/trunk

Proposed by Lee Trager
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
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Approve
Review via email: mp+321027@code.launchpad.net

Commit message

Add stress-ng short cpu and memory tests and fix stress_ng_memory_long test.

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.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

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.

Revision history for this message
Lee Trager (ltrager) wrote :

Fully agree and implemented. I've been using /bin/sh because only because the existing commissioning script use it.

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

The code looks good. I'll test it out a bit before I approve.

Revision history for this message
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.

Revision history for this message
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

review: Needs Fixing
Revision history for this message
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.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Thanks for the fix. Re-tested and it's looking good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/api/scripts.py'
--- src/maasserver/api/scripts.py 2017-03-23 18:20:00 +0000
+++ src/maasserver/api/scripts.py 2017-03-29 23:42:47 +0000
@@ -259,7 +259,8 @@
259 def download(self, request, name):259 def download(self, request, name):
260 """Download a script.260 """Download a script.
261261
262 :param revision: What revision to download, latest by default.262 :param revision: What revision to download, latest by default. Can use
263 rev as a shortcut.
263 :type revision: integer264 :type revision: integer
264 """265 """
265 if name.isdigit():266 if name.isdigit():
@@ -267,6 +268,8 @@
267 else:268 else:
268 script = get_object_or_404(Script, name=name)269 script = get_object_or_404(Script, name=name)
269 revision = get_optional_param(request.GET, 'revision', None, Int)270 revision = get_optional_param(request.GET, 'revision', None, Int)
271 if revision is None:
272 revision = get_optional_param(request.GET, 'rev', None, Int)
270 if revision is not None:273 if revision is not None:
271 for rev in script.script.previous_versions():274 for rev in script.script.previous_versions():
272 if rev.id == revision:275 if rev.id == revision:
273276
=== modified file 'src/maasserver/api/tests/test_scripts.py'
--- src/maasserver/api/tests/test_scripts.py 2017-03-23 18:20:00 +0000
+++ src/maasserver/api/tests/test_scripts.py 2017-03-29 23:42:47 +0000
@@ -356,6 +356,20 @@
356 self.assertEquals(356 self.assertEquals(
357 script.script.previous_version.data, response.content.decode())357 script.script.previous_version.data, response.content.decode())
358358
359 def test_download_gets_previous_rev(self):
360 script = factory.make_Script()
361 script.script = script.script.update(factory.make_string())
362 script.save()
363 response = self.client.get(
364 self.get_script_uri(script),
365 {
366 'op': 'download',
367 'rev': script.script.previous_version.id,
368 })
369 self.assertThat(response, HasStatusCode(http.client.OK))
370 self.assertEquals(
371 script.script.previous_version.data, response.content.decode())
372
359 def test_download_errors_on_unknown_revision(self):373 def test_download_errors_on_unknown_revision(self):
360 script = factory.make_Script()374 script = factory.make_Script()
361 response = self.client.get(375 response = self.client.get(
362376
=== modified file 'src/maasserver/forms/script.py'
--- src/maasserver/forms/script.py 2017-03-10 09:15:31 +0000
+++ src/maasserver/forms/script.py 2017-03-29 23:42:47 +0000
@@ -83,6 +83,11 @@
83 self, 'script_type',83 self, 'script_type',
84 'Must be %d, test, testing, %d, commission, or commissioning.'84 'Must be %d, test, testing, %d, commission, or commissioning.'
85 % (SCRIPT_TYPE.TESTING, SCRIPT_TYPE.COMMISSIONING))85 % (SCRIPT_TYPE.TESTING, SCRIPT_TYPE.COMMISSIONING))
86 # If a field wasn't passed in keep the old values when updating.
87 if self.instance.id is not None:
88 for field in self._meta.fields:
89 if field not in self.data:
90 cleaned_data[field] = getattr(self.instance, field)
86 return cleaned_data91 return cleaned_data
8792
88 def is_valid(self):93 def is_valid(self):
8994
=== modified file 'src/maasserver/forms/tests/test_script.py'
--- src/maasserver/forms/tests/test_script.py 2017-03-10 09:15:31 +0000
+++ src/maasserver/forms/tests/test_script.py 2017-03-29 23:42:47 +0000
@@ -193,6 +193,30 @@
193 ]193 ]
194 }, form.errors)194 }, form.errors)
195195
196 def test__update_script_doesnt_effect_other_fields(self):
197 script = factory.make_Script()
198 script_content = factory.make_string()
199 name = script.name
200 title = script.title
201 description = script.description
202 tags = script.tags
203 script_type = script.script_type
204 timeout = script.timeout
205 destructive = script.destructive
206
207 form = ScriptForm(data={'script': script_content}, instance=script)
208 self.assertTrue(form.is_valid(), form.errors)
209 script = form.save()
210
211 self.assertEquals(name, script.name)
212 self.assertEquals(title, script.title)
213 self.assertEquals(description, script.description)
214 self.assertEquals(tags, script.tags)
215 self.assertEquals(script_type, script.script_type)
216 self.assertEquals(timeout, script.timeout)
217 self.assertEquals(destructive, script.destructive)
218 self.assertFalse(script.default)
219
196 def test__can_use_script_type_name(self):220 def test__can_use_script_type_name(self):
197 script_type_name = random.choice([221 script_type_name = random.choice([
198 'test', 'testing',222 'test', 'testing',
199223
=== modified file 'src/metadataserver/builtin_scripts/__init__.py'
--- src/metadataserver/builtin_scripts/__init__.py 2017-03-29 21:13:51 +0000
+++ src/metadataserver/builtin_scripts/__init__.py 2017-03-29 23:42:47 +0000
@@ -7,6 +7,7 @@
7 'load_builtin_scripts',7 'load_builtin_scripts',
8]8]
99
10from datetime import timedelta
10import os11import os
1112
12import attr13import attr
@@ -48,7 +49,8 @@
48 tags = attr.ib(default=None, validator=instance_of(list))49 tags = attr.ib(default=None, validator=instance_of(list))
49 script_type = attr.ib(50 script_type = attr.ib(
50 default=SCRIPT_TYPE.TESTING, validator=instance_of(int))51 default=SCRIPT_TYPE.TESTING, validator=instance_of(int))
51 timeout = attr.ib(default=0, validator=instance_of(int))52 timeout = attr.ib(
53 default=timedelta(seconds=0), validator=instance_of(timedelta))
52 destructive = attr.ib(default=False, validator=instance_of(bool))54 destructive = attr.ib(default=False, validator=instance_of(bool))
53 filename = attr.ib(default=None, validator=instance_of(str))55 filename = attr.ib(default=None, validator=instance_of(str))
5456
@@ -63,7 +65,7 @@
63 title='Storage status',65 title='Storage status',
64 description='Validate SMART health for all drives in parallel.',66 description='Validate SMART health for all drives in parallel.',
65 tags=['storage', 'commissioning'],67 tags=['storage', 'commissioning'],
66 timeout=60 * 5,68 timeout=timedelta(minutes=5),
67 filename='smartctl.py',69 filename='smartctl.py',
68 ),70 ),
69 BuiltinScript(71 BuiltinScript(
@@ -73,7 +75,7 @@
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 '
74 'drives in parallel'),76 'drives in parallel'),
75 tags=['storage'],77 tags=['storage'],
76 timeout=60 * 10,78 timeout=timedelta(minutes=10),
77 filename='smartctl.py',79 filename='smartctl.py',
78 ),80 ),
79 BuiltinScript(81 BuiltinScript(
@@ -106,7 +108,7 @@
106 title='Network validation',108 title='Network validation',
107 description='Download a file from images.maas.io.',109 description='Download a file from images.maas.io.',
108 tags=['network', 'internet'],110 tags=['network', 'internet'],
109 timeout=60 * 5,111 timeout=timedelta(minutes=5),
110 filename='internet_connectivity.sh',112 filename='internet_connectivity.sh',
111 ),113 ),
112 BuiltinScript(114 BuiltinScript(
@@ -114,23 +116,39 @@
114 title='CPU validation',116 title='CPU validation',
115 description='Run the stress-ng CPU tests over 12 hours.',117 description='Run the stress-ng CPU tests over 12 hours.',
116 tags=['cpu'],118 tags=['cpu'],
117 timeout=60 * 60 * 12,119 timeout=timedelta(hours=12),
118 filename='stress_ng_cpu_long.sh',120 filename='stress-ng-cpu-long.sh',
121 ),
122 BuiltinScript(
123 name='stress-ng-cpu-short',
124 title='CPU validation',
125 description='Stress test the CPU for 5 minutes.',
126 tags=['cpu'],
127 timeout=timedelta(minutes=5),
128 filename='stress-ng-cpu-short.sh',
119 ),129 ),
120 BuiltinScript(130 BuiltinScript(
121 name='stress-ng-memory-long',131 name='stress-ng-memory-long',
122 title='Memory integrity',132 title='Memory integrity',
123 description='Run the stress-ng memory tests over 12 hours.',133 description='Run the stress-ng memory tests over 12 hours.',
124 tags=['memory'],134 tags=['memory'],
125 timeout=60 * 60 * 12,135 timeout=timedelta(hours=12),
126 filename='stress_ng_memory_long.sh',136 filename='stress-ng-memory-long.sh',
137 ),
138 BuiltinScript(
139 name='stress-ng-memory-short',
140 title='Memory validation',
141 description='Stress test memory for 5 minutes.',
142 tags=['memory'],
143 timeout=timedelta(minutes=5),
144 filename='stress-ng-memory-short.sh',
127 ),145 ),
128 BuiltinScript(146 BuiltinScript(
129 name='ntp',147 name='ntp',
130 title='NTP validation',148 title='NTP validation',
131 description='Run ntp clock set to verify NTP connectivity.',149 description='Run ntp clock set to verify NTP connectivity.',
132 tags=['network', 'ntp'],150 tags=['network', 'ntp'],
133 timeout=60,151 timeout=timedelta(minutes=1),
134 filename='ntp.sh',152 filename='ntp.sh',
135 ),153 ),
136]154]
@@ -161,11 +179,15 @@
161 # Don't add back old versions of a script. This prevents two179 # Don't add back old versions of a script. This prevents two
162 # connected regions with different versions of a script from180 # connected regions with different versions of a script from
163 # fighting with eachother.181 # fighting with eachother.
182 no_update = False
164 for vtf in script_in_db.script.previous_versions():183 for vtf in script_in_db.script.previous_versions():
165 if vtf.data == script_content:184 if vtf.data == script_content:
166 # Don't update anything if we detect we have an old185 # Don't update anything if we detect we have an old
167 # version of the builtin scripts186 # version of the builtin scripts
168 return187 no_update = True
188 break
189 if no_update:
190 continue
169 script_in_db.script = script_in_db.script.update(191 script_in_db.script = script_in_db.script.update(
170 script_content,192 script_content,
171 "Updated by maas-%s" % get_maas_package_version())193 "Updated by maas-%s" % get_maas_package_version())
172194
=== modified file 'src/metadataserver/builtin_scripts/internet_connectivity.sh'
--- src/metadataserver/builtin_scripts/internet_connectivity.sh 2017-03-10 16:34:33 +0000
+++ src/metadataserver/builtin_scripts/internet_connectivity.sh 2017-03-29 23:42:47 +0000
@@ -1,4 +1,4 @@
1#!/bin/sh -e1#!/bin/bash -e
2#2#
3# internet_connectivity - Check if the system has access to the Internet.3# internet_connectivity - Check if the system has access to the Internet.
4#4#
@@ -20,6 +20,7 @@
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/>.
2121
22# Download the index.sjson file used by MAAS to download images to validate22# Download the index.sjson file used by MAAS to download images to validate
23# internet connectivity. Close stderr so we don't get the progress from curl.23# internet connectivity.
24curl -I -A maas_internet_connectivity_test \24URL="https://images.maas.io/ephemeral-v3/daily/streams/v1/index.sjson"
25 https://images.maas.io/ephemeral-v3/daily/streams/v1/index.sjson25echo "Attempting to retrieve: $URL"
26curl -ILSsv -A maas_internet_connectivity_test $URL
2627
=== modified file 'src/metadataserver/builtin_scripts/memtester.sh'
--- src/metadataserver/builtin_scripts/memtester.sh 2017-03-23 18:20:00 +0000
+++ src/metadataserver/builtin_scripts/memtester.sh 2017-03-29 23:42:47 +0000
@@ -1,4 +1,4 @@
1#!/bin/sh -e1#!/bin/bash -e
2#2#
3# memtester - Run memtester against all available userspace memory.3# memtester - Run memtester against all available userspace memory.
4#4#
@@ -19,10 +19,11 @@
19# You should have received a copy of the GNU Affero General Public License19# You should have received a copy of the GNU Affero General Public License
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/>.
2121
22sudo apt-get install -q -y memtester22sudo -n apt-get install -q -y memtester
23echo
2324
24# Memtester can only test memory available to userspace. Reserve 32M so the25# Memtester can only test memory available to userspace. Reserve 32M so the
25# test doesn't fail due to the OOM killer. Only run memtester against available26# test doesn't fail due to the OOM killer. Only run memtester against available
26# RAM once.27# RAM once.
27sudo memtester \28sudo -n memtester \
28 $(awk '/MemAvailable/ { print ($2 - 32768) "K"}' /proc/meminfo) 129 $(awk '/MemAvailable/ { print ($2 - 32768) "K"}' /proc/meminfo) 1
2930
=== modified file 'src/metadataserver/builtin_scripts/ntp.sh'
--- src/metadataserver/builtin_scripts/ntp.sh 2017-03-23 18:20:00 +0000
+++ src/metadataserver/builtin_scripts/ntp.sh 2017-03-29 23:42:47 +0000
@@ -1,4 +1,4 @@
1#!/bin/sh -e1#!/bin/bash -e
2#2#
3# ntp - Run ntp clock set to verify NTP connectivity.3# ntp - Run ntp clock set to verify NTP connectivity.
4#4#
@@ -24,7 +24,7 @@
24# the configured NTP server is accessible.24# the configured NTP server is accessible.
25e=025e=0
26ntpq -np26ntpq -np
27sudo systemctl stop ntp.service27sudo -n systemctl stop ntp.service
28sudo timeout 10 ntpd -gq || e=$?28sudo -n timeout 10 ntpd -gq || e=$?
29sudo systemctl start ntp.service29sudo -n systemctl start ntp.service
30exit $e30exit $e
3131
=== renamed file 'src/metadataserver/builtin_scripts/stress_ng_cpu_long.sh' => 'src/metadataserver/builtin_scripts/stress-ng-cpu-long.sh'
--- src/metadataserver/builtin_scripts/stress_ng_cpu_long.sh 2017-03-23 18:20:00 +0000
+++ src/metadataserver/builtin_scripts/stress-ng-cpu-long.sh 2017-03-29 23:42:47 +0000
@@ -1,6 +1,6 @@
1#!/bin/sh -e1#!/bin/bash -e
2#2#
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.
4#4#
5# Author: Lee Trager <lee.trager@canonical.com>5# Author: Lee Trager <lee.trager@canonical.com>
6#6#
@@ -19,8 +19,8 @@
19# You should have received a copy of the GNU Affero General Public License19# You should have received a copy of the GNU Affero General Public License
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/>.
2121
22sudo apt-get install -q -y stress-ng22sudo -n apt-get install -q -y stress-ng
23echo
2324
24sudo stress-ng \25sudo -n stress-ng --aggressive -a 0 --class cpu,cpu-cache --ignite-cpu \
25 --aggressive -a 0 --class cpu,cpu-cache --ignite-cpu --log-brief \26 --log-brief --metrics-brief --times --tz --verify --timeout 12h
26 --metrics --times --tz --verify --timeout 12h
2727
=== added file 'src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh'
--- src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh 1970-01-01 00:00:00 +0000
+++ src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh 2017-03-29 23:42:47 +0000
@@ -0,0 +1,32 @@
1#!/bin/bash -e
2#
3# stress-ng-cpu-short - Stress test the CPU for 5 minutes.
4#
5# Author: Lee Trager <lee.trager@canonical.com>
6#
7# Copyright (C) 2017 Canonical
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU Affero General Public License as
11# published by the Free Software Foundation, either version 3 of the
12# License, or (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU Affero General Public License for more details.
18#
19# You should have received a copy of the GNU Affero General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22sudo -n apt-get install -q -y stress-ng
23echo
24
25sudo -n stress-ng --matrix 0 --ignite-cpu --log-brief --metrics-brief --times \
26 --tz --verify --timeout 2m
27echo
28sudo -n stress-ng --cache 0 --ignite-cpu --log-brief --metrics-brief --times \
29 --tz --verify --timeout 1m
30echo
31sudo -n stress-ng --cpu 0 --ignite-cpu --log-brief --metrics-brief --times --tz \
32 --verify --timeout 2m
033
=== renamed file 'src/metadataserver/builtin_scripts/stress_ng_memory_long.sh' => 'src/metadataserver/builtin_scripts/stress-ng-memory-long.sh'
--- src/metadataserver/builtin_scripts/stress_ng_memory_long.sh 2017-03-23 18:20:00 +0000
+++ src/metadataserver/builtin_scripts/stress-ng-memory-long.sh 2017-03-29 23:42:47 +0000
@@ -1,4 +1,4 @@
1#!/bin/sh -e1#!/bin/bash -e
2#2#
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.
4#4#
@@ -19,8 +19,18 @@
19# You should have received a copy of the GNU Affero General Public License19# You should have received a copy of the GNU Affero General Public License
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/>.
2121
22sudo apt-get install -q -y stress-ng22sudo -n apt-get install -q -y stress-ng
2323echo
24sudo stress-ng \24
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.
26 --times --tz --verify --timeout 12h26total_memory=$(awk '/MemAvailable/ { print ($2 - 65536) }' /proc/meminfo)
27threads=$(lscpu --all --parse | grep -v '#' | wc -l)
28memory_per_thread=$(($total_memory / $threads))
29# stress-ng only allows 4GB of memory per thread.
30if [ $memory_per_thread -ge 4194304 ]; then
31 threads=$(($total_memory / 4194304 + 1))
32 memory_per_thread=$(($total_memory / $threads))
33fi
34
35stress-ng --vm $threads --vm-bytes ${memory_per_thread}k --page-in \
36 --log-brief --metrics-brief --times --tz --verify --timeout 12h
2737
=== added file 'src/metadataserver/builtin_scripts/stress-ng-memory-short.sh'
--- src/metadataserver/builtin_scripts/stress-ng-memory-short.sh 1970-01-01 00:00:00 +0000
+++ src/metadataserver/builtin_scripts/stress-ng-memory-short.sh 2017-03-29 23:42:47 +0000
@@ -0,0 +1,36 @@
1#!/bin/bash -e
2#
3# stress-ng-memory-short - Stress test memory for 5 minutes.
4#
5# Author: Lee Trager <lee.trager@canonical.com>
6#
7# Copyright (C) 2017 Canonical
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU Affero General Public License as
11# published by the Free Software Foundation, either version 3 of the
12# License, or (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU Affero General Public License for more details.
18#
19# You should have received a copy of the GNU Affero General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22sudo -n apt-get install -q -y stress-ng
23echo
24
25# Reserve 64M so the test doesn't fail due to the OOM killer.
26total_memory=$(awk '/MemAvailable/ { print ($2 - 65536) }' /proc/meminfo)
27threads=$(lscpu --all --parse | grep -v '#' | wc -l)
28memory_per_thread=$(($total_memory / $threads))
29# stress-ng only allows 4GB of memory per thread.
30if [ $memory_per_thread -ge 4194304 ]; then
31 threads=$(($total_memory / 4194304 + 1))
32 memory_per_thread=$(($total_memory / $threads))
33fi
34
35stress-ng --vm $threads --vm-bytes ${memory_per_thread}k --page-in \
36 --log-brief --metrics-brief --times --tz --verify --timeout 5m
037
=== modified file 'src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py'
--- src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py 2017-03-23 18:20:00 +0000
+++ src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py 2017-03-29 23:42:47 +0000
@@ -34,8 +34,7 @@
34 script_in_db.script.comment)34 script_in_db.script.comment)
35 self.assertItemsEqual(script.tags, script_in_db.tags)35 self.assertItemsEqual(script.tags, script_in_db.tags)
36 self.assertEquals(script.script_type, script_in_db.script_type)36 self.assertEquals(script.script_type, script_in_db.script_type)
37 self.assertEquals(37 self.assertEquals(script.timeout, script_in_db.timeout)
38 timedelta(seconds=script.timeout), script_in_db.timeout)
39 self.assertEquals(script.destructive, script_in_db.destructive)38 self.assertEquals(script.destructive, script_in_db.destructive)
40 self.assertTrue(script_in_db.default)39 self.assertTrue(script_in_db.default)
4140
@@ -79,7 +78,8 @@
7978
80 def test_update_doesnt_revert_script(self):79 def test_update_doesnt_revert_script(self):
81 load_builtin_scripts()80 load_builtin_scripts()
82 update_script_values = random.choice(BUILTIN_SCRIPTS)81 update_script_index = random.randint(0, len(BUILTIN_SCRIPTS) - 2)
82 update_script_values = BUILTIN_SCRIPTS[update_script_index]
83 script = Script.objects.get(name=update_script_values.name)83 script = Script.objects.get(name=update_script_values.name)
84 # Put fake new data in to simulate another MAAS region updating84 # Put fake new data in to simulate another MAAS region updating
85 # to a newer version.85 # to a newer version.
@@ -99,6 +99,14 @@
99 script.timeout = user_timeout99 script.timeout = user_timeout
100 script.save()100 script.save()
101101
102 # Test that subsequent scripts still get updated
103 second_update_script_values = BUILTIN_SCRIPTS[update_script_index + 1]
104 second_script = Script.objects.get(
105 name=second_update_script_values.name)
106 # Put fake old data in to simulate updating a script.
107 second_script.title = factory.make_string()
108 second_script.save()
109
102 load_builtin_scripts()110 load_builtin_scripts()
103 script = reload_object(script)111 script = reload_object(script)
104112
@@ -111,3 +119,7 @@
111 self.assertEquals(user_tags, script.tags)119 self.assertEquals(user_tags, script.tags)
112 self.assertEquals(user_timeout, script.timeout)120 self.assertEquals(user_timeout, script.timeout)
113 self.assertTrue(script.default)121 self.assertTrue(script.default)
122
123 second_script = reload_object(second_script)
124 self.assertEquals(
125 second_update_script_values.title, second_script.title)
114126
=== modified file 'src/metadataserver/user_data/templates/base_user_data.sh'
--- src/metadataserver/user_data/templates/base_user_data.sh 2017-02-16 00:27:35 +0000
+++ src/metadataserver/user_data/templates/base_user_data.sh 2017-03-29 23:42:47 +0000
@@ -1,4 +1,4 @@
1#!/bin/sh1#!/bin/bash
2#2#
3# This script carries inside it multiple files. When executed, it creates3# This script carries inside it multiple files. When executed, it creates
4# the files into a temporary directory and uses them to execute commands4# the files into a temporary directory and uses them to execute commands
55
=== modified file 'src/metadataserver/user_data/templates/snippets/maas_enlist.sh'
--- src/metadataserver/user_data/templates/snippets/maas_enlist.sh 2017-03-08 10:10:12 +0000
+++ src/metadataserver/user_data/templates/snippets/maas_enlist.sh 2017-03-29 23:42:47 +0000
@@ -1,4 +1,4 @@
1#!/bin/sh1#!/bin/bash
2#2#
3# maas-enlist: MAAS Enlistment Tool3# maas-enlist: MAAS Enlistment Tool
4#4#
55
=== modified file 'src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py'
--- src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py 2017-03-03 00:50:43 +0000
+++ src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py 2017-03-29 23:42:47 +0000
@@ -233,6 +233,12 @@
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")
234 url = "%s/%s/" % (url, args.apiver)234 url = "%s/%s/" % (url, args.apiver)
235235
236 # Disable the OOM killer on the runner process, the OOM killer will still
237 # go after any tests spawned.
238 oom_score_adj_path = os.path.join(
239 '/proc', str(os.getpid()), 'oom_score_adj')
240 open(oom_score_adj_path, 'w').write('-1000')
241
236 heart_beat = HeartBeat(url, creds)242 heart_beat = HeartBeat(url, creds)
237 heart_beat.start()243 heart_beat.start()
238244
239245
=== modified file 'src/provisioningserver/refresh/node_info_scripts.py'
--- src/provisioningserver/refresh/node_info_scripts.py 2017-03-29 21:13:51 +0000
+++ src/provisioningserver/refresh/node_info_scripts.py 2017-03-29 23:42:47 +0000
@@ -60,19 +60,19 @@
6060
61# Built-in script to run lshw.61# Built-in script to run lshw.
62LSHW_SCRIPT = dedent("""\62LSHW_SCRIPT = dedent("""\
63 #!/bin/sh63 #!/bin/bash
64 sudo -n /usr/bin/lshw -xml64 sudo -n /usr/bin/lshw -xml
65 """)65 """)
6666
67# Built-in script to run `ip addr`67# Built-in script to run `ip addr`
68IPADDR_SCRIPT = dedent("""\68IPADDR_SCRIPT = dedent("""\
69 #!/bin/sh69 #!/bin/bash
70 ip addr70 ip addr
71 """)71 """)
7272
73# Built-in script to detect virtual instances.73# Built-in script to detect virtual instances.
74VIRTUALITY_SCRIPT = dedent("""\74VIRTUALITY_SCRIPT = dedent("""\
75 #!/bin/sh75 #!/bin/bash
76 # In Bourne Shell `type -p` does not work; `which` is closest.76 # In Bourne Shell `type -p` does not work; `which` is closest.
77 if which systemd-detect-virt > /dev/null; then77 if which systemd-detect-virt > /dev/null; then
78 # systemd-detect-virt prints "none" and returns nonzero if78 # systemd-detect-virt prints "none" and returns nonzero if
@@ -90,7 +90,7 @@
90 """)90 """)
9191
92CPUINFO_SCRIPT = dedent("""\92CPUINFO_SCRIPT = dedent("""\
93 #!/bin/sh93 #!/bin/bash
94 # Gather the standard output as it has some extra info94 # Gather the standard output as it has some extra info
95 lscpu95 lscpu
96 # Gather the machine readable output for processing96 # Gather the machine readable output for processing
@@ -108,7 +108,7 @@
108 """)108 """)
109109
110SRIOV_SCRIPT = dedent("""\110SRIOV_SCRIPT = dedent("""\
111 #!/bin/sh111 #!/bin/bash
112 for file in $(find /sys/devices/ -name sriov_numvfs); do112 for file in $(find /sys/devices/ -name sriov_numvfs); do
113 dir=$(dirname "$file")113 dir=$(dirname "$file")
114 for eth in $(ls "$dir/net/"); do114 for eth in $(ls "$dir/net/"); do
@@ -388,7 +388,7 @@
388388
389LIST_MODALIASES_OUTPUT_NAME = '00-maas-04-list-modaliases'389LIST_MODALIASES_OUTPUT_NAME = '00-maas-04-list-modaliases'
390LIST_MODALIASES_SCRIPT = dedent("""\390LIST_MODALIASES_SCRIPT = dedent("""\
391 #!/bin/sh391 #!/bin/bash
392 find /sys -name modalias -print0 | xargs -0 cat | sort -u392 find /sys -name modalias -print0 | xargs -0 cat | sort -u
393 """)393 """)
394394
395395
=== modified file 'src/provisioningserver/refresh/tests/test_node_info_scripts.py'
--- src/provisioningserver/refresh/tests/test_node_info_scripts.py 2017-03-23 18:20:00 +0000
+++ src/provisioningserver/refresh/tests/test_node_info_scripts.py 2017-03-29 23:42:47 +0000
@@ -944,7 +944,7 @@
944 self.sysdv.unlink()944 self.sysdv.unlink()
945 sysdv_name = factory.make_name("virt")945 sysdv_name = factory.make_name("virt")
946 with self.sysdv.open("w") as fd:946 with self.sysdv.open("w") as fd:
947 fd.write("#!/bin/sh\n")947 fd.write("#!/bin/bash\n")
948 fd.write("echo %s\n" % sysdv_name)948 fd.write("echo %s\n" % sysdv_name)
949 fd.write("exit 1\n")949 fd.write("exit 1\n")
950 self.sysdv.chmod(0o700)950 self.sysdv.chmod(0o700)
951951
=== modified file 'src/provisioningserver/refresh/tests/test_refresh.py'
--- src/provisioningserver/refresh/tests/test_refresh.py 2017-03-03 00:50:43 +0000
+++ src/provisioningserver/refresh/tests/test_refresh.py 2017-03-29 23:42:47 +0000
@@ -137,7 +137,7 @@
137 if script_name is None:137 if script_name is None:
138 script_name = factory.make_name('script_name')138 script_name = factory.make_name('script_name')
139 TEST_SCRIPT = dedent("""\139 TEST_SCRIPT = dedent("""\
140 #!/bin/sh140 #!/bin/bash
141 echo 'test script'141 echo 'test script'
142 """)142 """)
143 refresh.NODE_INFO_SCRIPTS = OrderedDict([143 refresh.NODE_INFO_SCRIPTS = OrderedDict([
@@ -151,7 +151,7 @@
151 if script_name is None:151 if script_name is None:
152 script_name = factory.make_name('script_name')152 script_name = factory.make_name('script_name')
153 TEST_SCRIPT = dedent("""\153 TEST_SCRIPT = dedent("""\
154 #!/bin/sh154 #!/bin/bash
155 echo 'test failed'155 echo 'test failed'
156 exit 1156 exit 1
157 """)157 """)
158158
=== modified file 'src/provisioningserver/rpc/tests/test_clusterservice.py'
--- src/provisioningserver/rpc/tests/test_clusterservice.py 2017-03-27 14:35:23 +0000
+++ src/provisioningserver/rpc/tests/test_clusterservice.py 2017-03-29 23:42:47 +0000
@@ -2479,7 +2479,7 @@
2479 @inlineCallbacks2479 @inlineCallbacks
2480 def test_spawnProcessAndNullifyStdout_nullifies_stdout(self):2480 def test_spawnProcessAndNullifyStdout_nullifies_stdout(self):
2481 done, protocol = makeDeferredWithProcessProtocol()2481 done, protocol = makeDeferredWithProcessProtocol()
2482 args = [b"/bin/sh", b'-c', b"echo foo"]2482 args = [b"/bin/bash", b'-c', b"echo foo"]
2483 outReceived = Mock()2483 outReceived = Mock()
2484 protocol.outReceived = outReceived2484 protocol.outReceived = outReceived
2485 spawnProcessAndNullifyStdout(protocol, args)2485 spawnProcessAndNullifyStdout(protocol, args)
@@ -2489,7 +2489,7 @@
2489 @inlineCallbacks2489 @inlineCallbacks
2490 def test_spawnProcessAndNullifyStdout_captures_stderr(self):2490 def test_spawnProcessAndNullifyStdout_captures_stderr(self):
2491 done, protocol = makeDeferredWithProcessProtocol()2491 done, protocol = makeDeferredWithProcessProtocol()
2492 args = [b"/bin/sh", b'-c', b"echo foo >&2"]2492 args = [b"/bin/bash", b'-c', b"echo foo >&2"]
2493 errReceived = Mock()2493 errReceived = Mock()
2494 protocol.errReceived = errReceived2494 protocol.errReceived = errReceived
2495 spawnProcessAndNullifyStdout(protocol, args)2495 spawnProcessAndNullifyStdout(protocol, args)
@@ -2500,7 +2500,7 @@
2500 def test_executeScanNetworksSubprocess(self):2500 def test_executeScanNetworksSubprocess(self):
2501 mock_scan_args = self.patch(2501 mock_scan_args = self.patch(
2502 clusterservice, 'get_scan_all_networks_args')2502 clusterservice, 'get_scan_all_networks_args')
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"]
2504 mock_log_msg = self.patch(clusterservice.log, 'msg')2504 mock_log_msg = self.patch(clusterservice.log, 'msg')
2505 d = executeScanNetworksSubprocess()2505 d = executeScanNetworksSubprocess()
2506 yield d2506 yield d