utils.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import unittest
  2. import sys
  3. import os
  4. import sys
  5. import time
  6. import json
  7. import urllib
  8. import urllib2
  9. import subprocess
  10. import signal
  11. username = "test_user"
  12. def serialize(value):
  13. if isinstance(value, str):
  14. return '"%s"' % value
  15. else:
  16. return str(value)
  17. def execute(scriptname, parameters=[], wait=False):
  18. if os.name == "nt":
  19. command = ["%s.bat" % scriptname] + parameters
  20. elif os.name == "posix":
  21. command = ["./%s.sh" % scriptname] + parameters
  22. else:
  23. raise Exception("Unknown OS: " + str(os.name))
  24. if wait:
  25. return subprocess.call(command, shell=False)
  26. else:
  27. return subprocess.Popen(command, shell=False)
  28. def kill(process):
  29. if os.name == "nt":
  30. subprocess.call(["taskkill", "/F", "/T", "/PID", "%i" % process.pid])
  31. elif os.name == "posix":
  32. subprocess.call(["pkill", "-P", "%i" % process.pid])
  33. def flush_data(data):
  34. if data:
  35. urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "data": json.dumps(data), "username": username})), timeout=10).read()
  36. return []
  37. def compile_file(mod_filename, filename, mode, proc):
  38. # Load in the file required
  39. try:
  40. timeout_val = 120
  41. import random
  42. username = str(random.random())
  43. while 1:
  44. proc2 = execute("compile", [mod_filename, username, filename, mode], wait=False)
  45. if proc.returncode is not None:
  46. # Modelverse has already terminated, which isn't a good sign!
  47. raise Exception("Modelverse died!")
  48. while proc2.returncode is None:
  49. time.sleep(0.01)
  50. proc2.poll()
  51. timeout_val -= 0.01
  52. if timeout_val < 0:
  53. kill(proc2)
  54. print("Compilation timeout expired!")
  55. return False
  56. if proc2.returncode not in [7, 56]:
  57. break
  58. # Make sure everything stopped correctly
  59. assert proc2.returncode == 0
  60. if proc2.returncode != 0:
  61. return False
  62. except:
  63. raise
  64. finally:
  65. try:
  66. kill(proc2)
  67. except UnboundLocalError:
  68. pass
  69. def run_file(files, parameters, expected, mode):
  70. # Resolve file
  71. import os.path
  72. time.sleep(0.01)
  73. try:
  74. # Run Modelverse server
  75. proc = execute("run_local_modelverse", ["bootstrap/bootstrap.m"], wait=False)
  76. for filename in files:
  77. if filename == "--fast":
  78. continue
  79. if os.path.isfile("integration/code/%s" % filename):
  80. mod_filename = "integration/code/%s" % filename
  81. elif os.path.isfile("bootstrap/%s" % filename):
  82. mod_filename = "bootstrap/%s" % filename
  83. else:
  84. raise Exception("File not found: %s" % filename)
  85. print("Found file " + str(mod_filename))
  86. compile_file(mod_filename, filename, mode, proc)
  87. if mode[-1] == "O":
  88. # Fire up the linker
  89. val = execute("link_and_load", [username] + files, wait=True)
  90. if val != 0:
  91. raise Exception("Linking error")
  92. # Send in the actual request and wait for replies
  93. data = []
  94. for p in parameters:
  95. if isinstance(p, tuple):
  96. for v in p:
  97. data.append(["V", serialize(v)])
  98. else:
  99. data.append(["V", serialize(p)])
  100. flush_data(data)
  101. for e in expected:
  102. c = len(e) if isinstance(e, set) else 1
  103. for _ in range(c):
  104. val = urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "get_output", "username": username})), timeout=10).read()
  105. if proc.returncode is not None:
  106. # Modelverse has already terminated, which isn't a good sign!
  107. raise Exception("Modelverse died!")
  108. val = val.split("=", 2)[2]
  109. print("Got %s, expect %s" % (val, e))
  110. if isinstance(e, set):
  111. assert str(val) in e
  112. if str(val) not in e:
  113. return False
  114. else:
  115. assert str(val) == e
  116. if str(val) != e:
  117. return False
  118. # All passed!
  119. return True
  120. except:
  121. raise
  122. finally:
  123. try:
  124. kill(proc)
  125. except UnboundLocalError:
  126. pass
  127. def run_barebone(parameters, expected, interface="0", timeout=False, wait=False, link=None):
  128. try:
  129. # Run Modelverse server
  130. proc = execute("run_local_modelverse", ["bootstrap/bootstrap.m"], wait=False)
  131. # Create user and set interface
  132. timeout_val = 15
  133. start = time.time()
  134. while 1:
  135. try:
  136. urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % username, "username": "user_manager"})), timeout=1).read()
  137. if interface is not None:
  138. urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": interface, "username": username})), timeout=1).read()
  139. break
  140. except:
  141. time.sleep(0.01)
  142. if proc.returncode is not None:
  143. # Modelverse has already terminated, which isn't a good sign!
  144. return False
  145. if time.time() - start > timeout_val:
  146. raise
  147. # Send in the actual request and wait for replies
  148. var_list = {}
  149. data = []
  150. for p in parameters:
  151. if isinstance(p, int):
  152. if p not in var_list:
  153. data = flush_data(data)
  154. val = urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "get_output", "username": username})), timeout=10).read()
  155. if proc.returncode is not None:
  156. # Modelverse has already terminated, which isn't a good sign!
  157. return False
  158. val = val.split("=", 2)[1].split("&", 1)[0]
  159. var_list[p] = val
  160. continue
  161. else:
  162. val = var_list[p]
  163. t = "R"
  164. else:
  165. val = p
  166. t = "V"
  167. data.append([t, val])
  168. data = flush_data(data)
  169. # Now do linking and loading
  170. if link is not None:
  171. # Execute linker
  172. timeout_val = 10
  173. proc2 = execute("link_and_load", [username] + link, wait=False)
  174. while proc2.returncode is None:
  175. time.sleep(0.01)
  176. proc2.poll()
  177. timeout_val -= 0.01
  178. if timeout_val < 0:
  179. kill(proc2)
  180. print("Linking timeout expired!")
  181. return False
  182. counter = 0
  183. for e in expected:
  184. print("Expect " + str(e))
  185. c = len(e) if isinstance(e, set) else 1
  186. for _ in range(c):
  187. try:
  188. val = urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "get_output", "username": username})), timeout=15).read()
  189. except:
  190. if timeout:
  191. return True
  192. else:
  193. raise
  194. val = val.split("=", 2)[2]
  195. print("Got %s, expect %s" % (val, e))
  196. if isinstance(e, set):
  197. assert str(val) in e
  198. if str(val) not in e:
  199. return False
  200. else:
  201. assert str(val) == e
  202. if str(val) != e:
  203. return False
  204. # All passed!
  205. return not timeout
  206. finally:
  207. kill(proc)