Question on running uboot_testpy with tbot

Hi,
I am trying to run the pytests on my unit. The documentation doesn't really explain how it works.
This is what I am trying:
$ tbot -vv -l kea.py -b rpi3.py -T tbot/contrib -p 'testpy_args=["-k", "help", "-vv"]' uboot_testpy tbot starting ... ├─Parameters: │ testpy_args = ['-k', 'help', '-vv'] ├─Calling uboot_testpy ... │ ├─Logging in on sglass@kea:22 ... │ ├─[sglass] bash --norc --noprofile │ ├─Calling uboot_setup_testhooks ... │ │ ├─[sglass] echo " ${HOME}" │ │ │ ## /home/sglass │ │ ├─[sglass] mkdir -p /home/sglass/tbot-workdir │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-testpy-tbot │ │ ├─Creating FIFOs ... │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] cat /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-scripts.sha256 │ │ │ ## 2d30892b61eb713ce9413e06c4f2a0cd00d2a74b6b8c2ac6624e1e49909b1897 │ │ ├─Hooks are up to date, skipping deployment ... │ │ ├─Adding hooks to $PATH ... │ │ ├─[sglass] echo " ${PATH}" │ │ │ ## /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─[sglass] export PATH=/home/sglass/tbot-workdir/uboot-testpy-tbot:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─Open console & command channels ... │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-console │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-commands │ │ └─Done. (0.028s) │ ├─Calling uboot_checkout ... │ │ ├─Builder: rpi3 │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-rpi3/.git │ │ ├─[sglass] git -C /home/sglass/tbot-workdir/uboot-rpi3 fetch │ │ └─Done. (0.121s) │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/.config │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/include/ autoconf.mk │ ├─[sglass] picocom -q -b 115200 /dev/ttyusb_port1 │ ├─POWERON (rpi3) │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1 │ ├─UBOOT (rpi3-u-boot) │ │ <> │ │ <> │ │ <> U-Boot 2020.10-rc2-00140-g392aa09f310 (Oct 30 2021 - 12:38:07 -0600) │ │ <> │ │ <> DRAM: 992 MiB │ │ <> RPI 3 Model B (0xa22082) │ │ <> MMC: mmc@7e202000: 0, sdhci@7e300000: 1 │ │ <> Loading Environment from FAT... *** Warning - bad CRC, using default environment │ │ <> │ │ <> In: serial │ │ <> Out: vidconsole │ │ <> Err: vidconsole │ │ <> Net: No ethernet found. │ │ <> Hit any key to stop autoboot: 0 │ │ <> U-Boot> │ ├─[sglass] cd /home/sglass/tbot-workdir/uboot-rpi3 │ ├─[sglass] ./test/py/test.py --build-dir . --board-type unknown -k help -vv │ │ ## +u-boot-test-flash unknown na │ │ ## ============================= test session starts ============================== │ │ ## platform linux -- Python 3.6.9, pytest-5.2.1, py-1.8.0, pluggy-0.13.0 -- /usr/bin/python3 │ │ ## cachedir: .pytest_cache │ │ ## rootdir: /home/sglass/tbot-workdir/uboot-rpi3/test/py, inifile: pytest.ini │ │ ## collected 324 items / 322 deselected / 2 selected
│ │ ## │ │ ## test/py/tests/test_fpga.py::test_fpga_help SKIPPED [ 50%]│ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1
│ ├─POWEROFF (rpi3) │ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ └─Fail. (38.376s) ├─Exception: │ Traceback (most recent call last): │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/main.py", line 345, in main │ func(**params) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/decorators.py", line 92, in wrapped │ return tc(*args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/decorators.py", line 157, in wrapped │ return tc(lh, *args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/tc/uboot/testpy.py", line 321, in testpy │ os.write(chan_console.fileno(), data) │ OSError: [Errno 9] Bad file descriptor ├───────────────────────────────────────── └─FAILURE (38.488s)
I don't see the output appearing and I'm not sure how pytest is sending the commands to the board?
Regards, Simon

Hi again,
The relevant part of test-log.html is
Section: flash [-] Section: test_fpga_help
TIME: NOW: 2021/10/30 13:41:52.662614
TIME: SINCE-PREV: 0:00:00.142842
TIME: SINCE-START: 0:00:00.148402
SKIPPED: ('/home/sglass/tbot-workdir/uboot-rpi3/test/py/conftest.py', 486, 'Skipped: .config feature "cmd_fpga" not enabled')
TIME: SINCE-SECTION: 0:00:00.000684
[-] Section: test_help
TIME: NOW: 2021/10/30 13:41:52.663392
TIME: SINCE-PREV: 0:00:00.000778
TIME: SINCE-START: 0:00:00.149180
[-] Section: test_help/Starting U-Boot
TIME: NOW: 2021/10/30 13:41:52.663511
TIME: SINCE-PREV: 0:00:00.000119
TIME: SINCE-START: 0:00:00.149299
Resetting board
[-] Stream: u-boot-test-reset
+u-boot-test-reset unknown na
TIME: NOW: 2021/10/30 13:41:52.666658
TIME: SINCE-PREV: 0:00:00.003147
TIME: SINCE-START: 0:00:00.152446
TIME: NOW: 2021/10/30 13:42:22.797678
TIME: SINCE-PREV: 0:00:30.131020
TIME: SINCE-START: 0:00:30.283466
TIME: SINCE-SECTION: 0:00:30.134391
FAILED: request = <SubRequest 'u_boot_console' for <Function test_help>>
@pytest.fixture(scope='function') def u_boot_console(request): """Generate the value of a test's u_boot_console fixture.
Args: request: The pytest request.
Returns: The fixture value. """
console.ensure_spawned()
test/py/conftest.py:364: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ test/py/u_boot_console_base.py:372: in ensure_spawned m = self.p.expect([pattern_u_boot_main_signon] + self.bad_patterns) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <u_boot_spawn.Spawn object at 0x7f5a4979e208> patterns = [re.compile('(U-Boot \d{4}\.\d{2}[^\r\n]*\))'), re.compile('(U-Boot SPL \d{4}\.\d{2}[^\r\n]*\))'), re.compile(...d{2}[^\r\n]*\))'), re.compile('Hit any key to stop autoboot: '), re.compile("Unknown command '.*' - try 'help'"), ...]
def expect(self, patterns): """Wait for the sub-process to emit specific data.
This function waits for the process to emit one pattern from the supplied list of patterns, or for a timeout to occur.
Args: patterns: A list of strings or regex objects that we expect to see in the sub-process' stdout.
Returns: The index within the patterns array of the pattern the process emitted.
Notable exceptions: Timeout, if the process did not emit any of the patterns within the expected time. """
for pi in range(len(patterns)): if type(patterns[pi]) == type(''): patterns[pi] = re.compile(patterns[pi])
tstart_s = time.time() try: while True: earliest_m = None earliest_pi = None for pi in range(len(patterns)): pattern = patterns[pi] m = pattern.search(self.buf) if not m: continue if earliest_m and m.start() >= earliest_m.start(): continue earliest_m = m earliest_pi = pi if earliest_m: pos = earliest_m.start() posafter = earliest_m.end() self.before = self.buf[:pos] self.after = self.buf[pos:posafter] self.output += self.buf[:posafter] self.buf = self.buf[posafter:] return earliest_pi tnow_s = time.time() if self.timeout: tdelta_ms = (tnow_s - tstart_s) * 1000 poll_maxwait = self.timeout - tdelta_ms if tdelta_ms > self.timeout: raise Timeout() else: poll_maxwait = None events = self.poll.poll(poll_maxwait) if not events:
raise Timeout()
E u_boot_spawn.Timeout
test/py/u_boot_spawn.py:170: Timeout
TIME: SINCE-SECTION: 0:00:30.159899
[-] Section: Status Report
TIME: NOW: 2021/10/30 13:42:22.825745
TIME: SINCE-PREV: 0:00:00.028067
TIME: SINCE-START: 0:00:30.311533
0 passed
1 skipped
... test_fpga_help
1 failed
... test_help
322 not run
Regards, Simon
On Sat, 30 Oct 2021 at 13:34, Simon Glass sjg@chromium.org wrote:
Hi,
I am trying to run the pytests on my unit. The documentation doesn't really explain how it works.
This is what I am trying:
$ tbot -vv -l kea.py -b rpi3.py -T tbot/contrib -p 'testpy_args=["-k", "help", "-vv"]' uboot_testpy tbot starting ... ├─Parameters: │ testpy_args = ['-k', 'help', '-vv'] ├─Calling uboot_testpy ... │ ├─Logging in on sglass@kea:22 ... │ ├─[sglass] bash --norc --noprofile │ ├─Calling uboot_setup_testhooks ... │ │ ├─[sglass] echo " ${HOME}" │ │ │ ## /home/sglass │ │ ├─[sglass] mkdir -p /home/sglass/tbot-workdir │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-testpy-tbot │ │ ├─Creating FIFOs ... │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] cat /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-scripts.sha256 │ │ │ ## 2d30892b61eb713ce9413e06c4f2a0cd00d2a74b6b8c2ac6624e1e49909b1897 │ │ ├─Hooks are up to date, skipping deployment ... │ │ ├─Adding hooks to $PATH ... │ │ ├─[sglass] echo " ${PATH}" │ │ │ ## /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─[sglass] export PATH=/home/sglass/tbot-workdir/uboot-testpy-tbot:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─Open console & command channels ... │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-console │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-commands │ │ └─Done. (0.028s) │ ├─Calling uboot_checkout ... │ │ ├─Builder: rpi3 │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-rpi3/.git │ │ ├─[sglass] git -C /home/sglass/tbot-workdir/uboot-rpi3 fetch │ │ └─Done. (0.121s) │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/.config │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/include/ autoconf.mk │ ├─[sglass] picocom -q -b 115200 /dev/ttyusb_port1 │ ├─POWERON (rpi3) │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1 │ ├─UBOOT (rpi3-u-boot) │ │ <> │ │ <> │ │ <> U-Boot 2020.10-rc2-00140-g392aa09f310 (Oct 30 2021 - 12:38:07 -0600) │ │ <> │ │ <> DRAM: 992 MiB │ │ <> RPI 3 Model B (0xa22082) │ │ <> MMC: mmc@7e202000: 0, sdhci@7e300000: 1 │ │ <> Loading Environment from FAT... *** Warning - bad CRC, using default environment │ │ <> │ │ <> In: serial │ │ <> Out: vidconsole │ │ <> Err: vidconsole │ │ <> Net: No ethernet found. │ │ <> Hit any key to stop autoboot: 0 │ │ <> U-Boot> │ ├─[sglass] cd /home/sglass/tbot-workdir/uboot-rpi3 │ ├─[sglass] ./test/py/test.py --build-dir . --board-type unknown -k help -vv │ │ ## +u-boot-test-flash unknown na │ │ ## ============================= test session starts ============================== │ │ ## platform linux -- Python 3.6.9, pytest-5.2.1, py-1.8.0, pluggy-0.13.0 -- /usr/bin/python3 │ │ ## cachedir: .pytest_cache │ │ ## rootdir: /home/sglass/tbot-workdir/uboot-rpi3/test/py, inifile: pytest.ini │ │ ## collected 324 items / 322 deselected / 2 selected
│ │ ## │ │ ## test/py/tests/test_fpga.py::test_fpga_help SKIPPED [ 50%]│ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1
│ ├─POWEROFF (rpi3) │ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ └─Fail. (38.376s) ├─Exception: │ Traceback (most recent call last): │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/main.py", line 345, in main │ func(**params) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/decorators.py", line 92, in wrapped │ return tc(*args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/decorators.py", line 157, in wrapped │ return tc(lh, *args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/tc/uboot/testpy.py", line 321, in testpy │ os.write(chan_console.fileno(), data) │ OSError: [Errno 9] Bad file descriptor ├───────────────────────────────────────── └─FAILURE (38.488s)
I don't see the output appearing and I'm not sure how pytest is sending the commands to the board?
Regards, Simon

Hi,
Just pinging this thread in case someone can explain how to use this feature.
Regards, Simon
On Sat, 30 Oct 2021 at 13:47, Simon Glass sjg@chromium.org wrote:
Hi again,
The relevant part of test-log.html is
Section: flash [-] Section: test_fpga_help
TIME: NOW: 2021/10/30 13:41:52.662614
TIME: SINCE-PREV: 0:00:00.142842
TIME: SINCE-START: 0:00:00.148402
SKIPPED: ('/home/sglass/tbot-workdir/uboot-rpi3/test/py/conftest.py', 486, 'Skipped: .config feature "cmd_fpga" not enabled')
TIME: SINCE-SECTION: 0:00:00.000684
[-] Section: test_help
TIME: NOW: 2021/10/30 13:41:52.663392
TIME: SINCE-PREV: 0:00:00.000778
TIME: SINCE-START: 0:00:00.149180
[-] Section: test_help/Starting U-Boot
TIME: NOW: 2021/10/30 13:41:52.663511
TIME: SINCE-PREV: 0:00:00.000119
TIME: SINCE-START: 0:00:00.149299
Resetting board
[-] Stream: u-boot-test-reset
+u-boot-test-reset unknown na
TIME: NOW: 2021/10/30 13:41:52.666658
TIME: SINCE-PREV: 0:00:00.003147
TIME: SINCE-START: 0:00:00.152446
TIME: NOW: 2021/10/30 13:42:22.797678
TIME: SINCE-PREV: 0:00:30.131020
TIME: SINCE-START: 0:00:30.283466
TIME: SINCE-SECTION: 0:00:30.134391
FAILED: request = <SubRequest 'u_boot_console' for <Function test_help>>
@pytest.fixture(scope='function') def u_boot_console(request): """Generate the value of a test's u_boot_console fixture. Args: request: The pytest request. Returns: The fixture value. """
console.ensure_spawned()
test/py/conftest.py:364: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ test/py/u_boot_console_base.py:372: in ensure_spawned m = self.p.expect([pattern_u_boot_main_signon] + self.bad_patterns) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <u_boot_spawn.Spawn object at 0x7f5a4979e208> patterns = [re.compile('(U-Boot \d{4}\.\d{2}[^\r\n]*\))'), re.compile('(U-Boot SPL \d{4}\.\d{2}[^\r\n]*\))'), re.compile(...d{2}[^\r\n]*\))'), re.compile('Hit any key to stop autoboot: '), re.compile("Unknown command '.*' - try 'help'"), ...]
def expect(self, patterns): """Wait for the sub-process to emit specific data. This function waits for the process to emit one pattern from the supplied list of patterns, or for a timeout to occur. Args: patterns: A list of strings or regex objects that we expect to see in the sub-process' stdout. Returns: The index within the patterns array of the pattern the process emitted. Notable exceptions: Timeout, if the process did not emit any of the patterns within the expected time. """ for pi in range(len(patterns)): if type(patterns[pi]) == type(''): patterns[pi] = re.compile(patterns[pi]) tstart_s = time.time() try: while True: earliest_m = None earliest_pi = None for pi in range(len(patterns)): pattern = patterns[pi] m = pattern.search(self.buf) if not m: continue if earliest_m and m.start() >= earliest_m.start(): continue earliest_m = m earliest_pi = pi if earliest_m: pos = earliest_m.start() posafter = earliest_m.end() self.before = self.buf[:pos] self.after = self.buf[pos:posafter] self.output += self.buf[:posafter] self.buf = self.buf[posafter:] return earliest_pi tnow_s = time.time() if self.timeout: tdelta_ms = (tnow_s - tstart_s) * 1000 poll_maxwait = self.timeout - tdelta_ms if tdelta_ms > self.timeout: raise Timeout() else: poll_maxwait = None events = self.poll.poll(poll_maxwait) if not events:
raise Timeout()
E u_boot_spawn.Timeout
test/py/u_boot_spawn.py:170: Timeout
TIME: SINCE-SECTION: 0:00:30.159899
[-] Section: Status Report
TIME: NOW: 2021/10/30 13:42:22.825745
TIME: SINCE-PREV: 0:00:00.028067
TIME: SINCE-START: 0:00:30.311533
0 passed
1 skipped
... test_fpga_help
1 failed
... test_help
322 not run
Regards, Simon
On Sat, 30 Oct 2021 at 13:34, Simon Glass sjg@chromium.org wrote:
Hi,
I am trying to run the pytests on my unit. The documentation doesn't really explain how it works.
This is what I am trying:
$ tbot -vv -l kea.py -b rpi3.py -T tbot/contrib -p 'testpy_args=["-k", "help", "-vv"]' uboot_testpy tbot starting ... ├─Parameters: │ testpy_args = ['-k', 'help', '-vv'] ├─Calling uboot_testpy ... │ ├─Logging in on sglass@kea:22 ... │ ├─[sglass] bash --norc --noprofile │ ├─Calling uboot_setup_testhooks ... │ │ ├─[sglass] echo " ${HOME}" │ │ │ ## /home/sglass │ │ ├─[sglass] mkdir -p /home/sglass/tbot-workdir │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-testpy-tbot │ │ ├─Creating FIFOs ... │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] cat /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-scripts.sha256 │ │ │ ## 2d30892b61eb713ce9413e06c4f2a0cd00d2a74b6b8c2ac6624e1e49909b1897 │ │ ├─Hooks are up to date, skipping deployment ... │ │ ├─Adding hooks to $PATH ... │ │ ├─[sglass] echo " ${PATH}" │ │ │ ## /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─[sglass] export PATH=/home/sglass/tbot-workdir/uboot-testpy-tbot:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─Open console & command channels ... │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-console │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-commands │ │ └─Done. (0.028s) │ ├─Calling uboot_checkout ... │ │ ├─Builder: rpi3 │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-rpi3/.git │ │ ├─[sglass] git -C /home/sglass/tbot-workdir/uboot-rpi3 fetch │ │ └─Done. (0.121s) │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/.config │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/include/autoconf.mk │ ├─[sglass] picocom -q -b 115200 /dev/ttyusb_port1 │ ├─POWERON (rpi3) │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1 │ ├─UBOOT (rpi3-u-boot) │ │ <> │ │ <> │ │ <> U-Boot 2020.10-rc2-00140-g392aa09f310 (Oct 30 2021 - 12:38:07 -0600) │ │ <> │ │ <> DRAM: 992 MiB │ │ <> RPI 3 Model B (0xa22082) │ │ <> MMC: mmc@7e202000: 0, sdhci@7e300000: 1 │ │ <> Loading Environment from FAT... *** Warning - bad CRC, using default environment │ │ <> │ │ <> In: serial │ │ <> Out: vidconsole │ │ <> Err: vidconsole │ │ <> Net: No ethernet found. │ │ <> Hit any key to stop autoboot: 0 │ │ <> U-Boot> │ ├─[sglass] cd /home/sglass/tbot-workdir/uboot-rpi3 │ ├─[sglass] ./test/py/test.py --build-dir . --board-type unknown -k help -vv │ │ ## +u-boot-test-flash unknown na │ │ ## ============================= test session starts ============================== │ │ ## platform linux -- Python 3.6.9, pytest-5.2.1, py-1.8.0, pluggy-0.13.0 -- /usr/bin/python3 │ │ ## cachedir: .pytest_cache │ │ ## rootdir: /home/sglass/tbot-workdir/uboot-rpi3/test/py, inifile: pytest.ini │ │ ## collected 324 items / 322 deselected / 2 selected │ │ ## │ │ ## test/py/tests/test_fpga.py::test_fpga_help SKIPPED [ 50%]│ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1
│ ├─POWEROFF (rpi3) │ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ └─Fail. (38.376s) ├─Exception: │ Traceback (most recent call last): │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/main.py", line 345, in main │ func(**params) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/decorators.py", line 92, in wrapped │ return tc(*args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/decorators.py", line 157, in wrapped │ return tc(lh, *args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/tc/uboot/testpy.py", line 321, in testpy │ os.write(chan_console.fileno(), data) │ OSError: [Errno 9] Bad file descriptor ├───────────────────────────────────────── └─FAILURE (38.488s)
I don't see the output appearing and I'm not sure how pytest is sending the commands to the board?
Regards, Simon

Hi Simon,
first of all, sorry for the super late response to this :/ I had it on my list for a long time but had trouble finding enough time to revisit the test/py integration properly. You see, the existing test/py integration has bitrotten quite a lot and I couldn't even get the existing code working in my environment anymore...
I've now tried reworking all this code for a more robust solution [1]. It has reached a state where it works well for me and if you are still interested, I'd be grateful for some feedback on how it fares for your needs. That said, if your lab and board config haven't changed, the old integration might still work for you.
The new one is not yet in a tbot release but will be shortly. In the meantime you could check it out from the master branch and documentation can be found here:
https://tbot.tools/contrib/uboot.html#tbot_contrib.uboot.testpy
More regarding your actual problem below.
[1]: https://github.com/Rahix/tbot/pull/64
On Sat, 2021-10-30 at 13:34 -0600, Simon Glass wrote:
Hi,
I am trying to run the pytests on my unit. The documentation doesn't really explain how it works.
This is what I am trying:
$ tbot -vv -l kea.py -b rpi3.py -T tbot/contrib -p 'testpy_args=["-k", "help", "-vv"]' uboot_testpy tbot starting ... ├─Parameters: │ testpy_args = ['-k', 'help', '-vv'] ├─Calling uboot_testpy ... │ ├─Logging in on sglass@kea:22 ... │ ├─[sglass] bash --norc --noprofile │ ├─Calling uboot_setup_testhooks ... │ │ ├─[sglass] echo " ${HOME}" │ │ │ ## /home/sglass │ │ ├─[sglass] mkdir -p /home/sglass/tbot-workdir │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-testpy-tbot │ │ ├─Creating FIFOs ... │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] cat /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-scripts.sha256 │ │ │ ## 2d30892b61eb713ce9413e06c4f2a0cd00d2a74b6b8c2ac6624e1e49909b1897 │ │ ├─Hooks are up to date, skipping deployment ... │ │ ├─Adding hooks to $PATH ... │ │ ├─[sglass] echo " ${PATH}" │ │ │ ## /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/l ocal/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─[sglass] export PATH=/home/sglass/tbot-workdir/uboot-testpy- tbot:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/u sr/local/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─Open console & command channels ... │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-console │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-commands │ │ └─Done. (0.028s) │ ├─Calling uboot_checkout ... │ │ ├─Builder: rpi3 │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-rpi3/.git │ │ ├─[sglass] git -C /home/sglass/tbot-workdir/uboot-rpi3 fetch │ │ └─Done. (0.121s) │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/.config │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/include/autoconf.mk │ ├─[sglass] picocom -q -b 115200 /dev/ttyusb_port1 │ ├─POWERON (rpi3) │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1 │ ├─UBOOT (rpi3-u-boot) │ │ <> │ │ <> │ │ <> U-Boot 2020.10-rc2-00140-g392aa09f310 (Oct 30 2021 - 12:38:07 -0600) │ │ <> │ │ <> DRAM: 992 MiB │ │ <> RPI 3 Model B (0xa22082) │ │ <> MMC: mmc@7e202000: 0, sdhci@7e300000: 1 │ │ <> Loading Environment from FAT... *** Warning - bad CRC, using default environment │ │ <> │ │ <> In: serial │ │ <> Out: vidconsole │ │ <> Err: vidconsole │ │ <> Net: No ethernet found. │ │ <> Hit any key to stop autoboot: 0 │ │ <> U-Boot> │ ├─[sglass] cd /home/sglass/tbot-workdir/uboot-rpi3 │ ├─[sglass] ./test/py/test.py --build-dir . --board-type unknown -k help -vv │ │ ## +u-boot-test-flash unknown na │ │ ## ============================= test session starts ============================== │ │ ## platform linux -- Python 3.6.9, pytest-5.2.1, py-1.8.0, pluggy-0.13.0 -- /usr/bin/python3 │ │ ## cachedir: .pytest_cache │ │ ## rootdir: /home/sglass/tbot-workdir/uboot-rpi3/test/py, inifile: pytest.ini │ │ ## collected 324 items / 322 deselected / 2 selected │ │ ## │ │ ## test/py/tests/test_fpga.py::test_fpga_help SKIPPED [ 50%]│ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1
│ ├─POWEROFF (rpi3) │ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ └─Fail. (38.376s) ├─Exception: │ Traceback (most recent call last): │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/main.py", line 345, in main │ func(**params) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/decorators.py", line 92, in wrapped │ return tc(*args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/decorators.py", line 157, in wrapped │ return tc(lh, *args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/tc/uboot/testpy.py", line 321, in testpy │ os.write(chan_console.fileno(), data) │ OSError: [Errno 9] Bad file descriptor ├───────────────────────────────────────── └─FAILURE (38.488s)
I don't see the output appearing and I'm not sure how pytest is sending the commands to the board?
The challenge here is that tbot is in control of the board (because we need seamless integration of tbot's board config) while test/py directs what should happen. To facilitate this, IO if funneled through tbot by means of some fifos/named pipes on the host where test/py is running. Roughly speaking, the setup looks like this (details may differ, depending on config):
+---------------------------------------------------------+ | "build host" | +---------------+ | has u-boot sources | | tbot host | | +----------+ | | //====================<bh channel>==[captures stdout/stderr]======test/py | | | | //=================<m_command channel>==[powercycle trigger]=== | | | | | //============<m_console channel>==[board rx/tx console]==invocation| | | | | | | | +----------+ | | +----+ | | +---------------------------------------------------------+ | |tbot| | | | |runs| | | +------------------------------------+ | |here| | | | lab host | | +----+ | | | from here, we | | | | | | can connect to | | | | | | the board | | | | | | | +----------------+ | | \============<board channel>==[board console]========== DUT | | \=================<lh channel>==[trigger powercycle] | | the device | | | +------------------------------------+ | that is tested | +---------------+ +----------------+
The board console is essentially forwared as is between test/py and the board. This is technically handled by tbot, but data is passed through verbatim.
The m_command channel is used to notify when test/py requests a powercycle of the board. tbot then calls the relevant methods from the board config.
The "bh" channel is where test/py is actually executed and from where pytest stdout is captured.
Lastly, we usually have an lh channel where the command to actually do a powercycle runs.
------
That all said, I am not really sure what is going wrong in your case. The traceback frame
│ File "tbot/tc/uboot/testpy.py", line 321, in testpy │ os.write(chan_console.fileno(), data) │ OSError: [Errno 9] Bad file descriptor
indicates that writing to the board's console failed (chan_console is the <board channel> from above). To me, this means either the terminal emulator you're using shut down (unlikely). Or the channel you are using does not support `.fileno()` correctly/returns some wrong file descriptor?
Maybe try a different connector if at all possible? E.g. using `SSHConnector` instead of `ParamikoConnector` or using `ConsoleConnector` instead of `PyserialConnector`...
If you can share you configs, I can take a closer look.
Regards,

Hi Harald,
On Thu, 27 Jan 2022 at 07:54, Harald Seiler hws@denx.de wrote:
Hi Simon,
first of all, sorry for the super late response to this :/ I had it on my list for a long time but had trouble finding enough time to revisit the test/py integration properly. You see, the existing test/py integration has bitrotten quite a lot and I couldn't even get the existing code working in my environment anymore...
I've now tried reworking all this code for a more robust solution [1]. It has reached a state where it works well for me and if you are still interested, I'd be grateful for some feedback on how it fares for your needs. That said, if your lab and board config haven't changed, the old integration might still work for you.
The new one is not yet in a tbot release but will be shortly. In the meantime you could check it out from the master branch and documentation can be found here:
https://tbot.tools/contrib/uboot.html#tbot_contrib.uboot.testpy
More regarding your actual problem below.
On Sat, 2021-10-30 at 13:34 -0600, Simon Glass wrote:
Hi,
I am trying to run the pytests on my unit. The documentation doesn't really explain how it works.
This is what I am trying:
$ tbot -vv -l kea.py -b rpi3.py -T tbot/contrib -p 'testpy_args=["-k", "help", "-vv"]' uboot_testpy tbot starting ... ├─Parameters: │ testpy_args = ['-k', 'help', '-vv'] ├─Calling uboot_testpy ... │ ├─Logging in on sglass@kea:22 ... │ ├─[sglass] bash --norc --noprofile │ ├─Calling uboot_setup_testhooks ... │ │ ├─[sglass] echo " ${HOME}" │ │ │ ## /home/sglass │ │ ├─[sglass] mkdir -p /home/sglass/tbot-workdir │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-testpy-tbot │ │ ├─Creating FIFOs ... │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] cat /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-scripts.sha256 │ │ │ ## 2d30892b61eb713ce9413e06c4f2a0cd00d2a74b6b8c2ac6624e1e49909b1897 │ │ ├─Hooks are up to date, skipping deployment ... │ │ ├─Adding hooks to $PATH ... │ │ ├─[sglass] echo " ${PATH}" │ │ │ ## /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/l ocal/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─[sglass] export PATH=/home/sglass/tbot-workdir/uboot-testpy- tbot:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/u sr/local/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─Open console & command channels ... │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-console │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-commands │ │ └─Done. (0.028s) │ ├─Calling uboot_checkout ... │ │ ├─Builder: rpi3 │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-rpi3/.git │ │ ├─[sglass] git -C /home/sglass/tbot-workdir/uboot-rpi3 fetch │ │ └─Done. (0.121s) │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/.config │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/include/autoconf.mk │ ├─[sglass] picocom -q -b 115200 /dev/ttyusb_port1 │ ├─POWERON (rpi3) │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1 │ ├─UBOOT (rpi3-u-boot) │ │ <> │ │ <> │ │ <> U-Boot 2020.10-rc2-00140-g392aa09f310 (Oct 30 2021 - 12:38:07 -0600) │ │ <> │ │ <> DRAM: 992 MiB │ │ <> RPI 3 Model B (0xa22082) │ │ <> MMC: mmc@7e202000: 0, sdhci@7e300000: 1 │ │ <> Loading Environment from FAT... *** Warning - bad CRC, using default environment │ │ <> │ │ <> In: serial │ │ <> Out: vidconsole │ │ <> Err: vidconsole │ │ <> Net: No ethernet found. │ │ <> Hit any key to stop autoboot: 0 │ │ <> U-Boot> │ ├─[sglass] cd /home/sglass/tbot-workdir/uboot-rpi3 │ ├─[sglass] ./test/py/test.py --build-dir . --board-type unknown -k help -vv │ │ ## +u-boot-test-flash unknown na │ │ ## ============================= test session starts ============================== │ │ ## platform linux -- Python 3.6.9, pytest-5.2.1, py-1.8.0, pluggy-0.13.0 -- /usr/bin/python3 │ │ ## cachedir: .pytest_cache │ │ ## rootdir: /home/sglass/tbot-workdir/uboot-rpi3/test/py, inifile: pytest.ini │ │ ## collected 324 items / 322 deselected / 2 selected │ │ ## │ │ ## test/py/tests/test_fpga.py::test_fpga_help SKIPPED [ 50%]│ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1
│ ├─POWEROFF (rpi3) │ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ └─Fail. (38.376s) ├─Exception: │ Traceback (most recent call last): │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/main.py", line 345, in main │ func(**params) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/decorators.py", line 92, in wrapped │ return tc(*args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/decorators.py", line 157, in wrapped │ return tc(lh, *args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.2-py3.8.egg/tbot/tc/uboot/testpy.py", line 321, in testpy │ os.write(chan_console.fileno(), data) │ OSError: [Errno 9] Bad file descriptor ├───────────────────────────────────────── └─FAILURE (38.488s)
I don't see the output appearing and I'm not sure how pytest is sending the commands to the board?
The challenge here is that tbot is in control of the board (because we need seamless integration of tbot's board config) while test/py directs what should happen. To facilitate this, IO if funneled through tbot by means of some fifos/named pipes on the host where test/py is running. Roughly speaking, the setup looks like this (details may differ, depending on config):
+---------------------------------------------------------+ | "build host" |
+---------------+ | has u-boot sources | | tbot host | | +----------+ | | //====================<bh channel>==[captures stdout/stderr]======test/py | | | | //=================<m_command channel>==[powercycle trigger]=== | | | | | //============<m_console channel>==[board rx/tx console]==invocation| | | | | | | | +----------+ | | +----+ | | +---------------------------------------------------------+ | |tbot| | | | |runs| | | +------------------------------------+ | |here| | | | lab host | | +----+ | | | from here, we | | | | | | can connect to | | | | | | the board | | | | | | | +----------------+ | | \============<board channel>==[board console]========== DUT | | \=================<lh channel>==[trigger powercycle] | | the device | | | +------------------------------------+ | that is tested | +---------------+ +----------------+
The board console is essentially forwared as is between test/py and the board. This is technically handled by tbot, but data is passed through verbatim.
The m_command channel is used to notify when test/py requests a powercycle of the board. tbot then calls the relevant methods from the board config.
The "bh" channel is where test/py is actually executed and from where pytest stdout is captured.
Lastly, we usually have an lh channel where the command to actually do a powercycle runs.
That all said, I am not really sure what is going wrong in your case. The traceback frame
│ File "tbot/tc/uboot/testpy.py", line 321, in testpy │ os.write(chan_console.fileno(), data) │ OSError: [Errno 9] Bad file descriptor
indicates that writing to the board's console failed (chan_console is the <board channel> from above). To me, this means either the terminal emulator you're using shut down (unlikely). Or the channel you are using does not support `.fileno()` correctly/returns some wrong file descriptor?
Maybe try a different connector if at all possible? E.g. using `SSHConnector` instead of `ParamikoConnector` or using `ConsoleConnector` instead of `PyserialConnector`...
If you can share you configs, I can take a closer look.
Thanks for all the info. I tried master and it mostly works, although Iget the same error:
tbot -vv -l kea.py -b rpi3.py -T tbot/contrib -p 'testpy_args=["-k", "help", "-vv"]' uboot_testpy tbot starting ... ├─Parameters: │ testpy_args = ['-k', 'help', '-vv'] ├─Calling uboot_testpy ... │ ├─Logging in on sglass@kea:22 ... │ ├─[sglass] bash --norc --noprofile │ ├─Calling uboot_setup_testhooks ... │ │ ├─[sglass] echo " ${HOME}" │ │ │ ## /home/sglass │ │ ├─[sglass] mkdir -p /home/sglass/tbot-workdir │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-testpy-tbot │ │ ├─Creating FIFOs ... │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_send │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_console_recv │ │ ├─[sglass] rm -rf /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] mkfifo /home/sglass/tbot-workdir/uboot-testpy-tbot/fifo_commands │ │ ├─[sglass] cat /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-scripts.sha256 │ │ │ ## 2d30892b61eb713ce9413e06c4f2a0cd00d2a74b6b8c2ac6624e1e49909b1897 │ │ ├─Hooks are up to date, skipping deployment ... │ │ ├─Adding hooks to $PATH ... │ │ ├─[sglass] echo " ${PATH}" │ │ │ ## /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─[sglass] export PATH=/home/sglass/tbot-workdir/uboot-testpy-tbot:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/cosarm/depot_tools:/home/sglass/.local/bin:/vid/software/devel/ubtest/u-boot-test-hooks/bin:/vid/software/devel/ubtest/standalone-hdctools │ │ ├─Open console & command channels ... │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-console │ │ ├─[sglass] /home/sglass/tbot-workdir/uboot-testpy-tbot/tbot-commands │ │ └─Done. (0.028s) │ ├─Calling uboot_checkout ... │ │ ├─Builder: rpi3 │ │ ├─[sglass] test -d /home/sglass/tbot-workdir/uboot-rpi3/.git │ │ ├─[sglass] git -C /home/sglass/tbot-workdir/uboot-rpi3 fetch │ │ │ ## remote: Enumerating objects: 16467, done. │ │ │ ## remote: Counting objects: 100% (7350/7350), done. │ │ │ ## remote: Compressing objects: 100% (2267/2267), done. │ │ │ ## remote: Total 4857 (delta 4223), reused 2903 (delta 2545) │ │ │ ## Receiving objects: 100% (4857/4857), 943.01 KiB | 18.13 MiB/s, done. │ │ │ ## Resolving deltas: 100% (4223/4223), completed with 1664 local objects. │ │ │ ## From git://ellesmere/u-boot │ │ │ ## + 7bc37ec5293...44a53218e33 acpi -> origin/acpi (forced update) │ │ │ ## * [new branch] acpi2 -> origin/acpi2 │ │ │ ## * [new branch] bin-doc -> origin/bin-doc │ │ │ ## + 94cc73dfc3f...fcc379bdbeb bm3f -> origin/bm3f (forced update) │ │ │ ## + cb586ac4001...7d7e1b96bdb cb3 -> origin/cb3 (forced update) │ │ │ ## * [new branch] conf2a -> origin/conf2a │ │ │ ## + 9f4e246ceef...9072e7357c0 conf3 -> origin/conf3 (forced update) │ │ │ ## 6c9e3d1fc08..2d2384bbaff dm-push -> origin/dm-push │ │ │ ## + 518a1b4a099...3a0072f9967 efi -> origin/efi (forced update) │ │ │ ## + b2ff5ec422b...7a00dec65d7 kconf2 -> origin/kconf2 (forced update) │ │ │ ## * [new branch] mki2 -> origin/mki2 │ │ │ ## * [new branch] rpi4 -> origin/rpi4 │ │ │ ## + f936e485c68...8e81bcd7801 ser -> origin/ser (forced update) │ │ │ ## * [new branch] sera -> origin/sera │ │ │ ## * [new branch] small -> origin/small │ │ │ ## * [new branch] try-m4 -> origin/try-m4 │ │ │ ## * [new branch] try-rk2 -> origin/try-rk2 │ │ │ ## * [new branch] try-sunix -> origin/try-sunix │ │ │ ## * [new branch] vid -> origin/vid │ │ │ ## * [new tag] archive/conf3-21-Jan-22 -> archive/conf3-21-Jan-22 │ │ │ ## * [new tag] archive/conf4-21-Jan-22 -> archive/conf4-21-Jan-22 │ │ │ ## * [new tag] archive/kconf-21-Jan-22 -> archive/kconf-21-Jan-22 │ │ │ ## * [new tag] archive/rpi2-21-Jan-22 -> archive/rpi2-21-Jan-22 │ │ │ ## * [new tag] archive/rpi3-21-Jan-22 -> archive/rpi3-21-Jan-22 │ │ │ ## * [new tag] dm-pull-26jan22 -> dm-pull-26jan22 │ │ │ ## * [new tag] fixes-for-2020.10-rc1 -> fixes-for-2020.10-rc1 │ │ │ ## * [new tag] next-2021-03-04 -> next-2021-03-04 │ │ │ ## * [new tag] video-2021-07-rc1 -> video-2021-07-rc1 │ │ │ ## * [new tag] video-2021-07-rc1-2 -> video-2021-07-rc1-2 │ │ │ ## * [new tag] video-2021-08-05 -> video-2021-08-05 │ │ │ ## * [new tag] video-20211009 -> video-20211009 │ │ │ ## * [new tag] video-20211228 -> video-20211228 │ │ │ ## * [new tag] video-for-2021-07-rc3 -> video-for-2021-07-rc3 │ │ │ ## * [new tag] video-for-2021.01 -> video-for-2021.01 │ │ │ ## * [new tag] video-for-2021.01-rc1 -> video-for-2021.01-rc1 │ │ │ ## * [new tag] video-for-v2021.04 -> video-for-v2021.04 │ │ │ ## * [new tag] video-for-v2021.04-rc3 -> video-for-v2021.04-rc3 │ │ │ ## * [new tag] video-next-20211228 -> video-next-20211228 │ │ └─Done. (1.585s) │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/.config │ ├─[sglass] test -e /home/sglass/tbot-workdir/uboot-rpi3/include/autoconf.mk │ ├─[sglass] picocom -q -b 115200 /dev/ttyusb_port1 │ ├─POWERON (rpi3) │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1 │ ├─UBOOT (rpi3-u-boot) │ │ <> │ │ <> │ │ <> U-Boot 2022.01-00116-g94cc73dfc3f (Jan 17 2022 - 14:42:07 -0700) │ │ <> │ │ <> DRAM: 992 MiB │ │ <> RPI 3 Model B (0xa22082) │ │ <> Core: 67 devices, 14 uclasses, devicetree: embed │ │ <> MMC: mmc@7e202000: 0, mmc@7e300000: 1 │ │ <> Loading Environment from FAT... Unable to read "uboot.env" from mmc0:1... │ │ <> In: serial │ │ <> Out: vidconsole │ │ <> Err: vidconsole │ │ <> Net: No ethernet found. │ │ <> starting USB... │ │ <> Bus usb@7e980000: USB DWC2 │ │ <> scanning bus usb@7e980000 for devices... usb_kbd usb_kbd: Timeout poll on interrupt endpoint │ │ <> Failed to get keyboard state from device 0c40:8000 │ │ <> 4 USB Device(s) found │ │ <> scanning usb for storage devices... 0 Storage Device(s) found │ │ <> Hit any key to stop autoboot: 0 │ │ <> U-Boot> │ ├─[sglass] cd /home/sglass/tbot-workdir/uboot-rpi3 │ ├─[sglass] ./test/py/test.py --build-dir . --board-type unknown -k help -vv │ │ ## +u-boot-test-flash unknown na │ │ ## ============================= test session starts ============================== │ │ ## platform linux -- Python 3.6.9, pytest-5.2.1, py-1.8.0, pluggy-0.13.0 -- /usr/bin/python3 │ │ ## cachedir: .pytest_cache │ │ ## rootdir: /home/sglass/tbot-workdir/uboot-rpi3/test/py, inifile: pytest.ini │ │ ## collected 343 items / 341 deselected / 2 selected │ │ ## │ │ ## test/py/tests/test_fpga.py::test_fpga_help SKIPPED [ 50%] │ │ ## test/py/tests/test_help.py::test_help │ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --dut │ ├─[sglass] ykushcmd -s YK17698 -g 1 │ │ ## │ │ ## │ │ ## Downstream port 1 is OFF │ │ ## │ ├─[sglass] ykushcmd -s YK17698 -u 1
│ ├─POWEROFF (rpi3) │ ├─[sglass] ykushcmd -s YK17698 -d 1 │ ├─[sglass] sd-mux-ctrl --device-serial sdwire-18 --ts │ ├─Exiting poweroff │ └─Fail. (43.705s) ├─Exception: │ Traceback (most recent call last): │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/main.py", line 345, in main │ func(**params) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/decorators.py", line 92, in wrapped │ return tc(*args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/decorators.py", line 157, in wrapped │ return tc(lh, *args, **kwargs) │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/tc/uboot/testpy.py", line 332, in testpy │ os.write(chan_console.fileno(), data) │ OSError: [Errno 9] Bad file descriptor ├───────────────────────────────────────── └─FAILURE (43.835s)
That happens after the tests finish, and what seems to be an exact 30 second delay from 'Exiting poweroff' to 'Fail'. I am not really any the wiser about what is happening there. The config is:
# Generated by labman from dut rpi3
import tbot from tbot.machine import board, channel, connector, linux from tbot.tc import git, shell, uboot from flash import Flash from send import Send from sdwire import Sdwire from ykush import Ykush
class Rpi3UBootBuilder(uboot.UBootBuilder): name = "rpi3" defconfig = "rpi_3_32b_defconfig" toolchain = "armv7-a"
class Rpi3( connector.ConsoleConnector, board.PowerControl, board.Board, Flash, Send, Sdwire, Ykush, ): name = "rpi3" desc = "Raspberry Pi 3b Fedora 34" console_uart = "/dev/ttyusb_port1" mount_point = "rpi3_b_boot" mount_uuid = "5B0C-97DF" sdwire_serial = "sdwire-18" ykush_port = "1" ykush_serial = "YK17698"
ether_mac = "b8:27:eb:b4:f9:f2"
def poweron(self) -> None: """Procedure to turn power on.""" self.sdwire_dut() self.ykush_reset()
def poweroff(self) -> None: """Procedure to turn power off.""" self.ykush_off() self.sdwire_ts() tbot.log.message('Exiting poweroff')
def connect(self, mach) -> channel.Channel: """Connect to the board's serial interface.""" return mach.open_channel("picocom", "-q", "-b", "115200", self.console_uart)
def flash(self, repo: git.GitRepository) -> None: self.sdwire_ts() self.flash_rpi(repo) self.sdwire_dut()
def send(self, repo: git.GitRepository) -> None: self.sdwire_ts() self.ykush_reset() self.send_None(repo) self.sdwire_dut()
class Rpi3UBoot( board.Connector, board.UBootAutobootIntercept, board.UBootShell, ): prompt = "U-Boot> " build = Rpi3UBootBuilder()
class Rpi3Linux( board.Connector, board.LinuxBootLogin, linux.Bash, ): username = "pi" password = "raspberry"
BOARD = Rpi3 UBOOT = Rpi3UBoot LINUX = Rpi3Linux
Also I saw a failure for self tests:
│ │ ├─selftest_machine_labhost_shell: │ │ │ Traceback (most recent call last): │ │ │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/tc/__init__.py", line 43, in testsuite │ │ │ test(**kwargs) │ │ │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/decorators.py", line 62, in wrapped │ │ │ return tc(*args, **kwargs) │ │ │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/tc/selftest/machine.py", line 54, in selftest_machine_labhost_shell │ │ │ selftest_machine_shell(lh) │ │ │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/decorators.py", line 62, in wrapped │ │ │ return tc(*args, **kwargs) │ │ │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/tc/selftest/machine.py", line 258, in selftest_machine_shell │ │ │ bs.terminate0() │ │ │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/machine/linux/util.py", line 158, in terminate0 │ │ │ retcode, output = self.terminate() │ │ │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/machine/linux/util.py", line 174, in terminate │ │ │ next(self._cmd_context) │ │ │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/machine/linux/bash.py", line 204, in cmd_context │ │ │ retcode = int(proxy_ch.read_until_prompt()) │ │ │ ValueError: invalid literal for int() with base 10: 'o $?\n' │ │ │ │ │ └─Fail. (1.050s) │ └─Fail. (1.091s) ├─Exception:
Finally, I have about 10 local patches which I'd like to send...
Regards, Simon

Hi Simon,
On Thu, 2022-01-27 at 09:05 -0700, Simon Glass wrote:
Hi Harald,
[...]
Thanks for all the info. I tried master and it mostly works, although Iget the same error:
[...]
│ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/tc/uboot/testpy.py", line 332, in testpy │ os.write(chan_console.fileno(), data) │ OSError: [Errno 9] Bad file descriptor ├───────────────────────────────────────── └─FAILURE (43.835s)
That happens after the tests finish, and what seems to be an exact 30 second delay from 'Exiting poweroff' to 'Fail'. I am not really any the wiser about what is happening there. The config is:
Did you try changing the channel as I mentioned? The channel is probably actually selected in the lab config where the connection to the machine labelled "sglass" is made. If that's still a ParamikoConnector, please try switching to the SSHConnector as a test (and the SSHConnector is generally preferred these days...).
# Generated by labman from dut rpi3
[...]
Also I saw a failure for self tests:
[...]
│ │ │ File "/home/sglass/.local/lib/python3.8/site-packages/tbot-0.9.4-py3.8.egg/tbot/machine/linux/bash.py", line 204, in cmd_context │ │ │ retcode = int(proxy_ch.read_until_prompt()) │ │ │ ValueError: invalid literal for int() with base 10: 'o $?\n' │ │ │ │ │ └─Fail. (1.050s) │ └─Fail. (1.091s) ├─Exception:
Hmm, that's the old selftests... Can you try running the new selftests in the tbot repository:
cd /path/to/tbot-sources python3 -m pytest selftest/
Finally, I have about 10 local patches which I'd like to send...
Sure, please go ahead! Either on the tbot list or on GitHub, whatever you prefer.
Regards,
participants (2)
-
Harald Seiler
-
Simon Glass