test_boto_sns.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests for the boto_sns state
  4. """
  5. # Import Python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import re
  8. # Import Salt Testing libs
  9. from tests.support.case import ModuleCase
  10. from tests.support.mixins import SaltReturnAssertsMixin
  11. from tests.support.unit import skipIf
  12. # Import 3rd-party libs
  13. try:
  14. import boto
  15. NO_BOTO_MODULE = False
  16. except ImportError:
  17. NO_BOTO_MODULE = True
  18. @skipIf(
  19. NO_BOTO_MODULE,
  20. "Please install the boto library before running boto integration tests.",
  21. )
  22. class BotoSNSTest(ModuleCase, SaltReturnAssertsMixin):
  23. def setUp(self):
  24. try:
  25. boto.connect_iam()
  26. except boto.exception.NoAuthHandlerFound:
  27. self.skipTest(
  28. "Please setup boto AWS credentials before running boto integration tests."
  29. )
  30. # The name of the topic you want to create.
  31. # Constraints: Topic names must be made up of only uppercase and
  32. # lowercase ASCII letters, numbers, underscores, and hyphens,
  33. # and must be between 1 and 256 characters long.
  34. # http://docs.aws.amazon.com/sns/latest/api/API_CreateTopic.html
  35. self.topic_name = re.sub(r"[^a-zA-Z_-]", "_", self.id())[0:256]
  36. self.run_function("boto_sns.delete", name=self.topic_name)
  37. def tearDown(self):
  38. self.run_function("boto_sns.delete", name=self.topic_name)
  39. def test_present_new_topic_no_subscriptions(self):
  40. ret = self.run_state("boto_sns.present", name=self.topic_name)
  41. self.assertSaltTrueReturn(ret)
  42. self.assertInSaltReturn(self.topic_name, ret, "name")
  43. self.assertInSaltComment(
  44. "AWS SNS topic {0} created.".format(self.topic_name), ret
  45. )
  46. self.assertSaltStateChangesEqual(
  47. ret, {"old": None, "new": {"topic": self.topic_name, "subscriptions": []}}
  48. )
  49. def test_present_new_topic_with_subscriptions(self):
  50. ret = self.run_state(
  51. "boto_sns.present",
  52. name=self.topic_name,
  53. subscriptions=[
  54. {
  55. "protocol": "https",
  56. "endpoint": "https://www.example.com/sns/endpoint",
  57. },
  58. {
  59. "protocol": "https",
  60. "endpoint": "https://www.example.com/sns/endpoint-2",
  61. },
  62. ],
  63. )
  64. self.assertSaltTrueReturn(ret)
  65. self.assertSaltStateChangesEqual(
  66. ret,
  67. {
  68. "old": None,
  69. "new": {
  70. "topic": self.topic_name,
  71. "subscriptions": [
  72. {
  73. "protocol": "https",
  74. "endpoint": "https://www.example.com/sns/endpoint",
  75. },
  76. {
  77. "protocol": "https",
  78. "endpoint": "https://www.example.com/sns/endpoint-2",
  79. },
  80. ],
  81. },
  82. },
  83. )
  84. self.assertInSaltComment(
  85. "AWS SNS subscription https:https://www.example.com/sns/endpoint set on topic {0}.".format(
  86. self.topic_name
  87. ),
  88. ret,
  89. )
  90. self.assertInSaltComment(
  91. "AWS SNS subscription https:https://www.example.com/sns/endpoint-2 set on topic {0}.".format(
  92. self.topic_name
  93. ),
  94. ret,
  95. )
  96. self.assertSubscriptionInTopic(
  97. {"Protocol": "https", "Endpoint": "https://www.example.com/sns/endpoint"},
  98. self.topic_name,
  99. )
  100. self.assertSubscriptionInTopic(
  101. {"Protocol": "https", "Endpoint": "https://www.example.com/sns/endpoint-2"},
  102. self.topic_name,
  103. )
  104. def test_present_is_idempotent(self):
  105. self.run_state(
  106. "boto_sns.present",
  107. name=self.topic_name,
  108. subscriptions=[
  109. {
  110. "protocol": "https",
  111. "endpoint": "https://www.example.com/sns/endpoint",
  112. }
  113. ],
  114. )
  115. ret = self.run_state(
  116. "boto_sns.present",
  117. name=self.topic_name,
  118. subscriptions=[
  119. {
  120. "protocol": "https",
  121. "endpoint": "https://www.example.com/sns/endpoint",
  122. }
  123. ],
  124. )
  125. self.assertSaltTrueReturn(ret)
  126. self.assertInSaltReturn(self.topic_name, ret, "name")
  127. self.assertInSaltComment(
  128. "AWS SNS topic {0} present.".format(self.topic_name), ret
  129. )
  130. self.assertInSaltComment(
  131. "AWS SNS subscription https:https://www.example.com/sns/endpoint already set on topic {0}.".format(
  132. self.topic_name
  133. ),
  134. ret,
  135. )
  136. self.assertSaltStateChangesEqual(ret, {})
  137. def test_present_add_subscription_to_existing_topic_with_no_subscription(self):
  138. self.run_state("boto_sns.present", name=self.topic_name)
  139. ret = self.run_state(
  140. "boto_sns.present",
  141. name=self.topic_name,
  142. subscriptions=[
  143. {
  144. "protocol": "https",
  145. "endpoint": "https://www.example.com/sns/endpoint",
  146. }
  147. ],
  148. )
  149. self.assertSaltTrueReturn(ret)
  150. self.assertSaltStateChangesEqual(
  151. ret,
  152. {
  153. "old": None,
  154. "new": {
  155. "subscriptions": [
  156. {
  157. "protocol": "https",
  158. "endpoint": "https://www.example.com/sns/endpoint",
  159. }
  160. ]
  161. },
  162. },
  163. )
  164. self.assertInSaltComment(
  165. "AWS SNS subscription https:https://www.example.com/sns/endpoint set on topic {0}.".format(
  166. self.topic_name
  167. ),
  168. ret,
  169. )
  170. self.assertSubscriptionInTopic(
  171. {"Protocol": "https", "Endpoint": "https://www.example.com/sns/endpoint"},
  172. self.topic_name,
  173. )
  174. def test_present_add_new_subscription_to_existing_topic_with_subscriptions(self):
  175. self.run_state(
  176. "boto_sns.present",
  177. name=self.topic_name,
  178. subscriptions=[
  179. {
  180. "protocol": "https",
  181. "endpoint": "https://www.example.com/sns/endpoint",
  182. }
  183. ],
  184. )
  185. ret = self.run_state(
  186. "boto_sns.present",
  187. name=self.topic_name,
  188. subscriptions=[
  189. {
  190. "protocol": "https",
  191. "endpoint": "https://www.example.com/sns/endpoint-2",
  192. }
  193. ],
  194. )
  195. self.assertSaltTrueReturn(ret)
  196. self.assertSaltStateChangesEqual(
  197. ret,
  198. {
  199. "old": None,
  200. "new": {
  201. "subscriptions": [
  202. {
  203. "protocol": "https",
  204. "endpoint": "https://www.example.com/sns/endpoint-2",
  205. }
  206. ]
  207. },
  208. },
  209. )
  210. self.assertInSaltComment(
  211. "AWS SNS subscription https:https://www.example.com/sns/endpoint-2 set on topic {0}.".format(
  212. self.topic_name
  213. ),
  214. ret,
  215. )
  216. self.assertSubscriptionInTopic(
  217. {"Protocol": "https", "Endpoint": "https://www.example.com/sns/endpoint"},
  218. self.topic_name,
  219. )
  220. self.assertSubscriptionInTopic(
  221. {"Protocol": "https", "Endpoint": "https://www.example.com/sns/endpoint-2"},
  222. self.topic_name,
  223. )
  224. def test_present_test_mode_no_subscriptions(self):
  225. ret = self.run_state("boto_sns.present", name=self.topic_name, test=True)
  226. self.assertSaltNoneReturn(ret)
  227. self.assertInSaltReturn(self.topic_name, ret, "name")
  228. self.assertInSaltComment(
  229. "AWS SNS topic {0} is set to be created.".format(self.topic_name), ret
  230. )
  231. self.assertSaltStateChangesEqual(ret, {})
  232. ret = self.run_function("boto_sns.exists", name=self.topic_name)
  233. self.assertFalse(ret)
  234. def test_present_test_mode_with_subscriptions(self):
  235. self.run_state("boto_sns.present", name=self.topic_name)
  236. ret = self.run_state(
  237. "boto_sns.present",
  238. name=self.topic_name,
  239. subscriptions=[
  240. {
  241. "protocol": "https",
  242. "endpoint": "https://www.example.com/sns/endpoint",
  243. }
  244. ],
  245. test=True,
  246. )
  247. self.assertSaltNoneReturn(ret)
  248. self.assertSaltStateChangesEqual(ret, {})
  249. self.assertInSaltComment(
  250. "AWS SNS subscription https:https://www.example.com/sns/endpoint to be set on topic {0}.".format(
  251. self.topic_name
  252. ),
  253. ret,
  254. )
  255. ret = self.run_function(
  256. "boto_sns.get_all_subscriptions_by_topic", name=self.topic_name
  257. )
  258. self.assertEqual([], ret)
  259. def test_absent_not_exist(self):
  260. ret = self.run_state("boto_sns.absent", name=self.topic_name)
  261. self.assertSaltTrueReturn(ret)
  262. self.assertInSaltReturn(self.topic_name, ret, "name")
  263. self.assertInSaltComment(
  264. "AWS SNS topic {0} does not exist.".format(self.topic_name), ret
  265. )
  266. self.assertSaltStateChangesEqual(ret, {})
  267. def test_absent_already_exists(self):
  268. self.run_state("boto_sns.present", name=self.topic_name)
  269. ret = self.run_state("boto_sns.absent", name=self.topic_name)
  270. self.assertSaltTrueReturn(ret)
  271. self.assertInSaltReturn(self.topic_name, ret, "name")
  272. self.assertInSaltComment(
  273. "AWS SNS topic {0} does not exist.".format(self.topic_name), ret
  274. )
  275. self.assertSaltStateChangesEqual(
  276. ret, {"new": None, "old": {"topic": self.topic_name}}
  277. )
  278. def test_absent_test_mode(self):
  279. self.run_state("boto_sns.present", name=self.topic_name)
  280. ret = self.run_state("boto_sns.absent", name=self.topic_name, test=True)
  281. self.assertSaltNoneReturn(ret)
  282. self.assertInSaltReturn(self.topic_name, ret, "name")
  283. self.assertInSaltComment(
  284. "AWS SNS topic {0} is set to be removed.".format(self.topic_name), ret
  285. )
  286. self.assertSaltStateChangesEqual(ret, {})
  287. ret = self.run_function("boto_sns.exists", name=self.topic_name)
  288. self.assertTrue(ret)
  289. def assertSubscriptionInTopic(self, subscription, topic_name):
  290. ret = self.run_function(
  291. "boto_sns.get_all_subscriptions_by_topic", name=topic_name
  292. )
  293. for _subscription in ret:
  294. try:
  295. self.assertDictContainsSubset(subscription, _subscription)
  296. return True
  297. except AssertionError:
  298. continue
  299. raise self.failureException(
  300. "Subscription {0} not found in topic {1} subscriptions: {2}".format(
  301. subscription, topic_name, ret
  302. )
  303. )