コード例 #1
0
    def connected(self, protocol):
        """Handles connection."""
        Service.connected(self, protocol)
        self.protocol = protocol

        self.send(Message(self.name, Message.TYPE_LOGIN))
        return
コード例 #2
0
ファイル: mailer.py プロジェクト: johnwilson/server-core
 def run(self):
     _period = 1000 * self.configreader["services"][self.name]["checkmail_interval"]
     beat = PeriodicCallback(self.cmd_processmails,
                             _period,
                             io_loop=self.ioloop)
     beat.start()
     Service.run(self)
コード例 #3
0
    def __init__(self, camera_factory=None):
        Service.__init__(self, cfg.CAMERA_NAME)

        self.camera_factory = camera_factory
        self.camera = None

        self.handlers[Message.TYPE_PARAMS] = self.handle_params

        self.client = Client(self, cfg.SERVER_HOST, cfg.SERVER_PORT)
        self.protocol = None

        self.frame_rate = 1.0
        return
コード例 #4
0
    def __init__(self, controller=None):
        Service.__init__(self, 'dispatcher')

        self.handlers[Message.TYPE_LOGIN] = self.handle_login
        self.handlers[Message.TYPE_IMAGE] = self.handle_image
        self.handlers[Message.TYPE_RESULT] = self.handle_result

        self.server = Server(self, cfg.SERVER_PORT)
        self.protocols = {}

        self.nodes = {}

        if cfg.DASHBOARD:
            self.dashboard = Dashboard()
            self.dashboard.start()

        else:
            self.dashboard = None

        measure_period = float(cfg.CONTROLLER_LOOP_TIME)/cfg.MEASURES_PER_LOOP
        self.monitor = Monitor(self.process_measurements, measure_period)
        self.monitor.register_item(self.ITEM_FPS, Monitor.ITEM_RATE)
        self.monitor.register_item(self.ITEM_MAKESPAN, Monitor.ITEM_AVG)
        self.monitor.register_item(self.ITEM_THROUGHPUT, Monitor.ITEM_RATE)

        self.controller = controller
        self.controller.dashboard = self.dashboard
        self.controller.dispatcher = self

        if self.dashboard:
            self.dashboard.controller = controller

        self.imagebuf = Queue.Queue()   # Buffer of encoded images
                                        # (time stamp, image data)

        # Initialize probe to blank image
        self.probe_image = self.generate_probe_image()

        self.tokens = Queue.Queue()
        self.job_id = 0

        self.job_image_cache = {}

        self.sub_loop = 0
        return
コード例 #5
0
def do_packet_ping(api_client, src_id, dst_id, socket_type):
    """Perform a packet ping from src to dst using the specified binary"""
    shim = Service(CONFIG.shim())

    with open(os.devnull, 'w') as null:
        p = subprocess.Popen(packet_ping_command(api_client, src_id, dst_id, socket_type),
                             stdout=null, stderr=null,
                             env={'LD_PRELOAD': shim.config.path,
                                  'OP_BINDTODEVICE': src_id})
        p.wait()
        expect(p.returncode).to(equal(0))
コード例 #6
0
ファイル: dataplane_spec.py プロジェクト: dlutton/openperf
def do_ping(api_client, ping_binary, src_id, dst_id, domain):
    """Perform a ping from src to dst using the specified binary"""
    shim = Service(CONFIG.shim())
    dst_ip = get_interface_address(api_client, dst_id, domain)

    with open(os.devnull, 'w') as null:
        p = subprocess.Popen(ping_command(ping_binary, dst_ip, domain),
                             stdout=null, stderr=null,
                             env={'LD_PRELOAD': shim.config.path,
                                  'OP_BINDTODEVICE': src_id})
        p.wait()
        expect(p.returncode).to(equal(0))
コード例 #7
0
ファイル: cpu_spec.py プロジェクト: Spirent/openperf
                            be_valid_cpu_generator,
                            be_valid_cpu_generator_result,
                            be_valid_dynamic_results)


CONFIG = Config(os.path.join(os.path.dirname(__file__),
                os.environ.get('MAMBA_CONFIG', 'config.yaml')))


def approximately_equal(a, b):
    return abs(a - b) < 0.01


with description('CPU Generator Module', 'cpu') as self:
    with before.all:
        service = Service(CONFIG.service())
        self._process = service.start()
        self._api = client.api.CpuGeneratorApi(service.client())
        if not check_modules_exists(service.client(), 'cpu'):
            self.skip()

    with after.all:
        try:
            for gen in self._api.list_cpu_generators():
                if gen.running:
                    self._api.stop_cpu_generator(gen.id)
                self._api.delete_cpu_generator(gen.id)

            self._process.terminate()
            self._process.wait()
        except AttributeError:
コード例 #8
0
    ports = ports_api.list_ports()
    expect(ports).to(have_len(be_above(1)))

    gen1 = generator_model(api_client)
    gen1.target_id = ports[0].id
    gen2 = generator_model(api_client)
    gen2.target_id = ports[1].id

    return [gen1, gen2]


with description('Packet Generator,', 'packet_generator') as self:
    with description('REST API'):

        with before.all:
            service = Service(CONFIG.service())
            self.process = service.start()
            self.api = client.api.PacketGeneratorsApi(service.client())

        with description('invalid HTTP methods,'):
            with description('/packet/generators,'):
                with it('returns 405'):
                    expect(lambda: self.api.api_client.call_api('/packet/generators', 'PUT')).to(
                        raise_api_exception(405, headers={'Allow': "DELETE, GET, POST"}))

            with description('/packet/generator-results,'):
                with it('returns 405'):
                    expect(lambda: self.api.api_client.call_api('/packet/generator-results', 'PUT')).to(
                        raise_api_exception(405, headers={'Allow': "DELETE, GET"}))

            with description('/packet/tx-flows,'):
コード例 #9
0
from expects import expect, be_empty
import os

import client.api
import client.models
from common import Config, Service
from common.matcher import be_valid_stack, raise_api_exception
from common.helper import check_modules_exists

CONFIG = Config(
    os.path.join(os.path.dirname(__file__),
                 os.environ.get('MAMBA_CONFIG', 'config.yaml')))

with description('Stacks,', 'stacks') as self:
    with before.all:
        service = Service(CONFIG.service())
        self.process = service.start()
        self.api = client.api.StacksApi(service.client())
        if not check_modules_exists(service.client(), 'packet-stack'):
            self.skip()

    with description('list,'):
        with it('returns valid stacks'):
            stacks = self.api.list_stacks()
            expect(stacks).not_to(be_empty)
            for stack in stacks:
                expect(stack).to(be_valid_stack)

        with description('unsupported method'):
            with it('returns 405'):
                expect(
コード例 #10
0
ファイル: bfs.py プロジェクト: johnwilson/server-core
 def __init__(self, id, name="bfs", configfile=None):
     Service.__init__(self, id, name, configfile)
     self.reserved_dbs = self.configreader["services"][self.name]["reserved_dbs"]
     self.collection = self.configreader["services"][self.name]["content_collection"]
     self.counter_collection = self.configreader["services"][self.name]["counter_collection"]
コード例 #11
0

def pcap_icmp_echo_request_lengths(pcap_file):
    lengths = []
    icmp_type = scapy.all.ICMP(type='echo-request').type
    for packet in scapy.all.rdpcap(pcap_file):
        if 'ICMP' in packet and packet['ICMP'].type == icmp_type:
            lengths.append(len(packet))
    return lengths


with description('Packet Capture,', 'packet_capture') as self:
    with description('REST API,'):

        with before.all:
            service = Service(CONFIG.service('dataplane'))
            self.process = service.start()
            self.api = client.api.PacketCapturesApi(service.client())
            self.intf_api = client.api.InterfacesApi(self.api.api_client)

            # By default, ping is a privileged process.  We need it unprivileged
            # to use LD_PRELOAD, so just make a copy as a regular user.
            self.temp_dir = tempfile.mkdtemp()
            shutil.copy(PING, self.temp_dir)
            self.temp_ping = os.path.join(self.temp_dir,
                                          os.path.basename(PING))
            expect(os.path.isfile(self.temp_ping))

        with description('invalid HTTP methods,'):
            with description('/packet/captures,'):
                with it('returns 405'):
コード例 #12
0
    return bsbgr


class has_location(Matcher):
    def __init__(self, expected):
        self._expected = CONFIG.service().base_url + expected

    def _match(self, subject):
        expect(subject).to(have_key('Location'))
        return subject['Location'] == self._expected, []


with description('Block,', 'block') as self:
    with description('REST API,'):
        with before.all:
            service = Service(CONFIG.service())
            self.process = service.start()
            self.api = client.api.BlockGeneratorApi(service.client())

        with description('invalid HTTP methods,'):
            with description('/block-devices,'):
                with it('returns 405'):
                    expect(lambda: self.api.api_client.call_api(
                        '/block-devices', 'PUT')).to(
                            raise_api_exception(405, headers={'Allow': "GET"}))

            with description('/block-files,'):
                with it('returns 405'):
                    expect(lambda: self.api.api_client.call_api(
                        '/block-files', 'PUT')).to(
                            raise_api_exception(405,
コード例 #13
0
ファイル: parser.py プロジェクト: johnwilson/server-core
 def __init__(self, id, name="parser", configfile=None):
     Service.__init__(self, id, name, configfile)
     self.parser_cmdline = CommandLineParser()
     self.parser_jsoncmdline = JSONCommandLineParser()
     self.parser_bql = BQLParser()
コード例 #14
0
                           get_block_dynamic_results_fields,
                           block_generator_model, file_model, bulk_start_model,
                           bulk_stop_model, wait_for_file_initialization_done)
from common.matcher import (be_valid_block_device, be_valid_block_file,
                            be_valid_block_generator,
                            be_valid_block_generator_result, has_location,
                            raise_api_exception, be_valid_dynamic_results)

CONFIG = Config(
    os.path.join(os.path.dirname(__file__),
                 os.environ.get('MAMBA_CONFIG', 'config.yaml')))

with description('Block,', 'block') as self:
    with description('REST API,'):
        with before.all:
            service = Service(CONFIG.service())
            self.process = service.start()
            self.api = client.api.BlockGeneratorApi(service.client())
            if not check_modules_exists(service.client(), 'block'):
                self.skip()

        with description('invalid HTTP methods,'):
            with description('/block-devices,'):
                with it('returns 405'):
                    expect(lambda: self.api.api_client.call_api(
                        '/block-devices', 'PUT')).to(
                            raise_api_exception(405, headers={'Allow': "GET"}))

            with description('/block-files,'):
                with it('returns 405'):
                    expect(lambda: self.api.api_client.call_api(
コード例 #15
0
                           example_ipv6_interface, example_ipv4andv6_interface,
                           ipv4_interface, ipv6_interface,
                           make_interface_protocols)
from common.matcher import be_valid_interface, raise_api_exception
from common.helper import check_modules_exists

CONFIG = Config(
    os.path.join(os.path.dirname(__file__),
                 os.environ.get('MAMBA_CONFIG', 'config.yaml')))
BULK_OP_SIZE = 4

with description('Interfaces,', 'interfaces') as self:
    with description('REST API,'):

        with before.all:
            service = Service(CONFIG.service())
            self.process = service.start()
            self.api = client.api.InterfacesApi(service.client())
            if not check_modules_exists(service.client(), 'packet-stack'):
                self.skip()

        with description('list,'):
            with description('Eth,'):
                with before.each:
                    intf = self.api.create_interface(
                        example_ipv4_interface(self.api.api_client))
                    expect(intf).to(be_valid_interface)
                    self.intf, self.cleanup = intf, intf

                with description('unfiltered,'):
                    with it('succeeds'):
コード例 #16
0
ファイル: mailcheck.py プロジェクト: johnwilson/server-core
 def __init__(self, id, name="emailcheck", configfile=None):
     Service.__init__(self, id, name, configfile)
コード例 #17
0
    for flow_id in gen_result.flows:
        flow = gen_api.get_tx_flow(flow_id)
        expect(flow).to(be_valid_transmit_flow)

    expect([f.id for f in gen_api.list_tx_flows() if f.id in gen_result.flows]).not_to(be_empty)


###
# Begin test proper
###
with description('Packet back to back', 'packet_b2b') as self:
    with description('generation and analysis,'):

        with before.all:
            service = Service(CONFIG.service())
            self.process = service.start()
            self.client = service.client()
            self.analyzer_api = client.api.PacketAnalyzersApi(service.client())
            self.generator_api = client.api.PacketGeneratorsApi(service.client())

        with description('with single traffic definition,'):
            with description('without signatures,'):
                with it('succeeds'):
                    ana_result, gen_result = configure_and_run_test(self.client,
                                                                    ANALYZER_CONFIG_NO_SIGS,
                                                                    GENERATOR_CONFIG_NO_SIGS)

                    # Validate results
                    exp_flow_count = 1
                    expect(len(ana_result.flows)).to(equal(exp_flow_count))
コード例 #18
0
from mamba import description, before, after, it
from expects import expect
import os

import client.api
from common import Config, Service
from common.helper import check_modules_exists

CONFIG = Config(
    os.path.join(os.path.dirname(__file__),
                 os.environ.get('MAMBA_CONFIG', 'config.yaml')))

with description('PacketIO arguments,', 'packetio_args'):
    with description('Empty core mask,'):
        with before.all:
            service = Service(CONFIG.service('packetio-args-1'))
            self.process = service.start()
            self.api = client.api.PortsApi(service.client())
            if not check_modules_exists(service.client(), 'packetio'):
                self.skip()

        with description('binary started,'):
            with it('has no port handlers'):
                expect(
                    lambda: self.api.list_ports().to(raise_api_exception(405)))

        with after.all:
            try:
                self.process.terminate()
                self.process.wait()
            except AttributeError:
コード例 #19
0
    return ta


def analyzer_models(api_client, protocol_counters=None, flow_counters=None):
    ana1 = analyzer_model(api_client, protocol_counters, flow_counters)
    ana2 = analyzer_model(api_client, protocol_counters, flow_counters)
    ana2.source_id = get_second_port_id(api_client)
    return [ana1, ana2]


with description('Packet Analyzer,', 'packet_analyzer') as self:
    with description('REST API,'):

        with before.all:
            service = Service(CONFIG.service())
            self.process = service.start()
            self.api = client.api.PacketAnalyzersApi(service.client())

        with description('invalid HTTP methods,'):
            with description('/packet/analyzers,'):
                with it('returns 405'):
                    expect(lambda: self.api.api_client.call_api(
                        '/packet/analyzers', 'PUT')).to(
                            raise_api_exception(
                                405, headers={'Allow': "DELETE, GET, POST"}))

            with description('/packet/analyzer-results,'):
                with it('returns 405'):
                    expect(lambda: self.api.api_client.call_api(
                        '/packet/analyzer-results', 'PUT')).to(
コード例 #20
0
 def disconnected(self, protocol):
     """Handles disconnection."""
     Service.disconnected(self, protocol)
     self.protocol = None
     self.stop_camera()
     return
コード例 #21
0
    s.config = config

    return s


def get_system_timesource(id=None):
    s = client.models.TimeSource()
    s.kind = 'system'
    s.id = 'test-source-' + str(id)

    return s


with description('Timesync,', 'timesync') as self:
    with before.all:
        service = Service(CONFIG.service())
        self.process = service.start()
        self.api = client.api.TimeSyncApi(service.client())

    with description('counters,'):
        with description('unsupported method,'):
            with it('returns 405'):
                expect(lambda: self.api.api_client.call_api(
                    '/time-counters', 'PUT')).to(
                        raise_api_exception(405, headers={'Allow': "GET"}))

        with description('GET,'):
            with description('list,'):
                with it('succeeds'):
                    counters = self.api.list_time_counters()
                    expect(counters).not_to(be_empty)
コード例 #22
0
ファイル: dataplane_spec.py プロジェクト: dlutton/openperf
    shim = Service(CONFIG.shim())
    dst_ip = get_interface_address(api_client, dst_id, domain)

    with open(os.devnull, 'w') as null:
        p = subprocess.Popen(ping_command(ping_binary, dst_ip, domain),
                             stdout=null, stderr=null,
                             env={'LD_PRELOAD': shim.config.path,
                                  'OP_BINDTODEVICE': src_id})
        p.wait()
        expect(p.returncode).to(equal(0))


with description('Dataplane,', 'dataplane') as self:

    with before.all:
        service = Service(CONFIG.service('dataplane'))
        self.process = service.start()
        self.api = client.api.InterfacesApi(service.client())
        if not check_modules_exists(service.client(), 'packetio'):
            self.skip()

    with description('ipv4,', 'dataplane:ipv4'):
        with description('ping,', 'dataplane:ipv4:ping'):
            with before.all:
                # By default, ping is a privileged process.  We need it unprivileged
                # to use LD_PRELOAD, so just make a copy as a regular user.
                self.temp_dir = tempfile.mkdtemp()
                shutil.copy(PING, self.temp_dir)
                self.temp_ping = os.path.join(self.temp_dir, os.path.basename(PING))
                expect(os.path.isfile(self.temp_ping))
コード例 #23
0
    ports = ports_api.list_ports()
    expect(ports).to(have_len(be_above(1)))

    gen1 = generator_model(api_client)
    gen1.target_id = ports[0].id
    gen2 = generator_model(api_client)
    gen2.target_id = ports[1].id

    return [gen1, gen2]


with description('Packet Generator,', 'packet_generator') as self:
    with description('REST API'):

        with before.all:
            service = Service(CONFIG.service())
            self.process = service.start()
            self.api = client.api.PacketGeneratorsApi(service.client())
            if not check_modules_exists(service.client(), 'packet-generator'):
                self.skip()

        with description('invalid HTTP methods,'):
            with description('/packet/generators,'):
                with it('returns 405'):
                    expect(lambda: self.api.api_client.call_api(
                        '/packet/generators', 'PUT')).to(
                            raise_api_exception(
                                405, headers={'Allow': "DELETE, GET, POST"}))

            with description('/packet/generator-results,'):
                with it('returns 405'):
コード例 #24
0

class has_location(Matcher):
    def __init__(self, expected):
        self._expected = expected

    def _match(self, subject):
        expect(subject).to(have_key('Location'))
        return subject['Location'] == self._expected, []


has_json_content_type = _has_json_content_type()

with description('Memory Generator Module', 'memory') as self:
    with before.all:
        service = Service(CONFIG.service())
        self._process = service.start()
        self._api = client.api.MemoryGeneratorApi(service.client())

    with after.all:
        try:
            self._process.terminate()
            self._process.wait()
        except AttributeError:
            pass

    with description('/memory-info'):
        with context('GET'):
            with before.all:
                self._result = self._api.memory_info_with_http_info(
                    _return_http_data_only=False)
コード例 #25
0
from mamba import description, before, after, it
from expects import *
import os

import client.api
import client.models
from common import Config, Service
from common.matcher import be_valid_module, raise_api_exception

CONFIG = Config(
    os.path.join(os.path.dirname(__file__),
                 os.environ.get('MAMBA_CONFIG', 'config.yaml')))

with description('Modules, ', 'modules') as self:
    with before.all:
        service = Service(CONFIG.service())
        self.process = service.start()
        self.api = client.api.ModulesApi(service.client())

    with description('list, '):
        with description('all, '):
            with it('returns list of modules'):
                modules = self.api.list_modules()
                expect(modules).not_to(be_empty)
                for module in modules:
                    expect(module).to(be_valid_module)

            with description('unsupported method, '):
                with it('returns 405'):
                    expect(lambda: self.api.api_client.call_api(
                        '/modules', 'PUT')).to(
コード例 #26
0
ファイル: mailer.py プロジェクト: johnwilson/server-core
 def __init__(self, id, name="email", configfile=None):
     Service.__init__(self, id, name, configfile)
     self.pending_emails_key = "pending.mails"
コード例 #27
0
ファイル: dataplane_spec.py プロジェクト: dlutton/openperf
def create_connected_endpoints(api_client, reader_id, writer_id, domain, protocol, null):
    """
    We need to create the server endpoint before the client endpoint, otherwise we
    run the risk of the client failing to connect before the server is started
    This function juggles the order as appropriate and returns the reader/writer
    subprocesses running the nc instances.  It also waits for verification that
    the client process has connected before returning.
    """

    shim = Service(CONFIG.shim())
    reader = None
    writer = None

    server_id = reader_id if is_server_interface(reader_id) else writer_id
    server_ip_addr = get_interface_address(api_client, server_id, domain)

    server_input = None
    if is_server_interface(writer_id):
        writer = subprocess.Popen(nc_command(server_ip_addr, version=domain, protocol=protocol, listen=True),
                                  stdin=subprocess.PIPE,
                                  stdout=null,
                                  stderr=subprocess.PIPE,
                                  close_fds=True,
                                  env={'LD_PRELOAD': shim.config.path,
                                       'OP_BINDTODEVICE': writer_id})
        server_input = writer.stdin

    if is_server_interface(reader_id):
        reader = subprocess.Popen(nc_command(server_ip_addr, version=domain, protocol=protocol, listen=True),
                                  stdin=subprocess.PIPE,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  close_fds=True,
                                  env={'LD_PRELOAD': shim.config.path,
                                       'OP_BINDTODEVICE': reader_id})
        server_input = reader.stdin

    try:
        # Use a writable stdin as a proxy for a listening server.  Using
        # the verbose option to nc can trigger a getnameinfo() call, which
        # can fail inside a container.
        wait_until_writable(server_input)
    except Exception as e:
        if reader: reader.kill()
        if writer: writer.kill()
        raise e

    client_output = None
    if not is_server_interface(writer_id):
        writer = subprocess.Popen(nc_command(server_ip_addr, version=domain, protocol=protocol, verbose=True),
                                  stdin=subprocess.PIPE,
                                  stdout=null,
                                  stderr=subprocess.PIPE,
                                  close_fds=True,
                                  env={'LD_PRELOAD': shim.config.path,
                                       'OP_BINDTODEVICE': writer_id})
        client_output = writer.stderr

    if not is_server_interface(reader_id):
        reader = subprocess.Popen(nc_command(server_ip_addr, version=domain, protocol=protocol, verbose=True),
                                  stdin=null,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  close_fds=True,
                                  env={'LD_PRELOAD': shim.config.path,
                                       'OP_BINDTODEVICE': reader_id})
        client_output = reader.stderr

    try:
        wait_for_keyword(client_output, "succeeded")
    except Exception as e:
        reader.kill()
        writer.kill()
        raise e

    return reader, writer
コード例 #28
0
ファイル: dataplane_spec.py プロジェクト: djoyner/openperf
    with open(os.devnull, 'w') as null:
        p = subprocess.Popen(ping_command(ping_binary, dst_ip),
                             stdout=null,
                             stderr=null,
                             env={
                                 'LD_PRELOAD': shim.config.path,
                                 'OP_BINDTODEVICE': src_id
                             })
        p.wait()
        expect(p.returncode).to(equal(0))


with description('Dataplane,', 'dataplane') as self:

    with before.all:
        service = Service(CONFIG.service('dataplane'))
        self.process = service.start()
        self.api = client.api.InterfacesApi(service.client())

    with description('ipv4,'):
        with description('ping,'):
            with before.all:
                # By default, ping is a privileged process.  We need it unprivileged
                # to use LD_PRELOAD, so just make a copy as a regular user.
                self.temp_dir = tempfile.mkdtemp()
                shutil.copy(PING, self.temp_dir)
                self.temp_ping = os.path.join(self.temp_dir,
                                              os.path.basename(PING))
                expect(os.path.isfile(self.temp_ping))

            with description('client interface,'):
コード例 #29
0
import os

import client.api
import client.models
from common import Config, Service
from common.matcher import be_valid_port, raise_api_exception


CONFIG = Config(os.path.join(os.path.dirname(__file__), os.environ.get('MAMBA_CONFIG', 'config.yaml')))


with description('Ports,', 'ports') as self:
    with description('REST API,'):

        with before.all:
            service = Service(CONFIG.service())
            self.process = service.start()
            self.api = client.api.PortsApi(service.client())

        with description('list,'):
            with description('unfiltered,'):
                with it('returns valid ports'):
                    ports = self.api.list_ports()
                    expect(ports).not_to(be_empty)
                    for port in ports:
                        expect(port).to(be_valid_port)

            with description('filtered,'):
                with description('known existing kind,'):
                    with it('returns valid ports of that kind'):
                        ports = self.api.list_ports(kind='dpdk')
コード例 #30
0
    ta.id = id
    ana = ana_api_client.create_packet_analyzer(ta)
    expect(ana).to(be_valid_packet_analyzer)

    return ana


CONFIG = Config(
    os.path.join(os.path.dirname(__file__),
                 os.environ.get('MAMBA_CONFIG', 'config.yaml')))

with description('MAC Learning,', 'learning') as self:
    with description('REST API'):

        with before.all:
            service = Service(CONFIG.service())
            self.process = service.start()
            self.ana_api = client.api.PacketAnalyzersApi(service.client())
            self.gen_api = client.api.PacketGeneratorsApi(service.client())
            self.intf_api = client.api.InterfacesApi(service.client())
            if not check_modules_exists(service.client(), 'packet-generator',
                                        'packet-analyzer'):
                self.skip()

        with description('packet-generator, '):
            with description('IPv4, '):
                with before.each:
                    self.source_ip = "192.168.22.10"
                    self.source_mac = "aa:bb:cc:dd:ee:01"
                    self.target_ip = "192.168.22.1"
                    self.intf1 = ipv4_interface(self.intf_api.api_client,