# Copyright (c) 2016 DENX Software Engineering GmbH
# Heiko Schocher <hs@denx.de>
#
# SPDX-License-Identifier:	GPL-2.0+
#

write a new testcase
=====================

A TC is written in python, so you can use python as usual. For accessing
the boards console, use functions from the tbotlib, therefore

First import the tbotlib with the line:

  from tbotlib import tbot

If your TC uses variables, please add a line which adds them to
the log file (for debugging purposes):

  logging.info("args: %s ...", tb.varname, ...)

Say tbot, for which board state your TC is valid with:

  tb.set_board_state("u-boot")

Then you are ready ... and you can use the tbotlib funtions
for writting/reading to the boards console.

Big fat warning:

A TC must worry about to end only if a board has finished the shell
command!

Not following this rule, will end in unpredictable behaviour.

(hopefully) useful tbotlib functions
====================================
- set the board state, you want to test
  tb.set_board_state(state)
  states are: "u-boot" or "linux"
  If tbot could not set the board state, tbot ends with failure.

- write a command to the boards console:
  tb.eof_write_con(command):
    write the command to the boards console. If this
    fails, tbot ends with failure

- write a command to boards console and wait for prompt:
  tb.eof_write_cmd(fd, command):
    fd: filedescriptor which is used, use tb.channel_con for boards console
    command: command which is written to fd

    Wait endless for board prompt

- write a list of commands to boards console:
  tb.eof_write_cmd_list(fd, cmdlist):
    fd: filedescriptor which is used, use tb.channel_con for boards console
    cmdlist: python list of commandstrings which is written to fd

- wait for boards prompt:
  tb.eof_read_end_state_con(retry):
    retry: deprecated, not used anymore, cleanup needed here...
    tbot waits endless for the boards prompt

- write a command, wait for prompt and check, if a string is read
  tb.write_cmd_check(fd, cmd, string):
    fd: filedescriptor which is used, use tb.channel_con for boards console
    cmd: command, which is send to fd
    string: string which should be read from fd

    return value:
      True, if string is read and tbot got back boards prompt
      False, else

  tb.eof_write_cmd_check(fd, cmd, string):
    same as tb.write_cmd_check(fd, cmd, string) except, that tbot
    ends immediately with Failure, if string is not read.

- read until prompt and search strings:
  tb.readline_and_search_strings(fd, strings):
    fd: filedescriptor which is used, use tb.channel_con for boards console
    strings: python list of strings, which can be read
      If one of this strings is read, this function return the index, which
      string is read. This function shoud be called in a while loop,
      until this function returns 'prompt'

- read a line from filedescriptor:
  not recommended to use, as the TC must check, if tprompt is read for every
  readen line. Also TC must ensure, that it ends only, if prompt is read.
  tb.read_line(fd, retry)
    fd: filedescriptor which is used, use tb.channel_con for boards console
    retry: retry of trying to reead a line

  return values:
    True, if a line is read. Readen line in tb.buf[fd]
    False, if something read, but not a complete line
    None, if nothing is read

  check if string contains prompt with:
  tb.is_end_fd(fd, string)
    fd: filedescriptor which is used, use tb.channel_con for boards console
    string: buffer, in which a prompt gets searched.

- calling other TC:
  eof_call_tc(name):
    call another TC from "src/tc"
    if the called TC fails with failure, tbot ends with failure

  call_tc(name):
    call another TC from "src/tc"
    if the TC which call_tc calls  fails, call_tc() returns False, else True

There are more functions, but for writting TC this should be enough. But
its software, so new useful functions can always pop up.

Heiko Schocher <hs@denx.de>
v1 2016.01.23
