You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
9.6 KiB
242 lines
9.6 KiB
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import sys
|
|
import telnetlib
|
|
import time
|
|
from datetime import datetime
|
|
|
|
import requests
|
|
|
|
#########################################################################
|
|
#
|
|
# parameters
|
|
#
|
|
#########################################################################
|
|
|
|
# echo -e "usage: $0 <my-topology.virl> <number of concurrent simulations> <username> <password> <node-timeout> <global-timeout> [debug level], e.g.,\n"
|
|
# echo "$0 /home/virl/git-virl-hs-fulda/GIT-VIRL-HS-Fulda/advcompnet-lab2-dcn-fabricpath.virl 6 guest password 0.5 500"
|
|
|
|
BASE_API_URL = "http://192.168.76.209:13080/v2"
|
|
|
|
TELNET_HOST = "192.168.76.209"
|
|
USERNAME = sys.argv[3]
|
|
PORT = 13080
|
|
|
|
# PASSWORD = getpass.getpass()
|
|
PASSWORD = sys.argv[4]
|
|
|
|
TIMEOUT = int(sys.argv[5])
|
|
GLOBAL_TIMEOUT = 1000
|
|
|
|
PROJECT_NAME = sys.argv[1]
|
|
# PROJECT_ID = "69e293ac-a339-4d1d-b2e3-047dc2da8566"
|
|
|
|
NUMBER_OF_CONCURRENT_BENCHMARK_PROJECTS = int(sys.argv[2])
|
|
NUMBER_OF_BENCHMARK_RUNS = 1
|
|
|
|
#########################################################################
|
|
#
|
|
# start of script
|
|
#
|
|
#########################################################################
|
|
|
|
# delete all stale benchmark projects left over from previous runs
|
|
r = requests.get(BASE_API_URL + '/projects', auth=(USERNAME, PASSWORD))
|
|
if r.status_code == 200:
|
|
for entry in r.json():
|
|
if str(entry['name']).startswith("benchmark"):
|
|
r = requests.delete(BASE_API_URL + '/projects/' + entry["project_id"], auth=(USERNAME, PASSWORD))
|
|
if r.status_code == 204:
|
|
print("Deleted stale project %s (%s)..." % (entry["project_id"], entry["name"]))
|
|
else:
|
|
sys.exit("Could not delete project")
|
|
else:
|
|
sys.exit("Could not get stale benchmark projects")
|
|
|
|
for run in range(1, NUMBER_OF_BENCHMARK_RUNS + 1):
|
|
|
|
print("Starting run %i..." % run)
|
|
|
|
# array containing the results of each run
|
|
results = []
|
|
|
|
# create timestamp on script start
|
|
time_start = time.time()
|
|
date_start = datetime.fromtimestamp(time_start).ctime()
|
|
print("Start at: %s " % date_start)
|
|
|
|
r = requests.get(BASE_API_URL + '/projects', auth=(USERNAME, PASSWORD))
|
|
if r.status_code == 200:
|
|
for entry in r.json():
|
|
if entry['name'] == PROJECT_NAME:
|
|
# print(entry['project_id'])
|
|
PROJECT_ID = entry['project_id']
|
|
else:
|
|
sys.exit("Could not get projects")
|
|
# array containing all created temporary benchmark projects
|
|
benchmarks = []
|
|
|
|
# duplicate project to create multiple temporary benchmark projects
|
|
for benchNumber in range(1, NUMBER_OF_CONCURRENT_BENCHMARK_PROJECTS + 1):
|
|
print("Adding benchmark %i" % benchNumber)
|
|
data = "{ \"name\": \"benchmark" + str(benchNumber) + "\"}"
|
|
r = requests.post(BASE_API_URL + '/projects/' + PROJECT_ID + '/duplicate', data, auth=(USERNAME, PASSWORD))
|
|
if r.status_code == 201:
|
|
entry = r.json()
|
|
print("Created benchmark project %s (%s) from %s (%s)" % (
|
|
entry['project_id'], entry['name'], PROJECT_ID, PROJECT_NAME))
|
|
benchmarks.append(entry)
|
|
data = "{}"
|
|
r = requests.post(BASE_API_URL + '/projects/' + entry['project_id'] + '/open', data,
|
|
auth=(USERNAME, PASSWORD))
|
|
if r.status_code == 201:
|
|
print("Opened benchmark project %s (%s)" % (entry['project_id'], entry['name']))
|
|
else:
|
|
sys.exit("Could not open benchmark project")
|
|
else:
|
|
sys.exit("Could not duplicate project")
|
|
|
|
# time.sleep(5)
|
|
|
|
# start all nodes in all projects
|
|
for benchmark in benchmarks:
|
|
data = "{}"
|
|
r = requests.post(BASE_API_URL + '/projects/' + benchmark["project_id"] + '/nodes/start', data,
|
|
auth=(USERNAME, PASSWORD))
|
|
if r.status_code == 204:
|
|
print("Started all nodes in project %s (%s) ..." % (benchmark["project_id"], benchmark["name"]))
|
|
else:
|
|
sys.exit("Could not start nodes")
|
|
|
|
# create timestamp when nodes are started
|
|
time_started = time.time()
|
|
date_started = datetime.fromtimestamp(time_started).ctime()
|
|
print("Started at: %s " % date_started)
|
|
|
|
# collect all active nodes in all projects to the nodes[] array
|
|
nodes = []
|
|
for benchmark in benchmarks:
|
|
print("Getting nodes from " + benchmark["name"] + "...")
|
|
r = requests.get(BASE_API_URL + '/projects/' + benchmark["project_id"] + '/nodes', auth=(USERNAME, PASSWORD))
|
|
if r.status_code == 200:
|
|
for entry in r.json():
|
|
print("Found node: " + entry["name"] + " state: " + entry["status"] + " console: " + str(
|
|
entry["console"]))
|
|
if entry["status"] == "started":
|
|
nodes.append(entry)
|
|
print("Added node...")
|
|
else:
|
|
sys.exit("Not all nodes active")
|
|
else:
|
|
sys.exit("Could get state to count nodes")
|
|
|
|
nodeCount = len(nodes)
|
|
print("Found %i nodes in all benchmarks..." % (len(nodes)))
|
|
|
|
# create timestamp when nodes are active
|
|
time_active = time.time()
|
|
date_active = datetime.fromtimestamp(time_active).ctime()
|
|
print("Active at: %s " % datetime.fromtimestamp(time_active).ctime())
|
|
|
|
# check if nodes are usable
|
|
usable_nodes = []
|
|
while len(nodes) > 0:
|
|
|
|
# perf output
|
|
# print(os.popen("top -b -n 1 | head -20 >> gns3bench-perf.log"))
|
|
|
|
time_globalTimeout = time.time()
|
|
print("(check duration: {:d} sec, timeout: {:d} sec)".format(int((time_globalTimeout - time_active)),
|
|
int(GLOBAL_TIMEOUT)))
|
|
|
|
# if usability of nodes is checked longer than global timeout, exit
|
|
# this can happen if nodes get stuck, e.g., due to high load, missing resources etc.
|
|
if time_globalTimeout - time_active > GLOBAL_TIMEOUT:
|
|
date_usable = 0
|
|
durationUsable = 0
|
|
avgConsoleDelay = 0
|
|
durationStart = time_started - time_start
|
|
durationActive = time_active - time_start
|
|
results.append("%s;%i;%i;%s;%s;%s;%s;%i;%i;%i;%f" % (
|
|
(PROJECT_NAME + ": TIMEOUT"), NUMBER_OF_CONCURRENT_BENCHMARK_PROJECTS, nodeCount, date_start,
|
|
date_started, date_active, date_usable, durationStart, durationActive, durationUsable, avgConsoleDelay))
|
|
results.append(" Occurred while still checking nodes: " + str(nodes))
|
|
|
|
f = open("gns3bench-error.log", "a")
|
|
f.writelines(results)
|
|
f.write("\r\n")
|
|
f.close()
|
|
sys.exit("global timeout")
|
|
|
|
for entry in nodes:
|
|
print("Checking node %s in %s..." % (entry["name"], entry["project_id"]))
|
|
try:
|
|
tn = telnetlib.Telnet(TELNET_HOST, entry["console"])
|
|
tn.write(b"\n" + b"\n" + b"\n")
|
|
response = tn.read_until(b" login:", timeout=TIMEOUT)
|
|
# print(response)
|
|
if response.find("login:".encode()) != -1:
|
|
print("Found usable node %s" % entry["name"])
|
|
usable_nodes.append(entry)
|
|
nodes.remove(entry)
|
|
except TimeoutError:
|
|
print("Connection to %s in project %s timed out" % (entry["name"], entry["project_id"]))
|
|
|
|
print(str(len(usable_nodes)) + " usable nodes...")
|
|
|
|
# create timestamp when all nodes are usable
|
|
time_usable = time.time()
|
|
date_usable = datetime.fromtimestamp(time_usable).ctime()
|
|
print("Usable at: %s " % datetime.fromtimestamp(time_usable).ctime())
|
|
|
|
durationStart = time_started - time_start
|
|
durationActive = time_active - time_start
|
|
durationUsable = time_usable - time_start
|
|
# print results
|
|
print("\n\n\nResult:")
|
|
print("Start: %f " % durationStart)
|
|
print("Active: %f " % durationActive)
|
|
print("Usable: %f " % durationUsable)
|
|
|
|
# file output
|
|
# Topology;ConcurrentSims;Nodes;Script-Start;Started;Active;Usable;Start Time (sec);Active Time (sec);Usable Time (sec);Average Console Delay (sec)
|
|
# advcompnet-lab-1-dcn-scenario1.virl;10;50;Mon Jun 12 12:48:51 GMT 2017;Mon Jun 12 12:51:49 GMT 2017;Mon Jun 12 12:55:33 GMT 2017;Mon Jun 12 12:56:23 GMT 2017;178;402;452;0,3453
|
|
avgConsoleDelay = 0
|
|
results.append("%s;%i;%i;%s;%s;%s;%s;%i;%i;%i;%f" % (
|
|
PROJECT_NAME, NUMBER_OF_CONCURRENT_BENCHMARK_PROJECTS, nodeCount, date_start, date_started, date_active,
|
|
date_usable, durationStart, durationActive, durationUsable, avgConsoleDelay))
|
|
|
|
f = open("gns3bench.log", "a")
|
|
f.writelines(results)
|
|
f.write("\r\n")
|
|
f.close()
|
|
print("Appended output to %s" % os.path.join(os.getcwd(), str(f.name)))
|
|
|
|
# stop here, if we don't won't to stop and delete benchmark projects
|
|
# sys.exit(0)
|
|
|
|
# print("waiting...")
|
|
# time.sleep(1)
|
|
|
|
# stop all nodes in all projects
|
|
# for benchmark in benchmarks:
|
|
# data = "{}"
|
|
# r = requests.post(BASE_API_URL + '/projects/' + benchmark["project_id"] + '/nodes/stop', data,
|
|
# auth=(USERNAME, PASSWORD))
|
|
# if r.status_code == 204:
|
|
# print("Stopped all nodes in project " + benchmark["project_id"] + "...")
|
|
# else:
|
|
# sys.exit("Could not stop nodes")
|
|
|
|
# delete the created benchmark projects
|
|
for benchmark in benchmarks:
|
|
r = requests.delete(BASE_API_URL + '/projects/' + benchmark["project_id"], auth=(USERNAME, PASSWORD))
|
|
if r.status_code == 204:
|
|
print("Deleted project " + benchmark["name"] + "...")
|
|
else:
|
|
sys.exit("Could not delete project")
|
|
|
|
print("%i runs finished" % NUMBER_OF_BENCHMARK_RUNS)
|
|
|
|
sys.exit(0)
|