TCF complex examples with multiple targets

Perez-Gonzalez, Inaky <inaky.perez-gonzalez@...>


As promised on the call on 11/19, here are some examples for complex
testcases with TCF.

As an example, this is testing the USB CDC sample; references for this
in, and

Now this is a simplified version of a more complext test case, for
clarity, but it should work to illustrate the point. The most complex
thing here is the HW that helps automating the plugging/unpluggin

import os
import time
import re

# We want an interconnect of the ones that connect a USB capable
# device to a USB host; this represents a setup in which the zephyr
# target has been connected as a 'TCF' thing to the linux target
# (that's why they declare they are part of a usb__host__device
# interconnect. We do this with a USBRLY08B relay board
# (,
# see the examples section)
# linux target is a Linux device that is part of the interconnect
# Zephyr target is a Zephyr device that can run the cdc sample, only
# on boards of type arduino_101 or quark_se_c1000_devboard
#'type == "usb__host__device"')'linux', name = 'linux')
name = "zephyr",
spec = """zephyr_board in [
'arduino_101', 'quark_se_c1000_devboard'
app_zephyr = os.path.join(os.environ['ZEPHYR_BASE'],
"samples", "subsys", "usb", "cdc_acm"))
class _test(

def build_20_zephyr(zephyr):
# Set the zephyr configuration before building the App; the
# app is built with a method build_50(zephyr) introduced by
# the app_zephyr plugin above -- see
zephyr.zephyr.config_file_write("usb", """

def start_50_zephyr(self):

def start(linux, zephyr):
# start up the test by powering everything off and ensuring
# the zephyr target is unplugged from the linux one; then
# power on the linux board and wait for the shell to come up.


def eval_01(self, linux, zephyr):
# Use the methods created by app_zephyr to power up the
# zephyr board (as it knows the best way to do it).
# Then plug the zephyr board to the linux host and wait for
# it to enumerate (we just give it 3secs and check
# /dev/ttyACM0 exists)

time.sleep(3)'udevadm info /dev/ttyACM0',

# Now check the Zephyr side, wait till we get the cdc_acm>
# prompt on console, have the Linux side read so it sets DTR
# and start sending stuff back and forth

linux.send("cat /dev/ttyACM0 &")
zephyr.expect("DTR set, start test")
linux.send('echo "Send Helloworld to cdc_acm port" > /dev/ttyACM0')
zephyr.expect("Send Helloworld to cdc_acm port")
linux.send('echo "quit" > /dev/ttyACM0')

In our setup, there is a Linux NUC called nuc-02 which is a member of
an interconnect called usb__nuc-02__a101-05 -- that interconnect
basically groups together the nuc-02 and a target called a101-05.

$ tcf list -vv nuc-02
interconnects: {
u'usb__nuc-02__a101-05': {},
things: [u'a101-05']
type: nuc-linux-fedora-x86_64

The nuc-02 declares it is part of the usb__nuc-02__a101-05
interconnect, and that there is a thing we can connect to it, the
target called a101-05::

$ tcf list -avv a101-05
interconnects: {
u'usb__nuc-02__a101-05': {}

note how both the nuc-02 and a101-05 declare themselves to be a part
of the usb__nuc-02__a101-05 network, which is::

$ tcf list -vav usb__nuc-02__a101-05
id: usb__nuc-02__a101-05
type: usb__host__device

note how the type is usb__host__device, which is what we match against
in the testcase.

A detailed explanation of a networking example is available in the
documentation in,
so I won't go in detail on it -- but it is basically the same concept,
but with IP networking.

(I also must admit I have not tried those examples on a while, so they
might have bitrotten a wee bit -- my apologies if that is the case).