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

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