added IoT job_execution and job mocks
This commit is contained in:
parent
3ea673b3d0
commit
cfd12b6d19
File diff suppressed because it is too large
Load Diff
@ -24,6 +24,15 @@ class InvalidRequestException(IoTClientError):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidStateTransitionException(IoTClientError):
|
||||||
|
def __init__(self, msg=None):
|
||||||
|
self.code = 409
|
||||||
|
super(InvalidStateTransitionException, self).__init__(
|
||||||
|
"InvalidStateTransitionException",
|
||||||
|
msg or "An attempt was made to change to an invalid state."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class VersionConflictException(IoTClientError):
|
class VersionConflictException(IoTClientError):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.code = 409
|
self.code = 409
|
||||||
|
@ -15,6 +15,7 @@ from moto.core import BaseBackend, BaseModel
|
|||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
ResourceNotFoundException,
|
ResourceNotFoundException,
|
||||||
InvalidRequestException,
|
InvalidRequestException,
|
||||||
|
InvalidStateTransitionException,
|
||||||
VersionConflictException
|
VersionConflictException
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -247,7 +248,6 @@ class FakeJob(BaseModel):
|
|||||||
self.document_parameters = document_parameters
|
self.document_parameters = document_parameters
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
|
||||||
obj = {
|
obj = {
|
||||||
'jobArn': self.job_arn,
|
'jobArn': self.job_arn,
|
||||||
'jobId': self.job_id,
|
'jobId': self.job_id,
|
||||||
@ -260,7 +260,7 @@ class FakeJob(BaseModel):
|
|||||||
'comment': self.comment,
|
'comment': self.comment,
|
||||||
'createdAt': self.created_at,
|
'createdAt': self.created_at,
|
||||||
'lastUpdatedAt': self.last_updated_at,
|
'lastUpdatedAt': self.last_updated_at,
|
||||||
'completedAt': self.completedAt,
|
'completedAt': self.completed_at,
|
||||||
'jobProcessDetails': self.job_process_details,
|
'jobProcessDetails': self.job_process_details,
|
||||||
'documentParameters': self.document_parameters,
|
'documentParameters': self.document_parameters,
|
||||||
'document': self.document,
|
'document': self.document,
|
||||||
@ -290,13 +290,13 @@ class FakeJobExecution(BaseModel):
|
|||||||
self.version_number = 123
|
self.version_number = 123
|
||||||
self.approximate_seconds_before_time_out = 123
|
self.approximate_seconds_before_time_out = 123
|
||||||
|
|
||||||
def to_dict(self):
|
def to_get_dict(self):
|
||||||
obj = {
|
obj = {
|
||||||
'jobId': self.job_id,
|
'jobId': self.job_id,
|
||||||
'status': self.status,
|
'status': self.status,
|
||||||
'forceCancel': self.force_canceled,
|
'forceCanceled': self.force_canceled,
|
||||||
'statusDetails': {'detailsMap': self.status_details_map},
|
'statusDetails': {'detailsMap': self.status_details_map},
|
||||||
'thing_arn': self.thing_arn,
|
'thingArn': self.thing_arn,
|
||||||
'queuedAt': self.queued_at,
|
'queuedAt': self.queued_at,
|
||||||
'startedAt': self.started_at,
|
'startedAt': self.started_at,
|
||||||
'lastUpdatedAt': self.last_updated_at,
|
'lastUpdatedAt': self.last_updated_at,
|
||||||
@ -307,6 +307,21 @@ class FakeJobExecution(BaseModel):
|
|||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
obj = {
|
||||||
|
'jobId': self.job_id,
|
||||||
|
'thingArn': self.thing_arn,
|
||||||
|
'jobExecutionSummary': {
|
||||||
|
'status': self.status,
|
||||||
|
'queuedAt': self.queued_at,
|
||||||
|
'startedAt': self.started_at,
|
||||||
|
'lastUpdatedAt': self.last_updated_at,
|
||||||
|
'executionNumber': self.execution_number,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
class IoTBackend(BaseBackend):
|
class IoTBackend(BaseBackend):
|
||||||
def __init__(self, region_name=None):
|
def __init__(self, region_name=None):
|
||||||
@ -760,24 +775,114 @@ class IoTBackend(BaseBackend):
|
|||||||
self.jobs[job_id] = job
|
self.jobs[job_id] = job
|
||||||
|
|
||||||
for thing_arn in targets:
|
for thing_arn in targets:
|
||||||
thing_name = thing_arn.split(':')[-1]
|
thing_name = thing_arn.split(':')[-1].split('/')[-1]
|
||||||
job_execution = FakeJobExecution(job_id, thing_arn)
|
job_execution = FakeJobExecution(job_id, thing_arn)
|
||||||
self.job_executions[(job_id, thing_name)] = job_execution
|
self.job_executions[(job_id, thing_name)] = job_execution
|
||||||
return job.job_arn, job_id, description
|
return job.job_arn, job_id, description
|
||||||
|
|
||||||
def describe_job(self, job_id):
|
def describe_job(self, job_id):
|
||||||
return self.jobs[job_id]
|
jobs = [_ for _ in self.jobs.values() if _.job_id == job_id]
|
||||||
|
if len(jobs) == 0:
|
||||||
|
raise ResourceNotFoundException()
|
||||||
|
return jobs[0]
|
||||||
|
|
||||||
def get_job_document(self, job_id):
|
def get_job_document(self, job_id):
|
||||||
return self.jobs[job_id]
|
return self.jobs[job_id]
|
||||||
|
|
||||||
|
def list_jobs(self, status, target_selection, max_results, token, thing_group_name, thing_group_id):
|
||||||
|
# TODO: implement filters
|
||||||
|
all_jobs = [_.to_dict() for _ in self.jobs.values()]
|
||||||
|
filtered_jobs = all_jobs
|
||||||
|
|
||||||
|
if token is None:
|
||||||
|
jobs = filtered_jobs[0:max_results]
|
||||||
|
next_token = str(max_results) if len(filtered_jobs) > max_results else None
|
||||||
|
else:
|
||||||
|
token = int(token)
|
||||||
|
jobs = filtered_jobs[token:token + max_results]
|
||||||
|
next_token = str(token + max_results) if len(filtered_jobs) > token + max_results else None
|
||||||
|
|
||||||
|
return jobs, next_token
|
||||||
|
|
||||||
def describe_job_execution(self, job_id, thing_name, execution_number):
|
def describe_job_execution(self, job_id, thing_name, execution_number):
|
||||||
# TODO filter with execution number
|
try:
|
||||||
return self.job_executions[(job_id, thing_name)]
|
job_execution = self.job_executions[(job_id, thing_name)]
|
||||||
|
except KeyError:
|
||||||
|
raise ResourceNotFoundException()
|
||||||
|
|
||||||
|
if job_execution is None or \
|
||||||
|
(execution_number is not None and job_execution.execution_number != execution_number):
|
||||||
|
raise ResourceNotFoundException()
|
||||||
|
|
||||||
|
return job_execution
|
||||||
|
|
||||||
|
def cancel_job_execution(self, job_id, thing_name, force, expected_version, status_details):
|
||||||
|
job_execution = self.job_executions[(job_id, thing_name)]
|
||||||
|
|
||||||
|
if job_execution is None:
|
||||||
|
raise ResourceNotFoundException()
|
||||||
|
|
||||||
|
job_execution.force_canceled = force if force is not None else job_execution.force_canceled
|
||||||
|
# TODO: implement expected_version and status_details (at most 10 can be specified)
|
||||||
|
|
||||||
|
if job_execution.status == 'IN_PROGRESS' and force:
|
||||||
|
job_execution.status = 'CANCELED'
|
||||||
|
self.job_executions[(job_id, thing_name)] = job_execution
|
||||||
|
elif job_execution.status != 'IN_PROGRESS':
|
||||||
|
job_execution.status = 'CANCELED'
|
||||||
|
self.job_executions[(job_id, thing_name)] = job_execution
|
||||||
|
else:
|
||||||
|
raise InvalidStateTransitionException()
|
||||||
|
|
||||||
|
def delete_job_execution(self, job_id, thing_name, execution_number, force):
|
||||||
|
job_execution = self.job_executions[(job_id, thing_name)]
|
||||||
|
|
||||||
|
if job_execution.execution_number != execution_number:
|
||||||
|
raise ResourceNotFoundException()
|
||||||
|
|
||||||
|
if job_execution.status == 'IN_PROGRESS' and force:
|
||||||
|
del self.job_executions[(job_id, thing_name)]
|
||||||
|
elif job_execution.status != 'IN_PROGRESS':
|
||||||
|
del self.job_executions[(job_id, thing_name)]
|
||||||
|
else:
|
||||||
|
raise InvalidStateTransitionException()
|
||||||
|
|
||||||
def list_job_executions_for_job(self, job_id, status, max_results, next_token):
|
def list_job_executions_for_job(self, job_id, status, max_results, next_token):
|
||||||
job_executions = [self.job_executions[je] for je in self.job_executions if je[0] == job_id]
|
job_executions = [self.job_executions[je].to_dict() for je in self.job_executions if je[0] == job_id]
|
||||||
# TODO: implement filters
|
|
||||||
|
if status is not None:
|
||||||
|
job_executions = list(filter(lambda elem:
|
||||||
|
status in elem["status"] and
|
||||||
|
elem["status"] == status, job_executions))
|
||||||
|
|
||||||
|
token = next_token
|
||||||
|
if token is None:
|
||||||
|
job_executions = job_executions[0:max_results]
|
||||||
|
next_token = str(max_results) if len(job_executions) > max_results else None
|
||||||
|
else:
|
||||||
|
token = int(token)
|
||||||
|
job_executions = job_executions[token:token + max_results]
|
||||||
|
next_token = str(token + max_results) if len(job_executions) > token + max_results else None
|
||||||
|
|
||||||
|
return job_executions, next_token
|
||||||
|
|
||||||
|
def list_job_executions_for_thing(self, thing_name, status, max_results, next_token):
|
||||||
|
job_executions = [self.job_executions[je].to_dict() for je in self.job_executions if je[1] == thing_name]
|
||||||
|
|
||||||
|
if status is not None:
|
||||||
|
job_executions = list(filter(lambda elem:
|
||||||
|
status in elem["status"] and
|
||||||
|
elem["status"] == status, job_executions))
|
||||||
|
|
||||||
|
token = next_token
|
||||||
|
if token is None:
|
||||||
|
job_executions = job_executions[0:max_results]
|
||||||
|
next_token = str(max_results) if len(job_executions) > max_results else None
|
||||||
|
else:
|
||||||
|
token = int(token)
|
||||||
|
job_executions = job_executions[token:token + max_results]
|
||||||
|
next_token = str(token + max_results) if len(job_executions) > token + max_results else None
|
||||||
|
|
||||||
return job_executions, next_token
|
return job_executions, next_token
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,15 +160,83 @@ class IoTResponse(BaseResponse):
|
|||||||
# TODO: needs to be implemented to get document_source's content from S3
|
# TODO: needs to be implemented to get document_source's content from S3
|
||||||
return json.dumps({'document': ''})
|
return json.dumps({'document': ''})
|
||||||
|
|
||||||
def list_job_executions_for_job(self):
|
def list_jobs(self):
|
||||||
job_executions, next_token = self.iot_backend.list_job_executions_for_job(job_id=self._get_param("jobId"),
|
status = self._get_param("status"),
|
||||||
status=self._get_param("status"),
|
target_selection = self._get_param("targetSelection"),
|
||||||
max_results=self._get_param(
|
max_results = self._get_int_param("maxResults", 50) # not the default, but makes testing easier
|
||||||
"maxResults"),
|
previous_next_token = self._get_param("nextToken")
|
||||||
next_token=self._get_param(
|
thing_group_name = self._get_param("thingGroupName"),
|
||||||
"nextToken"))
|
thing_group_id = self._get_param("thingGroupId")
|
||||||
|
jobs, next_token = self.iot_backend.list_jobs(status=status,
|
||||||
|
target_selection=target_selection,
|
||||||
|
max_results=max_results,
|
||||||
|
token=previous_next_token,
|
||||||
|
thing_group_name=thing_group_name,
|
||||||
|
thing_group_id=thing_group_id)
|
||||||
|
|
||||||
return json.dumps(dict(executionSummaries=[_.to_dict() for _ in job_executions], nextToken=next_token))
|
return json.dumps(dict(jobs=jobs, nextToken=next_token))
|
||||||
|
|
||||||
|
def describe_job_execution(self):
|
||||||
|
job_id = self._get_param("jobId")
|
||||||
|
thing_name = self._get_param("thingName")
|
||||||
|
execution_number = self._get_int_param("executionNumber")
|
||||||
|
job_execution = self.iot_backend.describe_job_execution(job_id=job_id,
|
||||||
|
thing_name=thing_name,
|
||||||
|
execution_number=execution_number)
|
||||||
|
|
||||||
|
return json.dumps(dict(execution=job_execution.to_get_dict()))
|
||||||
|
|
||||||
|
def cancel_job_execution(self):
|
||||||
|
job_id = self._get_param("jobId")
|
||||||
|
thing_name = self._get_param("thingName")
|
||||||
|
force = self._get_bool_param("force")
|
||||||
|
expected_version = self._get_int_param("expectedVersion")
|
||||||
|
status_details = self._get_param("statusDetails")
|
||||||
|
|
||||||
|
self.iot_backend.cancel_job_execution(job_id=job_id,
|
||||||
|
thing_name=thing_name,
|
||||||
|
force=force,
|
||||||
|
expected_version=expected_version,
|
||||||
|
status_details=status_details)
|
||||||
|
|
||||||
|
return json.dumps(dict())
|
||||||
|
|
||||||
|
def delete_job_execution(self):
|
||||||
|
job_id = self._get_param("jobId")
|
||||||
|
thing_name = self._get_param("thingName")
|
||||||
|
execution_number = self._get_int_param("executionNumber")
|
||||||
|
force = self._get_bool_param("force")
|
||||||
|
|
||||||
|
self.iot_backend.delete_job_execution(job_id=job_id,
|
||||||
|
thing_name=thing_name,
|
||||||
|
execution_number=execution_number,
|
||||||
|
force=force)
|
||||||
|
|
||||||
|
return json.dumps(dict())
|
||||||
|
|
||||||
|
def list_job_executions_for_job(self):
|
||||||
|
job_id = self._get_param("jobId")
|
||||||
|
status = self._get_param("status")
|
||||||
|
max_results = self._get_int_param("maxResults", 50) # not the default, but makes testing easier
|
||||||
|
next_token = self._get_param("nextToken")
|
||||||
|
job_executions, next_token = self.iot_backend.list_job_executions_for_job(job_id=job_id,
|
||||||
|
status=status,
|
||||||
|
max_results=max_results,
|
||||||
|
next_token=next_token)
|
||||||
|
|
||||||
|
return json.dumps(dict(executionSummaries=job_executions, nextToken=next_token))
|
||||||
|
|
||||||
|
def list_job_executions_for_thing(self):
|
||||||
|
thing_name = self._get_param("thingName")
|
||||||
|
status = self._get_param("status")
|
||||||
|
max_results = self._get_int_param("maxResults", 50) # not the default, but makes testing easier
|
||||||
|
next_token = self._get_param("nextToken")
|
||||||
|
job_executions, next_token = self.iot_backend.list_job_executions_for_thing(thing_name=thing_name,
|
||||||
|
status=status,
|
||||||
|
max_results=max_results,
|
||||||
|
next_token=next_token)
|
||||||
|
|
||||||
|
return json.dumps(dict(executionSummaries=job_executions, nextToken=next_token))
|
||||||
|
|
||||||
def create_keys_and_certificate(self):
|
def create_keys_and_certificate(self):
|
||||||
set_as_active = self._get_bool_param("setAsActive")
|
set_as_active = self._get_bool_param("setAsActive")
|
||||||
|
@ -4,9 +4,9 @@ import json
|
|||||||
import sure #noqa
|
import sure #noqa
|
||||||
import boto3
|
import boto3
|
||||||
|
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
from moto import mock_iot
|
from moto import mock_iot
|
||||||
|
|
||||||
|
|
||||||
@mock_iot
|
@mock_iot
|
||||||
def test_attach_policy():
|
def test_attach_policy():
|
||||||
client = boto3.client('iot', region_name='ap-northeast-1')
|
client = boto3.client('iot', region_name='ap-northeast-1')
|
||||||
@ -711,6 +711,69 @@ def test_create_job():
|
|||||||
job.should.have.key('description')
|
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
|
@mock_iot
|
||||||
def test_describe_job():
|
def test_describe_job():
|
||||||
client = boto3.client('iot', region_name='eu-west-1')
|
client = boto3.client('iot', region_name='eu-west-1')
|
||||||
@ -875,6 +938,162 @@ def test_get_job_document_with_document():
|
|||||||
job_document = client.get_job_document(jobId=job_id)
|
job_document = client.get_job_document(jobId=job_id)
|
||||||
job_document.should.have.key('document').which.should.equal("{\"field\": \"value\"}")
|
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
|
@mock_iot
|
||||||
def test_list_job_executions_for_job():
|
def test_list_job_executions_for_job():
|
||||||
client = boto3.client('iot', region_name='eu-west-1')
|
client = boto3.client('iot', region_name='eu-west-1')
|
||||||
@ -911,5 +1130,44 @@ def test_list_job_executions_for_job():
|
|||||||
|
|
||||||
job_execution = client.list_job_executions_for_job(jobId=job_id)
|
job_execution = client.list_job_executions_for_job(jobId=job_id)
|
||||||
job_execution.should.have.key('executionSummaries')
|
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['executionSummaries'][0].should.have.key('jobId').which.should.equal(job_id)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user