PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/boto-2.5.2/tests/unit/cloudformation/test_connection.py

#
Python | 620 lines | 615 code | 4 blank | 1 comment | 2 complexity | e3dab4143337681ff1e725ff18a7f912 MD5 | raw file
  1. #!/usr/bin/env python
  2. import unittest
  3. import httplib
  4. from datetime import datetime
  5. try:
  6. import json
  7. except ImportError:
  8. import simplejson as json
  9. from mock import Mock
  10. from tests.unit import AWSMockServiceTestCase
  11. from boto.cloudformation.connection import CloudFormationConnection
  12. SAMPLE_TEMPLATE = r"""
  13. {
  14. "AWSTemplateFormatVersion" : "2010-09-09",
  15. "Description" : "Sample template",
  16. "Parameters" : {
  17. "KeyName" : {
  18. "Description" : "key pair",
  19. "Type" : "String"
  20. }
  21. },
  22. "Resources" : {
  23. "Ec2Instance" : {
  24. "Type" : "AWS::EC2::Instance",
  25. "Properties" : {
  26. "KeyName" : { "Ref" : "KeyName" },
  27. "ImageId" : "ami-7f418316",
  28. "UserData" : { "Fn::Base64" : "80" }
  29. }
  30. }
  31. },
  32. "Outputs" : {
  33. "InstanceId" : {
  34. "Description" : "InstanceId of the newly created EC2 instance",
  35. "Value" : { "Ref" : "Ec2Instance" }
  36. }
  37. }
  38. """
  39. class CloudFormationConnectionBase(AWSMockServiceTestCase):
  40. connection_class = CloudFormationConnection
  41. def setUp(self):
  42. super(CloudFormationConnectionBase, self).setUp()
  43. self.stack_id = u'arn:aws:cloudformation:us-east-1:18:stack/Name/id'
  44. class TestCloudFormationCreateStack(CloudFormationConnectionBase):
  45. def default_body(self):
  46. return json.dumps(
  47. {u'CreateStackResponse':
  48. {u'CreateStackResult': {u'StackId': self.stack_id},
  49. u'ResponseMetadata': {u'RequestId': u'1'}}})
  50. def test_create_stack_has_correct_request_params(self):
  51. self.set_http_response(status_code=200)
  52. api_response = self.service_connection.create_stack(
  53. 'stack_name', template_url='http://url',
  54. template_body=SAMPLE_TEMPLATE,
  55. parameters=[('KeyName', 'myKeyName')],
  56. notification_arns=['arn:notify1', 'arn:notify2'],
  57. disable_rollback=True,
  58. timeout_in_minutes=20, capabilities=['CAPABILITY_IAM']
  59. )
  60. self.assertEqual(api_response, self.stack_id)
  61. # These are the parameters that are actually sent to the CloudFormation
  62. # service.
  63. self.assert_request_parameters({
  64. 'AWSAccessKeyId': 'aws_access_key_id',
  65. 'Action': 'CreateStack',
  66. 'Capabilities.member.1': 'CAPABILITY_IAM',
  67. 'ContentType': 'JSON',
  68. 'DisableRollback': 'true',
  69. 'NotificationARNs.member.1': 'arn:notify1',
  70. 'NotificationARNs.member.2': 'arn:notify2',
  71. 'Parameters.member.1.ParameterKey': 'KeyName',
  72. 'Parameters.member.1.ParameterValue': 'myKeyName',
  73. 'SignatureMethod': 'HmacSHA256',
  74. 'SignatureVersion': 2,
  75. 'StackName': 'stack_name',
  76. 'Version': '2010-05-15',
  77. 'TimeoutInMinutes': 20,
  78. 'TemplateBody': SAMPLE_TEMPLATE,
  79. 'TemplateURL': 'http://url',
  80. }, ignore_params_values=['Timestamp'])
  81. # The test_create_stack_has_correct_request_params verified all of the
  82. # params needed when making a create_stack service call. The rest of the
  83. # tests for create_stack only verify specific parts of the params sent
  84. # to CloudFormation.
  85. def test_create_stack_with_minimum_args(self):
  86. # This will fail in practice, but the API docs only require stack_name.
  87. self.set_http_response(status_code=200)
  88. api_response = self.service_connection.create_stack('stack_name')
  89. self.assertEqual(api_response, self.stack_id)
  90. self.assert_request_parameters({
  91. 'AWSAccessKeyId': 'aws_access_key_id',
  92. 'Action': 'CreateStack',
  93. 'ContentType': 'JSON',
  94. 'DisableRollback': 'false',
  95. 'SignatureMethod': 'HmacSHA256',
  96. 'SignatureVersion': 2,
  97. 'StackName': 'stack_name',
  98. 'Version': '2010-05-15',
  99. }, ignore_params_values=['Timestamp'])
  100. def test_create_stack_fails(self):
  101. self.set_http_response(status_code=400, reason='Bad Request',
  102. body='Invalid arg.')
  103. with self.assertRaises(self.service_connection.ResponseError):
  104. api_response = self.service_connection.create_stack(
  105. 'stack_name', template_body=SAMPLE_TEMPLATE,
  106. parameters=[('KeyName', 'myKeyName')])
  107. class TestCloudFormationUpdateStack(CloudFormationConnectionBase):
  108. def default_body(self):
  109. return json.dumps(
  110. {u'UpdateStackResponse':
  111. {u'UpdateStackResult': {u'StackId': self.stack_id},
  112. u'ResponseMetadata': {u'RequestId': u'1'}}})
  113. def test_update_stack_all_args(self):
  114. self.set_http_response(status_code=200)
  115. api_response = self.service_connection.update_stack(
  116. 'stack_name', template_url='http://url',
  117. template_body=SAMPLE_TEMPLATE,
  118. parameters=[('KeyName', 'myKeyName')],
  119. notification_arns=['arn:notify1', 'arn:notify2'],
  120. disable_rollback=True,
  121. timeout_in_minutes=20
  122. )
  123. self.assert_request_parameters({
  124. 'AWSAccessKeyId': 'aws_access_key_id',
  125. 'Action': 'UpdateStack',
  126. 'ContentType': 'JSON',
  127. 'DisableRollback': 'true',
  128. 'NotificationARNs.member.1': 'arn:notify1',
  129. 'NotificationARNs.member.2': 'arn:notify2',
  130. 'Parameters.member.1.ParameterKey': 'KeyName',
  131. 'Parameters.member.1.ParameterValue': 'myKeyName',
  132. 'SignatureMethod': 'HmacSHA256',
  133. 'SignatureVersion': 2,
  134. 'StackName': 'stack_name',
  135. 'Version': '2010-05-15',
  136. 'TimeoutInMinutes': 20,
  137. 'TemplateBody': SAMPLE_TEMPLATE,
  138. 'TemplateURL': 'http://url',
  139. }, ignore_params_values=['Timestamp'])
  140. def test_update_stack_with_minimum_args(self):
  141. self.set_http_response(status_code=200)
  142. api_response = self.service_connection.update_stack('stack_name')
  143. self.assertEqual(api_response, self.stack_id)
  144. self.assert_request_parameters({
  145. 'AWSAccessKeyId': 'aws_access_key_id',
  146. 'Action': 'UpdateStack',
  147. 'ContentType': 'JSON',
  148. 'DisableRollback': 'false',
  149. 'SignatureMethod': 'HmacSHA256',
  150. 'SignatureVersion': 2,
  151. 'StackName': 'stack_name',
  152. 'Version': '2010-05-15',
  153. }, ignore_params_values=['Timestamp'])
  154. def test_update_stack_fails(self):
  155. self.set_http_response(status_code=400, reason='Bad Request',
  156. body='Invalid arg.')
  157. with self.assertRaises(self.service_connection.ResponseError):
  158. api_response = self.service_connection.update_stack(
  159. 'stack_name', template_body=SAMPLE_TEMPLATE,
  160. parameters=[('KeyName', 'myKeyName')])
  161. class TestCloudFormationDeleteStack(CloudFormationConnectionBase):
  162. def default_body(self):
  163. return json.dumps(
  164. {u'DeleteStackResponse':
  165. {u'ResponseMetadata': {u'RequestId': u'1'}}})
  166. def test_delete_stack(self):
  167. self.set_http_response(status_code=200)
  168. api_response = self.service_connection.delete_stack('stack_name')
  169. self.assertEqual(api_response, json.loads(self.default_body()))
  170. self.assert_request_parameters({
  171. 'AWSAccessKeyId': 'aws_access_key_id',
  172. 'Action': 'DeleteStack',
  173. 'ContentType': 'JSON',
  174. 'SignatureMethod': 'HmacSHA256',
  175. 'SignatureVersion': 2,
  176. 'StackName': 'stack_name',
  177. 'Version': '2010-05-15',
  178. }, ignore_params_values=['Timestamp'])
  179. def test_delete_stack_fails(self):
  180. self.set_http_response(status_code=400)
  181. with self.assertRaises(self.service_connection.ResponseError):
  182. api_response = self.service_connection.delete_stack('stack_name')
  183. class TestCloudFormationDescribeStackResource(CloudFormationConnectionBase):
  184. def default_body(self):
  185. return json.dumps('fake server response')
  186. def test_describe_stack_resource(self):
  187. self.set_http_response(status_code=200)
  188. api_response = self.service_connection.describe_stack_resource(
  189. 'stack_name', 'resource_id')
  190. self.assertEqual(api_response, 'fake server response')
  191. self.assert_request_parameters({
  192. 'AWSAccessKeyId': 'aws_access_key_id',
  193. 'Action': 'DescribeStackResource',
  194. 'ContentType': 'JSON',
  195. 'LogicalResourceId': 'resource_id',
  196. 'SignatureMethod': 'HmacSHA256',
  197. 'SignatureVersion': 2,
  198. 'StackName': 'stack_name',
  199. 'Version': '2010-05-15',
  200. }, ignore_params_values=['Timestamp'])
  201. def test_describe_stack_resource_fails(self):
  202. self.set_http_response(status_code=400)
  203. with self.assertRaises(self.service_connection.ResponseError):
  204. api_response = self.service_connection.describe_stack_resource(
  205. 'stack_name', 'resource_id')
  206. class TestCloudFormationGetTemplate(CloudFormationConnectionBase):
  207. def default_body(self):
  208. return json.dumps('fake server response')
  209. def test_get_template(self):
  210. self.set_http_response(status_code=200)
  211. api_response = self.service_connection.get_template('stack_name')
  212. self.assertEqual(api_response, 'fake server response')
  213. self.assert_request_parameters({
  214. 'AWSAccessKeyId': 'aws_access_key_id',
  215. 'Action': 'GetTemplate',
  216. 'ContentType': 'JSON',
  217. 'SignatureMethod': 'HmacSHA256',
  218. 'SignatureVersion': 2,
  219. 'StackName': 'stack_name',
  220. 'Version': '2010-05-15',
  221. }, ignore_params_values=['Timestamp'])
  222. def test_get_template_fails(self):
  223. self.set_http_response(status_code=400)
  224. with self.assertRaises(self.service_connection.ResponseError):
  225. api_response = self.service_connection.get_template('stack_name')
  226. class TestCloudFormationGetStackevents(CloudFormationConnectionBase):
  227. def default_body(self):
  228. return """
  229. <DescribeStackEventsResult>
  230. <StackEvents>
  231. <member>
  232. <EventId>Event-1-Id</EventId>
  233. <StackId>arn:aws:cfn:us-east-1:1:stack</StackId>
  234. <StackName>MyStack</StackName>
  235. <LogicalResourceId>MyStack</LogicalResourceId>
  236. <PhysicalResourceId>MyStack_One</PhysicalResourceId>
  237. <ResourceType>AWS::CloudFormation::Stack</ResourceType>
  238. <Timestamp>2010-07-27T22:26:28Z</Timestamp>
  239. <ResourceStatus>CREATE_IN_PROGRESS</ResourceStatus>
  240. <ResourceStatusReason>User initiated</ResourceStatusReason>
  241. </member>
  242. <member>
  243. <EventId>Event-2-Id</EventId>
  244. <StackId>arn:aws:cfn:us-east-1:1:stack</StackId>
  245. <StackName>MyStack</StackName>
  246. <LogicalResourceId>MySG1</LogicalResourceId>
  247. <PhysicalResourceId>MyStack_SG1</PhysicalResourceId>
  248. <ResourceType>AWS::SecurityGroup</ResourceType>
  249. <Timestamp>2010-07-27T22:28:28Z</Timestamp>
  250. <ResourceStatus>CREATE_COMPLETE</ResourceStatus>
  251. </member>
  252. </StackEvents>
  253. </DescribeStackEventsResult>
  254. """
  255. def test_describe_stack_events(self):
  256. self.set_http_response(status_code=200)
  257. first, second = self.service_connection.describe_stack_events('stack_name', next_token='next_token')
  258. self.assertEqual(first.event_id, 'Event-1-Id')
  259. self.assertEqual(first.logical_resource_id, 'MyStack')
  260. self.assertEqual(first.physical_resource_id, 'MyStack_One')
  261. self.assertEqual(first.resource_properties, None)
  262. self.assertEqual(first.resource_status, 'CREATE_IN_PROGRESS')
  263. self.assertEqual(first.resource_status_reason, 'User initiated')
  264. self.assertEqual(first.resource_type, 'AWS::CloudFormation::Stack')
  265. self.assertEqual(first.stack_id, 'arn:aws:cfn:us-east-1:1:stack')
  266. self.assertEqual(first.stack_name, 'MyStack')
  267. self.assertIsNotNone(first.timestamp)
  268. self.assertEqual(second.event_id, 'Event-2-Id')
  269. self.assertEqual(second.logical_resource_id, 'MySG1')
  270. self.assertEqual(second.physical_resource_id, 'MyStack_SG1')
  271. self.assertEqual(second.resource_properties, None)
  272. self.assertEqual(second.resource_status, 'CREATE_COMPLETE')
  273. self.assertEqual(second.resource_status_reason, None)
  274. self.assertEqual(second.resource_type, 'AWS::SecurityGroup')
  275. self.assertEqual(second.stack_id, 'arn:aws:cfn:us-east-1:1:stack')
  276. self.assertEqual(second.stack_name, 'MyStack')
  277. self.assertIsNotNone(second.timestamp)
  278. self.assert_request_parameters({
  279. 'AWSAccessKeyId': 'aws_access_key_id',
  280. 'Action': 'DescribeStackEvents',
  281. 'NextToken': 'next_token',
  282. 'SignatureMethod': 'HmacSHA256',
  283. 'SignatureVersion': 2,
  284. 'StackName': 'stack_name',
  285. 'Version': '2010-05-15',
  286. }, ignore_params_values=['Timestamp'])
  287. class TestCloudFormationDescribeStackResources(CloudFormationConnectionBase):
  288. def default_body(self):
  289. return """
  290. <DescribeStackResourcesResult>
  291. <StackResources>
  292. <member>
  293. <StackId>arn:aws:cfn:us-east-1:1:stack</StackId>
  294. <StackName>MyStack</StackName>
  295. <LogicalResourceId>MyDBInstance</LogicalResourceId>
  296. <PhysicalResourceId>MyStack_DB1</PhysicalResourceId>
  297. <ResourceType>AWS::DBInstance</ResourceType>
  298. <Timestamp>2010-07-27T22:27:28Z</Timestamp>
  299. <ResourceStatus>CREATE_COMPLETE</ResourceStatus>
  300. </member>
  301. <member>
  302. <StackId>arn:aws:cfn:us-east-1:1:stack</StackId>
  303. <StackName>MyStack</StackName>
  304. <LogicalResourceId>MyAutoScalingGroup</LogicalResourceId>
  305. <PhysicalResourceId>MyStack_ASG1</PhysicalResourceId>
  306. <ResourceType>AWS::AutoScalingGroup</ResourceType>
  307. <Timestamp>2010-07-27T22:28:28Z</Timestamp>
  308. <ResourceStatus>CREATE_IN_PROGRESS</ResourceStatus>
  309. </member>
  310. </StackResources>
  311. </DescribeStackResourcesResult>
  312. """
  313. def test_describe_stack_resources(self):
  314. self.set_http_response(status_code=200)
  315. first, second = self.service_connection.describe_stack_resources(
  316. 'stack_name', 'logical_resource_id', 'physical_resource_id')
  317. self.assertEqual(first.description, None)
  318. self.assertEqual(first.logical_resource_id, 'MyDBInstance')
  319. self.assertEqual(first.physical_resource_id, 'MyStack_DB1')
  320. self.assertEqual(first.resource_status, 'CREATE_COMPLETE')
  321. self.assertEqual(first.resource_status_reason, None)
  322. self.assertEqual(first.resource_type, 'AWS::DBInstance')
  323. self.assertEqual(first.stack_id, 'arn:aws:cfn:us-east-1:1:stack')
  324. self.assertEqual(first.stack_name, 'MyStack')
  325. self.assertIsNotNone(first.timestamp)
  326. self.assertEqual(second.description, None)
  327. self.assertEqual(second.logical_resource_id, 'MyAutoScalingGroup')
  328. self.assertEqual(second.physical_resource_id, 'MyStack_ASG1')
  329. self.assertEqual(second.resource_status, 'CREATE_IN_PROGRESS')
  330. self.assertEqual(second.resource_status_reason, None)
  331. self.assertEqual(second.resource_type, 'AWS::AutoScalingGroup')
  332. self.assertEqual(second.stack_id, 'arn:aws:cfn:us-east-1:1:stack')
  333. self.assertEqual(second.stack_name, 'MyStack')
  334. self.assertIsNotNone(second.timestamp)
  335. self.assert_request_parameters({
  336. 'AWSAccessKeyId': 'aws_access_key_id',
  337. 'Action': 'DescribeStackResources',
  338. 'LogicalResourceId': 'logical_resource_id',
  339. 'PhysicalResourceId': 'physical_resource_id',
  340. 'SignatureMethod': 'HmacSHA256',
  341. 'SignatureVersion': 2,
  342. 'StackName': 'stack_name',
  343. 'Version': '2010-05-15',
  344. }, ignore_params_values=['Timestamp'])
  345. class TestCloudFormationDescribeStacks(CloudFormationConnectionBase):
  346. def default_body(self):
  347. return """
  348. <DescribeStacksResponse>
  349. <DescribeStacksResult>
  350. <Stacks>
  351. <member>
  352. <StackId>arn:aws:cfn:us-east-1:1:stack</StackId>
  353. <StackStatus>CREATE_COMPLETE</StackStatus>
  354. <StackName>MyStack</StackName>
  355. <StackStatusReason/>
  356. <Description>My Description</Description>
  357. <CreationTime>2012-05-16T22:55:31Z</CreationTime>
  358. <Capabilities>
  359. <member>CAPABILITY_IAM</member>
  360. </Capabilities>
  361. <DisableRollback>false</DisableRollback>
  362. <Parameters>
  363. <member>
  364. <ParameterValue>MyValue</ParameterValue>
  365. <ParameterKey>MyKey</ParameterKey>
  366. </member>
  367. </Parameters>
  368. <Outputs>
  369. <member>
  370. <OutputValue>http://url/</OutputValue>
  371. <Description>Server URL</Description>
  372. <OutputKey>ServerURL</OutputKey>
  373. </member>
  374. </Outputs>
  375. </member>
  376. </Stacks>
  377. </DescribeStacksResult>
  378. <ResponseMetadata>
  379. <RequestId>12345</RequestId>
  380. </ResponseMetadata>
  381. </DescribeStacksResponse>
  382. """
  383. def test_describe_stacks(self):
  384. self.set_http_response(status_code=200)
  385. stack = self.service_connection.describe_stacks('MyStack')[0]
  386. self.assertEqual(stack.creation_time,
  387. datetime(2012, 5, 16, 22, 55, 31))
  388. self.assertEqual(stack.description, 'My Description')
  389. self.assertEqual(stack.disable_rollback, True)
  390. self.assertEqual(stack.notification_arns, [])
  391. self.assertEqual(stack.stack_id, 'arn:aws:cfn:us-east-1:1:stack')
  392. self.assertEqual(stack.stack_status, 'CREATE_COMPLETE')
  393. self.assertEqual(stack.stack_name, 'MyStack')
  394. self.assertEqual(stack.stack_name_reason, None)
  395. self.assertEqual(stack.timeout_in_minutes, None)
  396. self.assertEqual(len(stack.outputs), 1)
  397. self.assertEqual(stack.outputs[0].description, 'Server URL')
  398. self.assertEqual(stack.outputs[0].key, 'ServerURL')
  399. self.assertEqual(stack.outputs[0].value, 'http://url/')
  400. self.assertEqual(len(stack.parameters), 1)
  401. self.assertEqual(stack.parameters[0].key, 'MyKey')
  402. self.assertEqual(stack.parameters[0].value, 'MyValue')
  403. self.assertEqual(len(stack.capabilities), 1)
  404. self.assertEqual(stack.capabilities[0].value, 'CAPABILITY_IAM')
  405. self.assert_request_parameters({
  406. 'AWSAccessKeyId': 'aws_access_key_id',
  407. 'Action': 'DescribeStacks',
  408. 'SignatureMethod': 'HmacSHA256',
  409. 'SignatureVersion': 2,
  410. 'StackName': 'MyStack',
  411. 'Version': '2010-05-15',
  412. }, ignore_params_values=['Timestamp'])
  413. class TestCloudFormationListStackResources(CloudFormationConnectionBase):
  414. def default_body(self):
  415. return """
  416. <ListStackResourcesResponse>
  417. <ListStackResourcesResult>
  418. <StackResourceSummaries>
  419. <member>
  420. <ResourceStatus>CREATE_COMPLETE</ResourceStatus>
  421. <LogicalResourceId>SampleDB</LogicalResourceId>
  422. <LastUpdatedTimestamp>2011-06-21T20:25:57Z</LastUpdatedTimestamp>
  423. <PhysicalResourceId>My-db-ycx</PhysicalResourceId>
  424. <ResourceType>AWS::RDS::DBInstance</ResourceType>
  425. </member>
  426. <member>
  427. <ResourceStatus>CREATE_COMPLETE</ResourceStatus>
  428. <LogicalResourceId>CPUAlarmHigh</LogicalResourceId>
  429. <LastUpdatedTimestamp>2011-06-21T20:29:23Z</LastUpdatedTimestamp>
  430. <PhysicalResourceId>MyStack-CPUH-PF</PhysicalResourceId>
  431. <ResourceType>AWS::CloudWatch::Alarm</ResourceType>
  432. </member>
  433. </StackResourceSummaries>
  434. </ListStackResourcesResult>
  435. <ResponseMetadata>
  436. <RequestId>2d06e36c-ac1d-11e0-a958-f9382b6eb86b</RequestId>
  437. </ResponseMetadata>
  438. </ListStackResourcesResponse>
  439. """
  440. def test_list_stack_resources(self):
  441. self.set_http_response(status_code=200)
  442. resources = self.service_connection.list_stack_resources('MyStack',
  443. next_token='next_token')
  444. self.assertEqual(len(resources), 2)
  445. self.assertEqual(resources[0].last_updated_timestamp,
  446. datetime(2011, 6, 21, 20, 25, 57))
  447. self.assertEqual(resources[0].logical_resource_id, 'SampleDB')
  448. self.assertEqual(resources[0].physical_resource_id, 'My-db-ycx')
  449. self.assertEqual(resources[0].resource_status, 'CREATE_COMPLETE')
  450. self.assertEqual(resources[0].resource_status_reason, None)
  451. self.assertEqual(resources[0].resource_type, 'AWS::RDS::DBInstance')
  452. self.assertEqual(resources[1].last_updated_timestamp,
  453. datetime(2011, 6, 21, 20, 29, 23))
  454. self.assertEqual(resources[1].logical_resource_id, 'CPUAlarmHigh')
  455. self.assertEqual(resources[1].physical_resource_id, 'MyStack-CPUH-PF')
  456. self.assertEqual(resources[1].resource_status, 'CREATE_COMPLETE')
  457. self.assertEqual(resources[1].resource_status_reason, None)
  458. self.assertEqual(resources[1].resource_type, 'AWS::CloudWatch::Alarm')
  459. self.assert_request_parameters({
  460. 'AWSAccessKeyId': 'aws_access_key_id',
  461. 'Action': 'ListStackResources',
  462. 'NextToken': 'next_token',
  463. 'SignatureMethod': 'HmacSHA256',
  464. 'SignatureVersion': 2,
  465. 'StackName': 'MyStack',
  466. 'Version': '2010-05-15',
  467. }, ignore_params_values=['Timestamp'])
  468. class TestCloudFormationListStacks(CloudFormationConnectionBase):
  469. def default_body(self):
  470. return """
  471. <ListStacksResponse>
  472. <ListStacksResult>
  473. <StackSummaries>
  474. <member>
  475. <StackId>arn:aws:cfn:us-east-1:1:stack/Test1/aa</StackId>
  476. <StackStatus>CREATE_IN_PROGRESS</StackStatus>
  477. <StackName>vpc1</StackName>
  478. <CreationTime>2011-05-23T15:47:44Z</CreationTime>
  479. <TemplateDescription>My Description.</TemplateDescription>
  480. </member>
  481. </StackSummaries>
  482. </ListStacksResult>
  483. </ListStacksResponse>
  484. """
  485. def test_list_stacks(self):
  486. self.set_http_response(status_code=200)
  487. stacks = self.service_connection.list_stacks(['CREATE_IN_PROGRESS'],
  488. next_token='next_token')
  489. self.assertEqual(len(stacks), 1)
  490. self.assertEqual(stacks[0].stack_id,
  491. 'arn:aws:cfn:us-east-1:1:stack/Test1/aa')
  492. self.assertEqual(stacks[0].stack_status, 'CREATE_IN_PROGRESS')
  493. self.assertEqual(stacks[0].stack_name, 'vpc1')
  494. self.assertEqual(stacks[0].creation_time,
  495. datetime(2011, 5, 23, 15, 47, 44))
  496. self.assertEqual(stacks[0].deletion_time, None)
  497. self.assertEqual(stacks[0].template_description, 'My Description.')
  498. self.assert_request_parameters({
  499. 'AWSAccessKeyId': 'aws_access_key_id',
  500. 'Action': 'ListStacks',
  501. 'NextToken': 'next_token',
  502. 'SignatureMethod': 'HmacSHA256',
  503. 'SignatureVersion': 2,
  504. 'StackStatusFilter.member.1': 'CREATE_IN_PROGRESS',
  505. 'Version': '2010-05-15',
  506. }, ignore_params_values=['Timestamp'])
  507. class TestCloudFormationValidateTemplate(CloudFormationConnectionBase):
  508. def default_body(self):
  509. return """
  510. <ValidateTemplateResponse xmlns="http://cloudformation.amazonaws.com/doc/2010-05-15/">
  511. <ValidateTemplateResult>
  512. <Description>My Description.</Description>
  513. <Parameters>
  514. <member>
  515. <NoEcho>false</NoEcho>
  516. <ParameterKey>InstanceType</ParameterKey>
  517. <Description>Type of instance to launch</Description>
  518. <DefaultValue>m1.small</DefaultValue>
  519. </member>
  520. <member>
  521. <NoEcho>false</NoEcho>
  522. <ParameterKey>KeyName</ParameterKey>
  523. <Description>EC2 KeyPair</Description>
  524. </member>
  525. </Parameters>
  526. </ValidateTemplateResult>
  527. <ResponseMetadata>
  528. <RequestId>0be7b6e8-e4a0-11e0-a5bd-9f8d5a7dbc91</RequestId>
  529. </ResponseMetadata>
  530. </ValidateTemplateResponse>
  531. """
  532. def test_validate_template(self):
  533. self.set_http_response(status_code=200)
  534. template = self.service_connection.validate_template(template_body=SAMPLE_TEMPLATE,
  535. template_url='http://url')
  536. self.assertEqual(template.description, 'My Description.')
  537. self.assertEqual(len(template.template_parameters), 2)
  538. param1, param2 = template.template_parameters
  539. self.assertEqual(param1.default_value, 'm1.small')
  540. self.assertEqual(param1.description, 'Type of instance to launch')
  541. self.assertEqual(param1.no_echo, True)
  542. self.assertEqual(param1.parameter_key, 'InstanceType')
  543. self.assertEqual(param2.default_value, None)
  544. self.assertEqual(param2.description, 'EC2 KeyPair')
  545. self.assertEqual(param2.no_echo, True)
  546. self.assertEqual(param2.parameter_key, 'KeyName')
  547. self.assert_request_parameters({
  548. 'AWSAccessKeyId': 'aws_access_key_id',
  549. 'Action': 'ValidateTemplate',
  550. 'SignatureMethod': 'HmacSHA256',
  551. 'SignatureVersion': 2,
  552. 'TemplateBody': SAMPLE_TEMPLATE,
  553. 'TemplateUrl': 'http://url',
  554. 'Version': '2010-05-15',
  555. }, ignore_params_values=['Timestamp'])
  556. if __name__ == '__main__':
  557. unittest.main()