From 46f9430bdd454faba1427dbc8f59a53098789050 Mon Sep 17 00:00:00 2001 From: Steve Pulec Date: Mon, 8 Jul 2013 22:20:55 -0400 Subject: [PATCH] Fix bug with modifying original reservations --- moto/ec2/models.py | 16 ++++++++++------ moto/ec2/responses/instances.py | 2 +- tests/test_ec2/test_instances.py | 4 ++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/moto/ec2/models.py b/moto/ec2/models.py index 6a48c453..1dac5e3b 100644 --- a/moto/ec2/models.py +++ b/moto/ec2/models.py @@ -129,23 +129,27 @@ class InstanceBackend(object): associated with the given instance_ids. """ reservations = [] - for reservation in self.reservations.values(): + for reservation in self.all_reservations(make_copy=True): reservation_instance_ids = [instance.id for instance in reservation.instances] matching_reservation = any(instance_id in reservation_instance_ids for instance_id in instance_ids) if matching_reservation: # We need to make a copy of the reservation because we have to modify the # instances to limit to those requested - reservation_copy = copy.deepcopy(reservation) - reservation_copy.instances = [instance for instance in reservation_copy.instances if instance.id in instance_ids] - reservations.append(reservation_copy) + reservation.instances = [instance for instance in reservation.instances if instance.id in instance_ids] + reservations.append(reservation) found_instance_ids = [instance.id for reservation in reservations for instance in reservation.instances] if len(found_instance_ids) != len(instance_ids): invalid_id = list(set(instance_ids).difference(set(found_instance_ids)))[0] raise InvalidIdError(invalid_id) return reservations - def all_reservations(self): - return self.reservations.values() + def all_reservations(self, make_copy=False): + if make_copy: + # Return copies so that other functions can modify them with changing + # the originals + return [copy.deepcopy(reservation) for reservation in self.reservations.values()] + else: + return [reservation for reservation in self.reservations.values()] class TagBackend(object): diff --git a/moto/ec2/responses/instances.py b/moto/ec2/responses/instances.py index 388fb844..1b6097a7 100644 --- a/moto/ec2/responses/instances.py +++ b/moto/ec2/responses/instances.py @@ -16,7 +16,7 @@ class InstanceResponse(object): template = Template(EC2_INVALID_INSTANCE_ID) return template.render(instance_id=exc.instance_id), dict(status=400) else: - reservations = ec2_backend.all_reservations() + reservations = ec2_backend.all_reservations(make_copy=True) filter_dict = filters_from_querystring(self.querystring) reservations = filter_reservations(reservations, filter_dict) diff --git a/tests/test_ec2/test_instances.py b/tests/test_ec2/test_instances.py index 7176566b..691e7908 100644 --- a/tests/test_ec2/test_instances.py +++ b/tests/test_ec2/test_instances.py @@ -96,6 +96,10 @@ def test_get_instances_filtering_by_state(): instance_ids = [instance.id for instance in reservations[0].instances] instance_ids.should.equal([instance2.id]) + # get_all_instances should still return all 3 + reservations = conn.get_all_instances() + reservations[0].instances.should.have.length_of(3) + conn.get_all_instances.when.called_with(filters={'not-implemented-filter': 'foobar'}).should.throw(NotImplementedError)