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.

216 lines
8.3 KiB

6 years ago
  1. #!/usr/bin/env python3
  2. import getpass
  3. import telnetlib
  4. import requests
  5. import json
  6. import time
  7. import sys
  8. import time
  9. from datetime import datetime
  10. import os
  11. #########################################################################
  12. #
  13. # parameters
  14. #
  15. #########################################################################
  16. # echo -e "usage: $0 <my-topology.virl> <number of concurrent simulations> <username> <password> <node-timeout> <global-timeout> [debug level], e.g.,\n"
  17. # echo "$0 /home/virl/git-virl-hs-fulda/GIT-VIRL-HS-Fulda/advcompnet-lab2-dcn-fabricpath.virl 6 guest password 0.5 500"
  18. BASE_API_URL = "http://192.168.76.209:13080/v2"
  19. TELNET_HOST = "192.168.76.209"
  20. USERNAME = sys.argv[3]
  21. PORT = 13080
  22. # PASSWORD = getpass.getpass()
  23. PASSWORD = sys.argv[4]
  24. TIMEOUT = int(sys.argv[5])
  25. PROJECT_NAME = sys.argv[1]
  26. # PROJECT_ID = "69e293ac-a339-4d1d-b2e3-047dc2da8566"
  27. NUMBER_OF_CONCURRENT_BENCHMARK_PROJECTS = int(sys.argv[2])
  28. NUMBER_OF_BENCHMARK_RUNS = 1
  29. #########################################################################
  30. #
  31. # start of script
  32. #
  33. #########################################################################
  34. # delete all stale benchmark projects left over from previous runs
  35. r = requests.get(BASE_API_URL + '/projects', auth=(USERNAME, PASSWORD))
  36. if r.status_code == 200:
  37. for entry in r.json():
  38. if str(entry['name']).startswith("benchmark"):
  39. r = requests.delete(BASE_API_URL + '/projects/' + entry["project_id"], auth=(USERNAME, PASSWORD))
  40. if r.status_code == 204:
  41. print("Deleted stale project %s (%s)..." % (entry["project_id"], entry["name"]))
  42. else:
  43. sys.exit("Could not delete project")
  44. else:
  45. sys.exit("Could not get stale benchmark projects")
  46. for run in range(1, NUMBER_OF_BENCHMARK_RUNS + 1):
  47. print("Starting run %i..." % run)
  48. # array containing the results of each run
  49. results = []
  50. # create timestamp on script start
  51. time_start = time.time()
  52. date_start = datetime.fromtimestamp(time_start).ctime()
  53. print("Start at: %s " % date_start)
  54. r = requests.get(BASE_API_URL + '/projects', auth=(USERNAME, PASSWORD))
  55. if r.status_code == 200:
  56. for entry in r.json():
  57. if entry['name'] == PROJECT_NAME:
  58. # print(entry['project_id'])
  59. PROJECT_ID = entry['project_id']
  60. else:
  61. sys.exit("Could not get projects")
  62. # array containing all created temporary benchmark projects
  63. benchmarks = []
  64. # duplicate project to create multiple temporary benchmark projects
  65. for benchNumber in range(1, NUMBER_OF_CONCURRENT_BENCHMARK_PROJECTS + 1):
  66. print("Adding benchmark %i" % benchNumber)
  67. data = "{ \"name\": \"benchmark" + str(benchNumber) + "\"}"
  68. r = requests.post(BASE_API_URL + '/projects/' + PROJECT_ID + '/duplicate', data, auth=(USERNAME, PASSWORD))
  69. if r.status_code == 201:
  70. entry = r.json()
  71. print("Created benchmark project %s (%s) from %s (%s)" % (
  72. entry['project_id'], entry['name'], PROJECT_ID, PROJECT_NAME))
  73. benchmarks.append(entry)
  74. data = "{}"
  75. r = requests.post(BASE_API_URL + '/projects/' + entry['project_id'] + '/open', data,
  76. auth=(USERNAME, PASSWORD))
  77. if r.status_code == 201:
  78. print("Opened benchmark project %s (%s)" % (entry['project_id'], entry['name']))
  79. else:
  80. sys.exit("Could not open benchmark project")
  81. else:
  82. sys.exit("Could not duplicate project")
  83. # time.sleep(5)
  84. # start all nodes in all projects
  85. for benchmark in benchmarks:
  86. data = "{}"
  87. r = requests.post(BASE_API_URL + '/projects/' + benchmark["project_id"] + '/nodes/start', data,
  88. auth=(USERNAME, PASSWORD))
  89. if r.status_code == 204:
  90. print("Started all nodes in project %s (%s) ..." % (benchmark["project_id"], benchmark["name"]))
  91. else:
  92. sys.exit("Could not start nodes")
  93. # create timestamp when nodes are started
  94. time_started = time.time()
  95. date_started = datetime.fromtimestamp(time_started).ctime()
  96. print("Started at: %s " % date_started)
  97. # collect all active nodes in all projects to the nodes[] array
  98. nodes = []
  99. for benchmark in benchmarks:
  100. print("Getting nodes from " + benchmark["name"] + "...")
  101. r = requests.get(BASE_API_URL + '/projects/' + benchmark["project_id"] + '/nodes', auth=(USERNAME, PASSWORD))
  102. if r.status_code == 200:
  103. for entry in r.json():
  104. print("Found node: " + entry["name"] + " state: " + entry["status"] + " console: " + str(
  105. entry["console"]))
  106. if entry["status"] == "started":
  107. nodes.append(entry)
  108. print("Added node...")
  109. else:
  110. sys.exit("Not all nodes active")
  111. else:
  112. sys.exit("Could get state to count nodes")
  113. nodeCount = len(nodes)
  114. print("Found %i nodes in all benchmarks..." % (len(nodes)))
  115. # create timestamp when nodes are active
  116. time_active = time.time()
  117. date_active = datetime.fromtimestamp(time_active).ctime()
  118. print("Active at: %s " % datetime.fromtimestamp(time_active).ctime())
  119. # check if nodes are usable
  120. usable_nodes = []
  121. while len(nodes) > 0:
  122. for entry in nodes:
  123. print("Checking node %s in %s..." % (entry["name"], entry["project_id"]))
  124. try:
  125. tn = telnetlib.Telnet(TELNET_HOST, entry["console"])
  126. tn.write(b"\n" + b"\n" + b"\n")
  127. response = tn.read_until(b" login:", timeout=TIMEOUT)
  128. # print(response)
  129. if response.find("login:".encode()) != -1:
  130. print("Found usable node %s" % entry["name"])
  131. usable_nodes.append(entry)
  132. nodes.remove(entry)
  133. except TimeoutError:
  134. print("Connection to %s in project %s timed out" % (entry["name"], entry["project_id"]))
  135. print(str(len(usable_nodes)) + " usable nodes...")
  136. # create timestamp when all nodes are usable
  137. time_usable = time.time()
  138. date_usable = datetime.fromtimestamp(time_usable).ctime()
  139. print("Usable at: %s " % datetime.fromtimestamp(time_usable).ctime())
  140. durationStart = time_started - time_start
  141. durationActive = time_active - time_start
  142. durationUsable = time_usable - time_start
  143. # print results
  144. print("\n\n\nResult:")
  145. print("Start: %f " % durationStart)
  146. print("Active: %f " % durationActive)
  147. print("Usable: %f " % durationUsable)
  148. # file output
  149. # Topology;ConcurrentSims;Nodes;Script-Start;Started;Active;Usable;Start Time (sec);Active Time (sec);Usable Time (sec);Average Console Delay (sec)
  150. # 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
  151. avgConsoleDelay = 0
  152. results.append("%s;%i;%i;%s;%s;%s;%s;%i;%i;%i;%f" % (
  153. PROJECT_NAME, NUMBER_OF_CONCURRENT_BENCHMARK_PROJECTS, nodeCount, date_start, date_started, date_active,
  154. date_usable, durationStart, durationActive, durationUsable, avgConsoleDelay))
  155. f = open("gns3bench.log", "a")
  156. f.writelines(results)
  157. f.write("\r\n")
  158. f.close()
  159. print("Appended output to %s" % os.path.join(os.getcwd(), str(f.name)))
  160. # stop here, if we don't won't to stop and delete benchmark projects
  161. # sys.exit(0)
  162. # print("waiting...")
  163. # time.sleep(1)
  164. # stop all nodes in all projects
  165. # for benchmark in benchmarks:
  166. # data = "{}"
  167. # r = requests.post(BASE_API_URL + '/projects/' + benchmark["project_id"] + '/nodes/stop', data,
  168. # auth=(USERNAME, PASSWORD))
  169. # if r.status_code == 204:
  170. # print("Stopped all nodes in project " + benchmark["project_id"] + "...")
  171. # else:
  172. # sys.exit("Could not stop nodes")
  173. # delete the created benchmark projects
  174. for benchmark in benchmarks:
  175. r = requests.delete(BASE_API_URL + '/projects/' + benchmark["project_id"], auth=(USERNAME, PASSWORD))
  176. if r.status_code == 204:
  177. print("Deleted project " + benchmark["name"] + "...")
  178. else:
  179. sys.exit("Could not delete project")
  180. print("%i runs finished" % NUMBER_OF_BENCHMARK_RUNS)
  181. sys.exit(0)