162 lines
6.3 KiB
Python

import asyncio
import logging
import os
import random
import string
import threading
import time
from socketio.server import SocketServer
from socketio.client import SocketClient
class PerformanceTest:
def __init__(self):
self.terminate = False
self._server = None
self._socket_client = None
self.received_messages = 0
self.sended_messages = 0
self.conditions = []
self.cps = {"miatel": 7, "comlink": 7, "spacetel": 7}
operators = {"miatel": 14, "comlink": 10, "spacetel": 4}
self.resources = {}
self.call_delays = {}
self.last_call_at = {}
self.call_locks = {}
for key, value in self.cps.items():
self.call_delays[key] = 1.0 / float(value)
self.last_call_at[key] = time.time()
self.call_locks[key] = asyncio.Lock()
i = 0
k = 0
while i < 15:
i += 1
for operator, cnt in operators.items():
j = 0
while j < cnt:
j += 1
k += 1
self.resources[k] = {"conditions": [], "is_busy": 0, "cs": threading.Lock(), "operator": operator}
self.timings = []
@asyncio.coroutine
def run(self):
while not self.terminate:
yield from asyncio.sleep(1)
def create_server(self):
loop = asyncio.get_event_loop()
path = os.path.dirname(os.path.abspath(__file__))
self._server = SocketServer({"test": self.test_server, "test_waiting": self.test_waiting}, path + '/configs/socket_server.ini')
loop.run_until_complete(self.run())
def create_client(self):
loop = asyncio.get_event_loop()
self._socket_client = SocketClient(["127.0.0.1", "54445"],
{"test": self.test_client, "action1": self.action1})
loop.create_task(self._socket_client.connector())
loop.run_until_complete(self.run())
def take_resource(self):
timed_out = False
message_showed = False
time_out = 300
while not timed_out:
for resource_id, resource in self.resources.items():
resource["cs"].acquire()
if not resource["is_busy"]:
resource["is_busy"] = 1
resource["cs"].release()
return resource_id, resource["operator"]
resource["cs"].release()
if not message_showed:
print("all resources as busy, wait")
message_showed = True
condition = threading.Condition()
with condition:
self.conditions.append(condition)
timed_out = not condition.wait(time_out)
raise Exception("failed to take resource")
def release_resource(self, resource_id):
resource = self.resources[resource_id]
resource["is_busy"] = 0
if len(self.conditions) > 0:
condition = self.conditions.pop(0)
with condition:
condition.notify()
resource["conditions"] = []
def sending_as_client(self, message, count=1, length=16, timeout=0.1, with_wait=False):
if self._socket_client is not None:
counter = 0
while counter < count:
counter += 1
self.sended_messages += 1
if with_wait:
print("start waiting for response")
time1 = time.time()
self._socket_client.append_message({"action": "test_waiting", "test": message, "time": time.time()}, True)
print("waiting response time: %f" % (time.time() - time1))
time.sleep(timeout)
else:
resource_id, operator = self.take_resource()
self._socket_client.append_message({"action": "test", "test": message, "time": time.time(),
"resource_id": resource_id, "operator": operator})
time.sleep(timeout)
else:
print("ERROR! no client exists!")
def server_worker(self, message):
repeat_cnt = random.choice([0, 1, 2, 3])
i = 0
while i < repeat_cnt:
i += 1
sleep_time = random.choice([1, 2, 0, 1, 1, 4, 1, 3, 2, 5, 10])
time.sleep(sleep_time)
self._server.broadcast_message({"action": "action1", "test": message["test"]})
sleep_time = random.choice([1, 2, 0, 1, 1, 4, 1, 3, 2, 5])
time.sleep(sleep_time)
self._server.broadcast_message(message)
@asyncio.coroutine
def test_server(self, message):
print("receiving time: %f" % (time.time() - message["time"]))
self.timings.append(time.time() - message["time"])
self.received_messages += 1
with (yield from self.call_locks[message["operator"]]):
current_delay = time.time() - self.last_call_at[message["operator"]]
if current_delay < self.call_delays[message["operator"]]:
yield from asyncio.sleep(self.call_delays[message["operator"]] - current_delay)
self.last_call_at[message["operator"]] = time.time()
worker_thread = threading.Thread(target=self.server_worker,
args=(message,))
worker_thread.daemon = True
worker_thread.start()
@asyncio.coroutine
def test_waiting(self, message):
print("receive waiting time: %f" % (time.time() - message["time"]))
self.timings.append(time.time() - message["time"])
self.received_messages += 1
time.sleep(5)
return {"action": "test_waiting", "response": "success"}
@asyncio.coroutine
def test_client(self, message):
self.timings.append(time.time() - message["time"])
self.received_messages += 1
self.release_resource(message["resource_id"])
@asyncio.coroutine
def action1(self, message):
action_tread = threading.Thread(target=self._action_worker)
action_tread.daemon = True
action_tread.start()
def _action_worker(self):
sleep_time = random.choice([1, 2, 0, 1, 1, 4, 12, 8, 3, 5])
time.sleep(sleep_time)