commit 3ef8df1c85e101e5037cacab70a0f9ec056737b8 Author: Sebastian Rieger Date: Fri Dec 29 22:44:28 2017 +0100 initial version diff --git a/gns3-bench.py b/gns3-bench.py new file mode 100644 index 0000000..7902ba8 --- /dev/null +++ b/gns3-bench.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python3 + +import getpass +import telnetlib +import requests +import json +import time +import sys +import time +from datetime import datetime +import os + +######################################################################### +# +# parameters +# +######################################################################### + +# echo -e "usage: $0 [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]) + +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: + 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)