Add boto tests for idempotent RunInstances calls
The EC2 API supports providing a unique client token to
the RunInstances call to ensure idempotency. In other words,
multiple RunInstances call with the same client token will
not start up multiple instances.
This adds a test for this condition, including ensuring that
a new instance is spawned when a client token is re-used
after the original instance linked to it has been terminated.
Fixes bug #1202404
Change-Id: Ia11eb9ac082a623a1ad03b89fb6dbf7cad9f9c99
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 89891d2..5062196 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -88,6 +88,53 @@
image["image_id"])
@attr(type='smoke')
+ def test_run_idempotent_instances(self):
+ # EC2 run instances idempotently
+
+ def _run_instance(client_token):
+ reservation = self.ec2_client.run_instances(
+ image_id=self.images["ami"]["image_id"],
+ kernel_id=self.images["aki"]["image_id"],
+ ramdisk_id=self.images["ari"]["image_id"],
+ instance_type=self.instance_type,
+ client_token=client_token)
+ rcuk = self.addResourceCleanUp(self.destroy_reservation,
+ reservation)
+ return (reservation, rcuk)
+
+ def _terminate_reservation(reservation, rcuk):
+ for instance in reservation.instances:
+ instance.terminate()
+ self.cancelResourceCleanUp(rcuk)
+
+ reservation_1, rcuk_1 = _run_instance('token_1')
+ reservation_2, rcuk_2 = _run_instance('token_2')
+ reservation_1a, rcuk_1a = _run_instance('token_1')
+
+ self.assertIsNotNone(reservation_1)
+ self.assertIsNotNone(reservation_2)
+ self.assertIsNotNone(reservation_1a)
+
+ # same reservation for token_1
+ self.assertEqual(reservation_1.id, reservation_1a.id)
+
+ # Cancel cleanup -- since it's a duplicate, it's
+ # handled by rcuk1
+ self.cancelResourceCleanUp(rcuk_1a)
+
+ _terminate_reservation(reservation_1, rcuk_1)
+ _terminate_reservation(reservation_2, rcuk_2)
+
+ reservation_3, rcuk_3 = _run_instance('token_1')
+ self.assertIsNotNone(reservation_3)
+
+ # make sure we don't get the old reservation back
+ self.assertNotEqual(reservation_1.id, reservation_3.id)
+
+ # clean up
+ _terminate_reservation(reservation_3, rcuk_3)
+
+ @attr(type='smoke')
def test_run_stop_terminate_instance(self):
# EC2 run, stop and terminate instance
image_ami = self.ec2_client.get_image(self.images["ami"]