autobahn 0.3.1__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. Python27/Lib/site-packages/autobahn/__init__.py +22 -0
  2. Python27/Lib/site-packages/autobahn/__init__.pyc +0 -0
  3. Python27/Lib/site-packages/autobahn/autobahn.py +76 -0
  4. Python27/Lib/site-packages/autobahn/autobahn.pyc +0 -0
  5. Python27/Lib/site-packages/autobahn/case/__init__.py +207 -0
  6. Python27/Lib/site-packages/autobahn/case/__init__.pyc +0 -0
  7. Python27/Lib/site-packages/autobahn/case/case.py +68 -0
  8. Python27/Lib/site-packages/autobahn/case/case.pyc +0 -0
  9. Python27/Lib/site-packages/autobahn/case/case1_1_1.py +31 -0
  10. Python27/Lib/site-packages/autobahn/case/case1_1_1.pyc +0 -0
  11. Python27/Lib/site-packages/autobahn/case/case1_1_2.py +31 -0
  12. Python27/Lib/site-packages/autobahn/case/case1_1_2.pyc +0 -0
  13. Python27/Lib/site-packages/autobahn/case/case1_1_3.py +31 -0
  14. Python27/Lib/site-packages/autobahn/case/case1_1_3.pyc +0 -0
  15. Python27/Lib/site-packages/autobahn/case/case1_1_4.py +31 -0
  16. Python27/Lib/site-packages/autobahn/case/case1_1_4.pyc +0 -0
  17. Python27/Lib/site-packages/autobahn/case/case1_1_5.py +31 -0
  18. Python27/Lib/site-packages/autobahn/case/case1_1_5.pyc +0 -0
  19. Python27/Lib/site-packages/autobahn/case/case1_1_6.py +31 -0
  20. Python27/Lib/site-packages/autobahn/case/case1_1_6.pyc +0 -0
  21. Python27/Lib/site-packages/autobahn/case/case1_1_7.py +31 -0
  22. Python27/Lib/site-packages/autobahn/case/case1_1_7.pyc +0 -0
  23. Python27/Lib/site-packages/autobahn/case/case1_1_8.py +31 -0
  24. Python27/Lib/site-packages/autobahn/case/case1_1_8.pyc +0 -0
  25. Python27/Lib/site-packages/autobahn/case/case1_2_1.py +31 -0
  26. Python27/Lib/site-packages/autobahn/case/case1_2_1.pyc +0 -0
  27. Python27/Lib/site-packages/autobahn/case/case1_2_2.py +31 -0
  28. Python27/Lib/site-packages/autobahn/case/case1_2_2.pyc +0 -0
  29. Python27/Lib/site-packages/autobahn/case/case1_2_3.py +31 -0
  30. Python27/Lib/site-packages/autobahn/case/case1_2_3.pyc +0 -0
  31. Python27/Lib/site-packages/autobahn/case/case1_2_4.py +31 -0
  32. Python27/Lib/site-packages/autobahn/case/case1_2_4.pyc +0 -0
  33. Python27/Lib/site-packages/autobahn/case/case1_2_5.py +31 -0
  34. Python27/Lib/site-packages/autobahn/case/case1_2_5.pyc +0 -0
  35. Python27/Lib/site-packages/autobahn/case/case1_2_6.py +31 -0
  36. Python27/Lib/site-packages/autobahn/case/case1_2_6.pyc +0 -0
  37. Python27/Lib/site-packages/autobahn/case/case1_2_7.py +31 -0
  38. Python27/Lib/site-packages/autobahn/case/case1_2_7.pyc +0 -0
  39. Python27/Lib/site-packages/autobahn/case/case1_2_8.py +31 -0
  40. Python27/Lib/site-packages/autobahn/case/case1_2_8.pyc +0 -0
  41. Python27/Lib/site-packages/autobahn/case/case2_1.py +30 -0
  42. Python27/Lib/site-packages/autobahn/case/case2_1.pyc +0 -0
  43. Python27/Lib/site-packages/autobahn/case/case2_10.py +37 -0
  44. Python27/Lib/site-packages/autobahn/case/case2_10.pyc +0 -0
  45. Python27/Lib/site-packages/autobahn/case/case2_11.py +28 -0
  46. Python27/Lib/site-packages/autobahn/case/case2_11.pyc +0 -0
  47. Python27/Lib/site-packages/autobahn/case/case2_2.py +31 -0
  48. Python27/Lib/site-packages/autobahn/case/case2_2.pyc +0 -0
  49. Python27/Lib/site-packages/autobahn/case/case2_3.py +31 -0
  50. Python27/Lib/site-packages/autobahn/case/case2_3.pyc +0 -0
  51. Python27/Lib/site-packages/autobahn/case/case2_4.py +31 -0
  52. Python27/Lib/site-packages/autobahn/case/case2_4.pyc +0 -0
  53. Python27/Lib/site-packages/autobahn/case/case2_5.py +31 -0
  54. Python27/Lib/site-packages/autobahn/case/case2_5.pyc +0 -0
  55. Python27/Lib/site-packages/autobahn/case/case2_6.py +31 -0
  56. Python27/Lib/site-packages/autobahn/case/case2_6.pyc +0 -0
  57. Python27/Lib/site-packages/autobahn/case/case2_7.py +30 -0
  58. Python27/Lib/site-packages/autobahn/case/case2_7.pyc +0 -0
  59. Python27/Lib/site-packages/autobahn/case/case2_8.py +30 -0
  60. Python27/Lib/site-packages/autobahn/case/case2_8.pyc +0 -0
  61. Python27/Lib/site-packages/autobahn/case/case2_9.py +32 -0
  62. Python27/Lib/site-packages/autobahn/case/case2_9.pyc +0 -0
  63. Python27/Lib/site-packages/autobahn/case/case3_1.py +30 -0
  64. Python27/Lib/site-packages/autobahn/case/case3_1.pyc +0 -0
  65. Python27/Lib/site-packages/autobahn/case/case3_2.py +34 -0
  66. Python27/Lib/site-packages/autobahn/case/case3_2.pyc +0 -0
  67. Python27/Lib/site-packages/autobahn/case/case3_3.py +34 -0
  68. Python27/Lib/site-packages/autobahn/case/case3_3.pyc +0 -0
  69. Python27/Lib/site-packages/autobahn/case/case3_4.py +34 -0
  70. Python27/Lib/site-packages/autobahn/case/case3_4.pyc +0 -0
  71. Python27/Lib/site-packages/autobahn/case/case3_5.py +31 -0
  72. Python27/Lib/site-packages/autobahn/case/case3_5.pyc +0 -0
  73. Python27/Lib/site-packages/autobahn/case/case3_6.py +31 -0
  74. Python27/Lib/site-packages/autobahn/case/case3_6.pyc +0 -0
  75. Python27/Lib/site-packages/autobahn/case/case3_7.py +30 -0
  76. Python27/Lib/site-packages/autobahn/case/case3_7.pyc +0 -0
  77. Python27/Lib/site-packages/autobahn/case/case4_1_1.py +30 -0
  78. Python27/Lib/site-packages/autobahn/case/case4_1_1.pyc +0 -0
  79. Python27/Lib/site-packages/autobahn/case/case4_1_2.py +30 -0
  80. Python27/Lib/site-packages/autobahn/case/case4_1_2.pyc +0 -0
  81. Python27/Lib/site-packages/autobahn/case/case4_1_3.py +34 -0
  82. Python27/Lib/site-packages/autobahn/case/case4_1_3.pyc +0 -0
  83. Python27/Lib/site-packages/autobahn/case/case4_1_4.py +34 -0
  84. Python27/Lib/site-packages/autobahn/case/case4_1_4.pyc +0 -0
  85. Python27/Lib/site-packages/autobahn/case/case4_1_5.py +34 -0
  86. Python27/Lib/site-packages/autobahn/case/case4_1_5.pyc +0 -0
  87. Python27/Lib/site-packages/autobahn/case/case4_2_1.py +30 -0
  88. Python27/Lib/site-packages/autobahn/case/case4_2_1.pyc +0 -0
  89. Python27/Lib/site-packages/autobahn/case/case4_2_2.py +30 -0
  90. Python27/Lib/site-packages/autobahn/case/case4_2_2.pyc +0 -0
  91. Python27/Lib/site-packages/autobahn/case/case4_2_3.py +34 -0
  92. Python27/Lib/site-packages/autobahn/case/case4_2_3.pyc +0 -0
  93. Python27/Lib/site-packages/autobahn/case/case4_2_4.py +34 -0
  94. Python27/Lib/site-packages/autobahn/case/case4_2_4.pyc +0 -0
  95. Python27/Lib/site-packages/autobahn/case/case4_2_5.py +34 -0
  96. Python27/Lib/site-packages/autobahn/case/case4_2_5.pyc +0 -0
  97. Python27/Lib/site-packages/autobahn/case/case5_1.py +31 -0
  98. Python27/Lib/site-packages/autobahn/case/case5_1.pyc +0 -0
  99. Python27/Lib/site-packages/autobahn/case/case5_10.py +31 -0
  100. Python27/Lib/site-packages/autobahn/case/case5_10.pyc +0 -0
  101. Python27/Lib/site-packages/autobahn/case/case5_11.py +31 -0
  102. Python27/Lib/site-packages/autobahn/case/case5_11.pyc +0 -0
  103. Python27/Lib/site-packages/autobahn/case/case5_12.py +31 -0
  104. Python27/Lib/site-packages/autobahn/case/case5_12.pyc +0 -0
  105. Python27/Lib/site-packages/autobahn/case/case5_13.py +31 -0
  106. Python27/Lib/site-packages/autobahn/case/case5_13.pyc +0 -0
  107. Python27/Lib/site-packages/autobahn/case/case5_14.py +31 -0
  108. Python27/Lib/site-packages/autobahn/case/case5_14.pyc +0 -0
  109. Python27/Lib/site-packages/autobahn/case/case5_15.py +35 -0
  110. Python27/Lib/site-packages/autobahn/case/case5_15.pyc +0 -0
  111. Python27/Lib/site-packages/autobahn/case/case5_16.py +33 -0
  112. Python27/Lib/site-packages/autobahn/case/case5_16.pyc +0 -0
  113. Python27/Lib/site-packages/autobahn/case/case5_17.py +33 -0
  114. Python27/Lib/site-packages/autobahn/case/case5_17.pyc +0 -0
  115. Python27/Lib/site-packages/autobahn/case/case5_18.py +31 -0
  116. Python27/Lib/site-packages/autobahn/case/case5_18.pyc +0 -0
  117. Python27/Lib/site-packages/autobahn/case/case5_19.py +56 -0
  118. Python27/Lib/site-packages/autobahn/case/case5_19.pyc +0 -0
  119. Python27/Lib/site-packages/autobahn/case/case5_2.py +31 -0
  120. Python27/Lib/site-packages/autobahn/case/case5_2.pyc +0 -0
  121. Python27/Lib/site-packages/autobahn/case/case5_20.py +31 -0
  122. Python27/Lib/site-packages/autobahn/case/case5_20.pyc +0 -0
  123. Python27/Lib/site-packages/autobahn/case/case5_3.py +32 -0
  124. Python27/Lib/site-packages/autobahn/case/case5_3.pyc +0 -0
  125. Python27/Lib/site-packages/autobahn/case/case5_4.py +32 -0
  126. Python27/Lib/site-packages/autobahn/case/case5_4.pyc +0 -0
  127. Python27/Lib/site-packages/autobahn/case/case5_5.py +32 -0
  128. Python27/Lib/site-packages/autobahn/case/case5_5.pyc +0 -0
  129. Python27/Lib/site-packages/autobahn/case/case5_6.py +34 -0
  130. Python27/Lib/site-packages/autobahn/case/case5_6.pyc +0 -0
  131. Python27/Lib/site-packages/autobahn/case/case5_7.py +34 -0
  132. Python27/Lib/site-packages/autobahn/case/case5_7.pyc +0 -0
  133. Python27/Lib/site-packages/autobahn/case/case5_8.py +34 -0
  134. Python27/Lib/site-packages/autobahn/case/case5_8.pyc +0 -0
  135. Python27/Lib/site-packages/autobahn/case/case5_9.py +31 -0
  136. Python27/Lib/site-packages/autobahn/case/case5_9.pyc +0 -0
  137. Python27/Lib/site-packages/autobahn/case/case6_1.py +30 -0
  138. Python27/Lib/site-packages/autobahn/case/case6_1.pyc +0 -0
  139. Python27/Lib/site-packages/autobahn/case/case6_2.py +32 -0
  140. Python27/Lib/site-packages/autobahn/case/case6_2.pyc +0 -0
  141. Python27/Lib/site-packages/autobahn/case/case6_3.py +33 -0
  142. Python27/Lib/site-packages/autobahn/case/case6_3.pyc +0 -0
  143. Python27/Lib/site-packages/autobahn/case/case9_1_1.py +54 -0
  144. Python27/Lib/site-packages/autobahn/case/case9_1_1.pyc +0 -0
  145. Python27/Lib/site-packages/autobahn/case/case9_1_2.py +31 -0
  146. Python27/Lib/site-packages/autobahn/case/case9_1_2.pyc +0 -0
  147. Python27/Lib/site-packages/autobahn/case/case9_1_3.py +31 -0
  148. Python27/Lib/site-packages/autobahn/case/case9_1_3.pyc +0 -0
  149. Python27/Lib/site-packages/autobahn/case/case9_1_4.py +31 -0
  150. Python27/Lib/site-packages/autobahn/case/case9_1_4.pyc +0 -0
  151. Python27/Lib/site-packages/autobahn/case/case9_1_5.py +31 -0
  152. Python27/Lib/site-packages/autobahn/case/case9_1_5.pyc +0 -0
  153. Python27/Lib/site-packages/autobahn/case/case9_1_6.py +31 -0
  154. Python27/Lib/site-packages/autobahn/case/case9_1_6.pyc +0 -0
  155. Python27/Lib/site-packages/autobahn/case/case9_2_1.py +54 -0
  156. Python27/Lib/site-packages/autobahn/case/case9_2_1.pyc +0 -0
  157. Python27/Lib/site-packages/autobahn/case/case9_2_2.py +31 -0
  158. Python27/Lib/site-packages/autobahn/case/case9_2_2.pyc +0 -0
  159. Python27/Lib/site-packages/autobahn/case/case9_2_3.py +31 -0
  160. Python27/Lib/site-packages/autobahn/case/case9_2_3.pyc +0 -0
  161. Python27/Lib/site-packages/autobahn/case/case9_2_4.py +31 -0
  162. Python27/Lib/site-packages/autobahn/case/case9_2_4.pyc +0 -0
  163. Python27/Lib/site-packages/autobahn/case/case9_2_5.py +31 -0
  164. Python27/Lib/site-packages/autobahn/case/case9_2_5.pyc +0 -0
  165. Python27/Lib/site-packages/autobahn/case/case9_2_6.py +31 -0
  166. Python27/Lib/site-packages/autobahn/case/case9_2_6.pyc +0 -0
  167. Python27/Lib/site-packages/autobahn/case/case9_3_1.py +55 -0
  168. Python27/Lib/site-packages/autobahn/case/case9_3_1.pyc +0 -0
  169. Python27/Lib/site-packages/autobahn/case/case9_3_2.py +32 -0
  170. Python27/Lib/site-packages/autobahn/case/case9_3_2.pyc +0 -0
  171. Python27/Lib/site-packages/autobahn/case/case9_3_3.py +32 -0
  172. Python27/Lib/site-packages/autobahn/case/case9_3_3.pyc +0 -0
  173. Python27/Lib/site-packages/autobahn/case/case9_3_4.py +32 -0
  174. Python27/Lib/site-packages/autobahn/case/case9_3_4.pyc +0 -0
  175. Python27/Lib/site-packages/autobahn/case/case9_3_5.py +32 -0
  176. Python27/Lib/site-packages/autobahn/case/case9_3_5.pyc +0 -0
  177. Python27/Lib/site-packages/autobahn/case/case9_3_6.py +32 -0
  178. Python27/Lib/site-packages/autobahn/case/case9_3_6.pyc +0 -0
  179. Python27/Lib/site-packages/autobahn/case/case9_3_7.py +32 -0
  180. Python27/Lib/site-packages/autobahn/case/case9_3_7.pyc +0 -0
  181. Python27/Lib/site-packages/autobahn/case/case9_3_8.py +32 -0
  182. Python27/Lib/site-packages/autobahn/case/case9_3_8.pyc +0 -0
  183. Python27/Lib/site-packages/autobahn/case/case9_3_9.py +32 -0
  184. Python27/Lib/site-packages/autobahn/case/case9_3_9.pyc +0 -0
  185. Python27/Lib/site-packages/autobahn/case/case9_4_1.py +55 -0
  186. Python27/Lib/site-packages/autobahn/case/case9_4_1.pyc +0 -0
  187. Python27/Lib/site-packages/autobahn/case/case9_4_2.py +32 -0
  188. Python27/Lib/site-packages/autobahn/case/case9_4_2.pyc +0 -0
  189. Python27/Lib/site-packages/autobahn/case/case9_4_3.py +32 -0
  190. Python27/Lib/site-packages/autobahn/case/case9_4_3.pyc +0 -0
  191. Python27/Lib/site-packages/autobahn/case/case9_4_4.py +32 -0
  192. Python27/Lib/site-packages/autobahn/case/case9_4_4.pyc +0 -0
  193. Python27/Lib/site-packages/autobahn/case/case9_4_5.py +32 -0
  194. Python27/Lib/site-packages/autobahn/case/case9_4_5.pyc +0 -0
  195. Python27/Lib/site-packages/autobahn/case/case9_4_6.py +32 -0
  196. Python27/Lib/site-packages/autobahn/case/case9_4_6.pyc +0 -0
  197. Python27/Lib/site-packages/autobahn/case/case9_4_7.py +32 -0
  198. Python27/Lib/site-packages/autobahn/case/case9_4_7.pyc +0 -0
  199. Python27/Lib/site-packages/autobahn/case/case9_4_8.py +32 -0
  200. Python27/Lib/site-packages/autobahn/case/case9_4_8.pyc +0 -0
  201. Python27/Lib/site-packages/autobahn/case/case9_4_9.py +32 -0
  202. Python27/Lib/site-packages/autobahn/case/case9_4_9.pyc +0 -0
  203. Python27/Lib/site-packages/autobahn/case/case9_5_1.py +58 -0
  204. Python27/Lib/site-packages/autobahn/case/case9_5_1.pyc +0 -0
  205. Python27/Lib/site-packages/autobahn/case/case9_5_2.py +28 -0
  206. Python27/Lib/site-packages/autobahn/case/case9_5_2.pyc +0 -0
  207. Python27/Lib/site-packages/autobahn/case/case9_5_3.py +28 -0
  208. Python27/Lib/site-packages/autobahn/case/case9_5_3.pyc +0 -0
  209. Python27/Lib/site-packages/autobahn/case/case9_5_4.py +28 -0
  210. Python27/Lib/site-packages/autobahn/case/case9_5_4.pyc +0 -0
  211. Python27/Lib/site-packages/autobahn/case/case9_5_5.py +28 -0
  212. Python27/Lib/site-packages/autobahn/case/case9_5_5.pyc +0 -0
  213. Python27/Lib/site-packages/autobahn/case/case9_5_6.py +28 -0
  214. Python27/Lib/site-packages/autobahn/case/case9_5_6.pyc +0 -0
  215. Python27/Lib/site-packages/autobahn/case/case9_6_1.py +58 -0
  216. Python27/Lib/site-packages/autobahn/case/case9_6_1.pyc +0 -0
  217. Python27/Lib/site-packages/autobahn/case/case9_6_2.py +28 -0
  218. Python27/Lib/site-packages/autobahn/case/case9_6_2.pyc +0 -0
  219. Python27/Lib/site-packages/autobahn/case/case9_6_3.py +28 -0
  220. Python27/Lib/site-packages/autobahn/case/case9_6_3.pyc +0 -0
  221. Python27/Lib/site-packages/autobahn/case/case9_6_4.py +28 -0
  222. Python27/Lib/site-packages/autobahn/case/case9_6_4.pyc +0 -0
  223. Python27/Lib/site-packages/autobahn/case/case9_6_5.py +28 -0
  224. Python27/Lib/site-packages/autobahn/case/case9_6_5.pyc +0 -0
  225. Python27/Lib/site-packages/autobahn/case/case9_6_6.py +28 -0
  226. Python27/Lib/site-packages/autobahn/case/case9_6_6.pyc +0 -0
  227. Python27/Lib/site-packages/autobahn/fuzzing.py +911 -0
  228. Python27/Lib/site-packages/autobahn/fuzzing.pyc +0 -0
  229. Python27/Lib/site-packages/autobahn/websocket.py +1505 -0
  230. Python27/Lib/site-packages/autobahn/websocket.pyc +0 -0
  231. Python27/Lib/site-packages/autobahn-0.3.1-py2.7.egg-info/PKG-INFO +10 -0
  232. Python27/Lib/site-packages/autobahn-0.3.1-py2.7.egg-info/SOURCES.txt +124 -0
  233. Python27/Lib/site-packages/autobahn-0.3.1-py2.7.egg-info/dependency_links.txt +1 -0
  234. Python27/Lib/site-packages/autobahn-0.3.1-py2.7.egg-info/not-zip-safe +1 -0
  235. Python27/Lib/site-packages/autobahn-0.3.1-py2.7.egg-info/requires.txt +1 -0
  236. Python27/Lib/site-packages/autobahn-0.3.1-py2.7.egg-info/top_level.txt +1 -0
@@ -0,0 +1,911 @@
1
+ ###############################################################################
2
+ ##
3
+ ## Copyright 2011 Tavendo GmbH
4
+ ##
5
+ ## Licensed under the Apache License, Version 2.0 (the "License");
6
+ ## you may not use this file except in compliance with the License.
7
+ ## You may obtain a copy of the License at
8
+ ##
9
+ ## http://www.apache.org/licenses/LICENSE-2.0
10
+ ##
11
+ ## Unless required by applicable law or agreed to in writing, software
12
+ ## distributed under the License is distributed on an "AS IS" BASIS,
13
+ ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ ## See the License for the specific language governing permissions and
15
+ ## limitations under the License.
16
+ ##
17
+ ###############################################################################
18
+
19
+ from twisted.internet import reactor
20
+ from twisted.python import log
21
+ from websocket import WebSocketProtocol, WebSocketServerFactory, WebSocketServerProtocol, HttpException
22
+ from case import Case, Cases, CaseCategories, CaseSubCategories, caseClasstoId, caseClasstoIdTuple
23
+ import json
24
+ import binascii
25
+ import datetime
26
+ import time
27
+ import random
28
+ import textwrap
29
+ import os
30
+
31
+
32
+ def getUtcNow():
33
+ now = datetime.datetime.utcnow()
34
+ return now.strftime("%Y-%m-%dT%H:%M:%SZ")
35
+
36
+
37
+ class FuzzingServerProtocol(WebSocketServerProtocol):
38
+
39
+ MAX_WIRE_LOG_DATA = 256
40
+
41
+
42
+ def connectionMade(self):
43
+ WebSocketServerProtocol.connectionMade(self)
44
+ self.case = None
45
+ self.runCase = None
46
+ self.caseAgent = None
47
+ self.caseStarted = None
48
+ self.caseStart = 0
49
+ self.caseEnd = 0
50
+
51
+ ## wire log
52
+ ##
53
+ self.createWirelog = True
54
+ self.wirelog = []
55
+
56
+ ## stats for octets and frames
57
+ ##
58
+ self.createStats = True
59
+ self.rxOctetStats = {}
60
+ self.rxFrameStats = {}
61
+ self.txOctetStats = {}
62
+ self.txFrameStats = {}
63
+
64
+
65
+ def connectionLost(self, reason):
66
+
67
+ WebSocketServerProtocol.connectionLost(self, reason)
68
+
69
+ if self.runCase:
70
+
71
+ self.runCase.onConnectionLost(self.failedByMe)
72
+ self.caseEnd = time.time()
73
+
74
+ caseResult = {"case": self.case,
75
+ "id": caseClasstoId(self.Case),
76
+ "description": self.Case.DESCRIPTION,
77
+ "expectation": self.Case.EXPECTATION,
78
+ "agent": self.caseAgent,
79
+ "started": self.caseStarted,
80
+ "duration": int(round(1000. * (self.caseEnd - self.caseStart))), # case execution time in ms
81
+ "reportTime": self.runCase.reportTime, # True/False switch to control report output of duration
82
+ "behavior": self.runCase.behavior,
83
+ "expected": self.runCase.expected,
84
+ "received": self.runCase.received,
85
+ "result": self.runCase.result,
86
+ "wirelog": self.wirelog,
87
+ "createWirelog": self.createWirelog,
88
+ "failedByMe": self.failedByMe,
89
+ "createStats": self.createStats,
90
+ "rxOctetStats": self.rxOctetStats,
91
+ "rxFrameStats": self.rxFrameStats,
92
+ "txOctetStats": self.txOctetStats,
93
+ "txFrameStats": self.txFrameStats}
94
+
95
+ self.factory.logCase(caseResult)
96
+
97
+
98
+ def binLogData(self, data):
99
+ if len(data) > FuzzingServerProtocol.MAX_WIRE_LOG_DATA:
100
+ dd = binascii.b2a_hex(data[:FuzzingServerProtocol.MAX_WIRE_LOG_DATA]) + " ..."
101
+ else:
102
+ dd = binascii.b2a_hex(data)
103
+ return dd
104
+
105
+
106
+ def asciiLogData(self, data):
107
+ if len(data) > FuzzingServerProtocol.MAX_WIRE_LOG_DATA:
108
+ dd = data[:FuzzingServerProtocol.MAX_WIRE_LOG_DATA] + " ..."
109
+ else:
110
+ dd = data
111
+ return dd
112
+
113
+
114
+ def logRxOctets(self, data):
115
+ if self.createStats:
116
+ l = len(data)
117
+ self.rxOctetStats[l] = self.rxOctetStats.get(l, 0) + 1
118
+ if self.createWirelog:
119
+ d = str(buffer(data))
120
+ self.wirelog.append(("RO", self.binLogData(d)))
121
+ else:
122
+ WebSocketServerProtocol.logRxOctets(self, data)
123
+
124
+
125
+ def logTxOctets(self, data, sync):
126
+ if self.createStats:
127
+ l = len(data)
128
+ self.txOctetStats[l] = self.txOctetStats.get(l, 0) + 1
129
+ if self.createWirelog:
130
+ d = str(buffer(data))
131
+ self.wirelog.append(("TO", self.binLogData(d), sync))
132
+ else:
133
+ WebSocketServerProtocol.logTxOctets(self, data, sync)
134
+
135
+
136
+ def logRxFrame(self, fin, rsv, opcode, masked, payload_len, mask, payload):
137
+ if self.createStats:
138
+ self.rxFrameStats[opcode] = self.rxFrameStats.get(opcode, 0) + 1
139
+ if self.createWirelog:
140
+ d = str(buffer(payload))
141
+ self.wirelog.append(("RF", self.asciiLogData(d), opcode, fin, rsv, masked, mask))
142
+ else:
143
+ WebSocketServerProtocol.logRxFrame(self, fin, rsv, opcode, masked, payload_len, mask, payload)
144
+
145
+
146
+ def logTxFrame(self, opcode, payload, fin, rsv, mask, payload_len, chopsize, sync):
147
+ if self.createStats:
148
+ self.txFrameStats[opcode] = self.txFrameStats.get(opcode, 0) + 1
149
+ if self.createWirelog:
150
+ d = str(buffer(payload))
151
+ self.wirelog.append(("TF", self.asciiLogData(d), opcode, fin, rsv, mask, payload_len, chopsize, sync))
152
+ else:
153
+ WebSocketServerProtocol.logTxFrame(self, opcode, payload, fin, rsv, mask, payload_len, chopsize, sync)
154
+
155
+
156
+ def continueLater(self, delay, fun):
157
+ self.wirelog.append(("CT", delay))
158
+ reactor.callLater(delay, fun)
159
+
160
+
161
+ def killAfter(self, delay):
162
+ self.wirelog.append(("KL", delay))
163
+ reactor.callLater(delay, self.failConnection)
164
+
165
+
166
+ def onConnect(self, host, path, params, origin, protocols):
167
+ if self.debug:
168
+ log.msg("connection received from %s for host %s, path %s, parms %s, origin %s, protocols %s" % (self.peerstr, host, path, str(params), origin, str(protocols)))
169
+
170
+ if params.has_key("agent"):
171
+ if len(params["agent"]) > 1:
172
+ raise Exception("multiple agents specified")
173
+ self.caseAgent = params["agent"][0]
174
+
175
+ if params.has_key("case"):
176
+ if len(params["case"]) > 1:
177
+ raise Exception("multiple test cases specified")
178
+ try:
179
+ self.case = int(params["case"][0])
180
+ except:
181
+ raise Exception("invalid test case ID %s" % params["case"][0])
182
+
183
+ if self.case:
184
+ if self.case >= 1 and self.case <= len(Cases):
185
+ self.Case = Cases[self.case - 1]
186
+ self.runCase = self.Case(self)
187
+ else:
188
+ raise Exception("case %s not found" % self.case)
189
+
190
+ if path == "/runCase":
191
+ if not self.runCase:
192
+ raise Exception("need case to run")
193
+ if not self.caseAgent:
194
+ raise Exception("need agent to run case")
195
+ self.caseStarted = getUtcNow()
196
+ print "Running test case ID %s for user agent %s for peer %s" % (caseClasstoId(self.Case), self.caseAgent, self.peerstr)
197
+
198
+ elif path == "/updateReports":
199
+ if not self.caseAgent:
200
+ raise Exception("need agent to update reports for")
201
+ print "Updating reports, requested by peer %s" % self.peerstr
202
+
203
+ elif path == "/getCaseCount":
204
+ pass
205
+
206
+ else:
207
+ print "Entering direct command mode for peer %s" % self.peerstr
208
+
209
+ self.path = path
210
+
211
+ return None
212
+
213
+
214
+ def onOpen(self):
215
+
216
+ if self.runCase:
217
+
218
+ cc = caseClasstoIdTuple(self.runCase.__class__)
219
+
220
+ ## FF7 crashes on these
221
+ ##
222
+ if self.caseAgent.find("Firefox/7") >= 0 and cc[0:2] == (9, 3):
223
+ print "Skipping fragmented message test case for broken FF/7 !!!"
224
+ self.runCase = None
225
+ self.sendClose()
226
+ return
227
+
228
+ ## FF and Chrome dont yet implement binary messages
229
+ ##
230
+ if (self.caseAgent.find("Firefox") >= 0 or self.caseAgent.find("Chrome") >= 0) and cc[0:2] in [(1, 2), (9, 2), (9, 4), (9,6)]:
231
+ print "Skipping binary message test case for browser client !!!"
232
+ self.runCase = None
233
+ self.sendClose()
234
+ return
235
+
236
+ self.caseStart = time.time()
237
+ self.runCase.onOpen()
238
+
239
+ elif self.path == "/updateReports":
240
+ self.factory.createReports()
241
+ self.sendClose()
242
+
243
+ elif self.path == "/getCaseCount":
244
+ self.sendMessage(json.dumps(len(Cases)))
245
+ self.sendClose()
246
+
247
+ else:
248
+ pass
249
+
250
+
251
+ def onPong(self, payload):
252
+ if self.runCase:
253
+ self.runCase.onPong(payload)
254
+ else:
255
+ if self.debug:
256
+ log.msg("Pong received: " + payload)
257
+
258
+
259
+ def onMessage(self, msg, binary):
260
+
261
+ if self.runCase:
262
+ self.runCase.onMessage(msg, binary)
263
+
264
+ else:
265
+
266
+ if binary:
267
+
268
+ raise Exception("binary command message")
269
+
270
+ else:
271
+
272
+ try:
273
+ obj = json.loads(msg)
274
+ except:
275
+ raise Exception("could not parse command")
276
+
277
+ ## send one frame as specified
278
+ ##
279
+ if obj[0] == "sendframe":
280
+ pl = obj[1].get("payload", "")
281
+ self.sendFrame(opcode = obj[1]["opcode"],
282
+ payload = pl.encode("UTF-8"),
283
+ fin = obj[1].get("fin", True),
284
+ rsv = obj[1].get("rsv", 0),
285
+ mask = obj[1].get("mask", None),
286
+ payload_len = obj[1].get("payload_len", None),
287
+ chopsize = obj[1].get("chopsize", None),
288
+ sync = obj[1].get("sync", False))
289
+
290
+ ## send multiple frames as specified
291
+ ##
292
+ elif obj[0] == "sendframes":
293
+ frames = obj[1]
294
+ for frame in frames:
295
+ pl = frame.get("payload", "")
296
+ self.sendFrame(opcode = frame["opcode"],
297
+ payload = pl.encode("UTF-8"),
298
+ fin = frame.get("fin", True),
299
+ rsv = frame.get("rsv", 0),
300
+ mask = frame.get("mask", None),
301
+ payload_len = frame.get("payload_len", None),
302
+ chopsize = frame.get("chopsize", None),
303
+ sync = frame.get("sync", False))
304
+
305
+ ## send close
306
+ ##
307
+ elif obj[0] == "close":
308
+ spec = obj[1]
309
+ self.sendClose(spec.get("code", None), spec.get("reason", None))
310
+
311
+ ## echo argument
312
+ ##
313
+ elif obj[0] == "echo":
314
+ spec = obj[1]
315
+ self.sendFrame(opcode = 1, payload = spec.get("payload", ""), payload_len = spec.get("payload_len", None))
316
+
317
+ else:
318
+ raise Exception("fuzzing server received unknown command" % obj[0])
319
+
320
+
321
+ class FuzzingServerFactory(WebSocketServerFactory):
322
+
323
+ protocol = FuzzingServerProtocol
324
+
325
+ ## CSS common for all reports
326
+ ##
327
+ css_common = """
328
+ body
329
+ {
330
+ background-color: #F4F4F4;
331
+ color: #333;
332
+ font-family: Segoe UI,Tahoma,Arial,Verdana,sans-serif;
333
+ }
334
+
335
+ p#intro
336
+ {
337
+ margin-left: 30px;
338
+ font-size: 1.2em;
339
+ }
340
+
341
+ p#case_desc
342
+ {
343
+ border-radius: 10px;
344
+ background-color: #eee;
345
+ padding: 20px;
346
+ margin: 20px;
347
+ }
348
+
349
+ p#case_expect
350
+ {
351
+ border-radius: 10px;
352
+ background-color: #eee;
353
+ padding: 20px;
354
+ margin: 20px;
355
+ }
356
+
357
+ p#case_result
358
+ {
359
+ border-radius: 10px;
360
+ background-color: #eee;
361
+ padding: 20px;
362
+ margin: 20px;
363
+ }
364
+
365
+ h1
366
+ {
367
+ }
368
+
369
+ h2
370
+ {
371
+ margin-top: 60px;
372
+ margin-left: 30px;
373
+ }
374
+
375
+ h3
376
+ {
377
+ margin-left: 50px;
378
+ }
379
+ """
380
+
381
+ ## CSS for Master report
382
+ ##
383
+ css_master = """
384
+ table
385
+ {
386
+ border-collapse: collapse;
387
+ border-spacing: 0px;
388
+ margin-left: 40px;
389
+ margin-bottom: 40px;
390
+ margin-top: 20px;
391
+ }
392
+
393
+ td
394
+ {
395
+ margin: 0;
396
+ border: 1px #fff solid;
397
+ padding-top: 6px;
398
+ padding-bottom: 6px;
399
+ padding-left: 16px;
400
+ padding-right: 16px;
401
+ }
402
+
403
+ tr#agent_case_result_row a
404
+ {
405
+ color: #eee;
406
+ }
407
+
408
+ td#agent
409
+ {
410
+ color: #fff;
411
+ font-size: 1.0em;
412
+ min-width: 140px;
413
+ text-align: center;
414
+ background-color: #048;
415
+ }
416
+
417
+ td#case_category
418
+ {
419
+ min-width: 180px;
420
+ color: #fff;
421
+ background-color: #000;
422
+ text-align: left;
423
+ padding-left: 20px;
424
+ font-size: 1.0em;
425
+ }
426
+
427
+ td#case_subcategory
428
+ {
429
+ color: #fff;
430
+ background-color: #333;
431
+ text-align: left;
432
+ padding-left: 30px;
433
+ font-size: 0.9em;
434
+ }
435
+
436
+ td#case
437
+ {
438
+ background-color: #666;
439
+ text-align: left;
440
+ padding-left: 40px;
441
+ font-size: 0.9em;
442
+ }
443
+
444
+ span#case_duration
445
+ {
446
+ font-size: 0.7em;
447
+ color: #fff;
448
+ }
449
+
450
+ td#case_ok
451
+ {
452
+ background-color: #0a0;
453
+ text-align: center;
454
+ }
455
+
456
+ td#case_non_strict
457
+ {
458
+ background-color: #aa0;
459
+ text-align: center;
460
+ }
461
+
462
+ td#case_failed
463
+ {
464
+ background-color: #900;
465
+ text-align: center;
466
+ }
467
+
468
+ td#case_missing
469
+ {
470
+ color: #fff;
471
+ background-color: #a05a2c;
472
+ text-align: center;
473
+ }
474
+ """
475
+
476
+ ## CSS for Agent/Case detail report
477
+ ##
478
+ css_detail = """
479
+ h2
480
+ {
481
+ margin-top: 30px;
482
+ }
483
+
484
+ p#case_ok
485
+ {
486
+ color: #fff;
487
+ border-radius: 10px;
488
+ background-color: #0a0;
489
+ padding: 20px;
490
+ margin: 20px;
491
+ font-size: 1.2em;
492
+ }
493
+
494
+ p#case_non_strict
495
+ {
496
+ color: #fff;
497
+ border-radius: 10px;
498
+ background-color: #990;
499
+ padding: 20px;
500
+ margin: 20px;
501
+ font-size: 1.2em;
502
+ }
503
+
504
+ p#case_failed
505
+ {
506
+ color: #fff;
507
+ border-radius: 10px;
508
+ background-color: #900;
509
+ padding: 20px;
510
+ margin: 20px;
511
+ font-size: 1.2em;
512
+ }
513
+
514
+ table
515
+ {
516
+ border-collapse: collapse;
517
+ border-spacing: 0px;
518
+ margin-left: 80px;
519
+ margin-bottom: 40px;
520
+ margin-top: 0px;
521
+ }
522
+
523
+ td
524
+ {
525
+ margin: 0;
526
+ font-size: 0.8em;
527
+ text-align: right;
528
+ border: 1px #fff solid;
529
+ padding-top: 6px;
530
+ padding-bottom: 6px;
531
+ padding-left: 16px;
532
+ padding-right: 16px;
533
+ }
534
+
535
+ tr#stats_header
536
+ {
537
+ color: #eee;
538
+ background-color: #000;
539
+ }
540
+
541
+ tr#stats_row
542
+ {
543
+ background-color: #fc3;
544
+ color: #000;
545
+ }
546
+
547
+ tr#stats_total
548
+ {
549
+ color: #fff;
550
+ background-color: #888;
551
+ }
552
+
553
+ div#wirelog
554
+ {
555
+ margin-top: 20px;
556
+ margin-bottom: 80px;
557
+ }
558
+
559
+ pre.wirelog_rx_octets {color: #aaa; margin: 0; background-color: #060; padding: 2px;}
560
+ pre.wirelog_tx_octets {color: #aaa; margin: 0; background-color: #600; padding: 2px;}
561
+ pre.wirelog_tx_octets_sync {color: #aaa; margin: 0; background-color: #606; padding: 2px;}
562
+
563
+ pre.wirelog_rx_frame {color: #fff; margin: 0; background-color: #0a0; padding: 2px;}
564
+ pre.wirelog_tx_frame {color: #fff; margin: 0; background-color: #a00; padding: 2px;}
565
+ pre.wirelog_tx_frame_sync {color: #fff; margin: 0; background-color: #a0a; padding: 2px;}
566
+
567
+ pre.wirelog_delay {color: #fff; margin: 0; background-color: #000; padding: 2px;}
568
+ pre.wirelog_kill_after {color: #fff; margin: 0; background-color: #000; padding: 2px;}
569
+
570
+ pre.wirelog_tcp_closed_by_server {color: #fff; margin: 0; background-color: #008; padding: 2px;}
571
+ pre.wirelog_tcp_closed_by_client {color: #fff; margin: 0; background-color: #000; padding: 2px;}
572
+ """
573
+
574
+
575
+ def __init__(self, debug = False, outdir = "reports"):
576
+ self.debug = debug
577
+ self.outdir = outdir
578
+ self.agents = {}
579
+ self.cases = {}
580
+
581
+
582
+ def startFactory(self):
583
+ pass
584
+
585
+
586
+ def stopFactory(self):
587
+ pass
588
+
589
+
590
+ def logCase(self, caseResults):
591
+
592
+ agent = caseResults["agent"]
593
+ case = caseResults["case"]
594
+
595
+ ## index by agent->case
596
+ ##
597
+ if not self.agents.has_key(agent):
598
+ self.agents[agent] = {}
599
+ self.agents[agent][case] = caseResults
600
+
601
+ ## index by case->agent
602
+ ##
603
+ if not self.cases.has_key(case):
604
+ self.cases[case] = {}
605
+ self.cases[case][agent] = caseResults
606
+
607
+
608
+ def getCase(self, agent, case):
609
+ return self.agents[agent][case]
610
+
611
+
612
+ def createReports(self):
613
+
614
+ if not os.path.exists(self.outdir):
615
+ os.makedirs(self.outdir)
616
+
617
+ self.createMasterReport(self.outdir)
618
+
619
+ for agentId in self.agents:
620
+ for caseNo in self.agents[agentId]:
621
+ self.createAgentCaseReport(agentId, caseNo, self.outdir)
622
+
623
+
624
+ def cleanForFilename(self, str):
625
+ s0 = ''.join([c if c in "abcdefghjiklmnopqrstuvwxyz0123456789" else " " for c in str.strip().lower()])
626
+ s1 = s0.strip()
627
+ s2 = s1.replace(' ', '_')
628
+ return s2
629
+
630
+
631
+ def makeAgentCaseReportFilename(self, agentId, caseNo):
632
+ c = (caseClasstoId(Cases[caseNo - 1])).replace('.', '_')
633
+ return self.cleanForFilename(agentId) + "_case_" + c + ".html"
634
+
635
+
636
+ def createMasterReport(self, outdir):
637
+
638
+ report_filename = "index.html"
639
+ f = open(os.path.join(outdir, report_filename), 'w')
640
+
641
+ f.write('<html><body><head><style lang="css">%s %s</style></head>' % (FuzzingServerFactory.css_common, FuzzingServerFactory.css_master))
642
+
643
+ f.write('<h1>WebSockets Protocol Test Report</h1>')
644
+
645
+ f.write('<p id="intro">Test summary report generated on</p>')
646
+ f.write('<p id="intro" style="margin-left: 80px;"><i>%s</i></p>' % getUtcNow())
647
+ f.write('<p id="intro">by <a href="%s">Autobahn</a> WebSockets.</p>' % "http://www.tavendo.de/autobahn")
648
+
649
+ f.write('<h2>Test Results</h2>')
650
+
651
+ f.write('<table id="agent_case_results">')
652
+
653
+ ## sorted list of agents for which test cases where run
654
+ ##
655
+ agentList = sorted(self.agents.keys())
656
+
657
+ ## create list of case indexes order by case ID
658
+ ##
659
+ cl = []
660
+ i = 1
661
+ for c in Cases:
662
+ cl.append((caseClasstoIdTuple(c) , i))
663
+ i += 1
664
+ cl = sorted(cl)
665
+ caseList = []
666
+ for c in cl:
667
+ caseList.append(c[1])
668
+
669
+ lastCaseCategory = None
670
+ lastCaseSubCategory = None
671
+
672
+ for caseNo in caseList:
673
+
674
+ ## Case ID and category
675
+ ##
676
+ caseId = caseClasstoId(Cases[caseNo - 1])
677
+ caseCategoryIndex = caseId.split('.')[0]
678
+ caseCategory = CaseCategories.get(caseCategoryIndex, "Misc")
679
+ caseSubCategoryIndex = '.'.join(caseId.split('.')[:2])
680
+ caseSubCategory = CaseSubCategories.get(caseSubCategoryIndex, None)
681
+
682
+ ## Category row
683
+ ##
684
+ if caseCategory != lastCaseCategory:
685
+ f.write('<tr id="case_category_row">')
686
+ f.write('<td id="case_category">%s %s</td>' % (caseCategoryIndex, caseCategory))
687
+ for agentId in agentList:
688
+ f.write('<td id="agent">%s</td>' % agentId)
689
+ f.write('</tr>')
690
+ lastCaseCategory = caseCategory
691
+ lastCaseSubCategory = None
692
+
693
+ if caseSubCategory != lastCaseSubCategory:
694
+ f.write('<tr id="case_subcategory_row">')
695
+ f.write('<td id="case_subcategory" colspan="%d">%s %s</td>' % (len(agentList) + 1, caseSubCategoryIndex, caseSubCategory))
696
+ lastCaseSubCategory = caseSubCategory
697
+
698
+ f.write('<tr id="agent_case_result_row">')
699
+ f.write('<td id="case"><a href="#case_desc_%d">Case %s</a></td>' % (caseNo, caseId))
700
+
701
+ ## Agent/Case Result
702
+ ##
703
+ for agentId in agentList:
704
+ if self.agents[agentId].has_key(caseNo):
705
+
706
+ case = self.agents[agentId][caseNo]
707
+
708
+ agent_case_report_file = self.makeAgentCaseReportFilename(agentId, caseNo)
709
+
710
+ if case["behavior"] == Case.OK:
711
+ td_text = "Pass"
712
+ td_class = "case_ok"
713
+ elif case["behavior"] == Case.NON_STRICT:
714
+ td_text = "Non-Strict"
715
+ td_class = "case_non_strict"
716
+ else:
717
+ td_text = "Fail"
718
+ td_class = "case_failed"
719
+
720
+ if case["reportTime"]:
721
+ f.write('<td id="%s"><a href="%s">%s</a><br/><span id="case_duration">%s ms</span></td>' % (td_class, agent_case_report_file, td_text, case["duration"]))
722
+ else:
723
+ f.write('<td id="%s"><a href="%s">%s</a></td>' % (td_class, agent_case_report_file, td_text))
724
+
725
+ else:
726
+ f.write('<td id="case_missing">Missing</td>')
727
+
728
+ f.write("</tr>")
729
+
730
+ f.write("</table>")
731
+
732
+ f.write('<h2>Test Cases</h2>')
733
+
734
+ for caseNo in caseList:
735
+
736
+ CCase = Cases[caseNo - 1]
737
+
738
+ f.write('<a name="case_desc_%d"></a>' % caseNo)
739
+ f.write('<h3 id="case_desc_title">Case %s</h2>' % caseClasstoId(CCase))
740
+ f.write('<p id="case_desc"><i>Description</i><br/><br/> %s</p>' % CCase.DESCRIPTION)
741
+ f.write('<p id="case_expect"><i>Expectation</i><br/><br/> %s</p>' % CCase.EXPECTATION)
742
+
743
+ f.write("</body></html>")
744
+
745
+ f.close()
746
+ return report_filename
747
+
748
+
749
+ def createAgentCaseReport(self, agentId, caseNo, outdir):
750
+
751
+ if not self.agents.has_key(agentId):
752
+ raise Exception("no test data stored for agent %s" % agentId)
753
+
754
+ if not self.agents[agentId].has_key(caseNo):
755
+ raise Exception("no test data stored for case %s with agent %s" % (caseNo, agentId))
756
+
757
+ case = self.agents[agentId][caseNo]
758
+
759
+ report_filename = self.makeAgentCaseReportFilename(agentId, caseNo)
760
+
761
+ f = open(os.path.join(outdir, report_filename), 'w')
762
+
763
+ f.write('<html><body><head><style lang="css">%s %s</style></head>' % (FuzzingServerFactory.css_common, FuzzingServerFactory.css_detail))
764
+
765
+ f.write('<h1>%s - Test Case %s</h1>' % (case["agent"], case["id"]))
766
+
767
+ if case["behavior"] == Case.OK:
768
+ f.write('<p id="case_ok"><b>Pass</b> (%s - %d ms)</p>' % (case["started"], case["duration"]))
769
+ elif case["behavior"] == Case.NON_STRICT:
770
+ f.write('<p id="case_non_strict"><b>Non-Strict</b> (%s - %d ms)</p>' % (case["started"], case["duration"]))
771
+ else:
772
+ f.write('<p id="case_failed"><b>Fail</b> (%s - %d ms)</p>' % (case["started"], case["duration"]))
773
+
774
+ f.write('<h2>Case</h2>')
775
+ f.write('<p id="case_desc"><i>Description</i><br/><br/>%s</p>' % case["description"])
776
+ f.write('<p id="case_expect"><i>Expectation</i><br/><br/>%s</p>' % case["expectation"])
777
+
778
+ f.write('<h2>Result</h2>')
779
+
780
+ if case["result"] and case["result"] != "":
781
+ f.write('<p id="case_result">%s</p>' % case["result"])
782
+
783
+ if case["expected"] and case["received"]:
784
+ es = str(case["expected"])
785
+ if len(es) > 400:
786
+ es = es[:400] + " ..."
787
+ f.write('<p id="case_result">Expected = %s</p>' % es)
788
+
789
+ rs = str(case["received"])
790
+ if len(rs) > 400:
791
+ rs = rs[:400] + " ..."
792
+ f.write('<p id="case_result">Actual = %s</p>' % rs)
793
+
794
+ f.write('<h2>Statistics</h2>')
795
+
796
+ if not case["createStats"]:
797
+ f.write('<p style="margin-left: 40px; color: #f00;"><i>Statistics for octets/frames disabled!</i></p>')
798
+ else:
799
+ ## octet stats
800
+ ##
801
+ for statdef in [("Received", case["rxOctetStats"]), ("Transmitted", case["txOctetStats"])]:
802
+ f.write('<h3>Octets %s by Chop Size</h3>' % statdef[0])
803
+ f.write('<table>')
804
+ stats = statdef[1]
805
+ total_cnt = 0
806
+ total_octets = 0
807
+ f.write('<tr id="stats_header"><td>Chop Size</td><td>Count</td><td>Octets</td></tr>')
808
+ for s in sorted(stats.keys()):
809
+ f.write('<tr id="stats_row"><td>%d</td><td>%d</td><td>%d</td></tr>' % (s, stats[s], s * stats[s]))
810
+ total_cnt += stats[s]
811
+ total_octets += s * stats[s]
812
+ f.write('<tr id="stats_total"><td>Total</td><td>%d</td><td>%d</td></tr>' % (total_cnt, total_octets))
813
+ f.write('</table>')
814
+
815
+ ## frame stats
816
+ ##
817
+ for statdef in [("Received", case["rxFrameStats"]), ("Transmitted", case["txFrameStats"])]:
818
+ f.write('<h3>Frames %s by Opcode</h3>' % statdef[0])
819
+ f.write('<table>')
820
+ stats = statdef[1]
821
+ total_cnt = 0
822
+ f.write('<tr id="stats_header"><td>Opcode</td><td>Count</td></tr>')
823
+ for s in sorted(stats.keys()):
824
+ f.write('<tr id="stats_row"><td>%d</td><td>%d</td></tr>' % (s, stats[s]))
825
+ total_cnt += stats[s]
826
+ f.write('<tr id="stats_total"><td>Total</td><td>%d</td></tr>' % (total_cnt))
827
+ f.write('</table>')
828
+
829
+ f.write('<h2>Wire Log</h2>')
830
+
831
+ if not case["createWirelog"]:
832
+ f.write('<p style="margin-left: 40px; color: #f00;"><i>Wire log after handshake disabled!</i></p>')
833
+
834
+ ## write out wire log
835
+ ##
836
+ f.write('<div id="wirelog">')
837
+ wl = case["wirelog"]
838
+ i = 0
839
+ for t in wl:
840
+
841
+ if t[0] == "RO":
842
+ prefix = "RX OCTETS"
843
+ css_class = "wirelog_rx_octets"
844
+
845
+ elif t[0] == "TO":
846
+ prefix = "TX OCTETS"
847
+ if t[2]:
848
+ css_class = "wirelog_tx_octets_sync"
849
+ else:
850
+ css_class = "wirelog_tx_octets"
851
+
852
+ elif t[0] == "RF":
853
+ prefix = "RX FRAME "
854
+ css_class = "wirelog_rx_frame"
855
+
856
+ elif t[0] == "TF":
857
+ prefix = "TX FRAME "
858
+ if t[8] or t[7] is not None:
859
+ css_class = "wirelog_tx_frame_sync"
860
+ else:
861
+ css_class = "wirelog_tx_frame"
862
+
863
+ elif t[0] in ["CT", "KL"]:
864
+ pass
865
+
866
+ else:
867
+ raise Exception("logic error")
868
+
869
+ if t[0] in ["RO", "TO", "RF", "TF"]:
870
+
871
+ lines = textwrap.wrap(t[1], 100)
872
+ if t[0] in ["RO", "TO"]:
873
+ if len(lines) > 0:
874
+ f.write('<pre class="%s">%03d %s: %s</pre>' % (css_class, i, prefix, lines[0]))
875
+ for ll in lines[1:]:
876
+ f.write('<pre class="%s">%s%s</pre>' % (css_class, (2+4+len(prefix))*" ", ll))
877
+ else:
878
+ if t[0] == "RF":
879
+ if t[6]:
880
+ mmask = binascii.b2a_hex(t[6])
881
+ else:
882
+ mmask = str(t[6])
883
+ f.write('<pre class="%s">%03d %s: OPCODE=%s, FIN=%s, RSV=%s, MASKED=%s, MASK=%s</pre>' % (css_class, i, prefix, str(t[2]), str(t[3]), str(t[4]), str(t[5]), mmask))
884
+ elif t[0] == "TF":
885
+ f.write('<pre class="%s">%03d %s: OPCODE=%s, FIN=%s, RSV=%s, MASK=%s, PAYLOAD-REPEAT-LEN=%s, CHOPSIZE=%s, SYNC=%s</pre>' % (css_class, i, prefix, str(t[2]), str(t[3]), str(t[4]), str(t[5]), str(t[6]), str(t[7]), str(t[8])))
886
+ else:
887
+ raise Exception("logic error")
888
+ for ll in lines:
889
+ f.write('<pre class="%s">%s%s</pre>' % (css_class, (2+4+len(prefix))*" ", ll))
890
+
891
+ elif t[0] == "CT":
892
+ f.write('<pre class="wirelog_delay">%03d DELAY %f sec</pre>' % (i, t[1]))
893
+
894
+ elif t[0] == "KL":
895
+ f.write('<pre class="wirelog_kill_after">%03d KILL AFTER %f sec</pre>' % (i, t[1]))
896
+
897
+ else:
898
+ raise Exception("logic error")
899
+
900
+ i += 1
901
+
902
+ if case["failedByMe"]:
903
+ f.write('<pre class="wirelog_tcp_closed_by_server">%03d TCP CLOSED BY SERVER</pre>' % i)
904
+ else:
905
+ f.write('<pre class="wirelog_tcp_closed_by_client">%03d TCP CLOSED BY CLIENT</pre>' % i)
906
+ f.write('</div>')
907
+
908
+ f.write("</body></html>")
909
+
910
+ f.close()
911
+ return report_filename