1895 lines
73 KiB
Python
1895 lines
73 KiB
Python
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
|
|
|
|
|
|
def generate_thing_group_tree(iot_client, tree_dict, _parent=None):
|
|
"""
|
|
Generates a thing group tree given the input tree structure.
|
|
:param iot_client: the iot client for boto3
|
|
:param tree_dict: dictionary with the key being the group_name, and the value being a sub tree.
|
|
tree_dict = {
|
|
"group_name_1a":{
|
|
"group_name_2a":{
|
|
"group_name_3a":{} or None
|
|
},
|
|
},
|
|
"group_name_1b":{}
|
|
}
|
|
:return: a dictionary of created groups, keyed by group name
|
|
"""
|
|
if tree_dict is None:
|
|
tree_dict = {}
|
|
created_dict = {}
|
|
for group_name in tree_dict.keys():
|
|
params = {"thingGroupName": group_name}
|
|
if _parent:
|
|
params["parentGroupName"] = _parent
|
|
created_group = iot_client.create_thing_group(**params)
|
|
created_dict[group_name] = created_group
|
|
subtree_dict = generate_thing_group_tree(
|
|
iot_client=iot_client, tree_dict=tree_dict[group_name], _parent=group_name
|
|
)
|
|
created_dict.update(created_dict)
|
|
created_dict.update(subtree_dict)
|
|
return created_dict
|
|
|
|
|
|
@mock_iot
|
|
def test_attach_policy():
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
policy_name = "my-policy"
|
|
doc = "{}"
|
|
|
|
cert = client.create_keys_and_certificate(setAsActive=True)
|
|
cert_arn = cert["certificateArn"]
|
|
client.create_policy(policyName=policy_name, policyDocument=doc)
|
|
client.attach_policy(policyName=policy_name, target=cert_arn)
|
|
|
|
res = client.list_attached_policies(target=cert_arn)
|
|
res.should.have.key("policies").which.should.have.length_of(1)
|
|
res["policies"][0]["policyName"].should.equal("my-policy")
|
|
|
|
|
|
@mock_iot
|
|
def test_detach_policy():
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
policy_name = "my-policy"
|
|
doc = "{}"
|
|
|
|
cert = client.create_keys_and_certificate(setAsActive=True)
|
|
cert_arn = cert["certificateArn"]
|
|
client.create_policy(policyName=policy_name, policyDocument=doc)
|
|
client.attach_policy(policyName=policy_name, target=cert_arn)
|
|
|
|
res = client.list_attached_policies(target=cert_arn)
|
|
res.should.have.key("policies").which.should.have.length_of(1)
|
|
res["policies"][0]["policyName"].should.equal("my-policy")
|
|
|
|
client.detach_policy(policyName=policy_name, target=cert_arn)
|
|
res = client.list_attached_policies(target=cert_arn)
|
|
res.should.have.key("policies").which.should.be.empty
|
|
|
|
|
|
@mock_iot
|
|
def test_list_attached_policies():
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
cert = client.create_keys_and_certificate(setAsActive=True)
|
|
policies = client.list_attached_policies(target=cert["certificateArn"])
|
|
policies["policies"].should.be.empty
|
|
|
|
|
|
@mock_iot
|
|
def test_policy_versions():
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
policy_name = "my-policy"
|
|
doc = "{}"
|
|
|
|
policy = client.create_policy(policyName=policy_name, policyDocument=doc)
|
|
policy.should.have.key("policyName").which.should.equal(policy_name)
|
|
policy.should.have.key("policyArn").which.should_not.be.none
|
|
policy.should.have.key("policyDocument").which.should.equal(json.dumps({}))
|
|
policy.should.have.key("policyVersionId").which.should.equal("1")
|
|
|
|
policy = client.get_policy(policyName=policy_name)
|
|
policy.should.have.key("policyName").which.should.equal(policy_name)
|
|
policy.should.have.key("policyArn").which.should_not.be.none
|
|
policy.should.have.key("policyDocument").which.should.equal(json.dumps({}))
|
|
policy.should.have.key("defaultVersionId").which.should.equal(
|
|
policy["defaultVersionId"]
|
|
)
|
|
|
|
policy1 = client.create_policy_version(
|
|
policyName=policy_name,
|
|
policyDocument=json.dumps({"version": "version_1"}),
|
|
setAsDefault=True,
|
|
)
|
|
policy1.should.have.key("policyArn").which.should_not.be.none
|
|
policy1.should.have.key("policyDocument").which.should.equal(
|
|
json.dumps({"version": "version_1"})
|
|
)
|
|
policy1.should.have.key("policyVersionId").which.should.equal("2")
|
|
policy1.should.have.key("isDefaultVersion").which.should.equal(True)
|
|
|
|
policy2 = client.create_policy_version(
|
|
policyName=policy_name,
|
|
policyDocument=json.dumps({"version": "version_2"}),
|
|
setAsDefault=False,
|
|
)
|
|
policy2.should.have.key("policyArn").which.should_not.be.none
|
|
policy2.should.have.key("policyDocument").which.should.equal(
|
|
json.dumps({"version": "version_2"})
|
|
)
|
|
policy2.should.have.key("policyVersionId").which.should.equal("3")
|
|
policy2.should.have.key("isDefaultVersion").which.should.equal(False)
|
|
|
|
policy = client.get_policy(policyName=policy_name)
|
|
policy.should.have.key("policyName").which.should.equal(policy_name)
|
|
policy.should.have.key("policyArn").which.should_not.be.none
|
|
policy.should.have.key("policyDocument").which.should.equal(
|
|
json.dumps({"version": "version_1"})
|
|
)
|
|
policy.should.have.key("defaultVersionId").which.should.equal(
|
|
policy1["policyVersionId"]
|
|
)
|
|
|
|
policy_versions = client.list_policy_versions(policyName=policy_name)
|
|
policy_versions.should.have.key("policyVersions").which.should.have.length_of(3)
|
|
list(
|
|
map(lambda item: item["isDefaultVersion"], policy_versions["policyVersions"])
|
|
).count(True).should.equal(1)
|
|
default_policy = list(
|
|
filter(lambda item: item["isDefaultVersion"], policy_versions["policyVersions"])
|
|
)
|
|
default_policy[0].should.have.key("versionId").should.equal(
|
|
policy1["policyVersionId"]
|
|
)
|
|
|
|
policy = client.get_policy(policyName=policy_name)
|
|
policy.should.have.key("policyName").which.should.equal(policy_name)
|
|
policy.should.have.key("policyArn").which.should_not.be.none
|
|
policy.should.have.key("policyDocument").which.should.equal(
|
|
json.dumps({"version": "version_1"})
|
|
)
|
|
policy.should.have.key("defaultVersionId").which.should.equal(
|
|
policy1["policyVersionId"]
|
|
)
|
|
|
|
client.set_default_policy_version(
|
|
policyName=policy_name, policyVersionId=policy2["policyVersionId"]
|
|
)
|
|
policy_versions = client.list_policy_versions(policyName=policy_name)
|
|
policy_versions.should.have.key("policyVersions").which.should.have.length_of(3)
|
|
list(
|
|
map(lambda item: item["isDefaultVersion"], policy_versions["policyVersions"])
|
|
).count(True).should.equal(1)
|
|
default_policy = list(
|
|
filter(lambda item: item["isDefaultVersion"], policy_versions["policyVersions"])
|
|
)
|
|
default_policy[0].should.have.key("versionId").should.equal(
|
|
policy2["policyVersionId"]
|
|
)
|
|
|
|
policy = client.get_policy(policyName=policy_name)
|
|
policy.should.have.key("policyName").which.should.equal(policy_name)
|
|
policy.should.have.key("policyArn").which.should_not.be.none
|
|
policy.should.have.key("policyDocument").which.should.equal(
|
|
json.dumps({"version": "version_2"})
|
|
)
|
|
policy.should.have.key("defaultVersionId").which.should.equal(
|
|
policy2["policyVersionId"]
|
|
)
|
|
|
|
client.delete_policy_version(policyName=policy_name, policyVersionId="1")
|
|
policy_versions = client.list_policy_versions(policyName=policy_name)
|
|
policy_versions.should.have.key("policyVersions").which.should.have.length_of(2)
|
|
|
|
client.delete_policy_version(
|
|
policyName=policy_name, policyVersionId=policy1["policyVersionId"]
|
|
)
|
|
policy_versions = client.list_policy_versions(policyName=policy_name)
|
|
policy_versions.should.have.key("policyVersions").which.should.have.length_of(1)
|
|
|
|
# should fail as it"s the default policy. Should use delete_policy instead
|
|
try:
|
|
client.delete_policy_version(
|
|
policyName=policy_name, policyVersionId=policy2["policyVersionId"]
|
|
)
|
|
assert False, "Should have failed in previous call"
|
|
except Exception as exception:
|
|
exception.response["Error"]["Message"].should.equal(
|
|
"Cannot delete the default version of a policy"
|
|
)
|
|
|
|
|
|
@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)
|
|
|
|
with assert_raises(ClientError) as e:
|
|
client.list_thing_principals(thingName="xxx")
|
|
|
|
e.exception.response["Error"]["Code"].should.equal("ResourceNotFoundException")
|
|
e.exception.response["Error"]["Message"].should.equal(
|
|
"Failed to list principals for thing xxx because the thing does not exist in your account"
|
|
)
|
|
|
|
|
|
@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)
|
|
|
|
|
|
class TestListThingGroup:
|
|
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"
|
|
tree_dict = {
|
|
group_name_1a: {
|
|
group_name_2a: {group_name_3a: {}, group_name_3b: {}},
|
|
group_name_2b: {group_name_3c: {}, group_name_3d: {}},
|
|
},
|
|
group_name_1b: {},
|
|
}
|
|
|
|
@mock_iot
|
|
def test_should_list_all_groups(self):
|
|
# setup
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
group_catalog = generate_thing_group_tree(client, self.tree_dict)
|
|
# test
|
|
resp = client.list_thing_groups()
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(8)
|
|
|
|
@mock_iot
|
|
def test_should_list_all_groups_non_recursively(self):
|
|
# setup
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
group_catalog = generate_thing_group_tree(client, self.tree_dict)
|
|
# test
|
|
resp = client.list_thing_groups(recursive=False)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(2)
|
|
|
|
@mock_iot
|
|
def test_should_list_all_groups_filtered_by_parent(self):
|
|
# setup
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
group_catalog = generate_thing_group_tree(client, self.tree_dict)
|
|
# test
|
|
resp = client.list_thing_groups(parentGroup=self.group_name_1a)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(6)
|
|
resp = client.list_thing_groups(parentGroup=self.group_name_2a)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(2)
|
|
resp = client.list_thing_groups(parentGroup=self.group_name_1b)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(0)
|
|
with assert_raises(ClientError) as e:
|
|
client.list_thing_groups(parentGroup="inexistant-group-name")
|
|
e.exception.response["Error"]["Code"].should.equal(
|
|
"ResourceNotFoundException"
|
|
)
|
|
|
|
@mock_iot
|
|
def test_should_list_all_groups_filtered_by_parent_non_recursively(self):
|
|
# setup
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
group_catalog = generate_thing_group_tree(client, self.tree_dict)
|
|
# test
|
|
resp = client.list_thing_groups(parentGroup=self.group_name_1a, recursive=False)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(2)
|
|
resp = client.list_thing_groups(parentGroup=self.group_name_2a, recursive=False)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(2)
|
|
|
|
@mock_iot
|
|
def test_should_list_all_groups_filtered_by_name_prefix(self):
|
|
# setup
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
group_catalog = generate_thing_group_tree(client, self.tree_dict)
|
|
# test
|
|
resp = client.list_thing_groups(namePrefixFilter="my-group-name-1")
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(2)
|
|
resp = client.list_thing_groups(namePrefixFilter="my-group-name-3")
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(4)
|
|
resp = client.list_thing_groups(namePrefixFilter="prefix-which-doesn-not-match")
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(0)
|
|
|
|
@mock_iot
|
|
def test_should_list_all_groups_filtered_by_name_prefix_non_recursively(self):
|
|
# setup
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
group_catalog = generate_thing_group_tree(client, self.tree_dict)
|
|
# test
|
|
resp = client.list_thing_groups(
|
|
namePrefixFilter="my-group-name-1", recursive=False
|
|
)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(2)
|
|
resp = client.list_thing_groups(
|
|
namePrefixFilter="my-group-name-3", recursive=False
|
|
)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(0)
|
|
|
|
@mock_iot
|
|
def test_should_list_all_groups_filtered_by_name_prefix_and_parent(self):
|
|
# setup
|
|
client = boto3.client("iot", region_name="ap-northeast-1")
|
|
group_catalog = generate_thing_group_tree(client, self.tree_dict)
|
|
# test
|
|
resp = client.list_thing_groups(
|
|
namePrefixFilter="my-group-name-2", parentGroup=self.group_name_1a
|
|
)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(2)
|
|
resp = client.list_thing_groups(
|
|
namePrefixFilter="my-group-name-3", parentGroup=self.group_name_1a
|
|
)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(4)
|
|
resp = client.list_thing_groups(
|
|
namePrefixFilter="prefix-which-doesn-not-match",
|
|
parentGroup=self.group_name_1a,
|
|
)
|
|
resp.should.have.key("thingGroups")
|
|
resp["thingGroups"].should.have.length_of(0)
|
|
|
|
|
|
@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"
|
|
tree_dict = {
|
|
group_name_1a: {group_name_2a: {},},
|
|
}
|
|
group_catalog = generate_thing_group_tree(client, tree_dict)
|
|
|
|
# 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")
|
|
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"
|
|
|
|
tree_dict = {
|
|
group_name_1a: {
|
|
group_name_2a: {group_name_3a: {}, group_name_3b: {}},
|
|
group_name_2b: {group_name_3c: {}, group_name_3d: {}},
|
|
},
|
|
group_name_1b: {},
|
|
}
|
|
group_catalog = generate_thing_group_tree(client, tree_dict)
|
|
|
|
# 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(group_catalog[group_name_1a]["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(group_catalog[group_name_1a]["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(group_catalog[group_name_1a]["thingGroupArn"])
|
|
thing_group_description3a["thingGroupMetadata"]["rootToParentThingGroups"][1][
|
|
"groupName"
|
|
].should.match(group_name_2a)
|
|
thing_group_description3a["thingGroupMetadata"]["rootToParentThingGroups"][1][
|
|
"groupArn"
|
|
].should.match(group_catalog[group_name_2a]["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(group_catalog[group_name_1a]["thingGroupArn"])
|
|
thing_group_description3b["thingGroupMetadata"]["rootToParentThingGroups"][1][
|
|
"groupName"
|
|
].should.match(group_name_2a)
|
|
thing_group_description3b["thingGroupMetadata"]["rootToParentThingGroups"][1][
|
|
"groupArn"
|
|
].should.match(group_catalog[group_name_2a]["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(group_catalog[group_name_1a]["thingGroupArn"])
|
|
thing_group_description3c["thingGroupMetadata"]["rootToParentThingGroups"][1][
|
|
"groupName"
|
|
].should.match(group_name_2b)
|
|
thing_group_description3c["thingGroupMetadata"]["rootToParentThingGroups"][1][
|
|
"groupArn"
|
|
].should.match(group_catalog[group_name_2b]["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(group_catalog[group_name_1a]["thingGroupArn"])
|
|
thing_group_description3d["thingGroupMetadata"]["rootToParentThingGroups"][1][
|
|
"groupName"
|
|
].should.match(group_name_2b)
|
|
thing_group_description3d["thingGroupMetadata"]["rootToParentThingGroups"][1][
|
|
"groupArn"
|
|
].should.match(group_catalog[group_name_2b]["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# job document
|
|
# job_document = {
|
|
# "field": "value"
|
|
# }
|
|
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_list_jobs():
|
|
client = boto3.client("iot", region_name="eu-west-1")
|
|
name = "my-thing"
|
|
job_id = "TestJob"
|
|
# thing# job document
|
|
# job_document = {
|
|
# "field": "value"
|
|
# }
|
|
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"}
|
|
|
|
job1 = 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},
|
|
)
|
|
|
|
job1.should.have.key("jobId").which.should.equal(job_id)
|
|
job1.should.have.key("jobArn")
|
|
job1.should.have.key("description")
|
|
|
|
job2 = client.create_job(
|
|
jobId=job_id + "1",
|
|
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},
|
|
)
|
|
|
|
job2.should.have.key("jobId").which.should.equal(job_id + "1")
|
|
job2.should.have.key("jobArn")
|
|
job2.should.have.key("description")
|
|
|
|
jobs = client.list_jobs()
|
|
jobs.should.have.key("jobs")
|
|
jobs.should_not.have.key("nextToken")
|
|
jobs["jobs"][0].should.have.key("jobId").which.should.equal(job_id)
|
|
jobs["jobs"][1].should.have.key("jobId").which.should.equal(job_id + "1")
|
|
|
|
|
|
@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)
|
|
|
|
|
|
@mock_iot
|
|
def test_delete_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("job")
|
|
job.should.have.key("job").which.should.have.key("jobId").which.should.equal(job_id)
|
|
|
|
client.delete_job(jobId=job_id)
|
|
|
|
client.list_jobs()["jobs"].should.have.length_of(0)
|
|
|
|
|
|
@mock_iot
|
|
def test_cancel_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("job")
|
|
job.should.have.key("job").which.should.have.key("jobId").which.should.equal(job_id)
|
|
|
|
job = client.cancel_job(jobId=job_id, reasonCode="Because", comment="You are")
|
|
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("jobId").which.should.equal(job_id)
|
|
job.should.have.key("job").which.should.have.key("status").which.should.equal(
|
|
"CANCELED"
|
|
)
|
|
job.should.have.key("job").which.should.have.key(
|
|
"forceCanceled"
|
|
).which.should.equal(False)
|
|
job.should.have.key("job").which.should.have.key("reasonCode").which.should.equal(
|
|
"Because"
|
|
)
|
|
job.should.have.key("job").which.should.have.key("comment").which.should.equal(
|
|
"You are"
|
|
)
|
|
|
|
|
|
@mock_iot
|
|
def test_get_job_document_with_document_source():
|
|
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_document = client.get_job_document(jobId=job_id)
|
|
job_document.should.have.key("document").which.should.equal("")
|
|
|
|
|
|
@mock_iot
|
|
def test_get_job_document_with_document():
|
|
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_document = client.get_job_document(jobId=job_id)
|
|
job_document.should.have.key("document").which.should.equal('{"field": "value"}')
|
|
|
|
|
|
@mock_iot
|
|
def test_describe_job_execution():
|
|
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")
|
|
|
|
job_execution = client.describe_job_execution(jobId=job_id, thingName=name)
|
|
job_execution.should.have.key("execution")
|
|
job_execution["execution"].should.have.key("jobId").which.should.equal(job_id)
|
|
job_execution["execution"].should.have.key("status").which.should.equal("QUEUED")
|
|
job_execution["execution"].should.have.key("forceCanceled").which.should.equal(
|
|
False
|
|
)
|
|
job_execution["execution"].should.have.key("statusDetails").which.should.equal(
|
|
{"detailsMap": {}}
|
|
)
|
|
job_execution["execution"].should.have.key("thingArn").which.should.equal(
|
|
thing["thingArn"]
|
|
)
|
|
job_execution["execution"].should.have.key("queuedAt")
|
|
job_execution["execution"].should.have.key("startedAt")
|
|
job_execution["execution"].should.have.key("lastUpdatedAt")
|
|
job_execution["execution"].should.have.key("executionNumber").which.should.equal(
|
|
123
|
|
)
|
|
job_execution["execution"].should.have.key("versionNumber").which.should.equal(123)
|
|
job_execution["execution"].should.have.key(
|
|
"approximateSecondsBeforeTimedOut"
|
|
).which.should.equal(123)
|
|
|
|
job_execution = client.describe_job_execution(
|
|
jobId=job_id, thingName=name, executionNumber=123
|
|
)
|
|
job_execution.should.have.key("execution")
|
|
job_execution["execution"].should.have.key("jobId").which.should.equal(job_id)
|
|
job_execution["execution"].should.have.key("status").which.should.equal("QUEUED")
|
|
job_execution["execution"].should.have.key("forceCanceled").which.should.equal(
|
|
False
|
|
)
|
|
job_execution["execution"].should.have.key("statusDetails").which.should.equal(
|
|
{"detailsMap": {}}
|
|
)
|
|
job_execution["execution"].should.have.key("thingArn").which.should.equal(
|
|
thing["thingArn"]
|
|
)
|
|
job_execution["execution"].should.have.key("queuedAt")
|
|
job_execution["execution"].should.have.key("startedAt")
|
|
job_execution["execution"].should.have.key("lastUpdatedAt")
|
|
job_execution["execution"].should.have.key("executionNumber").which.should.equal(
|
|
123
|
|
)
|
|
job_execution["execution"].should.have.key("versionNumber").which.should.equal(123)
|
|
job_execution["execution"].should.have.key(
|
|
"approximateSecondsBeforeTimedOut"
|
|
).which.should.equal(123)
|
|
|
|
try:
|
|
client.describe_job_execution(jobId=job_id, thingName=name, executionNumber=456)
|
|
except ClientError as exc:
|
|
error_code = exc.response["Error"]["Code"]
|
|
error_code.should.equal("ResourceNotFoundException")
|
|
else:
|
|
raise Exception("Should have raised error")
|
|
|
|
|
|
@mock_iot
|
|
def test_cancel_job_execution():
|
|
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")
|
|
|
|
client.cancel_job_execution(jobId=job_id, thingName=name)
|
|
job_execution = client.describe_job_execution(jobId=job_id, thingName=name)
|
|
job_execution.should.have.key("execution")
|
|
job_execution["execution"].should.have.key("status").which.should.equal("CANCELED")
|
|
|
|
|
|
@mock_iot
|
|
def test_delete_job_execution():
|
|
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")
|
|
|
|
client.delete_job_execution(jobId=job_id, thingName=name, executionNumber=123)
|
|
try:
|
|
client.describe_job_execution(jobId=job_id, thingName=name, executionNumber=123)
|
|
except ClientError as exc:
|
|
error_code = exc.response["Error"]["Code"]
|
|
error_code.should.equal("ResourceNotFoundException")
|
|
else:
|
|
raise Exception("Should have raised error")
|
|
|
|
|
|
@mock_iot
|
|
def test_list_job_executions_for_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")
|
|
|
|
job_execution = client.list_job_executions_for_job(jobId=job_id)
|
|
job_execution.should.have.key("executionSummaries")
|
|
job_execution["executionSummaries"][0].should.have.key(
|
|
"thingArn"
|
|
).which.should.equal(thing["thingArn"])
|
|
|
|
|
|
@mock_iot
|
|
def test_list_job_executions_for_thing():
|
|
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")
|
|
|
|
job_execution = client.list_job_executions_for_thing(thingName=name)
|
|
job_execution.should.have.key("executionSummaries")
|
|
job_execution["executionSummaries"][0].should.have.key("jobId").which.should.equal(
|
|
job_id
|
|
)
|