Live tests code documentation

class pierky.arouteserver.tests.live_tests.base.LiveScenario(methodName='runTest')

An helper class to run tests for a given scenario.

This class must be derived by scenario-specific classes that must:

  • set the MODULE_PATH attribute to __file__, in order to correctly locate files needed by the scenario.

  • fill the INSTANCES list with a list of BGPSpeakerInstance (or derived) instances representing all the BGP speakers involved in the scenario.

  • set the SHORT_DESCR with a short description of the scenario; it will be used to print tests description in the format “<SHORT_DESCR>: <test function docstring>”.

  • fill the DATA dictionary with IP prefixes IDs that represent all the IP addresses used by the scenario; this is useful to decouple real IP addresses from what they represent or are used to and to have a single definition of the tests functions and scenario configuration that can be used for both IPv4 and IPv6 tests.

    Example:

    DATA = {
        "rs_IPAddress": "192.0.2.2",
        "AS1_IPAddress": "192.0.2.11",
        "AS1_allowed_prefixes": "1.0.0.0/8",
        "AS1_good_prefix": "1.0.1.0/24",
        "AS101_prefixes": "101.0.0.0/8"
    }
    
  • optionally, if it’s needed by the scenario, the derived classes must also fill the AS_SET and R_SET dictionaries with the expected content of any expanded AS-SETs used in IRRDB validation:

    • AS_SET’s items must be in the format <AS_SET_name>: <list_of_authorized_origin_ASNs>.
    • R_SET’s items must be in the format <AS_SET_name>: <list_of_authorized_prefix_IDs> (where prefix IDs are those reported in the DATA dictionary).

    Example:

    AS_SET = {
        "AS-AS1": [1],
        "AS-AS1_CUSTOMERS": [101],
        "AS-AS2": [2],
        "AS-AS2_CUSTOMERS": [101]
    }
    R_SET = {
        "AS-AS1": [
            "AS1_allowed_prefixes"
        ],
        "AS-AS1_CUSTOMERS": [
            "AS101_prefixes"
        ]
    }
    
  • optionally, if it’s needed by the scenario, the derived classes can also set the RTT dictionary with the values of the RTTs of the clients. Keys can be IP addresses of clients or the prefix IDs used in the DATA dictionary to represent them.

    Example:

    RTT = {
        "192.0.2.11": 14,
        "2001:db8::11": 165,
        "AS1_IPAddress": 44
    }
    
  • optionally, if it’s needed by the scenario, the derived classes can also set the REJECT_CAUSE_COMMUNITY attribute with the pattern followed by BGP communities used to tag routes that are considered to be rejected (see the filtering.reject_policy general configuration section and the reject_cause community). The value of this attribute must be a regular expression that matches the standard, extended or large BGP communities used to tag invalid routes. For example, if the standard BGP community 65520:dyn_val is used, the value must be ^65520:(\d+)$. If this attribute is not None, routes that have LOCAL_PREF == 1 and the reject_cause BGP community with dyn_val == 0 are considered as filtered. The REJECTED_ROUTE_ANNOUNCED_BY_COMMUNITY attribute can also be set to match the community used to track the announcing ASN of invalid routes.

  • implement the set_instance_variables method, used to set local instance attributes for the instances used within the tests functions.

    Example:

    def set_instance_variables(self):
        self.AS1 = self._get_instance_by_name("AS1")
        self.AS2 = self._get_instance_by_name("AS2")
        self.AS131073 = self._get_instance_by_name("AS131073")
        self.rs = self._get_instance_by_name("rs")
    

Set the __test__ attribute of derived classes to False to avoid them to be used directly by nose to run tests; only the specific IPv4/IPv6 class (the one where the DATA dictionary is set) must have __test__ == True.

classmethod build_other_cfg(tpl_name)

Builds configuration files for BGP speakers which are not the route server.

Parameters:tpl_name (str) – the name of the Jinja2 template file relative to the scenario directory.
Returns:the path of the local rendered file.

To render the template, one attribute is used and consumed by Jinja2:

  • data, the scenario’s DATA dictionary.

The resulting file is saved into the local var directory and its absolute path is returned.

classmethod build_rs_cfg(tpl_dir_name, tpl_name, out_file_name, ip_ver, cfg_general=None, cfg_bogons='bogons.yml', cfg_clients='clients.yml', **kwargs)

Builds configuration file for the route server.

Parameters:
  • tpl_dir_name (str) – the directory where Jinja2 templates are located, relative to the current scenario.
  • tpl_name (str) – the name of the template to be rendered.
  • out_file_name (str) – the name of the destination file.
  • ip_ver (int) – the IP version for which this route server will operate. Use None if the configuration is valid for both IPv4 and IPv6.
  • cfg_general (str), cfg_bogons (str), cfg_clients (str) – the name of the 3 main files containing route server’s options and policies, clients definition and bogons IP addresses. File names are relative to the scenario directory.
Returns:

the path of the local rendered file.

The resulting file is saved into the local var directory and its absolute path is returned.

log_contains(inst, msg, instances={})

Test if the BGP speaker’s log contains the expected message.

This only works for BGP speaker instances that support message logging: currently only BIRD.

If no log entries are found, the TestCase.fail() method is called and the test fails.

Parameters:
  • inst – the BGPSpeakerInstance instance where the expected message is searched on.
  • msg (str) – the text that is expected to be found within BGP speaker’s log.
  • instances (dict) – a dictionary of pairs “<macro>: <BGPSpeakerInstance>” used to expand macros on the msg argument. Macros are expanded using the BGP speaker’s specific client ID or protocol name.

Example

Given self.rs the instance of the route server, and self.AS1 the instance of one of its clients, the following code expands the “{AS1}” macro using the BGP speaker specific name for the instance self.AS1 and then looks for it within the route server’s log:

self.log_contains(self.rs, "{AS1} bad ASN", {"AS1": self.AS1})

On BIRD, “{AS1}” will be expanded using the “protocol name” that BIRD uses to identify the BGP session with AS1.

receive_route(inst, prefix, other_inst=None, as_path=None, next_hop=None, std_comms=None, lrg_comms=None, ext_comms=None, local_pref=None, filtered=None, only_best=None, reject_reason=None)

Test if the BGP speaker receives the expected route(s).

If no routes matching the given criteria are found, the TestCase.fail() method is called and the test fails.

Parameters:
  • inst – the BGPSpeakerInstance instance where the routes are searched on.
  • prefix (str) – the IPv4/IPv6 prefix of the routes to search for.
  • other_inst – if given, only routes received from this BGPSpeakerInstance instance are considered.
  • as_path (str) – if given, only routes with this AS_PATH are considered.
  • next_hop – can be a string or a BGPSpeakerInstance instance; if given, only routes that have a NEXT_HOP address matching this one are considered.
  • lrg_comms, ext_comms (std_comms,) – if given, only routes that carry these BGP communities are considered. Use an empty list ([]) to consider only routes with no BGP comms.
  • local_pref (int) – if given, only routes with local-pref equal to this value are considered.
  • filtered (bool) – if given, only routes that have been (not) filtered are considered.
  • only_best (bool) – if given, only best routes are considered.
  • reject_reason (int) –

    valid only if filtered is True: if given the route must be reject with this reason code. It can be also a set of codes: in this case, the route must be rejected with one of those codes.

    The list of valid codes is reported in docs/CONFIG.rst or at https://arouteserver.readthedocs.io/en/latest/CONFIG.html#reject-policy

session_exists(inst_a, inst_b_or_ip)

Test if a BGP session between the two instances exists.

Parameters:
  • inst_a – the BGPSpeakerInstance instance where the BGP session is looked for.
  • inst_b_or_ip – the BGPSpeakerInstance instance or an IP address that inst_a is expected to peer with.
session_is_up(inst_a, inst_b)

Test if a BGP session between the two instances is up.

If a BGP session between the two instances is not up, the TestCase.fail() method is called and the test fails.

Parameters:
  • inst_a – the BGPSpeakerInstance instance where the BGP session is looked for.
  • inst_b – the BGPSpeakerInstance instance that inst_a is expected to peer with.
test_999_log_contains_errors()

{}: log contains errors

classmethod use_static_file(local_filename)

Prepare the local file in order to use it later.

Parameters:filename (str) – the name of the local file, relative to the scenario directory.
Returns:the path of the file to be used
class pierky.arouteserver.tests.live_tests.base.LiveScenario_TagRejectPolicy

Helper class to run a scenario as if reject_policy is set to ‘tag’.

When a scenario inherits this class, its route server is configured as if the reject_policy.policy is tag, the 65520:dyn_val value is used for the reject_cause BGP community and the rt:65520:dyn_val value for the rejected_route_announced_by one.

The general.yml file, or the file given in the orig_file argument of _get_cfg_general method, is cloned and reconfigured with the aforementioned settings.

This class is mostly used for OpenBGPD tests since the underlaying mechanism allows to track the reason that brought to consider the route as rejected and to test filters out during test cases execution.

This class should be used in multiple inheritance:

Example

class SkeletonScenario_OpenBGPDIPv4(LiveScenario_TagRejectPolicy, SkeletonScenario):

class pierky.arouteserver.tests.live_tests.instances.BGPSpeakerInstance(name, ip, mount=[], **kwargs)

This class abstracts a BGP speaker instance.

Currently, the start, stop, is_running and run_cmd methods are implemented by the DockerInstance and KVMInstance derived classes, while the restart, reload_config, get_bgp_session, get_routes and log_contains methods by the [Docker|KVM]Instance-derived BIRDInstance and OpenBGPDInstance classes.

bgp_session_is_up(other_inst, force_update=False)

Check if a BGP session with other_inst is up.

Parameters:
  • other_inst – the BGPSpeakerInstance instance that the current instance is expected to have a running BGP session with.
  • force_update (bool) – if True, the instance must bypass any caching mechanism used to keep the BGP sessions status.
Returns:

True if the current instance has a running BGP session with other_inst; False otherwise.

get_bgp_session(other_inst, force_update=False)

Get information about the BGP session with other_inst.

Parameters:
  • other_inst – the BGPSpeakerInstance instance that the current instance is expected to have a running BGP session with.
  • force_update (bool) – if True, the instance must bypass any caching mechanism used to keep the BGP sessions status.
Returns:

None if the BGP session is not found, otherwise a dictionary containing information about the BGP session:

  • ”ip”: “neighbor IP address”,
  • ”is_up”: [True|False]

get_routes(prefix, include_filtered=False, only_best=False)

Get a list of all the known routes for prefix.

Parameters:
  • prefix (str) – the IP prefix that returned routes must match. If None, all the routes are returned.
  • include_filtered (bool) – include filtered routes / rejected prefixes in the result.
  • only_best (bool) – include only the best route toward prefix.
Returns:

list of Route objects.

log_contains(s)

Verifies if the BGP speaker’s logs contain the expected message.

Parameters:s (str) – the message that is expected to be found in the BGP speaker’s logs.
Returns:True or False if the message is found or not.
log_contains_errors(allowed_errors=[], list_errors=False)

Returns True if the BGP speaker’s log contains warning/errors.

Parameters:
  • allowed_errors (list) – list of strings representing errors that are allowed to be found within the BGP speaker’s log.
  • list_errors (bool) – when set to True, the functions returns a touple (errors_found, list_of_errors).
Returns:

True of False if error messages or warnings are found within the BGP speaker’s logs. When list_errors is True, a touple (bool, str).

Return type:

When list_errors is False

exception pierky.arouteserver.tests.live_tests.instances.InstanceError
exception pierky.arouteserver.tests.live_tests.instances.InstanceNotRunning(name, *args, **kwargs)
class pierky.arouteserver.tests.live_tests.instances.Route(prefix, **kwargs)

Details about a route.

prefix

the IPv4/IPv6 prefix.

Type:str
via

the IP address of the peer from which the route has been received.

Type:str
as_path

the AS_PATH attribute of the route, in the “<asn> <asn> <asn>…” format (example: “1 2 345”).

Type:str
next_hop

the NEXT_HOP attribute of the route.

Type:str
filtered

True if the route has been rejected/filtered.

Type:bool
std_comms

list of standard BGP communities (strings in the “x:y” format).

Type:list
lrg_comms

list of large BGP communities (strings in the “x:y:z” format).

Type:list
ext_comms

list of extended BGP communities (strings in the “[rt|ro]:x:y” format).

Type:list
localpref

local-pref.

Type:int
reject_reasons

list of integers that identify the reasons for which the route is considered to be rejected.

Type:list
class pierky.arouteserver.tests.live_tests.bird.BIRDInstance(*args, **kwargs)

This class implements BIRD-specific methods.

This class is derived from DockerInstance, that implements some Docker-specific methods to start/stop the instance and to run commands on it.

get_bgp_session(other_inst_or_ip, force_update=False)

Get information about the BGP session with other_inst.

Parameters:
  • other_inst – the BGPSpeakerInstance instance that the current instance is expected to have a running BGP session with.
  • force_update (bool) – if True, the instance must bypass any caching mechanism used to keep the BGP sessions status.
Returns:

None if the BGP session is not found, otherwise a dictionary containing information about the BGP session:

  • ”ip”: “neighbor IP address”,
  • ”is_up”: [True|False]

get_routes(prefix, include_filtered=False, only_best=False)

Get a list of all the known routes for prefix.

Parameters:
  • prefix (str) – the IP prefix that returned routes must match. If None, all the routes are returned.
  • include_filtered (bool) – include filtered routes / rejected prefixes in the result.
  • only_best (bool) – include only the best route toward prefix.
Returns:

list of Route objects.

log_contains(s)

Verifies if the BGP speaker’s logs contain the expected message.

Parameters:s (str) – the message that is expected to be found in the BGP speaker’s logs.
Returns:True or False if the message is found or not.
log_contains_errors(allowed_errors=[], list_errors=False)

Returns True if the BGP speaker’s log contains warning/errors.

Parameters:
  • allowed_errors (list) – list of strings representing errors that are allowed to be found within the BGP speaker’s log.
  • list_errors (bool) – when set to True, the functions returns a touple (errors_found, list_of_errors).
Returns:

True of False if error messages or warnings are found within the BGP speaker’s logs. When list_errors is True, a touple (bool, str).

Return type:

When list_errors is False

reload_config()

Reload BIRD configuration.

It runs the “[birdcl/birdcl6] configure” command to reload BIRD’s configuration.

restart()

Restart BIRD.

It runs the “[birdcl/birdcl6] configure” and “restart all” commands.

class pierky.arouteserver.tests.live_tests.bird.BIRDInstanceIPv4(*args, **kwargs)
class pierky.arouteserver.tests.live_tests.bird.BIRDInstanceIPv6(*args, **kwargs)