OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 from tests.unit import unittest |
| 3 from tests.unit import AWSMockServiceTestCase |
| 4 |
| 5 from boto.ec2.connection import EC2Connection |
| 6 |
| 7 |
| 8 class TestEC2ConnectionBase(AWSMockServiceTestCase): |
| 9 connection_class = EC2Connection |
| 10 |
| 11 def setUp(self): |
| 12 super(TestEC2ConnectionBase, self).setUp() |
| 13 self.ec2 = self.service_connection |
| 14 |
| 15 |
| 16 class TestReservedInstanceOfferings(TestEC2ConnectionBase): |
| 17 |
| 18 def default_body(self): |
| 19 return """ |
| 20 <DescribeReservedInstancesOfferingsResponse> |
| 21 <requestId>d3253568-edcf-4897-9a3d-fb28e0b3fa38</requestId> |
| 22 <reservedInstancesOfferingsSet> |
| 23 <item> |
| 24 <reservedInstancesOfferingId>2964d1bf71d8</reservedInsta
ncesOfferingId> |
| 25 <instanceType>c1.medium</instanceType> |
| 26 <availabilityZone>us-east-1c</availabilityZone> |
| 27 <duration>94608000</duration> |
| 28 <fixedPrice>775.0</fixedPrice> |
| 29 <usagePrice>0.0</usagePrice> |
| 30 <productDescription>product description</productDescript
ion> |
| 31 <instanceTenancy>default</instanceTenancy> |
| 32 <currencyCode>USD</currencyCode> |
| 33 <offeringType>Heavy Utilization</offeringType> |
| 34 <recurringCharges> |
| 35 <item> |
| 36 <frequency>Hourly</frequency> |
| 37 <amount>0.095</amount> |
| 38 </item> |
| 39 </recurringCharges> |
| 40 <marketplace>false</marketplace> |
| 41 <pricingDetailsSet> |
| 42 <item> |
| 43 <price>0.045</price> |
| 44 <count>1</count> |
| 45 </item> |
| 46 </pricingDetailsSet> |
| 47 </item> |
| 48 <item> |
| 49 <reservedInstancesOfferingId>2dce26e46889</reservedInsta
ncesOfferingId> |
| 50 <instanceType>c1.medium</instanceType> |
| 51 <availabilityZone>us-east-1c</availabilityZone> |
| 52 <duration>94608000</duration> |
| 53 <fixedPrice>775.0</fixedPrice> |
| 54 <usagePrice>0.0</usagePrice> |
| 55 <productDescription>Linux/UNIX</productDescription> |
| 56 <instanceTenancy>default</instanceTenancy> |
| 57 <currencyCode>USD</currencyCode> |
| 58 <offeringType>Heavy Utilization</offeringType> |
| 59 <recurringCharges> |
| 60 <item> |
| 61 <frequency>Hourly</frequency> |
| 62 <amount>0.035</amount> |
| 63 </item> |
| 64 </recurringCharges> |
| 65 <marketplace>false</marketplace> |
| 66 <pricingDetailsSet/> |
| 67 </item> |
| 68 </reservedInstancesOfferingsSet> |
| 69 <nextToken>next_token</nextToken> |
| 70 </DescribeReservedInstancesOfferingsResponse> |
| 71 """ |
| 72 |
| 73 def test_get_reserved_instance_offerings(self): |
| 74 self.set_http_response(status_code=200) |
| 75 response = self.ec2.get_all_reserved_instances_offerings() |
| 76 self.assertEqual(len(response), 2) |
| 77 instance = response[0] |
| 78 self.assertEqual(instance.id, '2964d1bf71d8') |
| 79 self.assertEqual(instance.instance_type, 'c1.medium') |
| 80 self.assertEqual(instance.availability_zone, 'us-east-1c') |
| 81 self.assertEqual(instance.duration, 94608000) |
| 82 self.assertEqual(instance.fixed_price, '775.0') |
| 83 self.assertEqual(instance.usage_price, '0.0') |
| 84 self.assertEqual(instance.description, 'product description') |
| 85 self.assertEqual(instance.instance_tenancy, 'default') |
| 86 self.assertEqual(instance.currency_code, 'USD') |
| 87 self.assertEqual(instance.offering_type, 'Heavy Utilization') |
| 88 self.assertEqual(len(instance.recurring_charges), 1) |
| 89 self.assertEqual(instance.recurring_charges[0].frequency, 'Hourly') |
| 90 self.assertEqual(instance.recurring_charges[0].amount, '0.095') |
| 91 self.assertEqual(len(instance.pricing_details), 1) |
| 92 self.assertEqual(instance.pricing_details[0].price, '0.045') |
| 93 self.assertEqual(instance.pricing_details[0].count, '1') |
| 94 |
| 95 def test_get_reserved_instance_offerings_params(self): |
| 96 self.set_http_response(status_code=200) |
| 97 self.ec2.get_all_reserved_instances_offerings( |
| 98 reserved_instances_offering_ids=['id1','id2'], |
| 99 instance_type='t1.micro', |
| 100 availability_zone='us-east-1', |
| 101 product_description='description', |
| 102 instance_tenancy='dedicated', |
| 103 offering_type='offering_type', |
| 104 include_marketplace=False, |
| 105 min_duration=100, |
| 106 max_duration=1000, |
| 107 max_instance_count=1, |
| 108 next_token='next_token', |
| 109 max_results=10 |
| 110 ) |
| 111 self.assert_request_parameters({ |
| 112 'Action': 'DescribeReservedInstancesOfferings', |
| 113 'ReservedInstancesOfferingId.1': 'id1', |
| 114 'ReservedInstancesOfferingId.2': 'id2', |
| 115 'InstanceType': 't1.micro', |
| 116 'AvailabilityZone': 'us-east-1', |
| 117 'ProductDescription': 'description', |
| 118 'InstanceTenancy': 'dedicated', |
| 119 'OfferingType': 'offering_type', |
| 120 'IncludeMarketplace': 'false', |
| 121 'MinDuration': '100', |
| 122 'MaxDuration': '1000', |
| 123 'MaxInstanceCount': '1', |
| 124 'NextToken': 'next_token', |
| 125 'MaxResults': '10',}, |
| 126 ignore_params_values=['AWSAccessKeyId', 'SignatureMethod', |
| 127 'SignatureVersion', 'Timestamp', 'Version']) |
| 128 |
| 129 |
| 130 class TestPurchaseReservedInstanceOffering(TestEC2ConnectionBase): |
| 131 def default_body(self): |
| 132 return """<PurchaseReservedInstancesOffering />""" |
| 133 |
| 134 def test_serialized_api_args(self): |
| 135 self.set_http_response(status_code=200) |
| 136 response = self.ec2.purchase_reserved_instance_offering( |
| 137 'offering_id', 1, (100.0, 'USD')) |
| 138 self.assert_request_parameters({ |
| 139 'Action': 'PurchaseReservedInstancesOffering', |
| 140 'InstanceCount': 1, |
| 141 'ReservedInstancesOfferingId': 'offering_id', |
| 142 'LimitPrice.Amount': '100.0', |
| 143 'LimitPrice.CurrencyCode': 'USD',}, |
| 144 ignore_params_values=['AWSAccessKeyId', 'SignatureMethod', |
| 145 'SignatureVersion', 'Timestamp', |
| 146 'Version']) |
| 147 |
| 148 |
| 149 class TestCancelReservedInstancesListing(TestEC2ConnectionBase): |
| 150 def default_body(self): |
| 151 return """ |
| 152 <CancelReservedInstancesListingResponse> |
| 153 <requestId>request_id</requestId> |
| 154 <reservedInstancesListingsSet> |
| 155 <item> |
| 156 <reservedInstancesListingId>listing_id</reservedInstance
sListingId> |
| 157 <reservedInstancesId>instance_id</reservedInstancesId> |
| 158 <createDate>2012-07-12T16:55:28.000Z</createDate> |
| 159 <updateDate>2012-07-12T16:55:28.000Z</updateDate> |
| 160 <status>cancelled</status> |
| 161 <statusMessage>CANCELLED</statusMessage> |
| 162 <instanceCounts> |
| 163 <item> |
| 164 <state>Available</state> |
| 165 <instanceCount>0</instanceCount> |
| 166 </item> |
| 167 <item> |
| 168 <state>Sold</state> |
| 169 <instanceCount>0</instanceCount> |
| 170 </item> |
| 171 <item> |
| 172 <state>Cancelled</state> |
| 173 <instanceCount>1</instanceCount> |
| 174 </item> |
| 175 <item> |
| 176 <state>Pending</state> |
| 177 <instanceCount>0</instanceCount> |
| 178 </item> |
| 179 </instanceCounts> |
| 180 <priceSchedules> |
| 181 <item> |
| 182 <term>5</term> |
| 183 <price>166.64</price> |
| 184 <currencyCode>USD</currencyCode> |
| 185 <active>false</active> |
| 186 </item> |
| 187 <item> |
| 188 <term>4</term> |
| 189 <price>133.32</price> |
| 190 <currencyCode>USD</currencyCode> |
| 191 <active>false</active> |
| 192 </item> |
| 193 <item> |
| 194 <term>3</term> |
| 195 <price>99.99</price> |
| 196 <currencyCode>USD</currencyCode> |
| 197 <active>false</active> |
| 198 </item> |
| 199 <item> |
| 200 <term>2</term> |
| 201 <price>66.66</price> |
| 202 <currencyCode>USD</currencyCode> |
| 203 <active>false</active> |
| 204 </item> |
| 205 <item> |
| 206 <term>1</term> |
| 207 <price>33.33</price> |
| 208 <currencyCode>USD</currencyCode> |
| 209 <active>false</active> |
| 210 </item> |
| 211 </priceSchedules> |
| 212 <tagSet/> |
| 213 <clientToken>XqJIt1342112125076</clientToken> |
| 214 </item> |
| 215 </reservedInstancesListingsSet> |
| 216 </CancelReservedInstancesListingResponse> |
| 217 """ |
| 218 |
| 219 def test_reserved_instances_listing(self): |
| 220 self.set_http_response(status_code=200) |
| 221 response = self.ec2.cancel_reserved_instances_listing() |
| 222 self.assertEqual(len(response), 1) |
| 223 cancellation = response[0] |
| 224 self.assertEqual(cancellation.status, 'cancelled') |
| 225 self.assertEqual(cancellation.status_message, 'CANCELLED') |
| 226 self.assertEqual(len(cancellation.instance_counts), 4) |
| 227 first = cancellation.instance_counts[0] |
| 228 self.assertEqual(first.state, 'Available') |
| 229 self.assertEqual(first.instance_count, 0) |
| 230 self.assertEqual(len(cancellation.price_schedules), 5) |
| 231 schedule = cancellation.price_schedules[0] |
| 232 self.assertEqual(schedule.term, 5) |
| 233 self.assertEqual(schedule.price, '166.64') |
| 234 self.assertEqual(schedule.currency_code, 'USD') |
| 235 self.assertEqual(schedule.active, False) |
| 236 |
| 237 |
| 238 class TestCreateReservedInstancesListing(TestEC2ConnectionBase): |
| 239 def default_body(self): |
| 240 return """ |
| 241 <CreateReservedInstancesListingResponse> |
| 242 <requestId>request_id</requestId> |
| 243 <reservedInstancesListingsSet> |
| 244 <item> |
| 245 <reservedInstancesListingId>listing_id</reservedInstance
sListingId> |
| 246 <reservedInstancesId>instance_id</reservedInstancesId> |
| 247 <createDate>2012-07-17T17:11:09.449Z</createDate> |
| 248 <updateDate>2012-07-17T17:11:09.468Z</updateDate> |
| 249 <status>active</status> |
| 250 <statusMessage>ACTIVE</statusMessage> |
| 251 <instanceCounts> |
| 252 <item> |
| 253 <state>Available</state> |
| 254 <instanceCount>1</instanceCount> |
| 255 </item> |
| 256 <item> |
| 257 <state>Sold</state> |
| 258 <instanceCount>0</instanceCount> |
| 259 </item> |
| 260 <item> |
| 261 <state>Cancelled</state> |
| 262 <instanceCount>0</instanceCount> |
| 263 </item> |
| 264 <item> |
| 265 <state>Pending</state> |
| 266 <instanceCount>0</instanceCount> |
| 267 </item> |
| 268 </instanceCounts> |
| 269 <priceSchedules> |
| 270 <item> |
| 271 <term>11</term> |
| 272 <price>2.5</price> |
| 273 <currencyCode>USD</currencyCode> |
| 274 <active>true</active> |
| 275 </item> |
| 276 <item> |
| 277 <term>10</term> |
| 278 <price>2.5</price> |
| 279 <currencyCode>USD</currencyCode> |
| 280 <active>false</active> |
| 281 </item> |
| 282 <item> |
| 283 <term>9</term> |
| 284 <price>2.5</price> |
| 285 <currencyCode>USD</currencyCode> |
| 286 <active>false</active> |
| 287 </item> |
| 288 <item> |
| 289 <term>8</term> |
| 290 <price>2.0</price> |
| 291 <currencyCode>USD</currencyCode> |
| 292 <active>false</active> |
| 293 </item> |
| 294 <item> |
| 295 <term>7</term> |
| 296 <price>2.0</price> |
| 297 <currencyCode>USD</currencyCode> |
| 298 <active>false</active> |
| 299 </item> |
| 300 <item> |
| 301 <term>6</term> |
| 302 <price>2.0</price> |
| 303 <currencyCode>USD</currencyCode> |
| 304 <active>false</active> |
| 305 </item> |
| 306 <item> |
| 307 <term>5</term> |
| 308 <price>1.5</price> |
| 309 <currencyCode>USD</currencyCode> |
| 310 <active>false</active> |
| 311 </item> |
| 312 <item> |
| 313 <term>4</term> |
| 314 <price>1.5</price> |
| 315 <currencyCode>USD</currencyCode> |
| 316 <active>false</active> |
| 317 </item> |
| 318 <item> |
| 319 <term>3</term> |
| 320 <price>0.7</price> |
| 321 <currencyCode>USD</currencyCode> |
| 322 <active>false</active> |
| 323 </item> |
| 324 <item> |
| 325 <term>2</term> |
| 326 <price>0.7</price> |
| 327 <currencyCode>USD</currencyCode> |
| 328 <active>false</active> |
| 329 </item> |
| 330 <item> |
| 331 <term>1</term> |
| 332 <price>0.1</price> |
| 333 <currencyCode>USD</currencyCode> |
| 334 <active>false</active> |
| 335 </item> |
| 336 </priceSchedules> |
| 337 <tagSet/> |
| 338 <clientToken>myIdempToken1</clientToken> |
| 339 </item> |
| 340 </reservedInstancesListingsSet> |
| 341 </CreateReservedInstancesListingResponse> |
| 342 """ |
| 343 |
| 344 def test_create_reserved_instances_listing(self): |
| 345 self.set_http_response(status_code=200) |
| 346 response = self.ec2.create_reserved_instances_listing( |
| 347 'instance_id', 1, [('2.5', 11), ('2.0', 8)], 'client_token') |
| 348 self.assertEqual(len(response), 1) |
| 349 cancellation = response[0] |
| 350 self.assertEqual(cancellation.status, 'active') |
| 351 self.assertEqual(cancellation.status_message, 'ACTIVE') |
| 352 self.assertEqual(len(cancellation.instance_counts), 4) |
| 353 first = cancellation.instance_counts[0] |
| 354 self.assertEqual(first.state, 'Available') |
| 355 self.assertEqual(first.instance_count, 1) |
| 356 self.assertEqual(len(cancellation.price_schedules), 11) |
| 357 schedule = cancellation.price_schedules[0] |
| 358 self.assertEqual(schedule.term, 11) |
| 359 self.assertEqual(schedule.price, '2.5') |
| 360 self.assertEqual(schedule.currency_code, 'USD') |
| 361 self.assertEqual(schedule.active, True) |
| 362 |
| 363 self.assert_request_parameters({ |
| 364 'Action': 'CreateReservedInstancesListing', |
| 365 'ReservedInstancesId': 'instance_id', |
| 366 'InstanceCount': '1', |
| 367 'ClientToken': 'client_token', |
| 368 'PriceSchedules.0.Price': '2.5', |
| 369 'PriceSchedules.0.Term': '11', |
| 370 'PriceSchedules.1.Price': '2.0', |
| 371 'PriceSchedules.1.Term': '8',}, |
| 372 ignore_params_values=['AWSAccessKeyId', 'SignatureMethod', |
| 373 'SignatureVersion', 'Timestamp', |
| 374 'Version']) |
| 375 |
| 376 |
| 377 class TestDescribeSpotInstanceRequests(TestEC2ConnectionBase): |
| 378 def default_body(self): |
| 379 return """ |
| 380 <DescribeSpotInstanceRequestsResponse> |
| 381 <requestId>requestid</requestId> |
| 382 <spotInstanceRequestSet> |
| 383 <item> |
| 384 <spotInstanceRequestId>sir-id</spotInstanceRequestId> |
| 385 <spotPrice>0.003000</spotPrice> |
| 386 <type>one-time</type> |
| 387 <state>active</state> |
| 388 <status> |
| 389 <code>fulfilled</code> |
| 390 <updateTime>2012-10-19T18:09:26.000Z</updateTime> |
| 391 <message>Your Spot request is fulfilled.</message> |
| 392 </status> |
| 393 <launchGroup>mylaunchgroup</launchGroup> |
| 394 <launchSpecification> |
| 395 <imageId>ami-id</imageId> |
| 396 <keyName>mykeypair</keyName> |
| 397 <groupSet> |
| 398 <item> |
| 399 <groupId>sg-id</groupId> |
| 400 <groupName>groupname</groupName> |
| 401 </item> |
| 402 </groupSet> |
| 403 <instanceType>t1.micro</instanceType> |
| 404 <monitoring> |
| 405 <enabled>false</enabled> |
| 406 </monitoring> |
| 407 </launchSpecification> |
| 408 <instanceId>i-id</instanceId> |
| 409 <createTime>2012-10-19T18:07:05.000Z</createTime> |
| 410 <productDescription>Linux/UNIX</productDescription> |
| 411 <launchedAvailabilityZone>us-east-1d</launchedAvailabilityZo
ne> |
| 412 </item> |
| 413 </spotInstanceRequestSet> |
| 414 </DescribeSpotInstanceRequestsResponse> |
| 415 """ |
| 416 |
| 417 def test_describe_spot_instance_requets(self): |
| 418 self.set_http_response(status_code=200) |
| 419 response = self.ec2.get_all_spot_instance_requests() |
| 420 self.assertEqual(len(response), 1) |
| 421 spotrequest = response[0] |
| 422 self.assertEqual(spotrequest.id, 'sir-id') |
| 423 self.assertEqual(spotrequest.price, 0.003) |
| 424 self.assertEqual(spotrequest.type, 'one-time') |
| 425 self.assertEqual(spotrequest.state, 'active') |
| 426 self.assertEqual(spotrequest.fault, None) |
| 427 self.assertEqual(spotrequest.valid_from, None) |
| 428 self.assertEqual(spotrequest.valid_until, None) |
| 429 self.assertEqual(spotrequest.launch_group, 'mylaunchgroup') |
| 430 self.assertEqual(spotrequest.launched_availability_zone, 'us-east-1d') |
| 431 self.assertEqual(spotrequest.product_description, 'Linux/UNIX') |
| 432 self.assertEqual(spotrequest.availability_zone_group, None) |
| 433 self.assertEqual(spotrequest.create_time, |
| 434 '2012-10-19T18:07:05.000Z') |
| 435 self.assertEqual(spotrequest.instance_id, 'i-id') |
| 436 launch_spec = spotrequest.launch_specification |
| 437 self.assertEqual(launch_spec.key_name, 'mykeypair') |
| 438 self.assertEqual(launch_spec.instance_type, 't1.micro') |
| 439 self.assertEqual(launch_spec.image_id, 'ami-id') |
| 440 self.assertEqual(launch_spec.placement, None) |
| 441 self.assertEqual(launch_spec.kernel, None) |
| 442 self.assertEqual(launch_spec.ramdisk, None) |
| 443 self.assertEqual(launch_spec.monitored, False) |
| 444 self.assertEqual(launch_spec.subnet_id, None) |
| 445 self.assertEqual(launch_spec.block_device_mapping, None) |
| 446 self.assertEqual(launch_spec.instance_profile, None) |
| 447 self.assertEqual(launch_spec.ebs_optimized, False) |
| 448 status = spotrequest.status |
| 449 self.assertEqual(status.code, 'fulfilled') |
| 450 self.assertEqual(status.update_time, '2012-10-19T18:09:26.000Z') |
| 451 self.assertEqual(status.message, 'Your Spot request is fulfilled.') |
| 452 |
| 453 |
| 454 class TestCopySnapshot(TestEC2ConnectionBase): |
| 455 def default_body(self): |
| 456 return """ |
| 457 <CopySnapshotResponse xmlns="http://ec2.amazonaws.com/doc/2012-12-01/"> |
| 458 <requestId>request_id</requestId> |
| 459 <snapshotId>snap-copied-id</snapshotId> |
| 460 </CopySnapshotResponse> |
| 461 """ |
| 462 |
| 463 def test_copy_snapshot(self): |
| 464 self.set_http_response(status_code=200) |
| 465 snapshot_id = self.ec2.copy_snapshot('us-west-2', 'snap-id', |
| 466 'description') |
| 467 self.assertEqual(snapshot_id, 'snap-copied-id') |
| 468 |
| 469 self.assert_request_parameters({ |
| 470 'Action': 'CopySnapshot', |
| 471 'Description': 'description', |
| 472 'SourceRegion': 'us-west-2', |
| 473 'SourceSnapshotId': 'snap-id'}, |
| 474 ignore_params_values=['AWSAccessKeyId', 'SignatureMethod', |
| 475 'SignatureVersion', 'Timestamp', |
| 476 'Version']) |
| 477 |
| 478 |
| 479 if __name__ == '__main__': |
| 480 unittest.main() |
OLD | NEW |