-
Notifications
You must be signed in to change notification settings - Fork 213
Description
When running pytest tests using the strategies shipped with labgrid, the state can get confused if a timeout occurs while bringing up the target.
I ran into this issue when doing some simple endurance testing.
By way of an example, consider what happens if you run the following simple tests using the UBootStrategy (although others have the same problem).
@pymark.test.parameterize("iteration", [1, 2, 3, 4, 5])
def test_boot(target, strategy, iteration):
strategy.transition("shell")
Now suppose that a timeout occurs on iteration 1 while waiting for a login prompt. This causes the first test to fail, and leaves our strategy in the "u-boot" state.
At this point, we're in an inconsistent state. The target is almost certainly not at the u-boot prompt... It could be hung, or crashed, or it could have simply took too long to boot and is now at the login prompt.
Unfortunately, this will cause test 2 and all following tests to fail.
First because the u-boot driver was deactivated when the shell driver was activated in test #1, so when it tries to run:
elif status == Status.shell:
# transition to uboot
self.transition(Status.uboot)
self.uboot.boot("")
self.uboot.await_boot()
It skips over the transistion to uboot (since it is already there), but fails with an StateError when it tries to run uboot.boot("")
E labgrid.binding.StateError: UBootDriver(target=Target(name='main', env=Environment(config_file='test.yaml')), name=None, state=<BindingState.bound: 1>, prompt='=> ', autoboot='stop autoboot', password='', interrupt='\n', init_commands=(), password_prompt='enter Password:', boot_expression='', bootstring='Linux version \\d', boot_command='run bootcmd', boot_commands={}, login_timeout=30, boot_timeout=30) has not been activated, UBootDriver.boot cannot be called in state "bound"
Even if that weren't the case and we reactivated the uboot driver, our strategy would get a tiny bit farther, but will timeout waiting for the kernel to start booting in uboot.await_boot().
I think what needs to happen is for the Strategy to catch (and later re-reraise) any exceptions when it performs a transition, and set the state to "unknown".