utils.py 8.1 KB

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