Global replace of Nicira Networks.
[sliver-openvswitch.git] / python / ovstest / udp.py
1 # Copyright (c) 2011, 2012 Nicira, Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """
16 ovsudp contains listener and sender classes for UDP protocol
17 """
18
19 import array
20 import struct
21 import time
22
23 from twisted.internet.protocol import DatagramProtocol
24 from twisted.internet.task import LoopingCall
25
26
27 class UdpListener(DatagramProtocol):
28     """
29     Class that will listen for incoming UDP packets
30     """
31     def __init__(self):
32         self.stats = []
33
34     def datagramReceived(self, data, (_1, _2)):
35         """This function is called each time datagram is received"""
36         try:
37             self.stats.append(struct.unpack_from("Q", data, 0))
38         except struct.error:
39             pass  # ignore packets that are less than 8 bytes of size
40
41     def getResults(self):
42         """Returns number of packets that were actually received"""
43         return len(self.stats)
44
45
46 class UdpSender(DatagramProtocol):
47     """
48     Class that will send UDP packets to UDP Listener
49     """
50     def __init__(self, host, count, size, duration):
51         # LoopingCall does not know whether UDP socket is actually writable
52         self.looper = None
53         self.host = host
54         self.count = count
55         self.duration = duration
56         self.start = time.time()
57         self.sent = 0
58         self.data = array.array('c', 'X' * size)
59
60     def startProtocol(self):
61         self.looper = LoopingCall(self.sendData)
62         period = self.duration / float(self.count)
63         self.looper.start(period , now = False)
64
65     def stopProtocol(self):
66         if (self.looper is not None):
67             self.looper.stop()
68             self.looper = None
69
70     def datagramReceived(self, data, (host, port)):
71         pass
72
73     def sendData(self):
74         """This function is called from LoopingCall"""
75         if self.start + self.duration < time.time():
76             self.looper.stop()
77             self.looper = None
78
79         self.sent += 1
80         struct.pack_into('Q', self.data, 0, self.sent)
81         self.transport.write(self.data, self.host)
82
83     def getResults(self):
84         """Returns number of packets that were sent"""
85         return self.sent