diff --git a/riotctrl/ctrl.py b/riotctrl/ctrl.py index dc5dea1..949ab5c 100644 --- a/riotctrl/ctrl.py +++ b/riotctrl/ctrl.py @@ -13,7 +13,7 @@ import pexpect -DEVNULL = open(os.devnull, 'w') +DEVNULL = subprocess.DEVNULL MAKE = os.environ.get('MAKE', 'make') @@ -88,6 +88,7 @@ class RIOTCtrl(): TERM_STARTED_DELAY = int(os.environ.get('RIOT_TERM_START_DELAY') or 3) MAKE_ARGS = () + FLASH_TARGETS = ('flash',) RESET_TARGETS = ('reset',) TERM_TARGETS = ('cleanterm',) @@ -110,6 +111,20 @@ def board(self): """Return board type.""" return self.env['BOARD'] + def flash(self, *runargs, stdout=DEVNULL, stderr=DEVNULL, **runkwargs): + """Flash application in ``ctrl.application_directory`` to ctrl. + + :param stdout: stdout parameter passed to ctrl.make_run + (default: DEVNULL) + :param stderr: stdout parameter passed to ctrl.make_run + (default: DEVNULL) + :param *runargs: args passed to subprocess.run + :param *runkwargs: kwargs passed to subprocess.run + :return: subprocess.CompletedProcess object + """ + self.make_run(self.FLASH_TARGETS, *runargs, + stdout=stdout, stderr=stderr, **runkwargs) + def reset(self): """Reset current ctrl.""" # Make reset yields error on some boards even if successful diff --git a/riotctrl/tests/ctrl_test.py b/riotctrl/tests/ctrl_test.py index 57a8162..ce714cf 100644 --- a/riotctrl/tests/ctrl_test.py +++ b/riotctrl/tests/ctrl_test.py @@ -52,6 +52,28 @@ def test_riotctrl_curdir(): os.environ.update(_environ) +def test_riotctrl_flash(monkeypatch): + """Test the flash method of a riotctrl.""" + args = [] + kwargs = [] + + def make_run_mock(self, *_args, **_kwargs): + """ + Mocks RIOTCtrl's make_run method + """ + # pylint: disable=unused-argument + args.append(_args) + kwargs.append(_kwargs) + + monkeypatch.setattr(riotctrl.ctrl.RIOTCtrl, 'make_run', make_run_mock) + ctrl = riotctrl.ctrl.RIOTCtrl(APPLICATIONS_DIR) + ctrl.flash() + assert len(args) == len(kwargs) == 1 + assert args[-1] == (riotctrl.ctrl.RIOTCtrl.FLASH_TARGETS,) + assert kwargs[-1] == {'stderr': riotctrl.ctrl.DEVNULL, + 'stdout': riotctrl.ctrl.DEVNULL} + + @pytest.fixture(name='app_pidfile_env') def fixture_app_pidfile_env(): """Environment to use application pidfile""" @@ -202,12 +224,13 @@ def test_term_cleanup(app_pidfile_env): with ctrl.run_term(logfile=sys.stdout) as child: child.expect_exact('Running') # Ensure script is started correctly - content = open(tmpfile.name, 'r', encoding='utf-8').read() - assert content == 'Running\n' + with open(tmpfile.name, 'r', encoding='utf-8') as tempfile_r: + assert tempfile_r.read() == 'Running\n' # File should not exist anymore so no error to create one # File must exist to be cleaned by tempfile - open(tmpfile.name, 'x') + with open(tmpfile.name, 'x', encoding='utf-8'): + pass class CtrlMock1(riotctrl.ctrl.RIOTCtrl):