Introduce iperf3 testing infrastructure
Change-Id: I6ff6bef14feb535d98ca41b9788700d699e1ef1e
This commit is contained in:
parent
34735f1c49
commit
8a72586835
|
@ -0,0 +1,107 @@
|
||||||
|
# osmo_gsm_tester: specifics for running an iperf3 client and server
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 by sysmocom - s.f.m.c. GmbH
|
||||||
|
#
|
||||||
|
# Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
from . import log, util, process, pcap_recorder
|
||||||
|
|
||||||
|
DEFAULT_SRV_PORT = 5003
|
||||||
|
|
||||||
|
class IPerf3Server(log.Origin):
|
||||||
|
|
||||||
|
def __init__(self, suite_run, ip_address):
|
||||||
|
super().__init__(log.C_RUN, 'iperf3-srv_%s' % ip_address.get('addr'))
|
||||||
|
self.run_dir = None
|
||||||
|
self.config_file = None
|
||||||
|
self.process = None
|
||||||
|
self.suite_run = suite_run
|
||||||
|
self.ip_address = ip_address
|
||||||
|
self._port = DEFAULT_SRV_PORT
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self.log('Starting iperf3-srv')
|
||||||
|
self.run_dir = util.Dir(self.suite_run.get_test_run_dir().new_dir(self.name()))
|
||||||
|
|
||||||
|
pcap_recorder.PcapRecorder(self.suite_run, self.run_dir.new_dir('pcap'), None,
|
||||||
|
'host %s and port not 22' % self.addr())
|
||||||
|
|
||||||
|
self.log_file = self.run_dir.new_file('iperf3_srv.json')
|
||||||
|
self.process = process.Process(self.name(), self.run_dir,
|
||||||
|
('iperf3', '-s', '-B', self.addr(),
|
||||||
|
'-p', str(self._port), '-J',
|
||||||
|
'--logfile', os.path.abspath(self.log_file)),
|
||||||
|
env={})
|
||||||
|
self.suite_run.remember_to_stop(self.process)
|
||||||
|
self.process.launch()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.suite_run.stop_process(self.process)
|
||||||
|
|
||||||
|
def get_results(self):
|
||||||
|
with open(self.log_file) as f:
|
||||||
|
data = json.load(f)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def addr(self):
|
||||||
|
return self.ip_address.get('addr')
|
||||||
|
|
||||||
|
def port(self):
|
||||||
|
return self._port
|
||||||
|
|
||||||
|
def running(self):
|
||||||
|
return not self.process.terminated()
|
||||||
|
|
||||||
|
def create_client(self):
|
||||||
|
return IPerf3Client(self.suite_run, self)
|
||||||
|
|
||||||
|
class IPerf3Client(log.Origin):
|
||||||
|
|
||||||
|
def __init__(self, suite_run, iperf3srv):
|
||||||
|
super().__init__(log.C_RUN, 'iperf3-cli_%s' % iperf3srv.addr())
|
||||||
|
self.run_dir = None
|
||||||
|
self.config_file = None
|
||||||
|
self.process = None
|
||||||
|
self.server = iperf3srv
|
||||||
|
self.suite_run = suite_run
|
||||||
|
|
||||||
|
def run_test(self, netns=None):
|
||||||
|
self.log('Starting iperf3-client connecting to %s:%d' % (self.server.addr(), self.server.port()))
|
||||||
|
self.run_dir = util.Dir(self.suite_run.get_test_run_dir().new_dir(self.name()))
|
||||||
|
|
||||||
|
pcap_recorder.PcapRecorder(self.suite_run, self.run_dir.new_dir('pcap'), None,
|
||||||
|
'host %s and port not 22' % self.server.addr(), netns)
|
||||||
|
|
||||||
|
self.log_file = self.run_dir.new_file('iperf3_cli.json')
|
||||||
|
popen_args = ('iperf3', '-c', self.server.addr(),
|
||||||
|
'-p', str(self.server.port()), '-J',
|
||||||
|
'--logfile', os.path.abspath(self.log_file))
|
||||||
|
if netns:
|
||||||
|
self.process = process.NetNSProcess(self.name(), self.run_dir, netns, popen_args, env={})
|
||||||
|
else:
|
||||||
|
self.process = process.Process(self.name(), self.run_dir, popen_args, env={})
|
||||||
|
process.run_proc_sync(self.process)
|
||||||
|
return self.get_results()
|
||||||
|
|
||||||
|
def get_results(self):
|
||||||
|
with open(self.log_file) as f:
|
||||||
|
data = json.load(f)
|
||||||
|
return data
|
||||||
|
|
||||||
|
# vim: expandtab tabstop=4 shiftwidth=4
|
|
@ -23,7 +23,7 @@ import time
|
||||||
import pprint
|
import pprint
|
||||||
from . import config, log, util, resource, test
|
from . import config, log, util, resource, test
|
||||||
from .event_loop import MainLoop
|
from .event_loop import MainLoop
|
||||||
from . import osmo_nitb, osmo_hlr, osmo_mgcpgw, osmo_mgw, osmo_msc, osmo_bsc, osmo_stp, osmo_ggsn, osmo_sgsn, modem, esme, osmocon, ms_driver
|
from . import osmo_nitb, osmo_hlr, osmo_mgcpgw, osmo_mgw, osmo_msc, osmo_bsc, osmo_stp, osmo_ggsn, osmo_sgsn, modem, esme, osmocon, ms_driver, iperf3
|
||||||
|
|
||||||
class Timeout(Exception):
|
class Timeout(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -349,6 +349,12 @@ class SuiteRun(log.Origin):
|
||||||
self.register_for_cleanup(osmocon_obj)
|
self.register_for_cleanup(osmocon_obj)
|
||||||
return osmocon_obj
|
return osmocon_obj
|
||||||
|
|
||||||
|
def iperf3srv(self, ip_address=None):
|
||||||
|
if ip_address is None:
|
||||||
|
ip_address = self.ip_address()
|
||||||
|
iperf3srv_obj = iperf3.IPerf3Server(self, ip_address)
|
||||||
|
return iperf3srv_obj
|
||||||
|
|
||||||
def msisdn(self):
|
def msisdn(self):
|
||||||
msisdn = self.resources_pool.next_msisdn(self)
|
msisdn = self.resources_pool.next_msisdn(self)
|
||||||
self.log('using MSISDN', msisdn)
|
self.log('using MSISDN', msisdn)
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from osmo_gsm_tester.testenv import *
|
||||||
|
|
||||||
|
def print_results(cli_res, srv_res):
|
||||||
|
cli_sent = cli_res['end']['sum_sent']
|
||||||
|
cli_recv = cli_res['end']['sum_received']
|
||||||
|
print("RESULT client:")
|
||||||
|
print("\tSEND: %d KB, %d kbps, %d seconds (%d retrans)" % (cli_sent['bytes']/1000, cli_sent['bits_per_second']/1000, cli_sent['seconds'], cli_sent['retransmits']))
|
||||||
|
print("\tRECV: %d KB, %d kbps, %d seconds" % (cli_recv['bytes']/1000, cli_recv['bits_per_second']/1000, cli_recv['seconds']))
|
||||||
|
print("RESULT server:")
|
||||||
|
print("\tSEND: %d KB, %d kbps, %d seconds" % (cli_sent['bytes']/1000, cli_sent['bits_per_second']/1000, cli_sent['seconds']))
|
||||||
|
print("\tRECV: %d KB, %d kbps, %d seconds" % (cli_recv['bytes']/1000, cli_recv['bits_per_second']/1000, cli_recv['seconds']))
|
||||||
|
|
||||||
|
hlr = suite.hlr()
|
||||||
|
bts = suite.bts()
|
||||||
|
pcu = bts.pcu()
|
||||||
|
mgw_msc = suite.mgw()
|
||||||
|
mgw_bsc = suite.mgw()
|
||||||
|
stp = suite.stp()
|
||||||
|
ggsn = suite.ggsn()
|
||||||
|
sgsn = suite.sgsn(hlr, ggsn)
|
||||||
|
msc = suite.msc(hlr, mgw_msc, stp)
|
||||||
|
bsc = suite.bsc(msc, mgw_bsc, stp)
|
||||||
|
ms = suite.modem()
|
||||||
|
iperf3srv = suite.iperf3srv()
|
||||||
|
iperf3cli = iperf3srv.create_client()
|
||||||
|
|
||||||
|
bsc.bts_add(bts)
|
||||||
|
sgsn.bts_add(bts)
|
||||||
|
|
||||||
|
print('start iperfv3 server...')
|
||||||
|
iperf3srv.start()
|
||||||
|
|
||||||
|
print('start network...')
|
||||||
|
hlr.start()
|
||||||
|
stp.start()
|
||||||
|
ggsn.start()
|
||||||
|
sgsn.start()
|
||||||
|
msc.start()
|
||||||
|
mgw_msc.start()
|
||||||
|
mgw_bsc.start()
|
||||||
|
bsc.start()
|
||||||
|
|
||||||
|
bts.start()
|
||||||
|
wait(bsc.bts_is_connected, bts)
|
||||||
|
print('Waiting for bts to be ready...')
|
||||||
|
wait(bts.ready_for_pcu)
|
||||||
|
pcu.start()
|
||||||
|
|
||||||
|
hlr.subscriber_add(ms)
|
||||||
|
|
||||||
|
ms.connect(msc.mcc_mnc())
|
||||||
|
ms.attach()
|
||||||
|
|
||||||
|
ms.log_info()
|
||||||
|
|
||||||
|
print('waiting for modems to attach...')
|
||||||
|
wait(ms.is_connected, msc.mcc_mnc())
|
||||||
|
wait(msc.subscriber_attached, ms)
|
||||||
|
|
||||||
|
print('waiting for modems to attach to data services...')
|
||||||
|
wait(ms.is_attached)
|
||||||
|
|
||||||
|
# We need to use inet46 since ofono qmi only uses ipv4v6 eua (OS#2713)
|
||||||
|
ctx_id_v4 = ms.activate_context(apn='inet46', protocol=ms.CTX_PROT_IPv4)
|
||||||
|
print("Setting up data plan for %r" % repr(ctx_id_v4))
|
||||||
|
ms.setup_context_data_plane(ctx_id_v4)
|
||||||
|
|
||||||
|
print("Running iperf3 client to %s through %r" % (iperf3srv.addr(),repr(ctx_id_v4)))
|
||||||
|
res = iperf3cli.run_test(ms.netns())
|
||||||
|
iperf3srv.stop()
|
||||||
|
print_results(res, iperf3srv.get_results())
|
||||||
|
|
||||||
|
ms.deactivate_context(ctx_id_v4)
|
|
@ -1,6 +1,6 @@
|
||||||
resources:
|
resources:
|
||||||
ip_address:
|
ip_address:
|
||||||
- times: 8 # msc, bsc, hlr, stp, mgw*2, sgsn, ggsn
|
- times: 9 # msc, bsc, hlr, stp, mgw*2, sgsn, ggsn, iperf3srv
|
||||||
bts:
|
bts:
|
||||||
- times: 1
|
- times: 1
|
||||||
modem:
|
modem:
|
||||||
|
|
Loading…
Reference in New Issue