@@ -1,4 +1,3 @@
-import asyncio
import re
import subprocess
import os
@@ -57,7 +56,7 @@ class FVPRunner:
def add_line_callback(self, callback):
self._line_callbacks.append(callback)
- async def start(self, config, extra_args=[], terminal_choice="none"):
+ def start(self, config, extra_args=[], terminal_choice="none"):
cli = cli_from_config(config, terminal_choice)
cli += extra_args
@@ -69,8 +68,8 @@ class FVPRunner:
env[name] = os.environ[name]
self._logger.debug(f"Constructed FVP call: {shlex.join(cli)}")
- self._fvp_process = await asyncio.create_subprocess_exec(
- *cli,
+ self._fvp_process = subprocess.Popen(
+ cli,
stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
env=env)
@@ -82,13 +81,13 @@ class FVPRunner:
self._terminal_ports[terminal] = port
self.add_line_callback(detect_terminals)
- async def stop(self):
+ def stop(self):
if self._fvp_process:
self._logger.debug(f"Terminating FVP PID {self._fvp_process.pid}")
try:
self._fvp_process.terminate()
- await asyncio.wait_for(self._fvp_process.wait(), 10.0)
- except asyncio.TimeoutError:
+ self._fvp_process.wait(10.0)
+ except subprocess.TimeoutExpired:
self._logger.debug(f"Killing FVP PID {self._fvp_process.pid}")
self._fvp_process.kill()
except ProcessLookupError:
@@ -97,8 +96,8 @@ class FVPRunner:
for telnet in self._telnets:
try:
telnet.terminate()
- await asyncio.wait_for(telnet.wait(), 10.0)
- except asyncio.TimeoutError:
+ telnet.wait(10.0)
+ except subprocess.TimeoutExpired:
telnet.kill()
except ProcessLookupError:
pass
@@ -118,34 +117,34 @@ class FVPRunner:
else:
return 0
- async def run(self, until=None):
+ def run(self, until=None):
if until and until():
return
- async for line in self._fvp_process.stdout:
+ for line in self._fvp_process.stdout:
line = line.strip().decode("utf-8", errors="replace")
for callback in self._line_callbacks:
callback(line)
if until and until():
return
- async def _get_terminal_port(self, terminal, timeout):
+ def _get_terminal_port(self, terminal):
def terminal_exists():
return terminal in self._terminal_ports
- await asyncio.wait_for(self.run(terminal_exists), timeout)
+ self.run(terminal_exists)
return self._terminal_ports[terminal]
- async def create_telnet(self, terminal, timeout=15.0):
+ def create_telnet(self, terminal):
check_telnet()
- port = await self._get_terminal_port(terminal, timeout)
- telnet = await asyncio.create_subprocess_exec("telnet", "localhost", str(port), stdin=sys.stdin, stdout=sys.stdout)
+ port = self._get_terminal_port(terminal)
+ telnet = subprocess.Popen(["telnet", "localhost", str(port)], stdin=sys.stdin, stdout=sys.stdout)
self._telnets.append(telnet)
return telnet
- async def create_pexpect(self, terminal, timeout=15.0, **kwargs):
+ def create_pexpect(self, terminal, **kwargs):
check_telnet()
import pexpect
- port = await self._get_terminal_port(terminal, timeout)
+ port = self._get_terminal_port(terminal)
instance = pexpect.spawn(f"telnet localhost {port}", **kwargs)
self._pexpects.append(instance)
return instance
@@ -1,4 +1,3 @@
-import asyncio
import pathlib
import pexpect
import os
@@ -25,32 +24,18 @@ class OEFVPSSHTarget(OESSHTarget):
if not self.fvpconf.exists():
raise FileNotFoundError(f"Cannot find {self.fvpconf}")
- async def boot_fvp(self):
- self.fvp = runner.FVPRunner(self.logger)
- await self.fvp.start(self.config)
- self.logger.debug(f"Started FVP PID {self.fvp.pid()}")
- await self._after_start()
-
- async def _after_start(self):
+ def _after_start(self):
pass
- async def _after_stop(self):
- pass
-
- async def stop_fvp(self):
- returncode = await self.fvp.stop()
- await self._after_stop()
-
- self.logger.debug(f"Stopped FVP with return code {returncode}")
-
def start(self, **kwargs):
- # When we can assume Py3.7+, this can simply be asyncio.run()
- loop = asyncio.get_event_loop()
- loop.run_until_complete(asyncio.gather(self.boot_fvp()))
+ self.fvp = runner.FVPRunner(self.logger)
+ self.fvp.start(self.config)
+ self.logger.debug(f"Started FVP PID {self.fvp.pid()}")
+ self._after_start()
def stop(self, **kwargs):
- loop = asyncio.get_event_loop()
- loop.run_until_complete(asyncio.gather(self.stop_fvp()))
+ returncode = self.fvp.stop()
+ self.logger.debug(f"Stopped FVP with return code {returncode}")
class OEFVPTarget(OEFVPSSHTarget):
@@ -66,9 +51,9 @@ class OEFVPTarget(OEFVPSSHTarget):
# FVPs boot slowly, so allow ten minutes
self.boot_timeout = 10 * 60
- async def _after_start(self):
+ def _after_start(self):
self.logger.debug(f"Awaiting console on terminal {self.config['consoles']['default']}")
- console = await self.fvp.create_pexpect(self.config['consoles']['default'])
+ console = self.fvp.create_pexpect(self.config['consoles']['default'])
try:
console.expect("login\\:", timeout=self.boot_timeout)
self.logger.debug("Found login prompt")
@@ -100,11 +85,11 @@ class OEFVPSerialTarget(OEFVPSSHTarget):
self.test_log_suffix = pathlib.Path(bootlog).suffix
self.bootlog = bootlog
- async def _add_terminal(self, name, fvp_name):
+ def _add_terminal(self, name, fvp_name):
logfile = self._create_logfile(name)
self.logger.info(f'Creating terminal {name} on {fvp_name}')
self.terminals[name] = \
- await self.fvp.create_pexpect(fvp_name, logfile=logfile)
+ self.fvp.create_pexpect(fvp_name, logfile=logfile)
def _create_logfile(self, name):
fvp_log_file = f"{name}_log{self.test_log_suffix}"
@@ -117,9 +102,9 @@ class OEFVPSerialTarget(OEFVPSSHTarget):
os.symlink(fvp_log_file, fvp_log_symlink)
return open(fvp_log_path, 'wb')
- async def _after_start(self):
+ def _after_start(self):
for name, console in self.config["consoles"].items():
- await self._add_terminal(name, console)
+ self._add_terminal(name, console)
# testimage.bbclass expects to see a log file at `bootlog`,
# so make a symlink to the 'default' log file
@@ -81,13 +81,13 @@ class ConfFileTests(OESelftestTestCase):
class RunnerTests(OESelftestTestCase):
def create_mock(self):
- return unittest.mock.patch("asyncio.create_subprocess_exec")
+ return unittest.mock.patch("subprocess.Popen")
def test_start(self):
from fvp import runner
with self.create_mock() as m:
fvp = runner.FVPRunner(self.logger)
- asyncio.run(fvp.start({
+ fvp.start({
"fvp-bindir": "/usr/bin",
"exe": "FVP_Binary",
"parameters": {'foo': 'bar'},
@@ -96,13 +96,13 @@ class RunnerTests(OESelftestTestCase):
"terminals": {},
"args": ['--extra-arg'],
"env": {"FOO": "BAR"}
- }))
+ })
- m.assert_called_once_with('/usr/bin/FVP_Binary',
+ m.assert_called_once_with(['/usr/bin/FVP_Binary',
'--parameter', 'foo=bar',
'--data', 'data1',
'--application', 'a1=file',
- '--extra-arg',
+ '--extra-arg'],
stdin=unittest.mock.ANY,
stdout=unittest.mock.ANY,
stderr=unittest.mock.ANY,
@@ -113,7 +113,7 @@ class RunnerTests(OESelftestTestCase):
from fvp import runner
with self.create_mock() as m:
fvp = runner.FVPRunner(self.logger)
- asyncio.run(fvp.start({
+ fvp.start({
"fvp-bindir": "/usr/bin",
"exe": "FVP_Binary",
"parameters": {},
@@ -122,9 +122,9 @@ class RunnerTests(OESelftestTestCase):
"terminals": {},
"args": [],
"env": {"FOO": "BAR"}
- }))
+ })
- m.assert_called_once_with('/usr/bin/FVP_Binary',
+ m.assert_called_once_with(['/usr/bin/FVP_Binary'],
stdin=unittest.mock.ANY,
stdout=unittest.mock.ANY,
stderr=unittest.mock.ANY,
@@ -1,6 +1,5 @@
#! /usr/bin/env python3
-import asyncio
import os
import pathlib
import signal
@@ -47,11 +46,10 @@ def parse_args(arguments):
logger.debug(f"FVP arguments: {fvp_args}")
return args, fvp_args
-
-async def start_fvp(args, config, extra_args):
+def start_fvp(args, config, extra_args):
fvp = runner.FVPRunner(logger)
try:
- await fvp.start(config, extra_args, args.terminals)
+ fvp.start(config, extra_args, args.terminals)
if args.console:
fvp.add_line_callback(lambda line: logger.debug(f"FVP output: {line}"))
@@ -59,15 +57,16 @@ async def start_fvp(args, config, extra_args):
if not expected_terminal:
logger.error("--console used but FVP_CONSOLE not set in machine configuration")
return 1
- telnet = await fvp.create_telnet(expected_terminal)
- await telnet.wait()
+ telnet = fvp.create_telnet(expected_terminal)
+ telnet.wait()
logger.debug(f"Telnet quit, cancelling tasks")
else:
fvp.add_line_callback(lambda line: print(line))
- await fvp.run()
+ fvp.run()
finally:
- await fvp.stop()
+ fvp.stop()
+
def runfvp(cli_args):
args, extra_args = parse_args(cli_args)
@@ -77,14 +76,8 @@ def runfvp(cli_args):
config_file = conffile.find(args.config)
logger.debug(f"Loading {config_file}")
config = conffile.load(config_file)
+ start_fvp(args, config, extra_args)
- try:
- # When we can assume Py3.7+, this can simply be asyncio.run()
- loop = asyncio.get_event_loop()
- return loop.run_until_complete(start_fvp(args, config, extra_args))
- except asyncio.CancelledError:
- # This means telnet exited, which isn't an error
- return 0
if __name__ == "__main__":
try: