import boto3 import json import pytest from botocore.exceptions import ClientError from moto import mock_iot @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) with pytest.raises(ClientError) as exc: client.describe_job_execution(jobId=job_id, thingName=name, executionNumber=456) error_code = exc.value.response["Error"]["Code"] error_code.should.equal("ResourceNotFoundException") @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) with pytest.raises(ClientError) as exc: client.describe_job_execution(jobId=job_id, thingName=name, executionNumber=123) error_code = exc.value.response["Error"]["Code"] error_code.should.equal("ResourceNotFoundException") @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"]) job_execution = client.list_job_executions_for_job(jobId=job_id, status="QUEUED") 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 ) job_execution = client.list_job_executions_for_thing( thingName=name, status="QUEUED" ) job_execution.should.have.key("executionSummaries") job_execution["executionSummaries"][0].should.have.key("jobId").which.should.equal( job_id ) @mock_iot def test_list_job_executions_for_thing_paginated(): client = boto3.client("iot", region_name="eu-west-1") name = "my-thing" thing = client.create_thing(thingName=name) for idx in range(0, 10): client.create_job( jobId=f"TestJob_{idx}", targets=[thing["thingArn"]], document=json.dumps({"field": "value"}), ) res = client.list_job_executions_for_thing(thingName=name, maxResults=2) executions = res["executionSummaries"] executions.should.have.length_of(2) res.should.have.key("nextToken") res = client.list_job_executions_for_thing( thingName=name, maxResults=1, nextToken=res["nextToken"] ) executions = res["executionSummaries"] executions.should.have.length_of(1) res.should.have.key("nextToken") res = client.list_job_executions_for_thing( thingName=name, nextToken=res["nextToken"] ) executions = res["executionSummaries"] executions.should.have.length_of(7) res.shouldnt.have.key("nextToken")