Skip to content

Commit

Permalink
testutils/iotlab.py: Randomize the selected node
Browse files Browse the repository at this point in the history
It seems there have been some failures mainly
due to infrastructure. Specifically the samr21-xpro
failing to flash will cause many reruns with the same
faulty hardware.

Previously it would just take the first available
node in the list, which is deterministic but doesn't
help with flakey test reruns. This may cause an issue
with distance to other nodes, but if random selection
of nodes becomes a problem we would have to introduce
node pairing lists... Which is a bit more work.

This is at least a first step.
  • Loading branch information
MrKevinWeiss committed Jul 23, 2024
1 parent b79f8a7 commit 2296910
Showing 1 changed file with 34 additions and 3 deletions.
37 changes: 34 additions & 3 deletions testutils/iotlab.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import random
import re

from iotlabcli.auth import get_user_credentials
Expand All @@ -9,6 +10,7 @@
stop_experiment,
get_experiment,
exp_resources,
info_experiment,
AliasNodes,
)

Expand Down Expand Up @@ -151,6 +153,25 @@ def _wait(self):
ret = wait_experiment(Api(*self.user_credentials()), self.exp_id)
return ret

def _select_random_node(self, site, board):
api = Api(*self.user_credentials())
info = info_experiment(api, site=site)
choices = []
for iot_lab_nodes in info.values():
if not isinstance(iot_lab_nodes, list):
continue
for iot_lab_node in iot_lab_nodes:
if iot_lab_node.get("state", "") != "Alive":
continue
net_addr = iot_lab_node.get("network_address", "")
if board not in net_addr:
continue
choices.append(net_addr)
if not choices:
raise RuntimeError(f"No {board} found at {site}")
ret = random.choice(choices)
return ret

def _submit(self, site, duration):
"""Submit an experiment with required nodes"""
api = Api(*self.user_credentials())
Expand All @@ -159,9 +180,19 @@ def _submit(self, site, duration):
if ctrl.env.get('IOTLAB_NODE') is not None:
resources.append(exp_resources([ctrl.env.get('IOTLAB_NODE')]))
elif ctrl.board() is not None:
board = IoTLABExperiment._archi_from_board(ctrl.board())
alias = AliasNodes(1, site, board)
resources.append(exp_resources(alias))
# Since we cannot combine alias and phyical nodes in the same
# experiment and but we would prefer to use iotlab-m3 alias
# nodes because the m3 nodes can report that they are broken.
# Let's take the easiest solution and only use alias nodes
# if they are all iotlab-m3 nodes.
if all([ctrl.board() == 'iotlab-m3' for ctrl in self.ctrls]):
board = IoTLABExperiment._archi_from_board(ctrl.board())
alias = AliasNodes(1, site, board)
resources.append(exp_resources(alias))
else:
board = IoTLABExperiment.BOARD_ARCHI_MAP[ctrl.board()]['name']
net_addr = self._select_random_node(site, board)
resources.append(exp_resources([net_addr]))
else:
raise ValueError("neither BOARD or IOTLAB_NODE are set")
return submit_experiment(api, self.name, duration, resources)['id']
Expand Down

0 comments on commit 2296910

Please sign in to comment.