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

#!/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)