[PATCH v2] TCPListen and TCPConnect test set added
Radek Pazdera
rpazdera at redhat.com
Wed Aug 15 12:21:58 UTC 2012
On Tue, Aug 14, 2012 at 04:22:48PM +0200, Jan Tluka wrote:
> Tue, Aug 14, 2012 at 04:11:44PM CEST, jpirko at redhat.com wrote:
> >
> >Applying: TCPListen and TCPConnect test set added
> >/home/jirka/work/lnst/.git/rebase-apply/patch:205: trailing whitespace.
> > Test spawns server(s) listening for TCP connection(s) on port(s) defined by
> >warning: 1 line adds whitespace errors.
Those whitespace errors can be *really* annoying ...
I have them them in almost every patch I create.
Are there any tools or methods for avoiding them?
> >
> >But nevermind for now. I will fix this manually this time :)
>
> Thank you almighty!
>
> >
> >Jiri
> >
> >Mon, Aug 13, 2012 at 03:37:27PM CEST, jtluka at redhat.com wrote:
> >>Set of these tests provides possibility to test multiple TCP connections
> >>within two LNST commands. Data sent are random and every connection
> >>behaves differently in sense that number of packets is random as well.
> >>
> >>Following are two examples of commands in command sequence.
> >>
> >> <define>
> >> <alias name="my_range" value="10000-10100" />
> >> </define>
> >> <command machine_id="1" type="test" value="TCPListen" bg_id="1">
> >> <options>
> >> <option name="addr" value="{ip(1,1)}"/>
> >> <option name="port_range" value="{$my_range}"/>
> >> </options>
> >> </command>
> >> <command type="exec" value="sleep 5" />
> >> <command machine_id="2" type="test" value="TCPConnect" bg_id="2">
> >> <options>
> >> <option name="addr" value="{ip(1,1)}"/>
> >> <option name="port_range" value="{$my_range}"/>
> >> <option name="sleep" value="0.5" />
> >> </options>
> >> </command>
> >> <command machine_id="2" type="wait" value="2" />
> >> <command machine_id="1" type="wait" value="1" />
> >>
> >>Repeated generation of connections can be achieved using following
> >>command (see 'cont' option):
> >>
> >> <define>
> >> <alias name="my_range" value="10000-10100" />
> >> </define>
> >> <command machine_id="1" type="test" value="TCPListen" bg_id="1">
> >> <options>
> >> <option name="addr" value="{ip(1,1)}"/>
> >> <option name="port_range" value="{$my_range}"/>
> >> <option name="cont" value="yes" />
> >> </options>
> >> </command>
> >> <command type="exec" value="sleep 5" />
> >> <command machine_id="2" type="test" value="TCPConnect" bg_id="2">
> >> <options>
> >> <option name="addr" value="{ip(1,1)}"/>
> >> <option name="port_range" value="{$my_range}"/>
> >> <option name="sleep" value="0.5" />
> >> <option name="cont" value="yes" />
> >> </options>
> >> </command>
> >> <command type="exec" value="sleep 60" />
> >> <command machine_id="2" type="intr" value="2" />
> >> <command machine_id="1" type="kill" value="1" />
> >>
> >>
> >>---
> >> Tests/TestTCPConnect.py | 167 +++++++++++++++++++++++++++++++++++++++++++++++
> >> Tests/TestTCPListen.py | 127 +++++++++++++++++++++++++++++++++++
> >> 2 files changed, 294 insertions(+), 0 deletions(-)
> >> create mode 100644 Tests/TestTCPConnect.py
> >> create mode 100644 Tests/TestTCPListen.py
> >>
> >>diff --git a/Tests/TestTCPConnect.py b/Tests/TestTCPConnect.py
> >>new file mode 100644
> >>index 0000000..0a6c655
> >>--- /dev/null
> >>+++ b/Tests/TestTCPConnect.py
> >>@@ -0,0 +1,167 @@
> >>+"""
> >>+This module defines TCPConnect module
> >>+"""
> >>+
> >>+__author__ = """
> >>+jtluka at redhat.com (Jan Tluka)
> >>+"""
> >>+
> >>+import sys
> >>+import socket
> >>+import errno
> >>+from multiprocessing import Process, Lock
> >>+from signal import signal, SIGINT
> >>+from time import sleep
> >>+from random import randrange, sample
> >>+import logging
> >>+import re
> >>+from Common.TestsCommon import TestGeneric
> >>+
> >>+"""
> >>+Test description:
> >>+ Test spawns client(s) connecting to TCP port(s) defined by port or
> >>+ port_range option. When connected, the client sends random bursts of
> >>+ random data to server. If cont option is set the connections are initiated
> >>+ again and data is sent to server until interrupted by the controller.
> >>+
> >>+Parameters:
> >>+ addr ... mandatory, address to connect to
> >>+ port ... mandatory, port to send data
> >>+ sleep ... optional, sleep time between bursts, if undefined, the bursts
> >>+ are immediate
> >>+ cont ... optional, sets continuous mode of connecting, if set connections
> >>+ are infinitely re-spawned when closed
> >>+"""
> >>+
> >>+class ConnectionWorker():
> >>+ def __init__(self, host, port, sleep_time = None, continuous = None):
> >>+ self._tlock = Lock()
> >>+ self._terminate = 0
> >>+ self._host = host
> >>+ self._port = port
> >>+ self._sleep_time = sleep_time
> >>+ self._cont = continuous
> >>+ self._ascii = [chr(i) for i in range(0,255)]
> >>+
> >>+ def terminate(self):
> >>+ self._tlock.acquire()
> >>+ self._terminate=1
> >>+ self._tlock.release()
> >>+
> >>+ def run(self):
> >>+ loop = True
> >>+
> >>+ while loop:
> >>+ loop = (self._cont is not None)
> >>+ logging.debug("Starting connection to (%s) port %s " % (self._host,
> >>+ self._port))
> >>+
> >>+ try:
> >>+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> >>+ s.connect((self._host, self._port))
> >>+ except socket.error, msg:
> >>+ s.close()
> >>+ s = None
> >>+ logging.error(msg)
> >>+ return
> >>+
> >>+ for txs in range(10, randrange(20,100)):
> >>+ self._tlock.acquire()
> >>+ if self._terminate:
> >>+ self._tlock.release()
> >>+ logging.debug("Terminating connection on port %s" %
> >>+ self._port)
> >>+ loop = False
> >>+ break
> >>+ else:
> >>+ self._tlock.release()
> >>+
> >>+ rnd_str = "".join(sample(self._ascii, len(self._ascii)))
> >>+ data = s.sendall(rnd_str)
> >>+ if (self._sleep_time):
> >>+ sleep(self._sleep_time)
> >>+
> >>+ s.close()
> >>+
> >>+
> >>+class TestTCPConnect(TestGeneric):
> >>+ def _parse_options(self):
> >>+ addr = self.get_mopt("addr")
> >>+ if addr:
> >>+ self._host = addr
> >>+
> >>+ # either port or port_range should be set
> >>+ port = self.get_opt("port")
> >>+ if port:
> >>+ self._port = port
> >>+ else:
> >>+ port_range = self.get_opt("port_range")
> >>+ if port_range:
> >>+ self._port_range = port_range
> >>+ else:
> >>+ e = TestOptionMissing()
> >>+ raise e
> >>+
> >>+ sleep_time = float(self.get_opt("sleep"))
> >>+ if sleep_time:
> >>+ self._sleep_time = sleep_time
> >>+
> >>+ cont = self.get_opt("cont")
> >>+ if cont:
> >>+ self._cont = cont
> >>+
> >>+ def parse_port_range(self):
> >>+ if self._port_range == None:
> >>+ return []
> >>+
> >>+ for c in [',','-']:
> >>+ s = self._port_range.split(c)
> >>+ if len(s) == 2:
> >>+ break
> >>+
> >>+ if len(s) != 2:
> >>+ logging.error("Port range malformed! ", self._port_range)
> >>+
> >>+ low = int(s[0])
> >>+ high = int(s[1]) + 1
> >>+
> >>+ return range(low, high)
> >>+
> >>+ def _close_connections(self, signum, frame):
> >>+ logging.debug("Termination signal delivered ...")
> >>+ for cw in self._cw_instances:
> >>+ cw.terminate()
> >>+
> >>+ def _set_interrupt_handler(self):
> >>+ signal(SIGINT, self._close_connections)
> >>+
> >>+ def run(self):
> >>+ self._terminate = 0
> >>+ self._host = None
> >>+ self._port = None
> >>+ self._cont = None
> >>+ self._cw_instances = []
> >>+
> >>+ self._set_interrupt_handler()
> >>+
> >>+ self._parse_options()
> >>+
> >>+ ports = []
> >>+ if self._port:
> >>+ ports.extend(self._port)
> >>+ else:
> >>+ r = self.parse_port_range()
> >>+ ports.extend(r)
> >>+
> >>+ workers = []
> >>+ for p in ports:
> >>+ cw = ConnectionWorker(self._host, p, self._sleep_time, self._cont)
> >>+ self._cw_instances.append(cw)
> >>+
> >>+ w = Process(target=cw.run)
> >>+ w.start()
> >>+ workers.append(w)
> >>+
> >>+ logging.debug("Waiting for workers ...")
> >>+ for w in workers:
> >>+ w.join()
> >>diff --git a/Tests/TestTCPListen.py b/Tests/TestTCPListen.py
> >>new file mode 100644
> >>index 0000000..2b25f29
> >>--- /dev/null
> >>+++ b/Tests/TestTCPListen.py
> >>@@ -0,0 +1,127 @@
> >>+"""
> >>+This module defines TCPListen module
> >>+"""
> >>+
> >>+__author__ = """
> >>+jtluka at redhat.com (Jan Tluka)
> >>+"""
> >>+
> >>+import sys
> >>+import socket
> >>+import errno
> >>+import logging
> >>+import re
> >>+from multiprocessing import Process
> >>+from Common.TestsCommon import TestGeneric
> >>+
> >>+"""
> >>+Test description:
> >>+ Test spawns server(s) listening for TCP connection(s) on port(s) defined by
> >>+ port or port_range options. When client connects to the port, server reads
> >>+ the data sent and close the connection when no more data is available.
> >>+ If cont option is set the connection is reopened and server reads data
> >>+ again.
> >>+
> >>+Parameters:
> >>+ addr ... optional, address to bind to, if undefined listen on all ifaces
> >>+ port ... mandatory, port to listen on
> >>+ cont ... optional, if set the listening port is reopened when the
> >>+ connection is closed
> >>+"""
> >>+
> >>+class TestTCPListen(TestGeneric):
> >>+ def __init__(self, command):
> >>+ self._addr = None
> >>+ self._port = None
> >>+ self._cont = None
> >>+ TestGeneric.__init__(self, command)
> >>+
> >>+ def _parse_options(self):
> >>+ addr = self.get_opt("addr")
> >>+ if addr:
> >>+ self._addr = addr
> >>+
> >>+ # either port or port_range should be set
> >>+ port = self.get_opt("port")
> >>+ if port:
> >>+ self._port = port
> >>+ else:
> >>+ port_range = self.get_opt("port_range")
> >>+ if port_range:
> >>+ self._port_range = port_range
> >>+ else:
> >>+ e = TestOptionMissing()
> >>+ raise e
> >>+
> >>+ cont = self.get_opt("cont")
> >>+ if cont:
> >>+ self._cont = cont
> >>+
> >>+ def _worker(self, host, port):
> >>+ logging.debug("Starting listener (%s) on port %s " % (host, port))
> >>+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> >>+
> >>+ try:
> >>+ s.bind((host, port))
> >>+ s.listen(1)
> >>+ except socket.error, msg:
> >>+ s.close()
> >>+ s = None
> >>+ logging.error(msg)
> >>+ return
> >>+
> >>+ loop = 1
> >>+
> >>+ while loop or self._cont:
> >>+ conn, addr = s.accept()
> >>+ logging.debug('Connected from ' + addr[0] + ' port:' +
> >>+ str(addr[1]))
> >>+
> >>+ while 1:
> >>+ data = conn.recv(1024)
> >>+ if not data:
> >>+ logging.debug('Client disconnected: ' + addr[0] +
> >>+ ' port:' + str(addr[1]))
> >>+ break
> >>+
> >>+ conn.close()
> >>+ loop = 0
> >>+
> >>+ def _parse_port_range(self):
> >>+ if self._port_range == None:
> >>+ return []
> >>+
> >>+ for c in [',','-']:
> >>+ s = self._port_range.split(c)
> >>+ if len(s) == 2:
> >>+ break
> >>+
> >>+ if len(s) != 2:
> >>+ logging.error("Port range malformed! ", self._port_range)
> >>+
> >>+ low = int(s[0])
> >>+ high = int(s[1]) + 1
> >>+
> >>+ return range(low, high)
> >>+
> >>+ def run(self):
> >>+ self._parse_options()
> >>+
> >>+ ports = []
> >>+ if self._port:
> >>+ ports.extend(self._port)
> >>+ else:
> >>+ r = self._parse_port_range()
> >>+ ports.extend(r)
> >>+
> >>+ workers = []
> >>+
> >>+ for p in ports:
> >>+ w = Process(target=self._worker, args=(self._addr, p))
> >>+ w.start()
> >>+ workers.append(w)
> >>+
> >>+
> >>+ logging.debug("Waiting for workers ...")
> >>+ for w in workers:
> >>+ w.join()
> >>--
> >>1.7.6.5
> >>
> >>_______________________________________________
> >>LNST-developers mailing list
> >>LNST-developers at lists.fedorahosted.org
> >>https://lists.fedorahosted.org/mailman/listinfo/lnst-developers
> _______________________________________________
> LNST-developers mailing list
> LNST-developers at lists.fedorahosted.org
> https://lists.fedorahosted.org/mailman/listinfo/lnst-developers
More information about the LNST-developers
mailing list