/tests/integration/idem_aws/states/cloudwatch/test_metric_alarm.py

https://gitlab.com/pgeorgiev_vmw/idem-aws
Python | 319 lines | 296 code | 14 blank | 9 comment | 7 complexity | 5500b496a58a5345da8dd7d519961953 MD5 | raw file
  1. import copy
  2. import uuid
  3. from collections import ChainMap
  4. import pytest
  5. @pytest.mark.asyncio
  6. @pytest.mark.localstack(pro=True)
  7. async def test_metric_alarm(hub, ctx):
  8. metric_alarm_temp_name = "idem-test-metric-alarm-" + str(uuid.uuid4())
  9. alarm_description = "description"
  10. ok_actions = []
  11. actions_enabled = True
  12. metric_name = "CPUUtilization_test"
  13. namespace = "AWS/EC2"
  14. statistic = "Minimum"
  15. extended_statistic = None
  16. # For testing added dummy instance id
  17. dimensions = [{"Name": "InstanceId", "Value": "i-0aaab28e6c0c771d7"}]
  18. period = 60
  19. evaluation_periods = 1
  20. datapoints_to_alarm = 1
  21. threshold = 0.1
  22. comparison_operator = "GreaterThanThreshold"
  23. threshold_metric_id = ""
  24. tags = [{"Key": "alarm", "Value": metric_alarm_temp_name}]
  25. alarm_actions = [
  26. "arn:aws:swf:us-east-2:460671877902:action/actions/AWS_EC2.InstanceId.Stop/1.0"
  27. ]
  28. insufficient_data_actions = ["arn:aws:automate:us-east-2:ec2:stop"]
  29. # Create metric alarm with test flag
  30. test_ctx = copy.deepcopy(ctx)
  31. test_ctx["test"] = True
  32. ret = await hub.states.aws.cloudwatch.metric_alarm.present(
  33. test_ctx,
  34. name=metric_alarm_temp_name,
  35. alarm_description=alarm_description,
  36. ok_actions=ok_actions,
  37. actions_enabled=actions_enabled,
  38. alarm_actions=alarm_actions,
  39. insufficient_data_actions=insufficient_data_actions,
  40. metric_name=metric_name,
  41. namespace=namespace,
  42. statistic=statistic,
  43. extended_statistic=extended_statistic,
  44. dimensions=dimensions,
  45. period=period,
  46. evaluation_periods=evaluation_periods,
  47. datapoints_to_alarm=datapoints_to_alarm,
  48. threshold=threshold,
  49. comparison_operator=comparison_operator,
  50. threshold_metric_id=threshold_metric_id,
  51. tags=tags,
  52. )
  53. assert ret["result"], ret["comment"]
  54. assert not ret.get("old_state") and ret.get("new_state")
  55. assert (
  56. f"Would create aws.cloudwatch.metric_alarm {metric_alarm_temp_name}"
  57. in ret["comment"]
  58. )
  59. resource = ret.get("new_state")
  60. assert ok_actions == resource.get("ok_actions")
  61. assert insufficient_data_actions == resource.get("insufficient_data_actions")
  62. assert namespace == resource.get("namespace")
  63. assert_metric_alarm(
  64. hub,
  65. resource,
  66. metric_alarm_temp_name,
  67. alarm_description,
  68. actions_enabled,
  69. alarm_actions,
  70. metric_name,
  71. statistic,
  72. dimensions,
  73. period,
  74. evaluation_periods,
  75. datapoints_to_alarm,
  76. threshold,
  77. comparison_operator,
  78. tags,
  79. )
  80. # Create metric alarm in real
  81. ret = await hub.states.aws.cloudwatch.metric_alarm.present(
  82. ctx,
  83. name=metric_alarm_temp_name,
  84. alarm_description=alarm_description,
  85. ok_actions=ok_actions,
  86. actions_enabled=actions_enabled,
  87. alarm_actions=alarm_actions,
  88. insufficient_data_actions=insufficient_data_actions,
  89. metric_name=metric_name,
  90. namespace=namespace,
  91. statistic=statistic,
  92. extended_statistic=extended_statistic,
  93. dimensions=dimensions,
  94. period=period,
  95. evaluation_periods=evaluation_periods,
  96. datapoints_to_alarm=datapoints_to_alarm,
  97. threshold=threshold,
  98. comparison_operator=comparison_operator,
  99. tags=tags,
  100. )
  101. assert ret["result"], ret["comment"]
  102. assert f"Created '{metric_alarm_temp_name}'" in ret["comment"]
  103. assert not ret.get("old_state") and ret.get("new_state")
  104. resource = ret.get("new_state")
  105. assert ok_actions == resource.get("ok_actions")
  106. assert insufficient_data_actions == resource.get("insufficient_data_actions")
  107. assert namespace == resource.get("namespace")
  108. assert_metric_alarm(
  109. hub,
  110. resource,
  111. metric_alarm_temp_name,
  112. alarm_description,
  113. actions_enabled,
  114. alarm_actions,
  115. metric_name,
  116. statistic,
  117. dimensions,
  118. period,
  119. evaluation_periods,
  120. datapoints_to_alarm,
  121. threshold,
  122. comparison_operator,
  123. tags,
  124. )
  125. resource = ret.get("new_state")
  126. resource_id = resource.get("resource_id")
  127. # Describe metric alarm
  128. describe_ret = await hub.states.aws.cloudwatch.metric_alarm.describe(ctx)
  129. assert resource_id in describe_ret
  130. assert "aws.cloudwatch.metric_alarm.present" in describe_ret.get(resource_id)
  131. described_resource = describe_ret.get(resource_id).get(
  132. "aws.cloudwatch.metric_alarm.present"
  133. )
  134. described_resource_map = dict(ChainMap(*described_resource))
  135. described_resource_map["name"] = resource.get("name")
  136. assert ok_actions == resource.get("ok_actions")
  137. assert insufficient_data_actions == resource.get("insufficient_data_actions")
  138. assert namespace == resource.get("namespace")
  139. assert_metric_alarm(
  140. hub,
  141. described_resource_map,
  142. metric_alarm_temp_name,
  143. alarm_description,
  144. actions_enabled,
  145. alarm_actions,
  146. metric_name,
  147. statistic,
  148. dimensions,
  149. period,
  150. evaluation_periods,
  151. datapoints_to_alarm,
  152. threshold,
  153. comparison_operator,
  154. tags,
  155. )
  156. alarm_description = "test description by update"
  157. metric_name = "CPUUtilization_update"
  158. period = 120
  159. evaluation_periods = 2
  160. statistic = "Average"
  161. dimensions = [{"Name": "InstanceId", "Value": "i-0aaab28e6c0c771d8"}]
  162. datapoints_to_alarm = 2
  163. threshold = 0.5
  164. comparison_operator = "LessThanThreshold"
  165. tags = [
  166. {"Key": "alarm", "Value": metric_alarm_temp_name},
  167. {"Key": "Type", "Value": "EC2"},
  168. ]
  169. alarm_actions = [
  170. "arn:aws:swf:us-east-2:460671877902:action/actions/AWS_EC2.InstanceId.Terminate/1.0"
  171. ]
  172. # Update metric alarm with test flag
  173. ret = await hub.states.aws.cloudwatch.metric_alarm.present(
  174. test_ctx,
  175. name=metric_alarm_temp_name,
  176. resource_id=resource_id,
  177. alarm_description=alarm_description,
  178. actions_enabled=actions_enabled,
  179. alarm_actions=alarm_actions,
  180. metric_name=metric_name,
  181. namespace=namespace,
  182. statistic=statistic,
  183. dimensions=dimensions,
  184. period=period,
  185. evaluation_periods=evaluation_periods,
  186. datapoints_to_alarm=datapoints_to_alarm,
  187. threshold=threshold,
  188. comparison_operator=comparison_operator,
  189. tags=tags,
  190. )
  191. assert ret["result"], ret["comment"]
  192. assert ret.get("old_state") and ret.get("new_state")
  193. resource = ret.get("new_state")
  194. assert_metric_alarm(
  195. hub,
  196. resource,
  197. metric_alarm_temp_name,
  198. alarm_description,
  199. actions_enabled,
  200. alarm_actions,
  201. metric_name,
  202. statistic,
  203. dimensions,
  204. period,
  205. evaluation_periods,
  206. datapoints_to_alarm,
  207. threshold,
  208. comparison_operator,
  209. tags,
  210. )
  211. # Update metric alarm in real
  212. ret = await hub.states.aws.cloudwatch.metric_alarm.present(
  213. ctx,
  214. name=metric_alarm_temp_name,
  215. resource_id=resource_id,
  216. alarm_description=alarm_description,
  217. actions_enabled=actions_enabled,
  218. alarm_actions=alarm_actions,
  219. metric_name=metric_name,
  220. namespace=namespace,
  221. statistic=statistic,
  222. dimensions=dimensions,
  223. period=period,
  224. evaluation_periods=evaluation_periods,
  225. datapoints_to_alarm=datapoints_to_alarm,
  226. threshold=threshold,
  227. comparison_operator=comparison_operator,
  228. tags=tags,
  229. )
  230. assert ret["result"], ret["comment"]
  231. assert ret.get("old_state") and ret.get("new_state")
  232. resource = ret.get("new_state")
  233. assert_metric_alarm(
  234. hub,
  235. resource,
  236. metric_alarm_temp_name,
  237. alarm_description,
  238. actions_enabled,
  239. alarm_actions,
  240. metric_name,
  241. statistic,
  242. dimensions,
  243. period,
  244. evaluation_periods,
  245. datapoints_to_alarm,
  246. threshold,
  247. comparison_operator,
  248. tags,
  249. )
  250. # Delete metric alarm with test flag
  251. ret = await hub.states.aws.cloudwatch.metric_alarm.absent(
  252. test_ctx, name=metric_alarm_temp_name, resource_id=resource_id
  253. )
  254. assert ret["result"], ret["comment"]
  255. assert ret.get("old_state") and not ret.get("new_state")
  256. assert (
  257. f"Would delete aws.cloudwatch.metric_alarm '{metric_alarm_temp_name}'"
  258. in ret["comment"]
  259. )
  260. # Delete metric alarm in real
  261. ret = await hub.states.aws.cloudwatch.metric_alarm.absent(
  262. ctx, name=metric_alarm_temp_name, resource_id=resource_id
  263. )
  264. assert ret["result"], ret["comment"]
  265. assert ret.get("old_state") and not ret.get("new_state")
  266. # Delete already deleted metric alarm
  267. ret = await hub.states.aws.cloudwatch.metric_alarm.absent(
  268. ctx, name=metric_alarm_temp_name, resource_id=resource_id
  269. )
  270. assert ret["result"], ret["comment"]
  271. assert (not ret.get("old_state")) and (not ret.get("new_state"))
  272. assert f"'{metric_alarm_temp_name}' already absent" in ret["comment"]
  273. def assert_metric_alarm(
  274. hub,
  275. resource,
  276. metric_alarm_temp_name,
  277. alarm_description,
  278. actions_enabled,
  279. alarm_actions,
  280. metric_name,
  281. statistic,
  282. dimensions,
  283. period,
  284. evaluation_periods,
  285. datapoints_to_alarm,
  286. threshold,
  287. comparison_operator,
  288. tags,
  289. ):
  290. assert metric_alarm_temp_name == resource.get("name")
  291. assert alarm_description == resource.get("alarm_description")
  292. assert actions_enabled == resource.get("actions_enabled")
  293. assert alarm_actions == resource.get("alarm_actions")
  294. assert metric_name == resource.get("metric_name")
  295. assert statistic == resource.get("statistic")
  296. assert dimensions == resource.get("dimensions")
  297. assert period == resource.get("period")
  298. assert evaluation_periods == resource.get("evaluation_periods")
  299. assert datapoints_to_alarm == resource.get("datapoints_to_alarm")
  300. assert threshold == resource.get("threshold")
  301. assert comparison_operator == resource.get("comparison_operator")
  302. assert tags == resource.get("tags")
  303. assert hub.tool.aws.state_comparison_utils.are_lists_identical(
  304. tags, resource.get("tags")
  305. )