blob: d89731c69257ca49afd4bc5ffbdec5b89e96935d [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
2# SPDX-License-Identifier: MIT
3#
4
Brad Bishopd7bf8c12018-02-25 22:55:05 -05005from oeqa.selftest.case import OESelftestTestCase
6from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars, runqemu
7from oeqa.utils.sshcontrol import SSHControl
Brad Bishopd7bf8c12018-02-25 22:55:05 -05008import os
9import re
10import tempfile
11import shutil
Brad Bishop19323692019-04-05 15:28:33 -040012import oe.lsb
Andrew Geissler82c905d2020-04-13 13:39:40 -050013from oeqa.core.decorator.data import skipIfNotQemu
Brad Bishopd7bf8c12018-02-25 22:55:05 -050014
15class TestExport(OESelftestTestCase):
16
17 @classmethod
18 def tearDownClass(cls):
19 runCmd("rm -rf /tmp/sdk")
20 super(TestExport, cls).tearDownClass()
21
Brad Bishopd7bf8c12018-02-25 22:55:05 -050022 def test_testexport_basic(self):
23 """
24 Summary: Check basic testexport functionality with only ping test enabled.
25 Expected: 1. testexport directory must be created.
26 2. runexported.py must run without any error/exception.
27 3. ping test must succeed.
28 Product: oe-core
29 Author: Mariano Lopez <mariano.lopez@intel.com>
30 """
31
32 features = 'INHERIT += "testexport"\n'
33 # These aren't the actual IP addresses but testexport class needs something defined
34 features += 'TEST_SERVER_IP = "192.168.7.1"\n'
35 features += 'TEST_TARGET_IP = "192.168.7.1"\n'
36 features += 'TEST_SUITES = "ping"\n'
37 self.write_config(features)
38
39 # Build tesexport for core-image-minimal
40 bitbake('core-image-minimal')
41 bitbake('-c testexport core-image-minimal')
42
43 testexport_dir = get_bb_var('TEST_EXPORT_DIR', 'core-image-minimal')
44
45 # Verify if TEST_EXPORT_DIR was created
46 isdir = os.path.isdir(testexport_dir)
47 self.assertEqual(True, isdir, 'Failed to create testexport dir: %s' % testexport_dir)
48
49 with runqemu('core-image-minimal') as qemu:
50 # Attempt to run runexported.py to perform ping test
51 test_path = os.path.join(testexport_dir, "oe-test")
52 data_file = os.path.join(testexport_dir, 'data', 'testdata.json')
53 manifest = os.path.join(testexport_dir, 'data', 'manifest')
54 cmd = ("%s runtime --test-data-file %s --packages-manifest %s "
55 "--target-ip %s --server-ip %s --quiet"
56 % (test_path, data_file, manifest, qemu.ip, qemu.server_ip))
57 result = runCmd(cmd)
58 # Verify ping test was succesful
59 self.assertEqual(0, result.status, 'oe-test runtime returned a non 0 status')
60
Brad Bishopd7bf8c12018-02-25 22:55:05 -050061 def test_testexport_sdk(self):
62 """
63 Summary: Check sdk functionality for testexport.
64 Expected: 1. testexport directory must be created.
65 2. SDK tarball must exists.
66 3. Uncompressing of tarball must succeed.
67 4. Check if the SDK directory is added to PATH.
68 5. Run tar from the SDK directory.
69 Product: oe-core
70 Author: Mariano Lopez <mariano.lopez@intel.com>
71 """
72
73 features = 'INHERIT += "testexport"\n'
74 # These aren't the actual IP addresses but testexport class needs something defined
75 features += 'TEST_SERVER_IP = "192.168.7.1"\n'
76 features += 'TEST_TARGET_IP = "192.168.7.1"\n'
77 features += 'TEST_SUITES = "ping"\n'
78 features += 'TEST_EXPORT_SDK_ENABLED = "1"\n'
79 features += 'TEST_EXPORT_SDK_PACKAGES = "nativesdk-tar"\n'
80 self.write_config(features)
81
82 # Build tesexport for core-image-minimal
83 bitbake('core-image-minimal')
84 bitbake('-c testexport core-image-minimal')
85
86 needed_vars = ['TEST_EXPORT_DIR', 'TEST_EXPORT_SDK_DIR', 'TEST_EXPORT_SDK_NAME']
87 bb_vars = get_bb_vars(needed_vars, 'core-image-minimal')
88 testexport_dir = bb_vars['TEST_EXPORT_DIR']
89 sdk_dir = bb_vars['TEST_EXPORT_SDK_DIR']
90 sdk_name = bb_vars['TEST_EXPORT_SDK_NAME']
91
92 # Check for SDK
93 tarball_name = "%s.sh" % sdk_name
94 tarball_path = os.path.join(testexport_dir, sdk_dir, tarball_name)
95 msg = "Couldn't find SDK tarball: %s" % tarball_path
96 self.assertEqual(os.path.isfile(tarball_path), True, msg)
97
98 # Extract SDK and run tar from SDK
99 result = runCmd("%s -y -d /tmp/sdk" % tarball_path)
100 self.assertEqual(0, result.status, "Couldn't extract SDK")
101
102 env_script = result.output.split()[-1]
103 result = runCmd(". %s; which tar" % env_script, shell=True)
104 self.assertEqual(0, result.status, "Couldn't setup SDK environment")
105 is_sdk_tar = True if "/tmp/sdk" in result.output else False
106 self.assertTrue(is_sdk_tar, "Couldn't setup SDK environment")
107
108 tar_sdk = result.output
109 result = runCmd("%s --version" % tar_sdk)
110 self.assertEqual(0, result.status, "Couldn't run tar from SDK")
111
112
113class TestImage(OESelftestTestCase):
114
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500115 def test_testimage_install(self):
116 """
117 Summary: Check install packages functionality for testimage/testexport.
118 Expected: 1. Import tests from a directory other than meta.
119 2. Check install/uninstall of socat.
120 Product: oe-core
121 Author: Mariano Lopez <mariano.lopez@intel.com>
122 """
123 if get_bb_var('DISTRO') == 'poky-tiny':
124 self.skipTest('core-image-full-cmdline not buildable for poky-tiny')
125
126 features = 'INHERIT += "testimage"\n'
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800127 features += 'IMAGE_INSTALL_append = " libssl"\n'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500128 features += 'TEST_SUITES = "ping ssh selftest"\n'
129 self.write_config(features)
130
131 # Build core-image-sato and testimage
132 bitbake('core-image-full-cmdline socat')
133 bitbake('-c testimage core-image-full-cmdline')
134
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500135 def test_testimage_dnf(self):
136 """
137 Summary: Check package feeds functionality for dnf
138 Expected: 1. Check that remote package feeds can be accessed
139 Product: oe-core
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800140 Author: Alexander Kanavin <alex.kanavin@gmail.com>
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500141 """
142 if get_bb_var('DISTRO') == 'poky-tiny':
143 self.skipTest('core-image-full-cmdline not buildable for poky-tiny')
144
145 features = 'INHERIT += "testimage"\n'
146 features += 'TEST_SUITES = "ping ssh dnf_runtime dnf.DnfBasicTest.test_dnf_help"\n'
147 # We don't yet know what the server ip and port will be - they will be patched
148 # in at the start of the on-image test
149 features += 'PACKAGE_FEED_URIS = "http://bogus_ip:bogus_port"\n'
150 features += 'EXTRA_IMAGE_FEATURES += "package-management"\n'
151 features += 'PACKAGE_CLASSES = "package_rpm"\n'
152
Brad Bishop6f8dcde2018-10-16 10:47:12 +0800153 bitbake('gnupg-native -c addto_recipe_sysroot')
154
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500155 # Enable package feed signing
156 self.gpg_home = tempfile.mkdtemp(prefix="oeqa-feed-sign-")
Brad Bishop96ff1982019-08-19 13:50:42 -0400157 self.track_for_cleanup(self.gpg_home)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500158 signing_key_dir = os.path.join(self.testlayer_path, 'files', 'signing')
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500159 runCmd('gpgconf --list-dirs --homedir %s; gpg -v --batch --homedir %s --import %s' % (self.gpg_home, self.gpg_home, os.path.join(signing_key_dir, 'key.secret')), native_sysroot=get_bb_var("RECIPE_SYSROOT_NATIVE", "gnupg-native"), shell=True)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500160 features += 'INHERIT += "sign_package_feed"\n'
161 features += 'PACKAGE_FEED_GPG_NAME = "testuser"\n'
162 features += 'PACKAGE_FEED_GPG_PASSPHRASE_FILE = "%s"\n' % os.path.join(signing_key_dir, 'key.passphrase')
163 features += 'GPG_PATH = "%s"\n' % self.gpg_home
164 self.write_config(features)
165
166 # Build core-image-sato and testimage
167 bitbake('core-image-full-cmdline socat')
168 bitbake('-c testimage core-image-full-cmdline')
169
Andrew Geissler82c905d2020-04-13 13:39:40 -0500170 def test_testimage_virgl_gtk_sdl(self):
Brad Bishop19323692019-04-05 15:28:33 -0400171 """
Andrew Geissler82c905d2020-04-13 13:39:40 -0500172 Summary: Check host-assisted accelerate OpenGL functionality in qemu with gtk and SDL frontends
Brad Bishop19323692019-04-05 15:28:33 -0400173 Expected: 1. Check that virgl kernel driver is loaded and 3d acceleration is enabled
174 2. Check that kmscube demo runs without crashing.
175 Product: oe-core
176 Author: Alexander Kanavin <alex.kanavin@gmail.com>
177 """
178 if "DISPLAY" not in os.environ:
179 self.skipTest("virgl gtk test must be run inside a X session")
180 distro = oe.lsb.distro_identifier()
181 if distro and distro == 'debian-8':
182 self.skipTest('virgl isn\'t working with Debian 8')
Andrew Geisslerc182c622020-05-15 14:13:32 -0500183 if distro and distro == 'debian-9':
184 self.skipTest('virgl isn\'t working with Debian 9')
Brad Bishop64c979e2019-11-04 13:55:29 -0500185 if distro and distro == 'centos-7':
186 self.skipTest('virgl isn\'t working with Centos 7')
Andrew Geissler82c905d2020-04-13 13:39:40 -0500187 if distro and distro == 'opensuseleap-15.0':
188 self.skipTest('virgl isn\'t working with Opensuse 15.0')
Brad Bishop19323692019-04-05 15:28:33 -0400189
190 qemu_packageconfig = get_bb_var('PACKAGECONFIG', 'qemu-system-native')
Andrew Geissler1e34c2d2020-05-29 16:02:59 -0500191 qemu_distrofeatures = get_bb_var('DISTRO_FEATURES', 'qemu-system-native')
Brad Bishop19323692019-04-05 15:28:33 -0400192 features = 'INHERIT += "testimage"\n'
193 if 'gtk+' not in qemu_packageconfig:
194 features += 'PACKAGECONFIG_append_pn-qemu-system-native = " gtk+"\n'
Andrew Geissler82c905d2020-04-13 13:39:40 -0500195 if 'sdl' not in qemu_packageconfig:
196 features += 'PACKAGECONFIG_append_pn-qemu-system-native = " sdl"\n'
Andrew Geissler1e34c2d2020-05-29 16:02:59 -0500197 if 'opengl' not in qemu_distrofeatures:
198 features += 'DISTRO_FEATURES_append = " opengl"\n'
Brad Bishop19323692019-04-05 15:28:33 -0400199 features += 'TEST_SUITES = "ping ssh virgl"\n'
200 features += 'IMAGE_FEATURES_append = " ssh-server-dropbear"\n'
201 features += 'IMAGE_INSTALL_append = " kmscube"\n'
Andrew Geissler82c905d2020-04-13 13:39:40 -0500202 features_gtk = features + 'TEST_RUNQEMUPARAMS = "gtk gl"\n'
203 self.write_config(features_gtk)
204 bitbake('core-image-minimal')
205 bitbake('-c testimage core-image-minimal')
206 features_sdl = features + 'TEST_RUNQEMUPARAMS = "sdl gl"\n'
207 self.write_config(features_sdl)
Brad Bishop19323692019-04-05 15:28:33 -0400208 bitbake('core-image-minimal')
209 bitbake('-c testimage core-image-minimal')
210
Brad Bishop19323692019-04-05 15:28:33 -0400211 def test_testimage_virgl_headless(self):
212 """
213 Summary: Check host-assisted accelerate OpenGL functionality in qemu with egl-headless frontend
214 Expected: 1. Check that virgl kernel driver is loaded and 3d acceleration is enabled
215 2. Check that kmscube demo runs without crashing.
216 Product: oe-core
217 Author: Alexander Kanavin <alex.kanavin@gmail.com>
218 """
219 import subprocess, os
220 try:
221 content = os.listdir("/dev/dri")
222 if len([i for i in content if i.startswith('render')]) == 0:
223 self.skipTest("No render nodes found in /dev/dri: %s" %(content))
224 except FileNotFoundError:
225 self.skipTest("/dev/dri directory does not exist; no render nodes available on this machine.")
226 try:
227 dripath = subprocess.check_output("pkg-config --variable=dridriverdir dri", shell=True)
228 except subprocess.CalledProcessError as e:
229 self.skipTest("Could not determine the path to dri drivers on the host via pkg-config.\nPlease install Mesa development files (particularly, dri.pc) on the host machine.")
Andrew Geissler1e34c2d2020-05-29 16:02:59 -0500230 qemu_distrofeatures = get_bb_var('DISTRO_FEATURES', 'qemu-system-native')
Brad Bishop19323692019-04-05 15:28:33 -0400231 features = 'INHERIT += "testimage"\n'
Andrew Geissler1e34c2d2020-05-29 16:02:59 -0500232 if 'opengl' not in qemu_distrofeatures:
233 features += 'DISTRO_FEATURES_append = " opengl"\n'
Brad Bishop19323692019-04-05 15:28:33 -0400234 features += 'TEST_SUITES = "ping ssh virgl"\n'
235 features += 'IMAGE_FEATURES_append = " ssh-server-dropbear"\n'
236 features += 'IMAGE_INSTALL_append = " kmscube"\n'
237 features += 'TEST_RUNQEMUPARAMS = "egl-headless"\n'
238 self.write_config(features)
239 bitbake('core-image-minimal')
240 bitbake('-c testimage core-image-minimal')
241
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500242class Postinst(OESelftestTestCase):
Andrew Geissler82c905d2020-04-13 13:39:40 -0500243
244 def init_manager_loop(self, init_manager):
245 import oe.path
246
247 vars = get_bb_vars(("IMAGE_ROOTFS", "sysconfdir"), "core-image-minimal")
248 rootfs = vars["IMAGE_ROOTFS"]
249 self.assertIsNotNone(rootfs)
250 sysconfdir = vars["sysconfdir"]
251 self.assertIsNotNone(sysconfdir)
252 # Need to use oe.path here as sysconfdir starts with /
253 hosttestdir = oe.path.join(rootfs, sysconfdir, "postinst-test")
254 targettestdir = os.path.join(sysconfdir, "postinst-test")
255
256 for classes in ("package_rpm", "package_deb", "package_ipk"):
257 with self.subTest(init_manager=init_manager, package_class=classes):
258 features = 'CORE_IMAGE_EXTRA_INSTALL = "postinst-delayed-b"\n'
259 features += 'IMAGE_FEATURES += "package-management empty-root-password"\n'
260 features += 'PACKAGE_CLASSES = "%s"\n' % classes
261 if init_manager == "systemd":
262 features += 'DISTRO_FEATURES_append = " systemd"\n'
263 features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n'
264 features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n'
265 features += 'VIRTUAL-RUNTIME_initscripts = ""\n'
266 self.write_config(features)
267
268 bitbake('core-image-minimal')
269
270 self.assertTrue(os.path.isfile(os.path.join(hosttestdir, "rootfs")),
271 "rootfs state file was not created")
272
273 with runqemu('core-image-minimal') as qemu:
274 # Make the test echo a string and search for that as
275 # run_serial()'s status code is useless.'
276 for filename in ("rootfs", "delayed-a", "delayed-b"):
277 status, output = qemu.run_serial("test -f %s && echo found" % os.path.join(targettestdir, filename))
278 self.assertEqual(output, "found", "%s was not present on boot" % filename)
279
280
281
282 @skipIfNotQemu('qemuall', 'Test only runs in qemu')
283 def test_postinst_rootfs_and_boot_sysvinit(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500284 """
285 Summary: The purpose of this test case is to verify Post-installation
286 scripts are called when rootfs is created and also test
287 that script can be delayed to run at first boot.
288 Dependencies: NA
289 Steps: 1. Add proper configuration to local.conf file
290 2. Build a "core-image-minimal" image
291 3. Verify that file created by postinst_rootfs recipe is
292 present on rootfs dir.
293 4. Boot the image created on qemu and verify that the file
294 created by postinst_boot recipe is present on image.
295 Expected: The files are successfully created during rootfs and boot
296 time for 3 different package managers: rpm,ipk,deb and
Andrew Geissler82c905d2020-04-13 13:39:40 -0500297 for initialization managers: sysvinit.
298
299 """
300 self.init_manager_loop("sysvinit")
301
302
303 @skipIfNotQemu('qemuall', 'Test only runs in qemu')
304 def test_postinst_rootfs_and_boot_systemd(self):
305 """
306 Summary: The purpose of this test case is to verify Post-installation
307 scripts are called when rootfs is created and also test
308 that script can be delayed to run at first boot.
309 Dependencies: NA
310 Steps: 1. Add proper configuration to local.conf file
311 2. Build a "core-image-minimal" image
312 3. Verify that file created by postinst_rootfs recipe is
313 present on rootfs dir.
314 4. Boot the image created on qemu and verify that the file
315 created by postinst_boot recipe is present on image.
316 Expected: The files are successfully created during rootfs and boot
317 time for 3 different package managers: rpm,ipk,deb and
318 for initialization managers: systemd.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500319
320 """
Brad Bishop316dfdd2018-06-25 12:45:53 -0400321
Andrew Geissler82c905d2020-04-13 13:39:40 -0500322 self.init_manager_loop("systemd")
Brad Bishop316dfdd2018-06-25 12:45:53 -0400323
324
325 def test_failing_postinst(self):
326 """
327 Summary: The purpose of this test case is to verify that post-installation
328 scripts that contain errors are properly reported.
329 Expected: The scriptlet failure is properly reported.
330 The file that is created after the error in the scriptlet is not present.
331 Product: oe-core
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800332 Author: Alexander Kanavin <alex.kanavin@gmail.com>
Brad Bishop316dfdd2018-06-25 12:45:53 -0400333 """
334
335 import oe.path
336
337 vars = get_bb_vars(("IMAGE_ROOTFS", "sysconfdir"), "core-image-minimal")
338 rootfs = vars["IMAGE_ROOTFS"]
339 self.assertIsNotNone(rootfs)
340 sysconfdir = vars["sysconfdir"]
341 self.assertIsNotNone(sysconfdir)
342 # Need to use oe.path here as sysconfdir starts with /
343 hosttestdir = oe.path.join(rootfs, sysconfdir, "postinst-test")
344
345 for classes in ("package_rpm", "package_deb", "package_ipk"):
346 with self.subTest(package_class=classes):
347 features = 'CORE_IMAGE_EXTRA_INSTALL = "postinst-rootfs-failing"\n'
348 features += 'PACKAGE_CLASSES = "%s"\n' % classes
349 self.write_config(features)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800350 bb_result = bitbake('core-image-minimal', ignore_status=True)
351 self.assertGreaterEqual(bb_result.output.find("Postinstall scriptlets of ['postinst-rootfs-failing'] have failed."), 0,
Brad Bishop316dfdd2018-06-25 12:45:53 -0400352 "Warning about a failed scriptlet not found in bitbake output: %s" %(bb_result.output))
353
354 self.assertTrue(os.path.isfile(os.path.join(hosttestdir, "rootfs-before-failure")),
355 "rootfs-before-failure file was not created")
356 self.assertFalse(os.path.isfile(os.path.join(hosttestdir, "rootfs-after-failure")),
357 "rootfs-after-failure file was created")
358
Brad Bishop1d80a2e2019-11-15 16:35:03 -0500359class SystemTap(OESelftestTestCase):
360 """
361 Summary: The purpose of this test case is to verify native crosstap
362 works while talking to a target.
363 Expected: The script should successfully connect to the qemu machine
364 and run some systemtap examples on a qemu machine.
365 """
366
367 @classmethod
368 def setUpClass(cls):
369 super(SystemTap, cls).setUpClass()
370 cls.image = "core-image-minimal"
371
372 def default_config(self):
373 return """
374# These aren't the actual IP addresses but testexport class needs something defined
375TEST_SERVER_IP = "192.168.7.1"
376TEST_TARGET_IP = "192.168.7.2"
377
378EXTRA_IMAGE_FEATURES += "tools-profile dbg-pkgs"
379IMAGE_FEATURES_append = " ssh-server-dropbear"
380
381# enables kernel debug symbols
382KERNEL_EXTRA_FEATURES_append = " features/debug/debug-kernel.scc"
383KERNEL_EXTRA_FEATURES_append = " features/systemtap/systemtap.scc"
384
385# add systemtap run-time into target image if it is not there yet
386IMAGE_INSTALL_append = " systemtap"
387"""
388
389 def test_crosstap_helloworld(self):
390 self.write_config(self.default_config())
391 bitbake('systemtap-native')
392 systemtap_examples = os.path.join(get_bb_var("WORKDIR","systemtap-native"), "usr/share/systemtap/examples")
393 bitbake(self.image)
394
395 with runqemu(self.image) as qemu:
396 cmd = "crosstap -r root@192.168.7.2 -s %s/general/helloworld.stp " % systemtap_examples
397 result = runCmd(cmd)
398 self.assertEqual(0, result.status, 'crosstap helloworld returned a non 0 status:%s' % result.output)
399
400 def test_crosstap_pstree(self):
401 self.write_config(self.default_config())
402
403 bitbake('systemtap-native')
404 systemtap_examples = os.path.join(get_bb_var("WORKDIR","systemtap-native"), "usr/share/systemtap/examples")
405 bitbake(self.image)
406
407 with runqemu(self.image) as qemu:
408 cmd = "crosstap -r root@192.168.7.2 -s %s/process/pstree.stp" % systemtap_examples
409 result = runCmd(cmd)
410 self.assertEqual(0, result.status, 'crosstap pstree returned a non 0 status:%s' % result.output)
411
412 def test_crosstap_syscalls_by_proc(self):
413 self.write_config(self.default_config())
414
415 bitbake('systemtap-native')
416 systemtap_examples = os.path.join(get_bb_var("WORKDIR","systemtap-native"), "usr/share/systemtap/examples")
417 bitbake(self.image)
418
419 with runqemu(self.image) as qemu:
420 cmd = "crosstap -r root@192.168.7.2 -s %s/process/ syscalls_by_proc.stp" % systemtap_examples
421 result = runCmd(cmd)
422 self.assertEqual(0, result.status, 'crosstap syscalls_by_proc returned a non 0 status:%s' % result.output)
423
424 def test_crosstap_syscalls_by_pid(self):
425 self.write_config(self.default_config())
426
427 bitbake('systemtap-native')
428 systemtap_examples = os.path.join(get_bb_var("WORKDIR","systemtap-native"), "usr/share/systemtap/examples")
429 bitbake(self.image)
430
431 with runqemu(self.image) as qemu:
432 cmd = "crosstap -r root@192.168.7.2 -s %s/process/ syscalls_by_pid.stp" % systemtap_examples
433 result = runCmd(cmd)
434 self.assertEqual(0, result.status, 'crosstap syscalls_by_pid returned a non 0 status:%s' % result.output)
435