from __future__ import unicode_literals import json import sure # noqa import boto3 from moto import mock_iot from botocore.exceptions import ClientError from nose.tools import assert_raises @mock_iot def test_things(): client = boto3.client("iot", region_name="ap-northeast-1") name = "my-thing" type_name = "my-type-name" # thing type thing_type = client.create_thing_type(thingTypeName=type_name) thing_type.should.have.key("thingTypeName").which.should.equal(type_name) thing_type.should.have.key("thingTypeArn") res = client.list_thing_types() res.should.have.key("thingTypes").which.should.have.length_of(1) for thing_type in res["thingTypes"]: thing_type.should.have.key("thingTypeName").which.should_not.be.none thing_type = client.describe_thing_type(thingTypeName=type_name) thing_type.should.have.key("thingTypeName").which.should.equal(type_name) thing_type.should.have.key("thingTypeProperties") thing_type.should.have.key("thingTypeMetadata") # thing thing = client.create_thing(thingName=name, thingTypeName=type_name) thing.should.have.key("thingName").which.should.equal(name) thing.should.have.key("thingArn") res = client.list_things() res.should.have.key("things").which.should.have.length_of(1) for thing in res["things"]: thing.should.have.key("thingName").which.should_not.be.none thing.should.have.key("thingArn").which.should_not.be.none thing = client.update_thing( thingName=name, attributePayload={"attributes": {"k1": "v1"}} ) res = client.list_things() res.should.have.key("things").which.should.have.length_of(1) for thing in res["things"]: thing.should.have.key("thingName").which.should_not.be.none thing.should.have.key("thingArn").which.should_not.be.none res["things"][0]["attributes"].should.have.key("k1").which.should.equal("v1") thing = client.describe_thing(thingName=name) thing.should.have.key("thingName").which.should.equal(name) thing.should.have.key("defaultClientId") thing.should.have.key("thingTypeName") thing.should.have.key("attributes") thing.should.have.key("version") # delete thing client.delete_thing(thingName=name) res = client.list_things() res.should.have.key("things").which.should.have.length_of(0) # delete thing type client.delete_thing_type(thingTypeName=type_name) res = client.list_thing_types() res.should.have.key("thingTypes").which.should.have.length_of(0) @mock_iot def test_list_thing_types(): client = boto3.client("iot", region_name="ap-northeast-1") for i in range(0, 100): client.create_thing_type(thingTypeName=str(i + 1)) thing_types = client.list_thing_types() thing_types.should.have.key("nextToken") thing_types.should.have.key("thingTypes").which.should.have.length_of(50) thing_types["thingTypes"][0]["thingTypeName"].should.equal("1") thing_types["thingTypes"][-1]["thingTypeName"].should.equal("50") thing_types = client.list_thing_types(nextToken=thing_types["nextToken"]) thing_types.should.have.key("thingTypes").which.should.have.length_of(50) thing_types.should_not.have.key("nextToken") thing_types["thingTypes"][0]["thingTypeName"].should.equal("51") thing_types["thingTypes"][-1]["thingTypeName"].should.equal("100") @mock_iot def test_list_thing_types_with_typename_filter(): client = boto3.client("iot", region_name="ap-northeast-1") client.create_thing_type(thingTypeName="thing") client.create_thing_type(thingTypeName="thingType") client.create_thing_type(thingTypeName="thingTypeName") client.create_thing_type(thingTypeName="thingTypeNameGroup") client.create_thing_type(thingTypeName="shouldNotFind") client.create_thing_type(thingTypeName="find me it shall not") thing_types = client.list_thing_types(thingTypeName="thing") thing_types.should_not.have.key("nextToken") thing_types.should.have.key("thingTypes").which.should.have.length_of(4) thing_types["thingTypes"][0]["thingTypeName"].should.equal("thing") thing_types["thingTypes"][-1]["thingTypeName"].should.equal("thingTypeNameGroup") thing_types = client.list_thing_types(thingTypeName="thingTypeName") thing_types.should_not.have.key("nextToken") thing_types.should.have.key("thingTypes").which.should.have.length_of(2) thing_types["thingTypes"][0]["thingTypeName"].should.equal("thingTypeName") thing_types["thingTypes"][-1]["thingTypeName"].should.equal("thingTypeNameGroup") @mock_iot def test_list_things_with_next_token(): client = boto3.client("iot", region_name="ap-northeast-1") for i in range(0, 200): client.create_thing(thingName=str(i + 1)) things = client.list_things() things.should.have.key("nextToken") things.should.have.key("things").which.should.have.length_of(50) things["things"][0]["thingName"].should.equal("1") things["things"][0]["thingArn"].should.equal("arn:aws:iot:ap-northeast-1:1:thing/1") things["things"][-1]["thingName"].should.equal("50") things["things"][-1]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/50" ) things = client.list_things(nextToken=things["nextToken"]) things.should.have.key("nextToken") things.should.have.key("things").which.should.have.length_of(50) things["things"][0]["thingName"].should.equal("51") things["things"][0]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/51" ) things["things"][-1]["thingName"].should.equal("100") things["things"][-1]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/100" ) things = client.list_things(nextToken=things["nextToken"]) things.should.have.key("nextToken") things.should.have.key("things").which.should.have.length_of(50) things["things"][0]["thingName"].should.equal("101") things["things"][0]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/101" ) things["things"][-1]["thingName"].should.equal("150") things["things"][-1]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/150" ) things = client.list_things(nextToken=things["nextToken"]) things.should_not.have.key("nextToken") things.should.have.key("things").which.should.have.length_of(50) things["things"][0]["thingName"].should.equal("151") things["things"][0]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/151" ) things["things"][-1]["thingName"].should.equal("200") things["things"][-1]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/200" ) @mock_iot def test_list_things_with_attribute_and_thing_type_filter_and_next_token(): client = boto3.client("iot", region_name="ap-northeast-1") client.create_thing_type(thingTypeName="my-thing-type") for i in range(0, 200): if not (i + 1) % 3: attribute_payload = {"attributes": {"foo": "bar"}} elif not (i + 1) % 5: attribute_payload = {"attributes": {"bar": "foo"}} else: attribute_payload = {} if not (i + 1) % 2: thing_type_name = "my-thing-type" client.create_thing( thingName=str(i + 1), thingTypeName=thing_type_name, attributePayload=attribute_payload, ) else: client.create_thing( thingName=str(i + 1), attributePayload=attribute_payload ) # Test filter for thingTypeName things = client.list_things(thingTypeName=thing_type_name) things.should.have.key("nextToken") things.should.have.key("things").which.should.have.length_of(50) things["things"][0]["thingName"].should.equal("2") things["things"][0]["thingArn"].should.equal("arn:aws:iot:ap-northeast-1:1:thing/2") things["things"][-1]["thingName"].should.equal("100") things["things"][-1]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/100" ) all(item["thingTypeName"] == thing_type_name for item in things["things"]) things = client.list_things( nextToken=things["nextToken"], thingTypeName=thing_type_name ) things.should_not.have.key("nextToken") things.should.have.key("things").which.should.have.length_of(50) things["things"][0]["thingName"].should.equal("102") things["things"][0]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/102" ) things["things"][-1]["thingName"].should.equal("200") things["things"][-1]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/200" ) all(item["thingTypeName"] == thing_type_name for item in things["things"]) # Test filter for attributes things = client.list_things(attributeName="foo", attributeValue="bar") things.should.have.key("nextToken") things.should.have.key("things").which.should.have.length_of(50) things["things"][0]["thingName"].should.equal("3") things["things"][0]["thingArn"].should.equal("arn:aws:iot:ap-northeast-1:1:thing/3") things["things"][-1]["thingName"].should.equal("150") things["things"][-1]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/150" ) all(item["attributes"] == {"foo": "bar"} for item in things["things"]) things = client.list_things( nextToken=things["nextToken"], attributeName="foo", attributeValue="bar" ) things.should_not.have.key("nextToken") things.should.have.key("things").which.should.have.length_of(16) things["things"][0]["thingName"].should.equal("153") things["things"][0]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/153" ) things["things"][-1]["thingName"].should.equal("198") things["things"][-1]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/198" ) all(item["attributes"] == {"foo": "bar"} for item in things["things"]) # Test filter for attributes and thingTypeName things = client.list_things( thingTypeName=thing_type_name, attributeName="foo", attributeValue="bar" ) things.should_not.have.key("nextToken") things.should.have.key("things").which.should.have.length_of(33) things["things"][0]["thingName"].should.equal("6") things["things"][0]["thingArn"].should.equal("arn:aws:iot:ap-northeast-1:1:thing/6") things["things"][-1]["thingName"].should.equal("198") things["things"][-1]["thingArn"].should.equal( "arn:aws:iot:ap-northeast-1:1:thing/198" ) all( item["attributes"] == {"foo": "bar"} and item["thingTypeName"] == thing_type_name for item in things["things"] ) @mock_iot def test_certs(): client = boto3.client("iot", region_name="us-east-1") cert = client.create_keys_and_certificate(setAsActive=True) cert.should.have.key("certificateArn").which.should_not.be.none cert.should.have.key("certificateId").which.should_not.be.none cert.should.have.key("certificatePem").which.should_not.be.none cert.should.have.key("keyPair") cert["keyPair"].should.have.key("PublicKey").which.should_not.be.none cert["keyPair"].should.have.key("PrivateKey").which.should_not.be.none cert_id = cert["certificateId"] cert = client.describe_certificate(certificateId=cert_id) cert.should.have.key("certificateDescription") cert_desc = cert["certificateDescription"] cert_desc.should.have.key("certificateArn").which.should_not.be.none cert_desc.should.have.key("certificateId").which.should_not.be.none cert_desc.should.have.key("certificatePem").which.should_not.be.none cert_desc.should.have.key("status").which.should.equal("ACTIVE") cert_pem = cert_desc["certificatePem"] res = client.list_certificates() for cert in res["certificates"]: cert.should.have.key("certificateArn").which.should_not.be.none cert.should.have.key("certificateId").which.should_not.be.none cert.should.have.key("status").which.should_not.be.none cert.should.have.key("creationDate").which.should_not.be.none client.update_certificate(certificateId=cert_id, newStatus="REVOKED") cert = client.describe_certificate(certificateId=cert_id) cert_desc = cert["certificateDescription"] cert_desc.should.have.key("status").which.should.equal("REVOKED") client.delete_certificate(certificateId=cert_id) res = client.list_certificates() res.should.have.key("certificates") # Test register_certificate flow cert = client.register_certificate(certificatePem=cert_pem, setAsActive=True) cert.should.have.key("certificateId").which.should_not.be.none cert.should.have.key("certificateArn").which.should_not.be.none cert_id = cert["certificateId"] res = client.list_certificates() res.should.have.key("certificates").which.should.have.length_of(1) for cert in res["certificates"]: cert.should.have.key("certificateArn").which.should_not.be.none cert.should.have.key("certificateId").which.should_not.be.none cert.should.have.key("status").which.should_not.be.none cert.should.have.key("creationDate").which.should_not.be.none client.update_certificate(certificateId=cert_id, newStatus="REVOKED") cert = client.describe_certificate(certificateId=cert_id) cert_desc = cert["certificateDescription"] cert_desc.should.have.key("status").which.should.equal("REVOKED") client.delete_certificate(certificateId=cert_id) res = client.list_certificates() res.should.have.key("certificates") @mock_iot def test_delete_policy_validation(): doc = """{ "Version": "2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "iot: *" ], "Resource":"*" } ] } """ client = boto3.client("iot", region_name="ap-northeast-1") cert = client.create_keys_and_certificate(setAsActive=True) cert_arn = cert["certificateArn"] policy_name = "my-policy" client.create_policy(policyName=policy_name, policyDocument=doc) client.attach_principal_policy(policyName=policy_name, principal=cert_arn) with assert_raises(ClientError) as e: client.delete_policy(policyName=policy_name) e.exception.response["Error"]["Message"].should.contain( "The policy cannot be deleted as the policy is attached to one or more principals (name=%s)" % policy_name ) res = client.list_policies() res.should.have.key("policies").which.should.have.length_of(1) client.detach_principal_policy(policyName=policy_name, principal=cert_arn) client.delete_policy(policyName=policy_name) res = client.list_policies() res.should.have.key("policies").which.should.have.length_of(0) @mock_iot def test_delete_certificate_validation(): doc = """{ "Version": "2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "iot: *" ], "Resource":"*" } ] } """ client = boto3.client("iot", region_name="ap-northeast-1") cert = client.create_keys_and_certificate(setAsActive=True) cert_id = cert["certificateId"] cert_arn = cert["certificateArn"] policy_name = "my-policy" thing_name = "thing-1" client.create_policy(policyName=policy_name, policyDocument=doc) client.attach_principal_policy(policyName=policy_name, principal=cert_arn) client.create_thing(thingName=thing_name) client.attach_thing_principal(thingName=thing_name, principal=cert_arn) with assert_raises(ClientError) as e: client.delete_certificate(certificateId=cert_id) e.exception.response["Error"]["Message"].should.contain( "Certificate must be deactivated (not ACTIVE) before deletion." ) res = client.list_certificates() res.should.have.key("certificates").which.should.have.length_of(1) client.update_certificate(certificateId=cert_id, newStatus="REVOKED") with assert_raises(ClientError) as e: client.delete_certificate(certificateId=cert_id) e.exception.response["Error"]["Message"].should.contain( "Things must be detached before deletion (arn: %s)" % cert_arn ) res = client.list_certificates() res.should.have.key("certificates").which.should.have.length_of(1) client.detach_thing_principal(thingName=thing_name, principal=cert_arn) with assert_raises(ClientError) as e: client.delete_certificate(certificateId=cert_id) e.exception.response["Error"]["Message"].should.contain( "Certificate policies must be detached before deletion (arn: %s)" % cert_arn ) res = client.list_certificates() res.should.have.key("certificates").which.should.have.length_of(1) client.detach_principal_policy(policyName=policy_name, principal=cert_arn) client.delete_certificate(certificateId=cert_id) res = client.list_certificates() res.should.have.key("certificates").which.should.have.length_of(0) @mock_iot def test_certs_create_inactive(): client = boto3.client("iot", region_name="ap-northeast-1") cert = client.create_keys_and_certificate(setAsActive=False) cert_id = cert["certificateId"] cert = client.describe_certificate(certificateId=cert_id) cert.should.have.key("certificateDescription") cert_desc = cert["certificateDescription"] cert_desc.should.have.key("status").which.should.equal("INACTIVE") client.update_certificate(certificateId=cert_id, newStatus="ACTIVE") cert = client.describe_certificate(certificateId=cert_id) cert.should.have.key("certificateDescription") cert_desc = cert["certificateDescription"] cert_desc.should.have.key("status").which.should.equal("ACTIVE") @mock_iot def test_policy(): client = boto3.client("iot", region_name="ap-northeast-1") name = "my-policy" doc = "{}" policy = client.create_policy(policyName=name, policyDocument=doc) policy.should.have.key("policyName").which.should.equal(name) policy.should.have.key("policyArn").which.should_not.be.none policy.should.have.key("policyDocument").which.should.equal(doc) policy.should.have.key("policyVersionId").which.should.equal("1") policy = client.get_policy(policyName=name) policy.should.have.key("policyName").which.should.equal(name) policy.should.have.key("policyArn").which.should_not.be.none policy.should.have.key("policyDocument").which.should.equal(doc) policy.should.have.key("defaultVersionId").which.should.equal("1") res = client.list_policies() res.should.have.key("policies").which.should.have.length_of(1) for policy in res["policies"]: policy.should.have.key("policyName").which.should_not.be.none policy.should.have.key("policyArn").which.should_not.be.none client.delete_policy(policyName=name) res = client.list_policies() res.should.have.key("policies").which.should.have.length_of(0) @mock_iot def test_principal_policy(): client = boto3.client("iot", region_name="ap-northeast-1") policy_name = "my-policy" doc = "{}" client.create_policy(policyName=policy_name, policyDocument=doc) cert = client.create_keys_and_certificate(setAsActive=True) cert_arn = cert["certificateArn"] client.attach_policy(policyName=policy_name, target=cert_arn) res = client.list_principal_policies(principal=cert_arn) res.should.have.key("policies").which.should.have.length_of(1) for policy in res["policies"]: policy.should.have.key("policyName").which.should_not.be.none policy.should.have.key("policyArn").which.should_not.be.none # do nothing if policy have already attached to certificate client.attach_policy(policyName=policy_name, target=cert_arn) res = client.list_principal_policies(principal=cert_arn) res.should.have.key("policies").which.should.have.length_of(1) for policy in res["policies"]: policy.should.have.key("policyName").which.should_not.be.none policy.should.have.key("policyArn").which.should_not.be.none res = client.list_policy_principals(policyName=policy_name) res.should.have.key("principals").which.should.have.length_of(1) for principal in res["principals"]: principal.should_not.be.none client.detach_policy(policyName=policy_name, target=cert_arn) res = client.list_principal_policies(principal=cert_arn) res.should.have.key("policies").which.should.have.length_of(0) res = client.list_policy_principals(policyName=policy_name) res.should.have.key("principals").which.should.have.length_of(0) with assert_raises(ClientError) as e: client.detach_policy(policyName=policy_name, target=cert_arn) e.exception.response["Error"]["Code"].should.equal("ResourceNotFoundException") @mock_iot def test_principal_policy_deprecated(): client = boto3.client("iot", region_name="ap-northeast-1") policy_name = "my-policy" doc = "{}" policy = client.create_policy(policyName=policy_name, policyDocument=doc) cert = client.create_keys_and_certificate(setAsActive=True) cert_arn = cert["certificateArn"] client.attach_principal_policy(policyName=policy_name, principal=cert_arn) res = client.list_principal_policies(principal=cert_arn) res.should.have.key("policies").which.should.have.length_of(1) for policy in res["policies"]: policy.should.have.key("policyName").which.should_not.be.none policy.should.have.key("policyArn").which.should_not.be.none res = client.list_policy_principals(policyName=policy_name) res.should.have.key("principals").which.should.have.length_of(1) for principal in res["principals"]: principal.should_not.be.none client.detach_principal_policy(policyName=policy_name, principal=cert_arn) res = client.list_principal_policies(principal=cert_arn) res.should.have.key("policies").which.should.have.length_of(0) res = client.list_policy_principals(policyName=policy_name) res.should.have.key("principals").which.should.have.length_of(0) @mock_iot def test_principal_thing(): client = boto3.client("iot", region_name="ap-northeast-1") thing_name = "my-thing" thing = client.create_thing(thingName=thing_name) cert = client.create_keys_and_certificate(setAsActive=True) cert_arn = cert["certificateArn"] client.attach_thing_principal(thingName=thing_name, principal=cert_arn) res = client.list_principal_things(principal=cert_arn) res.should.have.key("things").which.should.have.length_of(1) for thing in res["things"]: thing.should_not.be.none res = client.list_thing_principals(thingName=thing_name) res.should.have.key("principals").which.should.have.length_of(1) for principal in res["principals"]: principal.should_not.be.none client.detach_thing_principal(thingName=thing_name, principal=cert_arn) res = client.list_principal_things(principal=cert_arn) res.should.have.key("things").which.should.have.length_of(0) res = client.list_thing_principals(thingName=thing_name) res.should.have.key("principals").which.should.have.length_of(0) @mock_iot def test_delete_principal_thing(): client = boto3.client("iot", region_name="ap-northeast-1") thing_name = "my-thing" thing = client.create_thing(thingName=thing_name) cert = client.create_keys_and_certificate(setAsActive=True) cert_arn = cert["certificateArn"] cert_id = cert["certificateId"] client.attach_thing_principal(thingName=thing_name, principal=cert_arn) client.delete_thing(thingName=thing_name) res = client.list_principal_things(principal=cert_arn) res.should.have.key("things").which.should.have.length_of(0) client.update_certificate(certificateId=cert_id, newStatus="INACTIVE") client.delete_certificate(certificateId=cert_id) @mock_iot def test_describe_thing_group_metadata_hierarchy(): client = boto3.client("iot", region_name="ap-northeast-1") group_name_1a = "my-group-name-1a" group_name_1b = "my-group-name-1b" group_name_2a = "my-group-name-2a" group_name_2b = "my-group-name-2b" group_name_3a = "my-group-name-3a" group_name_3b = "my-group-name-3b" group_name_3c = "my-group-name-3c" group_name_3d = "my-group-name-3d" # --1a # |--2a # | |--3a # | |--3b # | # |--2b # |--3c # |--3d # --1b # 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") thing_group1b = client.create_thing_group(thingGroupName=group_name_1b) thing_group1b.should.have.key("thingGroupName").which.should.equal(group_name_1b) thing_group1b.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") thing_group2b = client.create_thing_group( thingGroupName=group_name_2b, parentGroupName=group_name_1a ) thing_group2b.should.have.key("thingGroupName").which.should.equal(group_name_2b) thing_group2b.should.have.key("thingGroupArn") # 3 thing_group3a = client.create_thing_group( thingGroupName=group_name_3a, parentGroupName=group_name_2a ) thing_group3a.should.have.key("thingGroupName").which.should.equal(group_name_3a) thing_group3a.should.have.key("thingGroupArn") thing_group3b = client.create_thing_group( thingGroupName=group_name_3b, parentGroupName=group_name_2a ) thing_group3b.should.have.key("thingGroupName").which.should.equal(group_name_3b) thing_group3b.should.have.key("thingGroupArn") thing_group3c = client.create_thing_group( thingGroupName=group_name_3c, parentGroupName=group_name_2b ) thing_group3c.should.have.key("thingGroupName").which.should.equal(group_name_3c) thing_group3c.should.have.key("thingGroupArn") thing_group3d = client.create_thing_group( thingGroupName=group_name_3d, parentGroupName=group_name_2b ) thing_group3d.should.have.key("thingGroupName").which.should.equal(group_name_3d) thing_group3d.should.have.key("thingGroupArn") # describe groups # groups level 1 # 1a thing_group_description1a = client.describe_thing_group( thingGroupName=group_name_1a ) thing_group_description1a.should.have.key("thingGroupName").which.should.equal( group_name_1a ) thing_group_description1a.should.have.key("thingGroupProperties") thing_group_description1a.should.have.key("thingGroupMetadata") thing_group_description1a["thingGroupMetadata"].should.have.key("creationDate") thing_group_description1a.should.have.key("version") # 1b thing_group_description1b = client.describe_thing_group( thingGroupName=group_name_1b ) thing_group_description1b.should.have.key("thingGroupName").which.should.equal( group_name_1b ) thing_group_description1b.should.have.key("thingGroupProperties") thing_group_description1b.should.have.key("thingGroupMetadata") thing_group_description1b["thingGroupMetadata"].should.have.length_of(1) thing_group_description1b["thingGroupMetadata"].should.have.key("creationDate") thing_group_description1b.should.have.key("version") # groups level 2 # 2a thing_group_description2a = client.describe_thing_group( thingGroupName=group_name_2a ) thing_group_description2a.should.have.key("thingGroupName").which.should.equal( group_name_2a ) thing_group_description2a.should.have.key("thingGroupProperties") thing_group_description2a.should.have.key("thingGroupMetadata") thing_group_description2a["thingGroupMetadata"].should.have.length_of(3) thing_group_description2a["thingGroupMetadata"].should.have.key( "parentGroupName" ).being.equal(group_name_1a) thing_group_description2a["thingGroupMetadata"].should.have.key( "rootToParentThingGroups" ) thing_group_description2a["thingGroupMetadata"][ "rootToParentThingGroups" ].should.have.length_of(1) thing_group_description2a["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupName" ].should.match(group_name_1a) thing_group_description2a["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupArn" ].should.match(thing_group1a["thingGroupArn"]) thing_group_description2a.should.have.key("version") # 2b thing_group_description2b = client.describe_thing_group( thingGroupName=group_name_2b ) thing_group_description2b.should.have.key("thingGroupName").which.should.equal( group_name_2b ) thing_group_description2b.should.have.key("thingGroupProperties") thing_group_description2b.should.have.key("thingGroupMetadata") thing_group_description2b["thingGroupMetadata"].should.have.length_of(3) thing_group_description2b["thingGroupMetadata"].should.have.key( "parentGroupName" ).being.equal(group_name_1a) thing_group_description2b["thingGroupMetadata"].should.have.key( "rootToParentThingGroups" ) thing_group_description2b["thingGroupMetadata"][ "rootToParentThingGroups" ].should.have.length_of(1) thing_group_description2b["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupName" ].should.match(group_name_1a) thing_group_description2b["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupArn" ].should.match(thing_group1a["thingGroupArn"]) thing_group_description2b.should.have.key("version") # groups level 3 # 3a thing_group_description3a = client.describe_thing_group( thingGroupName=group_name_3a ) thing_group_description3a.should.have.key("thingGroupName").which.should.equal( group_name_3a ) thing_group_description3a.should.have.key("thingGroupProperties") thing_group_description3a.should.have.key("thingGroupMetadata") thing_group_description3a["thingGroupMetadata"].should.have.length_of(3) thing_group_description3a["thingGroupMetadata"].should.have.key( "parentGroupName" ).being.equal(group_name_2a) thing_group_description3a["thingGroupMetadata"].should.have.key( "rootToParentThingGroups" ) thing_group_description3a["thingGroupMetadata"][ "rootToParentThingGroups" ].should.have.length_of(2) thing_group_description3a["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupName" ].should.match(group_name_1a) thing_group_description3a["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupArn" ].should.match(thing_group1a["thingGroupArn"]) thing_group_description3a["thingGroupMetadata"]["rootToParentThingGroups"][1][ "groupName" ].should.match(group_name_2a) thing_group_description3a["thingGroupMetadata"]["rootToParentThingGroups"][1][ "groupArn" ].should.match(thing_group2a["thingGroupArn"]) thing_group_description3a.should.have.key("version") # 3b thing_group_description3b = client.describe_thing_group( thingGroupName=group_name_3b ) thing_group_description3b.should.have.key("thingGroupName").which.should.equal( group_name_3b ) thing_group_description3b.should.have.key("thingGroupProperties") thing_group_description3b.should.have.key("thingGroupMetadata") thing_group_description3b["thingGroupMetadata"].should.have.length_of(3) thing_group_description3b["thingGroupMetadata"].should.have.key( "parentGroupName" ).being.equal(group_name_2a) thing_group_description3b["thingGroupMetadata"].should.have.key( "rootToParentThingGroups" ) thing_group_description3b["thingGroupMetadata"][ "rootToParentThingGroups" ].should.have.length_of(2) thing_group_description3b["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupName" ].should.match(group_name_1a) thing_group_description3b["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupArn" ].should.match(thing_group1a["thingGroupArn"]) thing_group_description3b["thingGroupMetadata"]["rootToParentThingGroups"][1][ "groupName" ].should.match(group_name_2a) thing_group_description3b["thingGroupMetadata"]["rootToParentThingGroups"][1][ "groupArn" ].should.match(thing_group2a["thingGroupArn"]) thing_group_description3b.should.have.key("version") # 3c thing_group_description3c = client.describe_thing_group( thingGroupName=group_name_3c ) thing_group_description3c.should.have.key("thingGroupName").which.should.equal( group_name_3c ) thing_group_description3c.should.have.key("thingGroupProperties") thing_group_description3c.should.have.key("thingGroupMetadata") thing_group_description3c["thingGroupMetadata"].should.have.length_of(3) thing_group_description3c["thingGroupMetadata"].should.have.key( "parentGroupName" ).being.equal(group_name_2b) thing_group_description3c["thingGroupMetadata"].should.have.key( "rootToParentThingGroups" ) thing_group_description3c["thingGroupMetadata"][ "rootToParentThingGroups" ].should.have.length_of(2) thing_group_description3c["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupName" ].should.match(group_name_1a) thing_group_description3c["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupArn" ].should.match(thing_group1a["thingGroupArn"]) thing_group_description3c["thingGroupMetadata"]["rootToParentThingGroups"][1][ "groupName" ].should.match(group_name_2b) thing_group_description3c["thingGroupMetadata"]["rootToParentThingGroups"][1][ "groupArn" ].should.match(thing_group2b["thingGroupArn"]) thing_group_description3c.should.have.key("version") # 3d thing_group_description3d = client.describe_thing_group( thingGroupName=group_name_3d ) thing_group_description3d.should.have.key("thingGroupName").which.should.equal( group_name_3d ) thing_group_description3d.should.have.key("thingGroupProperties") thing_group_description3d.should.have.key("thingGroupMetadata") thing_group_description3d["thingGroupMetadata"].should.have.length_of(3) thing_group_description3d["thingGroupMetadata"].should.have.key( "parentGroupName" ).being.equal(group_name_2b) thing_group_description3d["thingGroupMetadata"].should.have.key( "rootToParentThingGroups" ) thing_group_description3d["thingGroupMetadata"][ "rootToParentThingGroups" ].should.have.length_of(2) thing_group_description3d["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupName" ].should.match(group_name_1a) thing_group_description3d["thingGroupMetadata"]["rootToParentThingGroups"][0][ "groupArn" ].should.match(thing_group1a["thingGroupArn"]) thing_group_description3d["thingGroupMetadata"]["rootToParentThingGroups"][1][ "groupName" ].should.match(group_name_2b) thing_group_description3d["thingGroupMetadata"]["rootToParentThingGroups"][1][ "groupArn" ].should.match(thing_group2b["thingGroupArn"]) thing_group_description3d.should.have.key("version") @mock_iot def test_thing_groups(): client = boto3.client("iot", region_name="ap-northeast-1") group_name = "my-group-name" # thing group thing_group = client.create_thing_group(thingGroupName=group_name) thing_group.should.have.key("thingGroupName").which.should.equal(group_name) thing_group.should.have.key("thingGroupArn") res = client.list_thing_groups() res.should.have.key("thingGroups").which.should.have.length_of(1) for thing_group in res["thingGroups"]: thing_group.should.have.key("groupName").which.should_not.be.none thing_group.should.have.key("groupArn").which.should_not.be.none thing_group = client.describe_thing_group(thingGroupName=group_name) thing_group.should.have.key("thingGroupName").which.should.equal(group_name) thing_group.should.have.key("thingGroupProperties") thing_group.should.have.key("thingGroupMetadata") thing_group.should.have.key("version") # delete thing group client.delete_thing_group(thingGroupName=group_name) res = client.list_thing_groups() res.should.have.key("thingGroups").which.should.have.length_of(0) # props create test props = { "thingGroupDescription": "my first thing group", "attributePayload": {"attributes": {"key1": "val01", "Key02": "VAL2"}}, } thing_group = client.create_thing_group( thingGroupName=group_name, thingGroupProperties=props ) thing_group.should.have.key("thingGroupName").which.should.equal(group_name) thing_group.should.have.key("thingGroupArn") thing_group = client.describe_thing_group(thingGroupName=group_name) thing_group.should.have.key("thingGroupProperties").which.should.have.key( "attributePayload" ).which.should.have.key("attributes") res_props = thing_group["thingGroupProperties"]["attributePayload"]["attributes"] res_props.should.have.key("key1").which.should.equal("val01") res_props.should.have.key("Key02").which.should.equal("VAL2") # props update test with merge new_props = {"attributePayload": {"attributes": {"k3": "v3"}, "merge": True}} client.update_thing_group(thingGroupName=group_name, thingGroupProperties=new_props) thing_group = client.describe_thing_group(thingGroupName=group_name) thing_group.should.have.key("thingGroupProperties").which.should.have.key( "attributePayload" ).which.should.have.key("attributes") res_props = thing_group["thingGroupProperties"]["attributePayload"]["attributes"] res_props.should.have.key("key1").which.should.equal("val01") res_props.should.have.key("Key02").which.should.equal("VAL2") res_props.should.have.key("k3").which.should.equal("v3") # props update test new_props = {"attributePayload": {"attributes": {"k4": "v4"}}} client.update_thing_group(thingGroupName=group_name, thingGroupProperties=new_props) thing_group = client.describe_thing_group(thingGroupName=group_name) thing_group.should.have.key("thingGroupProperties").which.should.have.key( "attributePayload" ).which.should.have.key("attributes") res_props = thing_group["thingGroupProperties"]["attributePayload"]["attributes"] res_props.should.have.key("k4").which.should.equal("v4") res_props.should_not.have.key("key1") @mock_iot def test_thing_group_relations(): client = boto3.client("iot", region_name="ap-northeast-1") name = "my-thing" group_name = "my-group-name" # thing group thing_group = client.create_thing_group(thingGroupName=group_name) thing_group.should.have.key("thingGroupName").which.should.equal(group_name) thing_group.should.have.key("thingGroupArn") # thing thing = client.create_thing(thingName=name) thing.should.have.key("thingName").which.should.equal(name) thing.should.have.key("thingArn") # add in 4 way client.add_thing_to_thing_group(thingGroupName=group_name, thingName=name) client.add_thing_to_thing_group( thingGroupArn=thing_group["thingGroupArn"], thingArn=thing["thingArn"] ) client.add_thing_to_thing_group( thingGroupName=group_name, thingArn=thing["thingArn"] ) client.add_thing_to_thing_group( thingGroupArn=thing_group["thingGroupArn"], thingName=name ) things = client.list_things_in_thing_group(thingGroupName=group_name) things.should.have.key("things") things["things"].should.have.length_of(1) thing_groups = client.list_thing_groups_for_thing(thingName=name) thing_groups.should.have.key("thingGroups") thing_groups["thingGroups"].should.have.length_of(1) # remove in 4 way client.remove_thing_from_thing_group(thingGroupName=group_name, thingName=name) client.remove_thing_from_thing_group( thingGroupArn=thing_group["thingGroupArn"], thingArn=thing["thingArn"] ) client.remove_thing_from_thing_group( thingGroupName=group_name, thingArn=thing["thingArn"] ) client.remove_thing_from_thing_group( thingGroupArn=thing_group["thingGroupArn"], thingName=name ) things = client.list_things_in_thing_group(thingGroupName=group_name) things.should.have.key("things") things["things"].should.have.length_of(0) # update thing group for thing client.update_thing_groups_for_thing(thingName=name, thingGroupsToAdd=[group_name]) things = client.list_things_in_thing_group(thingGroupName=group_name) things.should.have.key("things") things["things"].should.have.length_of(1) client.update_thing_groups_for_thing( thingName=name, thingGroupsToRemove=[group_name] ) things = client.list_things_in_thing_group(thingGroupName=group_name) things.should.have.key("things") things["things"].should.have.length_of(0) @mock_iot def test_create_job(): client = boto3.client("iot", region_name="eu-west-1") name = "my-thing" job_id = "TestJob" # thing thing = client.create_thing(thingName=name) thing.should.have.key("thingName").which.should.equal(name) thing.should.have.key("thingArn") # job document job_document = {"field": "value"} job = client.create_job( jobId=job_id, targets=[thing["thingArn"]], document=json.dumps(job_document), description="Description", presignedUrlConfig={ "roleArn": "arn:aws:iam::1:role/service-role/iot_job_role", "expiresInSec": 123, }, targetSelection="CONTINUOUS", jobExecutionsRolloutConfig={"maximumPerMinute": 10}, ) job.should.have.key("jobId").which.should.equal(job_id) job.should.have.key("jobArn") job.should.have.key("description") @mock_iot def test_describe_job(): client = boto3.client("iot", region_name="eu-west-1") name = "my-thing" job_id = "TestJob" # thing thing = client.create_thing(thingName=name) thing.should.have.key("thingName").which.should.equal(name) thing.should.have.key("thingArn") job = client.create_job( jobId=job_id, targets=[thing["thingArn"]], documentSource="https://s3-eu-west-1.amazonaws.com/bucket-name/job_document.json", presignedUrlConfig={ "roleArn": "arn:aws:iam::1:role/service-role/iot_job_role", "expiresInSec": 123, }, targetSelection="CONTINUOUS", jobExecutionsRolloutConfig={"maximumPerMinute": 10}, ) job.should.have.key("jobId").which.should.equal(job_id) job.should.have.key("jobArn") job = client.describe_job(jobId=job_id) job.should.have.key("documentSource") job.should.have.key("job") job.should.have.key("job").which.should.have.key("jobArn") job.should.have.key("job").which.should.have.key("jobId").which.should.equal(job_id) job.should.have.key("job").which.should.have.key("targets") job.should.have.key("job").which.should.have.key("jobProcessDetails") job.should.have.key("job").which.should.have.key("lastUpdatedAt") job.should.have.key("job").which.should.have.key("createdAt") job.should.have.key("job").which.should.have.key("jobExecutionsRolloutConfig") job.should.have.key("job").which.should.have.key( "targetSelection" ).which.should.equal("CONTINUOUS") job.should.have.key("job").which.should.have.key("presignedUrlConfig") job.should.have.key("job").which.should.have.key( "presignedUrlConfig" ).which.should.have.key("roleArn").which.should.equal( "arn:aws:iam::1:role/service-role/iot_job_role" ) job.should.have.key("job").which.should.have.key( "presignedUrlConfig" ).which.should.have.key("expiresInSec").which.should.equal(123) job.should.have.key("job").which.should.have.key( "jobExecutionsRolloutConfig" ).which.should.have.key("maximumPerMinute").which.should.equal(10) @mock_iot def test_describe_job_1(): client = boto3.client("iot", region_name="eu-west-1") name = "my-thing" job_id = "TestJob" # thing thing = client.create_thing(thingName=name) thing.should.have.key("thingName").which.should.equal(name) thing.should.have.key("thingArn") # job document job_document = {"field": "value"} job = client.create_job( jobId=job_id, targets=[thing["thingArn"]], document=json.dumps(job_document), presignedUrlConfig={ "roleArn": "arn:aws:iam::1:role/service-role/iot_job_role", "expiresInSec": 123, }, targetSelection="CONTINUOUS", jobExecutionsRolloutConfig={"maximumPerMinute": 10}, ) job.should.have.key("jobId").which.should.equal(job_id) job.should.have.key("jobArn") job = client.describe_job(jobId=job_id) job.should.have.key("job") job.should.have.key("job").which.should.have.key("jobArn") job.should.have.key("job").which.should.have.key("jobId").which.should.equal(job_id) job.should.have.key("job").which.should.have.key("targets") job.should.have.key("job").which.should.have.key("jobProcessDetails") job.should.have.key("job").which.should.have.key("lastUpdatedAt") job.should.have.key("job").which.should.have.key("createdAt") job.should.have.key("job").which.should.have.key("jobExecutionsRolloutConfig") job.should.have.key("job").which.should.have.key( "targetSelection" ).which.should.equal("CONTINUOUS") job.should.have.key("job").which.should.have.key("presignedUrlConfig") job.should.have.key("job").which.should.have.key( "presignedUrlConfig" ).which.should.have.key("roleArn").which.should.equal( "arn:aws:iam::1:role/service-role/iot_job_role" ) job.should.have.key("job").which.should.have.key( "presignedUrlConfig" ).which.should.have.key("expiresInSec").which.should.equal(123) job.should.have.key("job").which.should.have.key( "jobExecutionsRolloutConfig" ).which.should.have.key("maximumPerMinute").which.should.equal(10)