The Package

monk_tf.conn module

This module implements connection handling. Using the classes from this module you can connect directly to a target device via serial or ssh. Example:

import monk_tf.conn as mc
# create a serial connection
serial=mc.SerialConn(port="/dev/ttyUSB3", user="tester", pw="test")
# create a ssh connection
ssh=mc.SshConn(host="192.168.2.123", user="tester", pw="test")
# send a command
print serial.cmd("ls -al")
[...]
# send a command
ssh.cmd("ls -al")
[...]
class monk_tf.conn.ConnectionBase[source]

Bases: object

is the base class for all connections.

Don’t instantiate this class directly.

This class implements the behaviour of cmd() interactions, and it makes sure that it doesn’t login a user that is already logged in.

Extending this class requires to implement _get_exp() and _login().

cmd(msg, expect=None, timeout=30)[source]

send a shell command and retreive its output.

Parameters:
  • msg – the shell command
  • expect – a regex that represents the end of an interaction. Defaults to the prompt set on connection instantiation
  • timeout – how long a command call should wait for its desired result
Returns:

the stdout and stderr of the shell command

exp[source]

the pexpect object - Don’t bother with this if you don’t know what it means.

login(user=None, pw=None, timeout=30)[source]

attempts to authenticate to the connection.

Default for user and password are the one’s given to the connection on instantiation.

Parameters:
  • user – the username
  • pw – the password
  • timeout – how long the connection waits to see whether it is logged in already
class monk_tf.conn.SerialConn(name, port, user, pw, prompt='r?n?[^n]*#')[source]

Bases: monk_tf.conn.ConnectionBase

implements a serial connection.

Parameters:
  • name – the name of the connection
  • port – the path to the device file that is used for this connection
  • user – the user name for the login
  • pw – the password for the login
  • prompt – the default prompt to check for
class monk_tf.conn.SshConn(name, host, user, pw, prompt='r?n?[^n]*#')[source]

Bases: monk_tf.conn.ConnectionBase

implements an ssh connection.

Parameters:
  • name – the name of the connection
  • host – the URL to the device
  • user – the user name for the login
  • pw – the password for the login
  • prompt – the default prompt to check for

monk_tf.dev module

This module implements device handling. Using the classes from this module you can abstract a complete target device in a single object. On instantiation you give it some connections and then (theoretically) let the device handle the rest.

Example:

import monk_tf.dev as md
import monk_tf.conn as mc
# create a device with a ssh connection and a serial connection
d=md.Device(
    mc.SshConn('192.168.2.100', 'tester', 'secret'),
    mc.SerialConn('/dev/ttyUSB2', 'root', 'muchmoresecret'),
)
# send a command (the same way as with connections)
print d.cmd('ls -al')
[...]
exception monk_tf.dev.CantHandleException[source]

Bases: monk_tf.dev.DeviceException

is raised when a request cannot be handled by the connections of a Device.

class monk_tf.dev.DevelDevice(*args, **kwargs)[source]

Bases: monk_tf.dev.Hydra

Use this class instead of your other classes for development purposes

It does not reset anything and does not update. Everything else should work fine, though.

current_fw_version[source]
has_newest_firmware[source]
is_updated[source]
latest_build[source]
reset_config()[source]
update(link=None)[source]
class monk_tf.dev.Device(*args, **kwargs)[source]

Bases: object

is the API abstraction of a target device.

Parameters:
  • conns

    list of connections. The following works as well:

    ``Device(OneConnection(...), AnotherConnection(...),...)``
    
  • name – Device name for logging purposes.
cmd(msg, expect=None, timeout=30, login_timeout=None)[source]

Send a shell command to the target device.

Parameters:
  • msg – the shell command.
  • expect – if you don’t expect a prompt in the end but something else, you can add a regex here.
  • timeout – when command should return without finding what it’s looking for in the output. Will raise a :py:exception:`pexpect.Timeout` Exception.
Returns:

the standard output of the shell command.

exception monk_tf.dev.DeviceException[source]

Bases: exceptions.Exception

Base class for exceptions of the device layer.

class monk_tf.dev.Hydra(*args, **kwargs)[source]

Bases: monk_tf.dev.Device

is the device type of DResearch Fahrzeugelektronik GmbH.

current_fw_version[source]

the current version of the installed firmware

has_newest_firmware[source]

check whether the installed firmware is the newest on jenkins

is_updated[source]

check whether the device is already updated.

Currently it is implementd with dev.Hydra.has_newest_firmware().

latest_build[source]

get the latest build ID from jenkins

reset_config()[source]

reset the HydraIP configuration on the device

update(link=None)[source]

update the device to current build from Jenkins.

exception monk_tf.dev.UpdateFailedException[source]

Bases: monk_tf.dev.DeviceException

is raised if an update didn’t get finished or was rolled back.

monk_tf.fixture module

Instead of creating Device and AConnection objects by yourself, you can also choose to put corresponding data in a separate file and let this layer handle the object concstruction and destruction for you. Doing this will probably make your test code look more clean, keep the number of places where you need to change something as small as possible, and lets you reuse data that you already have described.

A hello world test with it looks like this:

import nose
from monk_tf import fixture

def test_hello():
    ''' say hello
    '''
    # set up
    h = fixture.Fixture('target_device.cfg')
    expected_out = "hello"
    # execute
    out = h.devs[0].cmd('echo "hello"')
    # assert
    nose.tools.eq_(expected_out, out)
    # tear down
    h.tear_down()

When using this layer setting up a device only takes one line of code. The rest of the information is in the target_device.cfg file. MONK currently comes with one text format parser predefined, which is the XiniParser. Xini is short for extended INI. You may, however, use any data format you want, if you extend the AParser class accordingly.

An example Xini data file might look like this:

[device1]
    type=Device
    [[serial1]]
        type=SerialConnection
        port=/dev/ttyUSB1
        user=example
        password=secret

As you can see it looks like an INI file. There are sections, consisting of a title enclosed in squared brackets ([]) and lists of properties, consisting of key-value pairs separated by equality signs (=). The unusual part is that the section serial1 is surrounded by two pairs of squared brackets ([]). This is the specialty of this format indicating that serial1 is a subsection of device1 and therefore is a nested section. This nesting can be done unlimited, by surrounding a section with more and more pairs of squared brackets ([]) according to the level of nesting intended. In this example serial1 belongs to device1 and the types indicate the corresponding MONK object to be created.

Classes

exception monk_tf.fixture.AFixtureException[source]

Bases: exceptions.Exception

Base class for exceptions of the fixture layer.

If you want to make sure that you catch all exceptions that are related to this layer, you should catch AFixtureExceptions. This also means that if you extend this list of exceptions you should inherit from this exception and not from Exception.

exception monk_tf.fixture.AParseException[source]

Bases: monk_tf.fixture.AFixtureException

Base class for exceptions concerning parsing errors.

class monk_tf.fixture.AParser[source]

Bases: dict

Base class for all parsers.

Do not instantiate this class! This basically just provides the API that is needed by Fixture to interact with the data that is parsed. Each child class should make sure that it always provides its parsed data like a dict would. If you require your own parser, you can extend this. XiniParser provides a very basic example.

exception monk_tf.fixture.CantParseException[source]

Bases: monk_tf.fixture.AFixtureException

is raised when a Fixture cannot parse a given file.

class monk_tf.fixture.Fixture(source=None, name=None, parsers=None, classes=None, lookfordbgsrc=True)[source]

Bases: object

Creates MONK objects based on dictionary like objects.

This is the class that provides the fundamental feature of this layer. It reads data files by trying to parse them via its list of known parsers and if it succeeds, it creates MONK objects based on the configuration given by the data file. Most likely these objects are one or more Device objects that have at least one AConnection object each. If more than one fixture file is read containing the same name on the highest level, then the latest data gets used. This does not work on lower levels of nesting, though. If you attempt to overwrite lower levels of nesting, what actually happens is that the highest layer gets overwritten and you lose the data that was stored in the older objects. This is simply how set.update() works.

One source of data (either a file name or a child class of AParser) can be given to an object of this class by its constructer, others can be added afterwards with the read() method. An example looks like this:

import monk_tf.fixture as mf

fixture = mf.Fixture('/etc/monk_tf/default_devices.cfg')
        .read('~/.monk/default_devices.cfg')
        # can also be a parser object
        .read(XiniParser('~/testsuite12345/suite_devices.cfg'))
Parameters:
  • source – The fixture file or AParser object to be read.
  • name – The name of this object.
  • parsers – An iterable of AParser classes to be used for parsing a given source.
  • classes – A dict of classes to class names. Used for parsing the type attribute in fixture files.
  • lookfordbgsrc – If True an environment variable is looked for to read a local debug config. If False it won’t be looked for.
cmd(msg)[source]

call cmd() from first Device

read(source)[source]

Read more data, either as a file name or as a parser.

Parameters:source – the data source; either a file name or a AParser child class instance.
Returns:self
tear_down()[source]

Can be used for explicit destruction of managed objects.

This should be called in every test case as the last step.

exception monk_tf.fixture.NoDeviceException[source]

Bases: monk_tf.fixture.AFixtureException

is raised when a :py:clas:`~monk_tf.fixture.Fixture` requires a device but has none.

exception monk_tf.fixture.NotXiniException[source]

Bases: monk_tf.fixture.AParseException

is raised when a fixture file could not be parsed as extended INI.

class monk_tf.fixture.XiniParser(infile=None, options=None, configspec=None, encoding=None, interpolation=True, raise_errors=False, list_values=True, create_empty=False, file_error=False, stringify=True, indent_type=None, default_encoding=None, unrepr=False, write_empty_values=False, _inspec=False)[source]

Bases: configobj.ConfigObj, monk_tf.fixture.AParser

Reads config files in extended INI format.

Parse a config file or create a config file object.

``ConfigObj(infile=None, configspec=None, encoding=None,
interpolation=True, raise_errors=False, list_values=True, create_empty=False, file_error=False, stringify=True, indent_type=None, default_encoding=None, unrepr=False, write_empty_values=False, _inspec=False)``

Module contents

This is the package overview of MONK. If anything is unclear, you might have a look into Getting Started.

The following texts describe the three layers that were explained in The Layers:

Table Of Contents

Previous topic

Intro

Next topic

Glossary

This Page