diff --git a/moto/iot/models.py b/moto/iot/models.py index 51a23b6c6..2e9979bda 100644 --- a/moto/iot/models.py +++ b/moto/iot/models.py @@ -842,6 +842,17 @@ class IoTBackend(BaseBackend): return thing_group.thing_group_name, thing_group.arn, thing_group.thing_group_id def delete_thing_group(self, thing_group_name, expected_version): + child_groups = [ + thing_group + for _, thing_group in self.thing_groups.items() + if thing_group.parent_group_name == thing_group_name + ] + if len(child_groups) > 0: + raise InvalidRequestException( + " Cannot delete thing group : " + + thing_group_name + + " when there are still child groups attached to it" + ) thing_group = self.describe_thing_group(thing_group_name) del self.thing_groups[thing_group.arn] diff --git a/tests/test_iot/test_iot.py b/tests/test_iot/test_iot.py index 2f43de5b9..58a820fee 100644 --- a/tests/test_iot/test_iot.py +++ b/tests/test_iot/test_iot.py @@ -756,6 +756,47 @@ def test_delete_principal_thing(): client.delete_certificate(certificateId=cert_id) +@mock_iot +def test_delete_thing_group(): + client = boto3.client("iot", region_name="ap-northeast-1") + group_name_1a = "my-group-name-1a" + group_name_2a = "my-group-name-2a" + # --1a + # |--2a + + # create thing groups tree + # 1 + thing_group1a = client.create_thing_group(thingGroupName=group_name_1a) + thing_group1a.should.have.key("thingGroupName").which.should.equal(group_name_1a) + thing_group1a.should.have.key("thingGroupArn") + # 2 + thing_group2a = client.create_thing_group( + thingGroupName=group_name_2a, parentGroupName=group_name_1a + ) + thing_group2a.should.have.key("thingGroupName").which.should.equal(group_name_2a) + thing_group2a.should.have.key("thingGroupArn") + + # delete group with child + try: + client.delete_thing_group(thingGroupName=group_name_1a) + except client.exceptions.InvalidRequestException as exc: + error_code = exc.response["Error"]["Code"] + error_code.should.equal("InvalidRequestException") + else: + raise Exception("Should have raised error") + + # delete child group + client.delete_thing_group(thingGroupName=group_name_2a) + res = client.list_thing_groups() + res.should.have.key("thingGroups").which.should.have.length_of(1) + res["thingGroups"].should_not.have.key(group_name_2a) + + # now that there is no child group, we can delete the previus group safely + client.delete_thing_group(thingGroupName=group_name_1a) + res = client.list_thing_groups() + res.should.have.key("thingGroups").which.should.have.length_of(0) + + @mock_iot def test_describe_thing_group_metadata_hierarchy(): client = boto3.client("iot", region_name="ap-northeast-1")