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.

214 lines
8.3 KiB

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