diff options
Diffstat (limited to 'meta/lib/oeqa')
-rw-r--r-- | meta/lib/oeqa/selftest/imagefeatures.py | 96 | ||||
-rw-r--r-- | meta/lib/oeqa/utils/commands.py | 49 |
2 files changed, 67 insertions, 78 deletions
diff --git a/meta/lib/oeqa/selftest/imagefeatures.py b/meta/lib/oeqa/selftest/imagefeatures.py index 1795b7bcf3..d48435fedf 100644 --- a/meta/lib/oeqa/selftest/imagefeatures.py +++ b/meta/lib/oeqa/selftest/imagefeatures.py | |||
@@ -1,20 +1,18 @@ | |||
1 | from oeqa.selftest.base import oeSelfTest | 1 | from oeqa.selftest.base import oeSelfTest |
2 | from oeqa.utils.commands import runCmd, bitbake, get_bb_var | 2 | from oeqa.utils.commands import runCmd, bitbake, get_bb_var, runqemu |
3 | from oeqa.utils.decorators import testcase | 3 | from oeqa.utils.decorators import testcase |
4 | import pexpect | 4 | from oeqa.utils.sshcontrol import SSHControl |
5 | from os.path import isfile | 5 | from os.path import isfile |
6 | from os import system, killpg | 6 | from os import system |
7 | import glob | 7 | import glob |
8 | import signal | 8 | import os |
9 | 9 | import sys | |
10 | import logging | ||
10 | 11 | ||
11 | class ImageFeatures(oeSelfTest): | 12 | class ImageFeatures(oeSelfTest): |
12 | 13 | ||
13 | test_user = 'tester' | 14 | test_user = 'tester' |
14 | root_user = 'root' | 15 | root_user = 'root' |
15 | prompt = r'qemux86:\S+[$#]\s+' | ||
16 | ssh_cmd = "ssh {} -l {} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" | ||
17 | get_ip_patt = r'\s+ip=(?P<qemu_ip>(\d+.){3}\d+)::' | ||
18 | 16 | ||
19 | @testcase(1107) | 17 | @testcase(1107) |
20 | def test_non_root_user_can_connect_via_ssh_without_password(self): | 18 | def test_non_root_user_can_connect_via_ssh_without_password(self): |
@@ -37,41 +35,12 @@ class ImageFeatures(oeSelfTest): | |||
37 | # Build a core-image-minimal | 35 | # Build a core-image-minimal |
38 | bitbake('core-image-minimal') | 36 | bitbake('core-image-minimal') |
39 | 37 | ||
40 | # Boot qemu image | 38 | with runqemu("core-image-minimal", self) as qemu: |
41 | proc_qemu = pexpect.spawn('runqemu qemux86 nographic') | 39 | # Attempt to ssh with each user into qemu with empty password |
42 | try: | 40 | for user in [self.root_user, self.test_user]: |
43 | proc_qemu.expect(self.get_ip_patt, timeout=100) | 41 | ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user=user) |
44 | qemu_ip = proc_qemu.match.group('qemu_ip') | 42 | status, output = ssh.run("true") |
45 | proc_qemu.expect('qemux86 login:', timeout=100) | 43 | self.assertEqual(status, 0, 'ssh to user %s failed with %s' % (user, output)) |
46 | except Exception as e: | ||
47 | try: | ||
48 | killpg(proc_qemu.pid, signal.SIGTERM) | ||
49 | except: | ||
50 | pass | ||
51 | self.fail('Failed to start qemu: %s' % e) | ||
52 | |||
53 | # Attempt to ssh with each user into qemu with empty password | ||
54 | for user in [self.root_user, self.test_user]: | ||
55 | proc_ssh = pexpect.spawn(self.ssh_cmd.format(qemu_ip, user)) | ||
56 | index = proc_ssh.expect([self.prompt, pexpect.TIMEOUT, pexpect.EOF]) | ||
57 | if index == 0: | ||
58 | # user successfully logged in with empty password | ||
59 | pass | ||
60 | elif index == 1: | ||
61 | killpg(proc_qemu.pid, signal.SIGTERM) | ||
62 | proc_ssh.terminate() | ||
63 | self.fail('Failed to ssh with {} user into qemu (timeout).'.format(user)) | ||
64 | else: | ||
65 | killpg(proc_qemu.pid, signal.SIGTERM) | ||
66 | proc_ssh.terminate() | ||
67 | self.fail('Failed to ssh with {} user into qemu (eof).'.format(user)) | ||
68 | proc_ssh.terminate() | ||
69 | |||
70 | # Cleanup | ||
71 | try: | ||
72 | killpg(proc_qemu.pid, signal.SIGTERM) | ||
73 | except: | ||
74 | pass | ||
75 | 44 | ||
76 | @testcase(1115) | 45 | @testcase(1115) |
77 | def test_all_users_can_connect_via_ssh_without_password(self): | 46 | def test_all_users_can_connect_via_ssh_without_password(self): |
@@ -82,7 +51,6 @@ class ImageFeatures(oeSelfTest): | |||
82 | Author: Ionut Chisanovici <ionutx.chisanovici@intel.com> | 51 | Author: Ionut Chisanovici <ionutx.chisanovici@intel.com> |
83 | AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com> | 52 | AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com> |
84 | """ | 53 | """ |
85 | |||
86 | features = 'EXTRA_IMAGE_FEATURES += "ssh-server-openssh allow-empty-password"\n' | 54 | features = 'EXTRA_IMAGE_FEATURES += "ssh-server-openssh allow-empty-password"\n' |
87 | features += 'INHERIT += "extrausers"\n' | 55 | features += 'INHERIT += "extrausers"\n' |
88 | features += 'EXTRA_USERS_PARAMS = "useradd -p \'\' {}; usermod -s /bin/sh {};"'.format(self.test_user, self.test_user) | 56 | features += 'EXTRA_USERS_PARAMS = "useradd -p \'\' {}; usermod -s /bin/sh {};"'.format(self.test_user, self.test_user) |
@@ -93,41 +61,13 @@ class ImageFeatures(oeSelfTest): | |||
93 | # Build a core-image-minimal | 61 | # Build a core-image-minimal |
94 | bitbake('core-image-minimal') | 62 | bitbake('core-image-minimal') |
95 | 63 | ||
96 | # Boot qemu image | 64 | with runqemu("core-image-minimal", self) as qemu: |
97 | proc_qemu = pexpect.spawn('runqemu qemux86 nographic') | 65 | # Attempt to ssh with each user into qemu with empty password |
98 | try: | 66 | for user in [self.root_user, self.test_user]: |
99 | proc_qemu.expect(self.get_ip_patt, timeout=100) | 67 | ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user=user) |
100 | qemu_ip = proc_qemu.match.group('qemu_ip') | 68 | status, output = ssh.run("true") |
101 | proc_qemu.expect('qemux86 login:', timeout=100) | 69 | self.assertEqual(status, 0, 'ssh to user tester failed with %s' % output) |
102 | except Exception as e: | ||
103 | try: | ||
104 | killpg(proc_qemu.pid, signal.SIGTERM) | ||
105 | except: | ||
106 | pass | ||
107 | self.fail('Failed to start qemu: %s' % e) | ||
108 | |||
109 | # Attempt to ssh with each user into qemu with empty password | ||
110 | for user in [self.root_user, self.test_user]: | ||
111 | proc_ssh = pexpect.spawn(self.ssh_cmd.format(qemu_ip, user)) | ||
112 | index = proc_ssh.expect([self.prompt, pexpect.TIMEOUT, pexpect.EOF]) | ||
113 | if index == 0: | ||
114 | # user successfully logged in with empty password | ||
115 | pass | ||
116 | elif index == 1: | ||
117 | killpg(proc_qemu.pid, signal.SIGTERM) | ||
118 | proc_ssh.terminate() | ||
119 | self.fail('Failed to ssh with {} user into qemu (timeout).'.format(user)) | ||
120 | else: | ||
121 | killpg(proc_qemu.pid, signal.SIGTERM) | ||
122 | proc_ssh.terminate() | ||
123 | self.fail('Failed to ssh with {} user into qemu (eof).'.format(user)) | ||
124 | proc_ssh.terminate() | ||
125 | 70 | ||
126 | # Cleanup | ||
127 | try: | ||
128 | killpg(proc_qemu.pid, signal.SIGTERM) | ||
129 | except: | ||
130 | pass | ||
131 | 71 | ||
132 | @testcase(1114) | 72 | @testcase(1114) |
133 | def test_rpm_version_4_support_on_image(self): | 73 | def test_rpm_version_4_support_on_image(self): |
diff --git a/meta/lib/oeqa/utils/commands.py b/meta/lib/oeqa/utils/commands.py index 1be7bedd40..50a08dc1fa 100644 --- a/meta/lib/oeqa/utils/commands.py +++ b/meta/lib/oeqa/utils/commands.py | |||
@@ -17,6 +17,7 @@ import logging | |||
17 | from oeqa.utils import CommandError | 17 | from oeqa.utils import CommandError |
18 | from oeqa.utils import ftools | 18 | from oeqa.utils import ftools |
19 | import re | 19 | import re |
20 | import contextlib | ||
20 | 21 | ||
21 | class Command(object): | 22 | class Command(object): |
22 | def __init__(self, command, bg=False, timeout=None, data=None, **options): | 23 | def __init__(self, command, bg=False, timeout=None, data=None, **options): |
@@ -173,3 +174,51 @@ def create_temp_layer(templayerdir, templayername, priority=999, recipepathspec= | |||
173 | f.write('BBFILE_PATTERN_%s = "^${LAYERDIR}/"\n' % templayername) | 174 | f.write('BBFILE_PATTERN_%s = "^${LAYERDIR}/"\n' % templayername) |
174 | f.write('BBFILE_PRIORITY_%s = "%d"\n' % (templayername, priority)) | 175 | f.write('BBFILE_PRIORITY_%s = "%d"\n' % (templayername, priority)) |
175 | f.write('BBFILE_PATTERN_IGNORE_EMPTY_%s = "1"\n' % templayername) | 176 | f.write('BBFILE_PATTERN_IGNORE_EMPTY_%s = "1"\n' % templayername) |
177 | |||
178 | |||
179 | @contextlib.contextmanager | ||
180 | def runqemu(pn, test): | ||
181 | |||
182 | import bb.tinfoil | ||
183 | import bb.build | ||
184 | |||
185 | tinfoil = bb.tinfoil.Tinfoil() | ||
186 | tinfoil.prepare(False) | ||
187 | try: | ||
188 | tinfoil.logger.setLevel(logging.WARNING) | ||
189 | import oeqa.targetcontrol | ||
190 | tinfoil.config_data.setVar("TEST_LOG_DIR", "${WORKDIR}/testimage") | ||
191 | tinfoil.config_data.setVar("TEST_QEMUBOOT_TIMEOUT", "90") | ||
192 | import oe.recipeutils | ||
193 | recipefile = oe.recipeutils.pn_to_recipe(tinfoil.cooker, pn) | ||
194 | recipedata = oe.recipeutils.parse_recipe(recipefile, [], tinfoil.config_data) | ||
195 | |||
196 | # The QemuRunner log is saved out, but we need to ensure it is at the right | ||
197 | # log level (and then ensure that since it's a child of the BitBake logger, | ||
198 | # we disable propagation so we don't then see the log events on the console) | ||
199 | logger = logging.getLogger('BitBake.QemuRunner') | ||
200 | logger.setLevel(logging.DEBUG) | ||
201 | logger.propagate = False | ||
202 | logdir = recipedata.getVar("TEST_LOG_DIR", True) | ||
203 | |||
204 | qemu = oeqa.targetcontrol.QemuTarget(recipedata) | ||
205 | finally: | ||
206 | # We need to shut down tinfoil early here in case we actually want | ||
207 | # to run tinfoil-using utilities with the running QEMU instance. | ||
208 | # Luckily QemuTarget doesn't need it after the constructor. | ||
209 | tinfoil.shutdown() | ||
210 | |||
211 | try: | ||
212 | qemu.deploy() | ||
213 | try: | ||
214 | qemu.start() | ||
215 | except bb.build.FuncFailed: | ||
216 | raise Exception('Failed to start QEMU - see the logs in %s' % logdir) | ||
217 | |||
218 | yield qemu | ||
219 | |||
220 | finally: | ||
221 | try: | ||
222 | qemu.stop() | ||
223 | except: | ||
224 | pass | ||