| OLD | NEW |
| 1 # Copyright (c) 2013 Amazon.com, Inc. or its affiliates. | 1 # Copyright (c) 2013 Amazon.com, Inc. or its affiliates. |
| 2 # All rights reserved. | 2 # All rights reserved. |
| 3 # | 3 # |
| 4 # Permission is hereby granted, free of charge, to any person obtaining a | 4 # Permission is hereby granted, free of charge, to any person obtaining a |
| 5 # copy of this software and associated documentation files (the | 5 # copy of this software and associated documentation files (the |
| 6 # "Software"), to deal in the Software without restriction, including | 6 # "Software"), to deal in the Software without restriction, including |
| 7 # without limitation the rights to use, copy, modify, merge, publish, dis- | 7 # without limitation the rights to use, copy, modify, merge, publish, dis- |
| 8 # tribute, sublicense, and/or sell copies of the Software, and to permit | 8 # tribute, sublicense, and/or sell copies of the Software, and to permit |
| 9 # persons to whom the Software is furnished to do so, subject to the fol- | 9 # persons to whom the Software is furnished to do so, subject to the fol- |
| 10 # lowing conditions: | 10 # lowing conditions: |
| 11 # | 11 # |
| 12 # The above copyright notice and this permission notice shall be included | 12 # The above copyright notice and this permission notice shall be included |
| 13 # in all copies or substantial portions of the Software. | 13 # in all copies or substantial portions of the Software. |
| 14 # | 14 # |
| 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | 16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
| 17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | 17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT |
| 18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | 18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 21 # IN THE SOFTWARE. | 21 # IN THE SOFTWARE. |
| 22 from __future__ import with_statement | 22 from __future__ import with_statement |
| 23 | 23 |
| 24 import boto.utils | 24 import boto.utils |
| 25 | 25 |
| 26 from datetime import datetime | 26 from datetime import datetime |
| 27 from time import time |
| 27 from tests.unit import AWSMockServiceTestCase | 28 from tests.unit import AWSMockServiceTestCase |
| 28 | 29 |
| 29 from boto.emr.connection import EmrConnection | 30 from boto.emr.connection import EmrConnection |
| 30 from boto.emr.emrobject import JobFlowStepList | 31 from boto.emr.emrobject import BootstrapAction, BootstrapActionList, \ |
| 32 ClusterStatus, ClusterSummaryList, \ |
| 33 ClusterSummary, ClusterTimeline, InstanceInfo, \ |
| 34 InstanceList, InstanceGroupInfo, \ |
| 35 InstanceGroup, InstanceGroupList, JobFlow, \ |
| 36 JobFlowStepList, Step, StepSummaryList, Cluster |
| 31 | 37 |
| 32 # These tests are just checking the basic structure of | 38 # These tests are just checking the basic structure of |
| 33 # the Elastic MapReduce code, by picking a few calls | 39 # the Elastic MapReduce code, by picking a few calls |
| 34 # and verifying we get the expected results with mocked | 40 # and verifying we get the expected results with mocked |
| 35 # responses. The integration tests actually verify the | 41 # responses. The integration tests actually verify the |
| 36 # API calls interact with the service correctly. | 42 # API calls interact with the service correctly. |
| 37 class TestListClusters(AWSMockServiceTestCase): | 43 class TestListClusters(AWSMockServiceTestCase): |
| 38 connection_class = EmrConnection | 44 connection_class = EmrConnection |
| 39 | 45 |
| 40 def default_body(self): | 46 def default_body(self): |
| 41 return """<ListClustersOutput><Clusters></Clusters></ListClustersOutput>
""" | 47 return """ |
| 48 <ListClustersResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-3
1"> |
| 49 <ListClustersResult> |
| 50 <Clusters> |
| 51 <member> |
| 52 <Id>j-aaaaaaaaaaaa</Id> |
| 53 <Status> |
| 54 <StateChangeReason> |
| 55 <Message>Terminated by user request</Message> |
| 56 <Code>USER_REQUEST</Code> |
| 57 </StateChangeReason> |
| 58 <State>TERMINATED</State> |
| 59 <Timeline> |
| 60 <CreationDateTime>2014-01-24T01:21:21Z</CreationDateTime> |
| 61 <ReadyDateTime>2014-01-24T01:25:26Z</ReadyDateTime> |
| 62 <EndDateTime>2014-01-24T02:19:46Z</EndDateTime> |
| 63 </Timeline> |
| 64 </Status> |
| 65 <Name>analytics test</Name> |
| 66 </member> |
| 67 <member> |
| 68 <Id>j-aaaaaaaaaaaab</Id> |
| 69 <Status> |
| 70 <StateChangeReason> |
| 71 <Message>Terminated by user request</Message> |
| 72 <Code>USER_REQUEST</Code> |
| 73 </StateChangeReason> |
| 74 <State>TERMINATED</State> |
| 75 <Timeline> |
| 76 <CreationDateTime>2014-01-21T02:53:08Z</CreationDateTime> |
| 77 <ReadyDateTime>2014-01-21T02:56:40Z</ReadyDateTime> |
| 78 <EndDateTime>2014-01-21T03:40:22Z</EndDateTime> |
| 79 </Timeline> |
| 80 </Status> |
| 81 <Name>test job</Name> |
| 82 </member> |
| 83 </Clusters> |
| 84 </ListClustersResult> |
| 85 <ResponseMetadata> |
| 86 <RequestId>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</RequestId> |
| 87 </ResponseMetadata> |
| 88 </ListClustersResponse> |
| 89 """ |
| 42 | 90 |
| 43 def test_list_clusters(self): | 91 def test_list_clusters(self): |
| 44 self.set_http_response(status_code=200) | 92 self.set_http_response(status_code=200) |
| 45 response = self.service_connection.list_clusters() | 93 response = self.service_connection.list_clusters() |
| 46 | 94 |
| 47 self.assert_request_parameters({ | 95 self.assert_request_parameters({ |
| 48 'Action': 'ListClusters', | 96 'Action': 'ListClusters', |
| 49 'Version': '2009-03-31', | 97 'Version': '2009-03-31', |
| 50 }) | 98 }) |
| 51 | 99 |
| 100 self.assertTrue(isinstance(response, ClusterSummaryList)) |
| 101 |
| 102 self.assertEqual(len(response.clusters), 2) |
| 103 self.assertTrue(isinstance(response.clusters[0], ClusterSummary)) |
| 104 self.assertEqual(response.clusters[0].name, 'analytics test') |
| 105 |
| 106 self.assertTrue(isinstance(response.clusters[0].status, ClusterStatus)) |
| 107 |
| 108 self.assertTrue(isinstance(response.clusters[0].status.timeline, Cluster
Timeline)) |
| 109 |
| 110 self.assertEqual(response.clusters[0].status.timeline.creationdatetime,
'2014-01-24T01:21:21Z') |
| 111 self.assertEqual(response.clusters[0].status.timeline.readydatetime, '20
14-01-24T01:25:26Z') |
| 112 self.assertEqual(response.clusters[0].status.timeline.enddatetime, '2014
-01-24T02:19:46Z') |
| 113 |
| 114 |
| 52 def test_list_clusters_created_before(self): | 115 def test_list_clusters_created_before(self): |
| 53 self.set_http_response(status_code=200) | 116 self.set_http_response(status_code=200) |
| 54 | 117 |
| 55 date = datetime.now() | 118 date = datetime.now() |
| 56 response = self.service_connection.list_clusters(created_before=date) | 119 response = self.service_connection.list_clusters(created_before=date) |
| 57 | 120 |
| 58 self.assert_request_parameters({ | 121 self.assert_request_parameters({ |
| 59 'Action': 'ListClusters', | 122 'Action': 'ListClusters', |
| 60 'CreatedBefore': date.strftime(boto.utils.ISO8601), | 123 'CreatedBefore': date.strftime(boto.utils.ISO8601), |
| 61 'Version': '2009-03-31' | 124 'Version': '2009-03-31' |
| (...skipping 23 matching lines...) Expand all Loading... |
| 85 'ClusterStates.member.1': 'RUNNING', | 148 'ClusterStates.member.1': 'RUNNING', |
| 86 'ClusterStates.member.2': 'WAITING', | 149 'ClusterStates.member.2': 'WAITING', |
| 87 'Version': '2009-03-31' | 150 'Version': '2009-03-31' |
| 88 }) | 151 }) |
| 89 | 152 |
| 90 | 153 |
| 91 class TestListInstanceGroups(AWSMockServiceTestCase): | 154 class TestListInstanceGroups(AWSMockServiceTestCase): |
| 92 connection_class = EmrConnection | 155 connection_class = EmrConnection |
| 93 | 156 |
| 94 def default_body(self): | 157 def default_body(self): |
| 95 return """<ListInstanceGroupsOutput><InstanceGroups></InstanceGroups></L
istInstanceGroupsOutput>""" | 158 return """ |
| 159 <ListInstanceGroupsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/200
9-03-31"> |
| 160 <ListInstanceGroupsResult> |
| 161 <InstanceGroups> |
| 162 <member> |
| 163 <Id>ig-aaaaaaaaaaaaa</Id> |
| 164 <InstanceType>m1.large</InstanceType> |
| 165 <Market>ON_DEMAND</Market> |
| 166 <Status> |
| 167 <StateChangeReason> |
| 168 <Message>Job flow terminated</Message> |
| 169 <Code>CLUSTER_TERMINATED</Code> |
| 170 </StateChangeReason> |
| 171 <State>TERMINATED</State> |
| 172 <Timeline> |
| 173 <CreationDateTime>2014-01-24T01:21:21Z</CreationDateTime> |
| 174 <ReadyDateTime>2014-01-24T01:25:08Z</ReadyDateTime> |
| 175 <EndDateTime>2014-01-24T02:19:46Z</EndDateTime> |
| 176 </Timeline> |
| 177 </Status> |
| 178 <Name>Master instance group</Name> |
| 179 <RequestedInstanceCount>1</RequestedInstanceCount> |
| 180 <RunningInstanceCount>0</RunningInstanceCount> |
| 181 <InstanceGroupType>MASTER</InstanceGroupType> |
| 182 </member> |
| 183 <member> |
| 184 <Id>ig-aaaaaaaaaaab</Id> |
| 185 <InstanceType>m1.large</InstanceType> |
| 186 <Market>ON_DEMAND</Market> |
| 187 <Status> |
| 188 <StateChangeReason> |
| 189 <Message>Job flow terminated</Message> |
| 190 <Code>CLUSTER_TERMINATED</Code> |
| 191 </StateChangeReason> |
| 192 <State>TERMINATED</State> |
| 193 <Timeline> |
| 194 <CreationDateTime>2014-01-24T01:21:21Z</CreationDateTime> |
| 195 <ReadyDateTime>2014-01-24T01:25:26Z</ReadyDateTime> |
| 196 <EndDateTime>2014-01-24T02:19:46Z</EndDateTime> |
| 197 </Timeline> |
| 198 </Status> |
| 199 <Name>Core instance group</Name> |
| 200 <RequestedInstanceCount>2</RequestedInstanceCount> |
| 201 <RunningInstanceCount>0</RunningInstanceCount> |
| 202 <InstanceGroupType>CORE</InstanceGroupType> |
| 203 </member> |
| 204 </InstanceGroups> |
| 205 </ListInstanceGroupsResult> |
| 206 <ResponseMetadata> |
| 207 <RequestId>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</RequestId> |
| 208 </ResponseMetadata> |
| 209 </ListInstanceGroupsResponse> |
| 210 |
| 211 """ |
| 96 | 212 |
| 97 def test_list_instance_groups(self): | 213 def test_list_instance_groups(self): |
| 98 self.set_http_response(200) | 214 self.set_http_response(200) |
| 99 | 215 |
| 100 with self.assertRaises(TypeError): | 216 with self.assertRaises(TypeError): |
| 101 self.service_connection.list_instance_groups() | 217 self.service_connection.list_instance_groups() |
| 102 | 218 |
| 103 response = self.service_connection.list_instance_groups(cluster_id='j-12
3') | 219 response = self.service_connection.list_instance_groups(cluster_id='j-12
3') |
| 104 | 220 |
| 105 self.assert_request_parameters({ | 221 self.assert_request_parameters({ |
| 106 'Action': 'ListInstanceGroups', | 222 'Action': 'ListInstanceGroups', |
| 107 'ClusterId': 'j-123', | 223 'ClusterId': 'j-123', |
| 108 'Version': '2009-03-31' | 224 'Version': '2009-03-31' |
| 109 }) | 225 }) |
| 110 | 226 |
| 227 self.assertTrue(isinstance(response, InstanceGroupList)) |
| 228 self.assertEqual(len(response.instancegroups), 2) |
| 229 self.assertTrue(isinstance(response.instancegroups[0], InstanceGroupInfo
)) |
| 230 self.assertEqual(response.instancegroups[0].id, 'ig-aaaaaaaaaaaaa') |
| 231 self.assertEqual(response.instancegroups[0].instancegrouptype, "MASTER") |
| 232 self.assertEqual(response.instancegroups[0].instancetype, "m1.large") |
| 233 self.assertEqual(response.instancegroups[0].market, "ON_DEMAND") |
| 234 self.assertEqual(response.instancegroups[0].name, "Master instance group
") |
| 235 self.assertEqual(response.instancegroups[0].requestedinstancecount, '1') |
| 236 self.assertEqual(response.instancegroups[0].runninginstancecount, '0') |
| 237 self.assertTrue(isinstance(response.instancegroups[0].status, ClusterSta
tus)) |
| 238 self.assertEqual(response.instancegroups[0].status.state, 'TERMINATED') |
| 239 # status.statechangereason is not parsed into an object |
| 240 #self.assertEqual(response.instancegroups[0].status.statechangereason.co
de, 'CLUSTER_TERMINATED') |
| 241 |
| 111 class TestListInstances(AWSMockServiceTestCase): | 242 class TestListInstances(AWSMockServiceTestCase): |
| 112 connection_class = EmrConnection | 243 connection_class = EmrConnection |
| 113 | 244 |
| 114 def default_body(self): | 245 def default_body(self): |
| 115 return """<ListInstancesOutput><Instances></Instances></ListInstancesOut
put>""" | 246 return """ |
| 247 <ListInstancesResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-
31"> |
| 248 <ListInstancesResult> |
| 249 <Instances> |
| 250 <member> |
| 251 <Id>ci-123456789abc</Id> |
| 252 <Status> |
| 253 <StateChangeReason> |
| 254 <Message>Cluster was terminated.</Message> |
| 255 <Code>CLUSTER_TERMINATED</Code> |
| 256 </StateChangeReason> |
| 257 <State>TERMINATED</State> |
| 258 <Timeline> |
| 259 <CreationDateTime>2014-01-24T01:21:26Z</CreationDateTime> |
| 260 <ReadyDateTime>2014-01-24T01:25:25Z</ReadyDateTime> |
| 261 <EndDateTime>2014-01-24T02:19:46Z</EndDateTime> |
| 262 </Timeline> |
| 263 </Status> |
| 264 <PrivateDnsName>ip-10-0-0-60.us-west-1.compute.internal</PrivateDnsName> |
| 265 <PublicIpAddress>54.0.0.1</PublicIpAddress> |
| 266 <PublicDnsName>ec2-54-0-0-1.us-west-1.compute.amazonaws.com</PublicDnsNa
me> |
| 267 <Ec2InstanceId>i-aaaaaaaa</Ec2InstanceId> |
| 268 <PrivateIpAddress>10.0.0.60</PrivateIpAddress> |
| 269 </member> |
| 270 <member> |
| 271 <Id>ci-123456789abd</Id> |
| 272 <Status> |
| 273 <StateChangeReason> |
| 274 <Message>Cluster was terminated.</Message> |
| 275 <Code>CLUSTER_TERMINATED</Code> |
| 276 </StateChangeReason> |
| 277 <State>TERMINATED</State> |
| 278 <Timeline> |
| 279 <CreationDateTime>2014-01-24T01:21:26Z</CreationDateTime> |
| 280 <ReadyDateTime>2014-01-24T01:25:25Z</ReadyDateTime> |
| 281 <EndDateTime>2014-01-24T02:19:46Z</EndDateTime> |
| 282 </Timeline> |
| 283 </Status> |
| 284 <PrivateDnsName>ip-10-0-0-61.us-west-1.compute.internal</PrivateDnsName> |
| 285 <PublicIpAddress>54.0.0.2</PublicIpAddress> |
| 286 <PublicDnsName>ec2-54-0-0-2.us-west-1.compute.amazonaws.com</PublicDnsNa
me> |
| 287 <Ec2InstanceId>i-aaaaaaab</Ec2InstanceId> |
| 288 <PrivateIpAddress>10.0.0.61</PrivateIpAddress> |
| 289 </member> |
| 290 <member> |
| 291 <Id>ci-123456789abe3</Id> |
| 292 <Status> |
| 293 <StateChangeReason> |
| 294 <Message>Cluster was terminated.</Message> |
| 295 <Code>CLUSTER_TERMINATED</Code> |
| 296 </StateChangeReason> |
| 297 <State>TERMINATED</State> |
| 298 <Timeline> |
| 299 <CreationDateTime>2014-01-24T01:21:33Z</CreationDateTime> |
| 300 <ReadyDateTime>2014-01-24T01:25:08Z</ReadyDateTime> |
| 301 <EndDateTime>2014-01-24T02:19:46Z</EndDateTime> |
| 302 </Timeline> |
| 303 </Status> |
| 304 <PrivateDnsName>ip-10-0-0-62.us-west-1.compute.internal</PrivateDnsName> |
| 305 <PublicIpAddress>54.0.0.3</PublicIpAddress> |
| 306 <PublicDnsName>ec2-54-0-0-3.us-west-1.compute.amazonaws.com</PublicDnsNa
me> |
| 307 <Ec2InstanceId>i-aaaaaaac</Ec2InstanceId> |
| 308 <PrivateIpAddress>10.0.0.62</PrivateIpAddress> |
| 309 </member> |
| 310 </Instances> |
| 311 </ListInstancesResult> |
| 312 <ResponseMetadata> |
| 313 <RequestId>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</RequestId> |
| 314 </ResponseMetadata> |
| 315 </ListInstancesResponse> |
| 316 """ |
| 116 | 317 |
| 117 def test_list_instances(self): | 318 def test_list_instances(self): |
| 118 self.set_http_response(200) | 319 self.set_http_response(200) |
| 119 | 320 |
| 120 with self.assertRaises(TypeError): | 321 with self.assertRaises(TypeError): |
| 121 self.service_connection.list_instances() | 322 self.service_connection.list_instances() |
| 122 | 323 |
| 123 response = self.service_connection.list_instances(cluster_id='j-123') | 324 response = self.service_connection.list_instances(cluster_id='j-123') |
| 325 self.assertTrue(isinstance(response, InstanceList)) |
| 326 self.assertEqual(len(response.instances), 3) |
| 327 self.assertTrue(isinstance(response.instances[0], InstanceInfo)) |
| 328 self.assertEqual(response.instances[0].ec2instanceid, 'i-aaaaaaaa') |
| 329 self.assertEqual(response.instances[0].id, 'ci-123456789abc') |
| 330 self.assertEqual(response.instances[0].privatednsname , 'ip-10-0-0-60.us
-west-1.compute.internal') |
| 331 self.assertEqual(response.instances[0].privateipaddress , '10.0.0.60') |
| 332 self.assertEqual(response.instances[0].publicdnsname , 'ec2-54-0-0-1.us-
west-1.compute.amazonaws.com') |
| 333 self.assertEqual(response.instances[0].publicipaddress , '54.0.0.1') |
| 334 |
| 124 | 335 |
| 125 self.assert_request_parameters({ | 336 self.assert_request_parameters({ |
| 126 'Action': 'ListInstances', | 337 'Action': 'ListInstances', |
| 127 'ClusterId': 'j-123', | 338 'ClusterId': 'j-123', |
| 128 'Version': '2009-03-31' | 339 'Version': '2009-03-31' |
| 129 }) | 340 }) |
| 130 | 341 |
| 131 def test_list_instances_with_group_id(self): | 342 def test_list_instances_with_group_id(self): |
| 132 self.set_http_response(200) | 343 self.set_http_response(200) |
| 133 response = self.service_connection.list_instances( | 344 response = self.service_connection.list_instances( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 155 'InstanceGroupTypeList.member.1': 'MASTER', | 366 'InstanceGroupTypeList.member.1': 'MASTER', |
| 156 'InstanceGroupTypeList.member.2': 'TASK', | 367 'InstanceGroupTypeList.member.2': 'TASK', |
| 157 'Version': '2009-03-31' | 368 'Version': '2009-03-31' |
| 158 }) | 369 }) |
| 159 | 370 |
| 160 | 371 |
| 161 class TestListSteps(AWSMockServiceTestCase): | 372 class TestListSteps(AWSMockServiceTestCase): |
| 162 connection_class = EmrConnection | 373 connection_class = EmrConnection |
| 163 | 374 |
| 164 def default_body(self): | 375 def default_body(self): |
| 165 return """<ListStepsOutput><Steps></Steps></ListStepsOutput>""" | 376 return """<ListStepsOutput><Steps><member><Name>Step 1</Name></member></
Steps></ListStepsOutput>""" |
| 166 | 377 |
| 167 def test_list_steps(self): | 378 def test_list_steps(self): |
| 168 self.set_http_response(200) | 379 self.set_http_response(200) |
| 169 | 380 |
| 170 with self.assertRaises(TypeError): | 381 with self.assertRaises(TypeError): |
| 171 self.service_connection.list_steps() | 382 self.service_connection.list_steps() |
| 172 | 383 |
| 173 response = self.service_connection.list_steps(cluster_id='j-123') | 384 response = self.service_connection.list_steps(cluster_id='j-123') |
| 174 | 385 |
| 175 self.assert_request_parameters({ | 386 self.assert_request_parameters({ |
| 176 'Action': 'ListSteps', | 387 'Action': 'ListSteps', |
| 177 'ClusterId': 'j-123', | 388 'ClusterId': 'j-123', |
| 178 'Version': '2009-03-31' | 389 'Version': '2009-03-31' |
| 179 }) | 390 }) |
| 391 self.assertTrue(isinstance(response, StepSummaryList)) |
| 392 self.assertEqual(response.steps[0].name, 'Step 1') |
| 180 | 393 |
| 181 def test_list_steps_with_states(self): | 394 def test_list_steps_with_states(self): |
| 182 self.set_http_response(200) | 395 self.set_http_response(200) |
| 183 response = self.service_connection.list_steps( | 396 response = self.service_connection.list_steps( |
| 184 cluster_id='j-123', step_states=[ | 397 cluster_id='j-123', step_states=[ |
| 185 'COMPLETED', | 398 'COMPLETED', |
| 186 'FAILED' | 399 'FAILED' |
| 187 ]) | 400 ]) |
| 188 | 401 |
| 189 self.assert_request_parameters({ | 402 self.assert_request_parameters({ |
| 190 'Action': 'ListSteps', | 403 'Action': 'ListSteps', |
| 191 'ClusterId': 'j-123', | 404 'ClusterId': 'j-123', |
| 192 'StepStateList.member.1': 'COMPLETED', | 405 'StepStateList.member.1': 'COMPLETED', |
| 193 'StepStateList.member.2': 'FAILED', | 406 'StepStateList.member.2': 'FAILED', |
| 194 'Version': '2009-03-31' | 407 'Version': '2009-03-31' |
| 195 }) | 408 }) |
| 196 | 409 self.assertTrue(isinstance(response, StepSummaryList)) |
| 410 self.assertEqual(response.steps[0].name, 'Step 1') |
| 197 | 411 |
| 198 class TestListBootstrapActions(AWSMockServiceTestCase): | 412 class TestListBootstrapActions(AWSMockServiceTestCase): |
| 199 connection_class = EmrConnection | 413 connection_class = EmrConnection |
| 200 | 414 |
| 201 def default_body(self): | 415 def default_body(self): |
| 202 return """<ListBootstrapActionsOutput></ListBootstrapActionsOutput>""" | 416 return """<ListBootstrapActionsOutput></ListBootstrapActionsOutput>""" |
| 203 | 417 |
| 204 def test_list_bootstrap_actions(self): | 418 def test_list_bootstrap_actions(self): |
| 205 self.set_http_response(200) | 419 self.set_http_response(200) |
| 206 | 420 |
| 207 with self.assertRaises(TypeError): | 421 with self.assertRaises(TypeError): |
| 208 self.service_connection.list_bootstrap_actions() | 422 self.service_connection.list_bootstrap_actions() |
| 209 | 423 |
| 210 response = self.service_connection.list_bootstrap_actions(cluster_id='j-
123') | 424 response = self.service_connection.list_bootstrap_actions(cluster_id='j-
123') |
| 211 | 425 |
| 212 self.assert_request_parameters({ | 426 self.assert_request_parameters({ |
| 213 'Action': 'ListBootstrapActions', | 427 'Action': 'ListBootstrapActions', |
| 214 'ClusterId': 'j-123', | 428 'ClusterId': 'j-123', |
| 215 'Version': '2009-03-31' | 429 'Version': '2009-03-31' |
| 216 }) | 430 }) |
| 217 | 431 |
| 218 | 432 |
| 219 class TestDescribeCluster(AWSMockServiceTestCase): | 433 class TestDescribeCluster(AWSMockServiceTestCase): |
| 220 connection_class = EmrConnection | 434 connection_class = EmrConnection |
| 221 | 435 |
| 222 def default_body(self): | 436 def default_body(self): |
| 223 return """<DescribeClusterOutput></DescribeClusterOutput>""" | 437 return """ |
| 438 <DescribeClusterResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-0
3-31"> |
| 439 <DescribeClusterResult> |
| 440 <Cluster> |
| 441 <Id>j-aaaaaaaaa</Id> |
| 442 <Tags/> |
| 443 <Ec2InstanceAttributes> |
| 444 <Ec2AvailabilityZone>us-west-1c</Ec2AvailabilityZone> |
| 445 <Ec2KeyName>my_secret_key</Ec2KeyName> |
| 446 </Ec2InstanceAttributes> |
| 447 <RunningAmiVersion>2.4.2</RunningAmiVersion> |
| 448 <VisibleToAllUsers>true</VisibleToAllUsers> |
| 449 <Status> |
| 450 <StateChangeReason> |
| 451 <Message>Terminated by user request</Message> |
| 452 <Code>USER_REQUEST</Code> |
| 453 </StateChangeReason> |
| 454 <State>TERMINATED</State> |
| 455 <Timeline> |
| 456 <CreationDateTime>2014-01-24T01:21:21Z</CreationDateTime> |
| 457 <ReadyDateTime>2014-01-24T01:25:26Z</ReadyDateTime> |
| 458 <EndDateTime>2014-01-24T02:19:46Z</EndDateTime> |
| 459 </Timeline> |
| 460 </Status> |
| 461 <AutoTerminate>false</AutoTerminate> |
| 462 <Name>test analytics</Name> |
| 463 <RequestedAmiVersion>2.4.2</RequestedAmiVersion> |
| 464 <Applications> |
| 465 <member> |
| 466 <Name>hadoop</Name> |
| 467 <Version>1.0.3</Version> |
| 468 </member> |
| 469 </Applications> |
| 470 <TerminationProtected>false</TerminationProtected> |
| 471 </Cluster> |
| 472 </DescribeClusterResult> |
| 473 <ResponseMetadata> |
| 474 <RequestId>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</RequestId> |
| 475 </ResponseMetadata> |
| 476 </DescribeClusterResponse> |
| 477 """ |
| 224 | 478 |
| 225 def test_describe_cluster(self): | 479 def test_describe_cluster(self): |
| 226 self.set_http_response(200) | 480 self.set_http_response(200) |
| 227 | 481 |
| 228 with self.assertRaises(TypeError): | 482 with self.assertRaises(TypeError): |
| 229 self.service_connection.describe_cluster() | 483 self.service_connection.describe_cluster() |
| 230 | 484 |
| 231 response = self.service_connection.describe_cluster(cluster_id='j-123') | 485 response = self.service_connection.describe_cluster(cluster_id='j-123') |
| 232 | 486 |
| 487 self.assertTrue(isinstance(response, Cluster)) |
| 488 self.assertEqual(response.id, 'j-aaaaaaaaa') |
| 489 self.assertEqual(response.runningamiversion, '2.4.2') |
| 490 self.assertEqual(response.visibletoallusers, 'true') |
| 491 self.assertEqual(response.autoterminate, 'false') |
| 492 self.assertEqual(response.name, 'test analytics') |
| 493 self.assertEqual(response.requestedamiversion, '2.4.2') |
| 494 self.assertEqual(response.terminationprotected, 'false') |
| 495 self.assertEqual(response.ec2instanceattributes.ec2availabilityzone, "us
-west-1c") |
| 496 self.assertEqual(response.ec2instanceattributes.ec2keyname, 'my_secret_k
ey') |
| 497 self.assertEqual(response.status.state, 'TERMINATED') |
| 498 self.assertEqual(response.applications[0].name, 'hadoop') |
| 499 self.assertEqual(response.applications[0].version, '1.0.3') |
| 500 |
| 233 self.assert_request_parameters({ | 501 self.assert_request_parameters({ |
| 234 'Action': 'DescribeCluster', | 502 'Action': 'DescribeCluster', |
| 235 'ClusterId': 'j-123', | 503 'ClusterId': 'j-123', |
| 236 'Version': '2009-03-31' | 504 'Version': '2009-03-31' |
| 237 }) | 505 }) |
| 238 | 506 |
| 239 | 507 |
| 240 class TestDescribeStep(AWSMockServiceTestCase): | 508 class TestDescribeStep(AWSMockServiceTestCase): |
| 241 connection_class = EmrConnection | 509 connection_class = EmrConnection |
| 242 | 510 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 response = self.service_connection.remove_tags('j-123', ['FirstKey', 'Se
condKey']) | 671 response = self.service_connection.remove_tags('j-123', ['FirstKey', 'Se
condKey']) |
| 404 | 672 |
| 405 self.assertTrue(response) | 673 self.assertTrue(response) |
| 406 self.assert_request_parameters({ | 674 self.assert_request_parameters({ |
| 407 'Action': 'RemoveTags', | 675 'Action': 'RemoveTags', |
| 408 'ResourceId': 'j-123', | 676 'ResourceId': 'j-123', |
| 409 'TagKeys.member.1': 'FirstKey', | 677 'TagKeys.member.1': 'FirstKey', |
| 410 'TagKeys.member.2': 'SecondKey', | 678 'TagKeys.member.2': 'SecondKey', |
| 411 'Version': '2009-03-31' | 679 'Version': '2009-03-31' |
| 412 }) | 680 }) |
| 681 |
| 682 class DescribeJobFlowsTestBase(AWSMockServiceTestCase): |
| 683 connection_class = EmrConnection |
| 684 |
| 685 def default_body(self): |
| 686 return """ |
| 687 <DescribeJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-
03-31"> |
| 688 <DescribeJobFlowsResult> |
| 689 <JobFlows> |
| 690 <member> |
| 691 <AmiVersion>2.4.2</AmiVersion> |
| 692 <ExecutionStatusDetail> |
| 693 <CreationDateTime>2014-01-24T01:21:21Z</CreationDateTime> |
| 694 <LastStateChangeReason>Terminated by user request</LastStateChangeReas
on> |
| 695 <StartDateTime>2014-01-24T01:25:26Z</StartDateTime> |
| 696 <ReadyDateTime>2014-01-24T01:25:26Z</ReadyDateTime> |
| 697 <State>TERMINATED</State> |
| 698 <EndDateTime>2014-01-24T02:19:46Z</EndDateTime> |
| 699 </ExecutionStatusDetail> |
| 700 <BootstrapActions/> |
| 701 <VisibleToAllUsers>true</VisibleToAllUsers> |
| 702 <SupportedProducts/> |
| 703 <Name>test analytics</Name> |
| 704 <JobFlowId>j-aaaaaa</JobFlowId> |
| 705 <Steps> |
| 706 <member> |
| 707 <ExecutionStatusDetail> |
| 708 <CreationDateTime>2014-01-24T01:21:21Z</CreationDateTime> |
| 709 <StartDateTime>2014-01-24T01:25:26Z</StartDateTime> |
| 710 <State>COMPLETED</State> |
| 711 <EndDateTime>2014-01-24T01:26:08Z</EndDateTime> |
| 712 </ExecutionStatusDetail> |
| 713 <StepConfig> |
| 714 <HadoopJarStep> |
| 715 <Args> |
| 716 <member>s3://us-west-1.elasticmapreduce/libs/hive/hive-script<
/member> |
| 717 <member>--base-path</member> |
| 718 <member>s3://us-west-1.elasticmapreduce/libs/hive/</member> |
| 719 <member>--install-hive</member> |
| 720 <member>--hive-versions</member> |
| 721 <member>0.11.0.1</member> |
| 722 </Args> |
| 723 <Jar>s3://us-west-1.elasticmapreduce/libs/script-runner/script-r
unner.jar</Jar> |
| 724 <Properties/> |
| 725 </HadoopJarStep> |
| 726 <Name>Setup hive</Name> |
| 727 <ActionOnFailure>TERMINATE_JOB_FLOW</ActionOnFailure> |
| 728 </StepConfig> |
| 729 </member> |
| 730 </Steps> |
| 731 <Instances> |
| 732 <Placement> |
| 733 <AvailabilityZone>us-west-1c</AvailabilityZone> |
| 734 </Placement> |
| 735 <MasterInstanceType>m1.large</MasterInstanceType> |
| 736 <Ec2KeyName>my_key</Ec2KeyName> |
| 737 <KeepJobFlowAliveWhenNoSteps>true</KeepJobFlowAliveWhenNoSteps> |
| 738 <InstanceGroups> |
| 739 <member> |
| 740 <CreationDateTime>2014-01-24T01:21:21Z</CreationDateTime> |
| 741 <InstanceRunningCount>0</InstanceRunningCount> |
| 742 <StartDateTime>2014-01-24T01:23:56Z</StartDateTime> |
| 743 <ReadyDateTime>2014-01-24T01:25:08Z</ReadyDateTime> |
| 744 <State>ENDED</State> |
| 745 <EndDateTime>2014-01-24T02:19:46Z</EndDateTime> |
| 746 <InstanceRequestCount>1</InstanceRequestCount> |
| 747 <InstanceType>m1.large</InstanceType> |
| 748 <LastStateChangeReason>Job flow terminated</LastStateChangeReason> |
| 749 <Market>ON_DEMAND</Market> |
| 750 <InstanceGroupId>ig-aaaaaa</InstanceGroupId> |
| 751 <InstanceRole>MASTER</InstanceRole> |
| 752 <Name>Master instance group</Name> |
| 753 </member> |
| 754 <member> |
| 755 <CreationDateTime>2014-01-24T01:21:21Z</CreationDateTime> |
| 756 <InstanceRunningCount>0</InstanceRunningCount> |
| 757 <StartDateTime>2014-01-24T01:25:26Z</StartDateTime> |
| 758 <ReadyDateTime>2014-01-24T01:25:26Z</ReadyDateTime> |
| 759 <State>ENDED</State> |
| 760 <EndDateTime>2014-01-24T02:19:46Z</EndDateTime> |
| 761 <InstanceRequestCount>2</InstanceRequestCount> |
| 762 <InstanceType>m1.large</InstanceType> |
| 763 <LastStateChangeReason>Job flow terminated</LastStateChangeReason> |
| 764 <Market>ON_DEMAND</Market> |
| 765 <InstanceGroupId>ig-aaaaab</InstanceGroupId> |
| 766 <InstanceRole>CORE</InstanceRole> |
| 767 <Name>Core instance group</Name> |
| 768 </member> |
| 769 </InstanceGroups> |
| 770 <SlaveInstanceType>m1.large</SlaveInstanceType> |
| 771 <MasterInstanceId>i-aaaaaa</MasterInstanceId> |
| 772 <HadoopVersion>1.0.3</HadoopVersion> |
| 773 <NormalizedInstanceHours>12</NormalizedInstanceHours> |
| 774 <MasterPublicDnsName>ec2-184-0-0-1.us-west-1.compute.amazonaws.com</Ma
sterPublicDnsName> |
| 775 <InstanceCount>3</InstanceCount> |
| 776 <TerminationProtected>false</TerminationProtected> |
| 777 </Instances> |
| 778 </member> |
| 779 </JobFlows> |
| 780 </DescribeJobFlowsResult> |
| 781 <ResponseMetadata> |
| 782 <RequestId>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</RequestId> |
| 783 </ResponseMetadata> |
| 784 </DescribeJobFlowsResponse> |
| 785 """ |
| 786 |
| 787 class TestDescribeJobFlows(DescribeJobFlowsTestBase): |
| 788 |
| 789 def test_describe_jobflows_response(self): |
| 790 self.set_http_response(200) |
| 791 |
| 792 response = self.service_connection.describe_jobflows() |
| 793 self.assertTrue(isinstance(response, list)) |
| 794 |
| 795 jf = response[0] |
| 796 self.assertTrue(isinstance(jf, JobFlow)) |
| 797 self.assertEqual(jf.amiversion, '2.4.2') |
| 798 self.assertEqual(jf.visibletoallusers, 'true') |
| 799 self.assertEqual(jf.name, 'test analytics') |
| 800 self.assertEqual(jf.jobflowid, 'j-aaaaaa') |
| 801 self.assertEqual(jf.ec2keyname, 'my_key') |
| 802 self.assertEqual(jf.masterinstancetype, 'm1.large') |
| 803 self.assertEqual(jf.availabilityzone, 'us-west-1c') |
| 804 self.assertEqual(jf.keepjobflowalivewhennosteps, 'true') |
| 805 self.assertEqual(jf.slaveinstancetype, 'm1.large') |
| 806 self.assertEqual(jf.masterinstanceid, 'i-aaaaaa') |
| 807 self.assertEqual(jf.hadoopversion, '1.0.3') |
| 808 self.assertEqual(jf.normalizedinstancehours, '12') |
| 809 self.assertEqual(jf.masterpublicdnsname, 'ec2-184-0-0-1.us-west-1.comput
e.amazonaws.com') |
| 810 self.assertEqual(jf.instancecount, '3') |
| 811 self.assertEqual(jf.terminationprotected, 'false') |
| 812 |
| 813 self.assertTrue(isinstance(jf.steps, list)) |
| 814 step = jf.steps[0] |
| 815 self.assertTrue(isinstance(step, Step)) |
| 816 self.assertEqual(step.jar, 's3://us-west-1.elasticmapreduce/libs/script-
runner/script-runner.jar') |
| 817 self.assertEqual(step.name, 'Setup hive') |
| 818 self.assertEqual(step.actiononfailure, 'TERMINATE_JOB_FLOW') |
| 819 |
| 820 self.assertTrue(isinstance(jf.instancegroups, list)) |
| 821 ig = jf.instancegroups[0] |
| 822 self.assertTrue(isinstance(ig, InstanceGroup)) |
| 823 self.assertEqual(ig.creationdatetime, '2014-01-24T01:21:21Z') |
| 824 self.assertEqual(ig.state, 'ENDED') |
| 825 self.assertEqual(ig.instancerequestcount, '1') |
| 826 self.assertEqual(ig.instancetype, 'm1.large') |
| 827 self.assertEqual(ig.laststatechangereason, 'Job flow terminated') |
| 828 self.assertEqual(ig.market, 'ON_DEMAND') |
| 829 self.assertEqual(ig.instancegroupid, 'ig-aaaaaa') |
| 830 self.assertEqual(ig.instancerole, 'MASTER') |
| 831 self.assertEqual(ig.name, 'Master instance group') |
| 832 |
| 833 def test_describe_jobflows_no_args(self): |
| 834 self.set_http_response(200) |
| 835 |
| 836 self.service_connection.describe_jobflows() |
| 837 |
| 838 self.assert_request_parameters({ |
| 839 'Action': 'DescribeJobFlows', |
| 840 }, ignore_params_values=['Version']) |
| 841 |
| 842 def test_describe_jobflows_filtered(self): |
| 843 self.set_http_response(200) |
| 844 |
| 845 now = datetime.now() |
| 846 a_bit_before = datetime.fromtimestamp(time() - 1000) |
| 847 |
| 848 self.service_connection.describe_jobflows(states=['WAITING', 'RUNNING'],
jobflow_ids=['j-aaaaaa', 'j-aaaaab'], created_after=a_bit_before, created_befor
e=now) |
| 849 self.assert_request_parameters({ |
| 850 'Action': 'DescribeJobFlows', |
| 851 'JobFlowIds.member.1': 'j-aaaaaa', |
| 852 'JobFlowIds.member.2': 'j-aaaaab', |
| 853 'JobFlowStates.member.1': 'WAITING', |
| 854 'JobFlowStates.member.2': 'RUNNING', |
| 855 'CreatedAfter': a_bit_before.strftime(boto.utils.ISO8601), |
| 856 'CreatedBefore': now.strftime(boto.utils.ISO8601), |
| 857 }, ignore_params_values=['Version']) |
| 858 |
| 859 class TestDescribeJobFlow(DescribeJobFlowsTestBase): |
| 860 def test_describe_jobflow(self): |
| 861 self.set_http_response(200) |
| 862 |
| 863 response = self.service_connection.describe_jobflow('j-aaaaaa') |
| 864 self.assertTrue(isinstance(response, JobFlow)) |
| 865 self.assert_request_parameters({ |
| 866 'Action': 'DescribeJobFlows', |
| 867 'JobFlowIds.member.1': 'j-aaaaaa', |
| 868 }, ignore_params_values=['Version']) |
| OLD | NEW |