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.

test_uri_pattern.py 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. ###############################################################################
  2. #
  3. # The MIT License (MIT)
  4. #
  5. # Copyright (c) Crossbar.io Technologies GmbH
  6. #
  7. # Permission is hereby granted, free of charge, to any person obtaining a copy
  8. # of this software and associated documentation files (the "Software"), to deal
  9. # in the Software without restriction, including without limitation the rights
  10. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. # copies of the Software, and to permit persons to whom the Software is
  12. # furnished to do so, subject to the following conditions:
  13. #
  14. # The above copyright notice and this permission notice shall be included in
  15. # all copies or substantial portions of the Software.
  16. #
  17. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. # THE SOFTWARE.
  24. #
  25. ###############################################################################
  26. from __future__ import absolute_import
  27. from autobahn import wamp
  28. from autobahn.wamp.uri import Pattern, RegisterOptions, SubscribeOptions
  29. import unittest
  30. class TestUris(unittest.TestCase):
  31. def test_invalid_uris(self):
  32. for u in [u"",
  33. u"com.myapp.<product:foo>.update",
  34. u"com.myapp.<123:int>.update",
  35. u"com.myapp.<:product>.update",
  36. u"com.myapp.<product:>.update",
  37. u"com.myapp.<int:>.update",
  38. ]:
  39. self.assertRaises(Exception, Pattern, u, Pattern.URI_TARGET_ENDPOINT)
  40. def test_valid_uris(self):
  41. for u in [u"com.myapp.proc1",
  42. u"123",
  43. u"com.myapp.<product:int>.update",
  44. u"com.myapp.<category:string>.<subcategory>.list"
  45. u"com.myapp.something..update"
  46. ]:
  47. p = Pattern(u, Pattern.URI_TARGET_ENDPOINT)
  48. self.assertIsInstance(p, Pattern)
  49. def test_parse_uris(self):
  50. tests = [
  51. (u"com.myapp.<product:int>.update", [
  52. (u"com.myapp.0.update", {u'product': 0}),
  53. (u"com.myapp.123456.update", {u'product': 123456}),
  54. (u"com.myapp.aaa.update", None),
  55. (u"com.myapp..update", None),
  56. (u"com.myapp.0.delete", None),
  57. ]
  58. ),
  59. (u"com.myapp.<product:string>.update", [
  60. (u"com.myapp.box.update", {u'product': u'box'}),
  61. (u"com.myapp.123456.update", {u'product': u'123456'}),
  62. (u"com.myapp..update", None),
  63. ]
  64. ),
  65. (u"com.myapp.<product>.update", [
  66. (u"com.myapp.0.update", {u'product': u'0'}),
  67. (u"com.myapp.abc.update", {u'product': u'abc'}),
  68. (u"com.myapp..update", None),
  69. ]
  70. ),
  71. (u"com.myapp.<category:string>.<subcategory:string>.list", [
  72. (u"com.myapp.cosmetic.shampoo.list", {u'category': u'cosmetic', u'subcategory': u'shampoo'}),
  73. (u"com.myapp...list", None),
  74. (u"com.myapp.cosmetic..list", None),
  75. (u"com.myapp..shampoo.list", None),
  76. ]
  77. )
  78. ]
  79. for test in tests:
  80. pat = Pattern(test[0], Pattern.URI_TARGET_ENDPOINT)
  81. for ptest in test[1]:
  82. uri = ptest[0]
  83. kwargs_should = ptest[1]
  84. if kwargs_should is not None:
  85. args_is, kwargs_is = pat.match(uri)
  86. self.assertEqual(kwargs_is, kwargs_should)
  87. else:
  88. self.assertRaises(Exception, pat.match, uri)
  89. class TestDecorators(unittest.TestCase):
  90. def test_decorate_endpoint(self):
  91. @wamp.register(u"com.calculator.square")
  92. def square(_):
  93. """Do nothing."""
  94. self.assertTrue(hasattr(square, '_wampuris'))
  95. self.assertTrue(type(square._wampuris) == list)
  96. self.assertEqual(len(square._wampuris), 1)
  97. self.assertIsInstance(square._wampuris[0], Pattern)
  98. self.assertTrue(square._wampuris[0].is_endpoint())
  99. self.assertFalse(square._wampuris[0].is_handler())
  100. self.assertFalse(square._wampuris[0].is_exception())
  101. self.assertEqual(square._wampuris[0].uri(), u"com.calculator.square")
  102. self.assertEqual(square._wampuris[0]._type, Pattern.URI_TYPE_EXACT)
  103. @wamp.register(u"com.myapp.product.<product:int>.update")
  104. def update_product(product=None, label=None):
  105. """Do nothing."""
  106. self.assertTrue(hasattr(update_product, '_wampuris'))
  107. self.assertTrue(type(update_product._wampuris) == list)
  108. self.assertEqual(len(update_product._wampuris), 1)
  109. self.assertIsInstance(update_product._wampuris[0], Pattern)
  110. self.assertTrue(update_product._wampuris[0].is_endpoint())
  111. self.assertFalse(update_product._wampuris[0].is_handler())
  112. self.assertFalse(update_product._wampuris[0].is_exception())
  113. self.assertEqual(update_product._wampuris[0].uri(), u"com.myapp.product.<product:int>.update")
  114. self.assertEqual(update_product._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
  115. @wamp.register(u"com.myapp.<category:string>.<cid:int>.update")
  116. def update(category=None, cid=None):
  117. """Do nothing."""
  118. self.assertTrue(hasattr(update, '_wampuris'))
  119. self.assertTrue(type(update._wampuris) == list)
  120. self.assertEqual(len(update._wampuris), 1)
  121. self.assertIsInstance(update._wampuris[0], Pattern)
  122. self.assertTrue(update._wampuris[0].is_endpoint())
  123. self.assertFalse(update._wampuris[0].is_handler())
  124. self.assertFalse(update._wampuris[0].is_exception())
  125. self.assertEqual(update._wampuris[0].uri(), u"com.myapp.<category:string>.<cid:int>.update")
  126. self.assertEqual(update._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
  127. @wamp.register(u"com.myapp.circle.<name:string>",
  128. RegisterOptions(match=u"wildcard", details_arg="details"))
  129. def circle(name=None, details=None):
  130. """ Do nothing. """
  131. self.assertTrue(hasattr(circle, '_wampuris'))
  132. self.assertTrue(type(circle._wampuris) == list)
  133. self.assertEqual(len(circle._wampuris), 1)
  134. self.assertIsInstance(circle._wampuris[0], Pattern)
  135. self.assertIsInstance(circle._wampuris[0].options, RegisterOptions)
  136. self.assertEqual(circle._wampuris[0].options.match, u"wildcard")
  137. self.assertEqual(circle._wampuris[0].options.details_arg, "details")
  138. self.assertTrue(circle._wampuris[0].is_endpoint())
  139. self.assertFalse(circle._wampuris[0].is_handler())
  140. self.assertFalse(circle._wampuris[0].is_exception())
  141. self.assertEqual(circle._wampuris[0].uri(), u"com.myapp.circle.<name:string>")
  142. self.assertEqual(circle._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
  143. @wamp.register(u"com.myapp.something..update",
  144. RegisterOptions(match=u"wildcard", details_arg="details"))
  145. def something(dynamic=None, details=None):
  146. """ Do nothing. """
  147. self.assertTrue(hasattr(something, '_wampuris'))
  148. self.assertTrue(type(something._wampuris) == list)
  149. self.assertEqual(len(something._wampuris), 1)
  150. self.assertIsInstance(something._wampuris[0], Pattern)
  151. self.assertIsInstance(something._wampuris[0].options, RegisterOptions)
  152. self.assertEqual(something._wampuris[0].options.match, u"wildcard")
  153. self.assertEqual(something._wampuris[0].options.details_arg, "details")
  154. self.assertTrue(something._wampuris[0].is_endpoint())
  155. self.assertFalse(something._wampuris[0].is_handler())
  156. self.assertFalse(something._wampuris[0].is_exception())
  157. self.assertEqual(something._wampuris[0].uri(), u"com.myapp.something..update")
  158. self.assertEqual(something._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
  159. def test_decorate_handler(self):
  160. @wamp.subscribe(u"com.myapp.on_shutdown")
  161. def on_shutdown():
  162. """Do nothing."""
  163. self.assertTrue(hasattr(on_shutdown, '_wampuris'))
  164. self.assertTrue(type(on_shutdown._wampuris) == list)
  165. self.assertEqual(len(on_shutdown._wampuris), 1)
  166. self.assertIsInstance(on_shutdown._wampuris[0], Pattern)
  167. self.assertFalse(on_shutdown._wampuris[0].is_endpoint())
  168. self.assertTrue(on_shutdown._wampuris[0].is_handler())
  169. self.assertFalse(on_shutdown._wampuris[0].is_exception())
  170. self.assertEqual(on_shutdown._wampuris[0].uri(), u"com.myapp.on_shutdown")
  171. self.assertEqual(on_shutdown._wampuris[0]._type, Pattern.URI_TYPE_EXACT)
  172. @wamp.subscribe(u"com.myapp.product.<product:int>.on_update")
  173. def on_product_update(product=None, label=None):
  174. """Do nothing."""
  175. self.assertTrue(hasattr(on_product_update, '_wampuris'))
  176. self.assertTrue(type(on_product_update._wampuris) == list)
  177. self.assertEqual(len(on_product_update._wampuris), 1)
  178. self.assertIsInstance(on_product_update._wampuris[0], Pattern)
  179. self.assertFalse(on_product_update._wampuris[0].is_endpoint())
  180. self.assertTrue(on_product_update._wampuris[0].is_handler())
  181. self.assertFalse(on_product_update._wampuris[0].is_exception())
  182. self.assertEqual(on_product_update._wampuris[0].uri(), u"com.myapp.product.<product:int>.on_update")
  183. self.assertEqual(on_product_update._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
  184. @wamp.subscribe(u"com.myapp.<category:string>.<cid:int>.on_update")
  185. def on_update(category=None, cid=None, label=None):
  186. """Do nothing."""
  187. self.assertTrue(hasattr(on_update, '_wampuris'))
  188. self.assertTrue(type(on_update._wampuris) == list)
  189. self.assertEqual(len(on_update._wampuris), 1)
  190. self.assertIsInstance(on_update._wampuris[0], Pattern)
  191. self.assertFalse(on_update._wampuris[0].is_endpoint())
  192. self.assertTrue(on_update._wampuris[0].is_handler())
  193. self.assertFalse(on_update._wampuris[0].is_exception())
  194. self.assertEqual(on_update._wampuris[0].uri(), u"com.myapp.<category:string>.<cid:int>.on_update")
  195. self.assertEqual(on_update._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
  196. @wamp.subscribe(u"com.myapp.on.<event:string>",
  197. SubscribeOptions(match=u"wildcard", details_arg="details"))
  198. def on_event(event=None, details=None):
  199. """ Do nothing. """
  200. self.assertTrue(hasattr(on_event, '_wampuris'))
  201. self.assertTrue(type(on_event._wampuris) == list)
  202. self.assertEqual(len(on_event._wampuris), 1)
  203. self.assertIsInstance(on_event._wampuris[0], Pattern)
  204. self.assertIsInstance(on_event._wampuris[0].options, SubscribeOptions)
  205. self.assertEqual(on_event._wampuris[0].options.match, u"wildcard")
  206. self.assertEqual(on_event._wampuris[0].options.details_arg, "details")
  207. self.assertFalse(on_event._wampuris[0].is_endpoint())
  208. self.assertTrue(on_event._wampuris[0].is_handler())
  209. self.assertFalse(on_event._wampuris[0].is_exception())
  210. self.assertEqual(on_event._wampuris[0].uri(), u"com.myapp.on.<event:string>")
  211. self.assertEqual(on_event._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
  212. def test_decorate_exception(self):
  213. @wamp.error(u"com.myapp.error")
  214. class AppError(Exception):
  215. """Do nothing."""
  216. self.assertTrue(hasattr(AppError, '_wampuris'))
  217. self.assertTrue(type(AppError._wampuris) == list)
  218. self.assertEqual(len(AppError._wampuris), 1)
  219. self.assertIsInstance(AppError._wampuris[0], Pattern)
  220. self.assertFalse(AppError._wampuris[0].is_endpoint())
  221. self.assertFalse(AppError._wampuris[0].is_handler())
  222. self.assertTrue(AppError._wampuris[0].is_exception())
  223. self.assertEqual(AppError._wampuris[0].uri(), u"com.myapp.error")
  224. self.assertEqual(AppError._wampuris[0]._type, Pattern.URI_TYPE_EXACT)
  225. @wamp.error(u"com.myapp.product.<product:int>.product_inactive")
  226. class ProductInactiveError(Exception):
  227. """Do nothing."""
  228. self.assertTrue(hasattr(ProductInactiveError, '_wampuris'))
  229. self.assertTrue(type(ProductInactiveError._wampuris) == list)
  230. self.assertEqual(len(ProductInactiveError._wampuris), 1)
  231. self.assertIsInstance(ProductInactiveError._wampuris[0], Pattern)
  232. self.assertFalse(ProductInactiveError._wampuris[0].is_endpoint())
  233. self.assertFalse(ProductInactiveError._wampuris[0].is_handler())
  234. self.assertTrue(ProductInactiveError._wampuris[0].is_exception())
  235. self.assertEqual(ProductInactiveError._wampuris[0].uri(), u"com.myapp.product.<product:int>.product_inactive")
  236. self.assertEqual(ProductInactiveError._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
  237. @wamp.error(u"com.myapp.<category:string>.<product:int>.inactive")
  238. class ObjectInactiveError(Exception):
  239. """Do nothing."""
  240. self.assertTrue(hasattr(ObjectInactiveError, '_wampuris'))
  241. self.assertTrue(type(ObjectInactiveError._wampuris) == list)
  242. self.assertEqual(len(ObjectInactiveError._wampuris), 1)
  243. self.assertIsInstance(ObjectInactiveError._wampuris[0], Pattern)
  244. self.assertFalse(ObjectInactiveError._wampuris[0].is_endpoint())
  245. self.assertFalse(ObjectInactiveError._wampuris[0].is_handler())
  246. self.assertTrue(ObjectInactiveError._wampuris[0].is_exception())
  247. self.assertEqual(ObjectInactiveError._wampuris[0].uri(), u"com.myapp.<category:string>.<product:int>.inactive")
  248. self.assertEqual(ObjectInactiveError._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
  249. def test_match_decorated_endpoint(self):
  250. @wamp.register(u"com.calculator.square")
  251. def square(x):
  252. return x
  253. args, kwargs = square._wampuris[0].match(u"com.calculator.square")
  254. self.assertEqual(square(666, **kwargs), 666)
  255. @wamp.register(u"com.myapp.product.<product:int>.update")
  256. def update_product(product=None, label=None):
  257. return product, label
  258. args, kwargs = update_product._wampuris[0].match(u"com.myapp.product.123456.update")
  259. kwargs['label'] = "foobar"
  260. self.assertEqual(update_product(**kwargs), (123456, "foobar"))
  261. @wamp.register(u"com.myapp.<category:string>.<cid:int>.update")
  262. def update(category=None, cid=None, label=None):
  263. return category, cid, label
  264. args, kwargs = update._wampuris[0].match(u"com.myapp.product.123456.update")
  265. kwargs['label'] = "foobar"
  266. self.assertEqual(update(**kwargs), ("product", 123456, "foobar"))
  267. def test_match_decorated_handler(self):
  268. @wamp.subscribe(u"com.myapp.on_shutdown")
  269. def on_shutdown():
  270. pass
  271. args, kwargs = on_shutdown._wampuris[0].match(u"com.myapp.on_shutdown")
  272. self.assertEqual(on_shutdown(**kwargs), None)
  273. @wamp.subscribe(u"com.myapp.product.<product:int>.on_update")
  274. def on_product_update(product=None, label=None):
  275. return product, label
  276. args, kwargs = on_product_update._wampuris[0].match(u"com.myapp.product.123456.on_update")
  277. kwargs['label'] = "foobar"
  278. self.assertEqual(on_product_update(**kwargs), (123456, "foobar"))
  279. @wamp.subscribe(u"com.myapp.<category:string>.<cid:int>.on_update")
  280. def on_update(category=None, cid=None, label=None):
  281. return category, cid, label
  282. args, kwargs = on_update._wampuris[0].match(u"com.myapp.product.123456.on_update")
  283. kwargs['label'] = "foobar"
  284. self.assertEqual(on_update(**kwargs), ("product", 123456, "foobar"))
  285. def test_match_decorated_exception(self):
  286. @wamp.error(u"com.myapp.error")
  287. class AppError(Exception):
  288. def __init__(self, msg):
  289. Exception.__init__(self, msg)
  290. def __eq__(self, other):
  291. return self.__class__ == other.__class__ and \
  292. self.args == other.args
  293. args, kwargs = AppError._wampuris[0].match(u"com.myapp.error")
  294. # noinspection PyArgumentList
  295. self.assertEqual(AppError(u"fuck", **kwargs), AppError(u"fuck"))
  296. @wamp.error(u"com.myapp.product.<product:int>.product_inactive")
  297. class ProductInactiveError(Exception):
  298. def __init__(self, msg, product=None):
  299. Exception.__init__(self, msg)
  300. self.product = product
  301. def __eq__(self, other):
  302. return self.__class__ == other.__class__ and \
  303. self.args == other.args and \
  304. self.product == other.product
  305. args, kwargs = ProductInactiveError._wampuris[0].match(u"com.myapp.product.123456.product_inactive")
  306. self.assertEqual(ProductInactiveError("fuck", **kwargs), ProductInactiveError("fuck", 123456))
  307. @wamp.error(u"com.myapp.<category:string>.<product:int>.inactive")
  308. class ObjectInactiveError(Exception):
  309. def __init__(self, msg, category=None, product=None):
  310. Exception.__init__(self, msg)
  311. self.category = category
  312. self.product = product
  313. def __eq__(self, other):
  314. return self.__class__ == other.__class__ and \
  315. self.args == other.args and \
  316. self.category == other.category and \
  317. self.product == other.product
  318. args, kwargs = ObjectInactiveError._wampuris[0].match(u"com.myapp.product.123456.inactive")
  319. self.assertEqual(ObjectInactiveError("fuck", **kwargs), ObjectInactiveError("fuck", "product", 123456))
  320. class KwException(Exception):
  321. def __init__(self, *args, **kwargs):
  322. Exception.__init__(self, *args)
  323. self.kwargs = kwargs
  324. # what if the WAMP error message received
  325. # contains args/kwargs that cannot be
  326. # consumed by the constructor of the exception
  327. # class defined for the WAMP error URI?
  328. # 1. we can bail out (but we are already signaling an error)
  329. # 2. we can require a generic constructor
  330. # 3. we can map only unconsumed args/kwargs to generic attributes
  331. # 4. we can silently drop unconsumed args/kwargs
  332. class MockSession(object):
  333. def __init__(self):
  334. self._ecls_to_uri_pat = {}
  335. self._uri_to_ecls = {}
  336. def define(self, exception, error=None):
  337. if error is None:
  338. assert(hasattr(exception, '_wampuris'))
  339. self._ecls_to_uri_pat[exception] = exception._wampuris
  340. self._uri_to_ecls[exception._wampuris[0].uri()] = exception
  341. else:
  342. assert(not hasattr(exception, '_wampuris'))
  343. self._ecls_to_uri_pat[exception] = [Pattern(error, Pattern.URI_TARGET_HANDLER)]
  344. self._uri_to_ecls[error] = exception
  345. def map_error(self, error, args=None, kwargs=None):
  346. # FIXME:
  347. # 1. map to ecls based on error URI wildcard/prefix
  348. # 2. extract additional args/kwargs from error URI
  349. if error in self._uri_to_ecls:
  350. ecls = self._uri_to_ecls[error]
  351. try:
  352. # the following might fail, eg. TypeError when
  353. # signature of exception constructor is incompatible
  354. # with args/kwargs or when the exception constructor raises
  355. if kwargs:
  356. if args:
  357. exc = ecls(*args, **kwargs)
  358. else:
  359. exc = ecls(**kwargs)
  360. else:
  361. if args:
  362. exc = ecls(*args)
  363. else:
  364. exc = ecls()
  365. except Exception:
  366. # FIXME: log e
  367. exc = KwException(error, *args, **kwargs)
  368. else:
  369. # this never fails
  370. args = args or []
  371. kwargs = kwargs or {}
  372. exc = KwException(error, *args, **kwargs)
  373. return exc
  374. class TestDecoratorsAdvanced(unittest.TestCase):
  375. def test_decorate_exception_non_exception(self):
  376. def test():
  377. # noinspection PyUnusedLocal
  378. @wamp.error(u"com.test.error")
  379. class Foo(object):
  380. pass
  381. self.assertRaises(Exception, test)
  382. def test_decorate_endpoint_multiple(self):
  383. # noinspection PyUnusedLocal
  384. @wamp.register(u"com.oldapp.oldproc")
  385. @wamp.register(u"com.calculator.square")
  386. def square(x):
  387. """Do nothing."""
  388. self.assertTrue(hasattr(square, '_wampuris'))
  389. self.assertTrue(type(square._wampuris) == list)
  390. self.assertEqual(len(square._wampuris), 2)
  391. for i in range(2):
  392. self.assertIsInstance(square._wampuris[i], Pattern)
  393. self.assertTrue(square._wampuris[i].is_endpoint())
  394. self.assertFalse(square._wampuris[i].is_handler())
  395. self.assertFalse(square._wampuris[i].is_exception())
  396. self.assertEqual(square._wampuris[i]._type, Pattern.URI_TYPE_EXACT)
  397. self.assertEqual(square._wampuris[0].uri(), u"com.calculator.square")
  398. self.assertEqual(square._wampuris[1].uri(), u"com.oldapp.oldproc")
  399. def test_marshal_decorated_exception(self):
  400. @wamp.error(u"com.myapp.error")
  401. class AppError(Exception):
  402. pass
  403. try:
  404. raise AppError("fuck")
  405. except Exception as e:
  406. self.assertEqual(e._wampuris[0].uri(), u"com.myapp.error")
  407. @wamp.error(u"com.myapp.product.<product:int>.product_inactive")
  408. class ProductInactiveError(Exception):
  409. def __init__(self, msg, product=None):
  410. Exception.__init__(self, msg)
  411. self.product = product
  412. try:
  413. raise ProductInactiveError("fuck", 123456)
  414. except Exception as e:
  415. self.assertEqual(e._wampuris[0].uri(), u"com.myapp.product.<product:int>.product_inactive")
  416. session = MockSession()
  417. session.define(AppError)
  418. def test_define_exception_undecorated(self):
  419. session = MockSession()
  420. class AppError(Exception):
  421. pass
  422. # defining an undecorated exception requires
  423. # an URI to be provided
  424. self.assertRaises(Exception, session.define, AppError)
  425. session.define(AppError, u"com.myapp.error")
  426. exc = session.map_error(u"com.myapp.error")
  427. self.assertIsInstance(exc, AppError)
  428. def test_define_exception_decorated(self):
  429. session = MockSession()
  430. @wamp.error(u"com.myapp.error")
  431. class AppError(Exception):
  432. pass
  433. # when defining a decorated exception
  434. # an URI must not be provided
  435. self.assertRaises(Exception, session.define, AppError, u"com.myapp.error")
  436. session.define(AppError)
  437. exc = session.map_error(u"com.myapp.error")
  438. self.assertIsInstance(exc, AppError)
  439. def test_map_exception_undefined(self):
  440. session = MockSession()
  441. exc = session.map_error(u"com.myapp.error")
  442. self.assertIsInstance(exc, Exception)
  443. def test_map_exception_args(self):
  444. session = MockSession()
  445. @wamp.error(u"com.myapp.error")
  446. class AppError(Exception):
  447. pass
  448. @wamp.error(u"com.myapp.error.product_inactive")
  449. class ProductInactiveError(Exception):
  450. def __init__(self, product=None):
  451. self.product = product
  452. # define exceptions in mock session
  453. session.define(AppError)
  454. session.define(ProductInactiveError)
  455. for test in [
  456. # (u"com.myapp.foo.error", [], {}, KwException),
  457. (u"com.myapp.error", [], {}, AppError),
  458. (u"com.myapp.error", ["you are doing it wrong"], {}, AppError),
  459. (u"com.myapp.error", ["you are doing it wrong", 1, 2, 3], {}, AppError),
  460. (u"com.myapp.error.product_inactive", [], {}, ProductInactiveError),
  461. (u"com.myapp.error.product_inactive", [], {"product": 123456}, ProductInactiveError),
  462. ]:
  463. error, args, kwargs, ecls = test
  464. exc = session.map_error(error, args, kwargs)
  465. self.assertIsInstance(exc, ecls)
  466. self.assertEqual(list(exc.args), args)