Merge pull request #1634 from sthuber90/master

Fixes #1624 and closes #1633
This commit is contained in:
Steve Pulec 2018-06-01 07:31:15 -04:00 committed by GitHub
commit 0f816566df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 381 additions and 26 deletions

View File

@ -58,6 +58,7 @@
- [ ] get_room - [ ] get_room
- [ ] get_room_skill_parameter - [ ] get_room_skill_parameter
- [ ] get_skill_group - [ ] get_skill_group
- [ ] list_device_events
- [ ] list_skills - [ ] list_skills
- [ ] list_tags - [ ] list_tags
- [ ] put_room_skill_parameter - [ ] put_room_skill_parameter
@ -351,6 +352,7 @@
- [ ] delete_scaling_plan - [ ] delete_scaling_plan
- [ ] describe_scaling_plan_resources - [ ] describe_scaling_plan_resources
- [ ] describe_scaling_plans - [ ] describe_scaling_plans
- [ ] update_scaling_plan
## batch - 93% implemented ## batch - 93% implemented
- [ ] cancel_job - [ ] cancel_job
@ -434,6 +436,7 @@
- [ ] get_applied_schema_version - [ ] get_applied_schema_version
- [ ] get_directory - [ ] get_directory
- [ ] get_facet - [ ] get_facet
- [ ] get_object_attributes
- [ ] get_object_information - [ ] get_object_information
- [ ] get_schema_as_json - [ ] get_schema_as_json
- [ ] get_typed_link_facet_information - [ ] get_typed_link_facet_information
@ -764,6 +767,8 @@
- [ ] create_pipeline - [ ] create_pipeline
- [ ] delete_custom_action_type - [ ] delete_custom_action_type
- [ ] delete_pipeline - [ ] delete_pipeline
- [ ] delete_webhook
- [ ] deregister_webhook_with_third_party
- [ ] disable_stage_transition - [ ] disable_stage_transition
- [ ] enable_stage_transition - [ ] enable_stage_transition
- [ ] get_job_details - [ ] get_job_details
@ -774,6 +779,7 @@
- [ ] list_action_types - [ ] list_action_types
- [ ] list_pipeline_executions - [ ] list_pipeline_executions
- [ ] list_pipelines - [ ] list_pipelines
- [ ] list_webhooks
- [ ] poll_for_jobs - [ ] poll_for_jobs
- [ ] poll_for_third_party_jobs - [ ] poll_for_third_party_jobs
- [ ] put_action_revision - [ ] put_action_revision
@ -782,6 +788,8 @@
- [ ] put_job_success_result - [ ] put_job_success_result
- [ ] put_third_party_job_failure_result - [ ] put_third_party_job_failure_result
- [ ] put_third_party_job_success_result - [ ] put_third_party_job_success_result
- [ ] put_webhook
- [ ] register_webhook_with_third_party
- [ ] retry_stage_execution - [ ] retry_stage_execution
- [ ] start_pipeline_execution - [ ] start_pipeline_execution
- [ ] update_pipeline - [ ] update_pipeline
@ -1057,6 +1065,7 @@
- [ ] create_project - [ ] create_project
- [ ] create_remote_access_session - [ ] create_remote_access_session
- [ ] create_upload - [ ] create_upload
- [ ] create_vpce_configuration
- [ ] delete_device_pool - [ ] delete_device_pool
- [ ] delete_instance_profile - [ ] delete_instance_profile
- [ ] delete_network_profile - [ ] delete_network_profile
@ -1064,6 +1073,7 @@
- [ ] delete_remote_access_session - [ ] delete_remote_access_session
- [ ] delete_run - [ ] delete_run
- [ ] delete_upload - [ ] delete_upload
- [ ] delete_vpce_configuration
- [ ] get_account_settings - [ ] get_account_settings
- [ ] get_device - [ ] get_device
- [ ] get_device_instance - [ ] get_device_instance
@ -1079,6 +1089,7 @@
- [ ] get_suite - [ ] get_suite
- [ ] get_test - [ ] get_test
- [ ] get_upload - [ ] get_upload
- [ ] get_vpce_configuration
- [ ] install_to_remote_access_session - [ ] install_to_remote_access_session
- [ ] list_artifacts - [ ] list_artifacts
- [ ] list_device_instances - [ ] list_device_instances
@ -1098,6 +1109,7 @@
- [ ] list_tests - [ ] list_tests
- [ ] list_unique_problems - [ ] list_unique_problems
- [ ] list_uploads - [ ] list_uploads
- [ ] list_vpce_configurations
- [ ] purchase_offering - [ ] purchase_offering
- [ ] renew_offering - [ ] renew_offering
- [ ] schedule_run - [ ] schedule_run
@ -1108,6 +1120,7 @@
- [ ] update_instance_profile - [ ] update_instance_profile
- [ ] update_network_profile - [ ] update_network_profile
- [ ] update_project - [ ] update_project
- [ ] update_vpce_configuration
## directconnect - 0% implemented ## directconnect - 0% implemented
- [ ] allocate_connection_on_interconnect - [ ] allocate_connection_on_interconnect
@ -1264,7 +1277,7 @@
- [ ] update_radius - [ ] update_radius
- [ ] verify_trust - [ ] verify_trust
## dynamodb - 22% implemented ## dynamodb - 21% implemented
- [ ] batch_get_item - [ ] batch_get_item
- [ ] batch_write_item - [ ] batch_write_item
- [ ] create_backup - [ ] create_backup
@ -1276,6 +1289,7 @@
- [ ] describe_backup - [ ] describe_backup
- [ ] describe_continuous_backups - [ ] describe_continuous_backups
- [ ] describe_global_table - [ ] describe_global_table
- [ ] describe_global_table_settings
- [ ] describe_limits - [ ] describe_limits
- [ ] describe_table - [ ] describe_table
- [ ] describe_time_to_live - [ ] describe_time_to_live
@ -1293,6 +1307,7 @@
- [ ] untag_resource - [ ] untag_resource
- [ ] update_continuous_backups - [ ] update_continuous_backups
- [ ] update_global_table - [ ] update_global_table
- [ ] update_global_table_settings
- [ ] update_item - [ ] update_item
- [ ] update_table - [ ] update_table
- [ ] update_time_to_live - [ ] update_time_to_live
@ -1341,6 +1356,7 @@
- [ ] create_default_vpc - [ ] create_default_vpc
- [X] create_dhcp_options - [X] create_dhcp_options
- [ ] create_egress_only_internet_gateway - [ ] create_egress_only_internet_gateway
- [ ] create_fleet
- [ ] create_flow_logs - [ ] create_flow_logs
- [ ] create_fpga_image - [ ] create_fpga_image
- [X] create_image - [X] create_image
@ -1375,6 +1391,7 @@
- [X] delete_customer_gateway - [X] delete_customer_gateway
- [ ] delete_dhcp_options - [ ] delete_dhcp_options
- [ ] delete_egress_only_internet_gateway - [ ] delete_egress_only_internet_gateway
- [ ] delete_fleets
- [ ] delete_flow_logs - [ ] delete_flow_logs
- [ ] delete_fpga_image - [ ] delete_fpga_image
- [X] delete_internet_gateway - [X] delete_internet_gateway
@ -1416,6 +1433,9 @@
- [ ] describe_egress_only_internet_gateways - [ ] describe_egress_only_internet_gateways
- [ ] describe_elastic_gpus - [ ] describe_elastic_gpus
- [ ] describe_export_tasks - [ ] describe_export_tasks
- [ ] describe_fleet_history
- [ ] describe_fleet_instances
- [ ] describe_fleets
- [ ] describe_flow_logs - [ ] describe_flow_logs
- [ ] describe_fpga_image_attribute - [ ] describe_fpga_image_attribute
- [ ] describe_fpga_images - [ ] describe_fpga_images
@ -1512,6 +1532,7 @@
- [X] import_key_pair - [X] import_key_pair
- [ ] import_snapshot - [ ] import_snapshot
- [ ] import_volume - [ ] import_volume
- [ ] modify_fleet
- [ ] modify_fpga_image_attribute - [ ] modify_fpga_image_attribute
- [ ] modify_hosts - [ ] modify_hosts
- [ ] modify_id_format - [ ] modify_id_format
@ -1884,8 +1905,11 @@
- [ ] delete_delivery_stream - [ ] delete_delivery_stream
- [ ] describe_delivery_stream - [ ] describe_delivery_stream
- [ ] list_delivery_streams - [ ] list_delivery_streams
- [ ] list_tags_for_delivery_stream
- [ ] put_record - [ ] put_record
- [ ] put_record_batch - [ ] put_record_batch
- [ ] tag_delivery_stream
- [ ] untag_delivery_stream
- [ ] update_destination - [ ] update_destination
## fms - 0% implemented ## fms - 0% implemented
@ -2375,7 +2399,7 @@
- [ ] unsubscribe_from_event - [ ] unsubscribe_from_event
- [ ] update_assessment_target - [ ] update_assessment_target
## iot - 29% implemented ## iot - 30% implemented
- [ ] accept_certificate_transfer - [ ] accept_certificate_transfer
- [X] add_thing_to_thing_group - [X] add_thing_to_thing_group
- [ ] associate_targets_with_job - [ ] associate_targets_with_job
@ -2387,7 +2411,7 @@
- [ ] clear_default_authorizer - [ ] clear_default_authorizer
- [ ] create_authorizer - [ ] create_authorizer
- [ ] create_certificate_from_csr - [ ] create_certificate_from_csr
- [ ] create_job - [X] create_job
- [X] create_keys_and_certificate - [X] create_keys_and_certificate
- [ ] create_ota_update - [ ] create_ota_update
- [X] create_policy - [X] create_policy
@ -2420,7 +2444,7 @@
- [ ] describe_endpoint - [ ] describe_endpoint
- [ ] describe_event_configurations - [ ] describe_event_configurations
- [ ] describe_index - [ ] describe_index
- [ ] describe_job - [X] describe_job
- [ ] describe_job_execution - [ ] describe_job_execution
- [ ] describe_role_alias - [ ] describe_role_alias
- [ ] describe_stream - [ ] describe_stream
@ -2512,6 +2536,38 @@
- [ ] start_next_pending_job_execution - [ ] start_next_pending_job_execution
- [ ] update_job_execution - [ ] update_job_execution
## iotanalytics - 0% implemented
- [ ] batch_put_message
- [ ] cancel_pipeline_reprocessing
- [ ] create_channel
- [ ] create_dataset
- [ ] create_dataset_content
- [ ] create_datastore
- [ ] create_pipeline
- [ ] delete_channel
- [ ] delete_dataset
- [ ] delete_dataset_content
- [ ] delete_datastore
- [ ] delete_pipeline
- [ ] describe_channel
- [ ] describe_dataset
- [ ] describe_datastore
- [ ] describe_logging_options
- [ ] describe_pipeline
- [ ] get_dataset_content
- [ ] list_channels
- [ ] list_datasets
- [ ] list_datastores
- [ ] list_pipelines
- [ ] put_logging_options
- [ ] run_pipeline_activity
- [ ] sample_channel_data
- [ ] start_pipeline_reprocessing
- [ ] update_channel
- [ ] update_dataset
- [ ] update_datastore
- [ ] update_pipeline
## kinesis - 56% implemented ## kinesis - 56% implemented
- [X] add_tags_to_stream - [X] add_tags_to_stream
- [X] create_stream - [X] create_stream
@ -3513,6 +3569,9 @@
- [ ] update_tags_for_domain - [ ] update_tags_for_domain
- [ ] view_billing - [ ] view_billing
## runtime.sagemaker - 0% implemented
- [ ] invoke_endpoint
## s3 - 15% implemented ## s3 - 15% implemented
- [ ] abort_multipart_upload - [ ] abort_multipart_upload
- [ ] complete_multipart_upload - [ ] complete_multipart_upload
@ -3938,6 +3997,7 @@
- [ ] delete_activation - [ ] delete_activation
- [ ] delete_association - [ ] delete_association
- [ ] delete_document - [ ] delete_document
- [ ] delete_inventory
- [ ] delete_maintenance_window - [ ] delete_maintenance_window
- [X] delete_parameter - [X] delete_parameter
- [X] delete_parameters - [X] delete_parameters
@ -3961,6 +4021,7 @@
- [ ] describe_instance_patch_states - [ ] describe_instance_patch_states
- [ ] describe_instance_patch_states_for_patch_group - [ ] describe_instance_patch_states_for_patch_group
- [ ] describe_instance_patches - [ ] describe_instance_patches
- [ ] describe_inventory_deletions
- [ ] describe_maintenance_window_execution_task_invocations - [ ] describe_maintenance_window_execution_task_invocations
- [ ] describe_maintenance_window_execution_tasks - [ ] describe_maintenance_window_execution_tasks
- [ ] describe_maintenance_window_executions - [ ] describe_maintenance_window_executions
@ -4378,6 +4439,7 @@
- [ ] create_user - [ ] create_user
- [ ] delete_alias - [ ] delete_alias
- [ ] delete_group - [ ] delete_group
- [ ] delete_mailbox_permissions
- [ ] delete_resource - [ ] delete_resource
- [ ] delete_user - [ ] delete_user
- [ ] deregister_from_work_mail - [ ] deregister_from_work_mail
@ -4390,35 +4452,48 @@
- [ ] list_aliases - [ ] list_aliases
- [ ] list_group_members - [ ] list_group_members
- [ ] list_groups - [ ] list_groups
- [ ] list_mailbox_permissions
- [ ] list_organizations - [ ] list_organizations
- [ ] list_resource_delegates - [ ] list_resource_delegates
- [ ] list_resources - [ ] list_resources
- [ ] list_users - [ ] list_users
- [ ] put_mailbox_permissions
- [ ] register_to_work_mail - [ ] register_to_work_mail
- [ ] reset_password - [ ] reset_password
- [ ] update_primary_email_address - [ ] update_primary_email_address
- [ ] update_resource - [ ] update_resource
## workspaces - 0% implemented ## workspaces - 0% implemented
- [ ] associate_ip_groups
- [ ] authorize_ip_rules
- [ ] create_ip_group
- [ ] create_tags - [ ] create_tags
- [ ] create_workspaces - [ ] create_workspaces
- [ ] delete_ip_group
- [ ] delete_tags - [ ] delete_tags
- [ ] describe_ip_groups
- [ ] describe_tags - [ ] describe_tags
- [ ] describe_workspace_bundles - [ ] describe_workspace_bundles
- [ ] describe_workspace_directories - [ ] describe_workspace_directories
- [ ] describe_workspaces - [ ] describe_workspaces
- [ ] describe_workspaces_connection_status - [ ] describe_workspaces_connection_status
- [ ] disassociate_ip_groups
- [ ] modify_workspace_properties - [ ] modify_workspace_properties
- [ ] modify_workspace_state
- [ ] reboot_workspaces - [ ] reboot_workspaces
- [ ] rebuild_workspaces - [ ] rebuild_workspaces
- [ ] revoke_ip_rules
- [ ] start_workspaces - [ ] start_workspaces
- [ ] stop_workspaces - [ ] stop_workspaces
- [ ] terminate_workspaces - [ ] terminate_workspaces
- [ ] update_rules_of_ip_group
## xray - 0% implemented ## xray - 0% implemented
- [ ] batch_get_traces - [ ] batch_get_traces
- [ ] get_encryption_config
- [ ] get_service_graph - [ ] get_service_graph
- [ ] get_trace_graph - [ ] get_trace_graph
- [ ] get_trace_summaries - [ ] get_trace_summaries
- [ ] put_encryption_config
- [ ] put_telemetry_records - [ ] put_telemetry_records
- [ ] put_trace_segments - [ ] put_trace_segments

View File

@ -41,7 +41,7 @@ publish: upload_pypi_artifact \
push_dockerhub_image push_dockerhub_image
implementation_coverage: implementation_coverage:
./scripts/implementation_coverage.py > IMPLEMENTATION_COVERAGE.md ./scripts/implementation_coverage.py
git commit IMPLEMENTATION_COVERAGE.md -m "Updating implementation coverage" || true git commit IMPLEMENTATION_COVERAGE.md -m "Updating implementation coverage" || true
scaffold: scaffold:

View File

@ -5,7 +5,7 @@ from datetime import datetime
import time import time
from moto.core.responses import BaseResponse from moto.core.responses import BaseResponse
from .models import ecr_backends from .models import ecr_backends, DEFAULT_REGISTRY_ID
class ECRResponse(BaseResponse): class ECRResponse(BaseResponse):
@ -120,7 +120,7 @@ class ECRResponse(BaseResponse):
def get_authorization_token(self): def get_authorization_token(self):
registry_ids = self._get_param('registryIds') registry_ids = self._get_param('registryIds')
if not registry_ids: if not registry_ids:
registry_ids = [self.region] registry_ids = [DEFAULT_REGISTRY_ID]
auth_data = [] auth_data = []
for registry_id in registry_ids: for registry_id in registry_ids:
password = '{}-auth-token'.format(registry_id) password = '{}-auth-token'.format(registry_id)
@ -128,7 +128,7 @@ class ECRResponse(BaseResponse):
auth_data.append({ auth_data.append({
'authorizationToken': auth_token, 'authorizationToken': auth_token,
'expiresAt': time.mktime(datetime(2015, 1, 1).timetuple()), 'expiresAt': time.mktime(datetime(2015, 1, 1).timetuple()),
'proxyEndpoint': 'https://012345678910.dkr.ecr.{}.amazonaws.com'.format(registry_id) 'proxyEndpoint': 'https://{}.dkr.ecr.{}.amazonaws.com'.format(registry_id, self.region)
}) })
return json.dumps({'authorizationData': auth_data}) return json.dumps({'authorizationData': auth_data})

View File

@ -5,6 +5,8 @@ import string
import random import random
import hashlib import hashlib
import uuid import uuid
import re
from datetime import datetime
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from collections import OrderedDict from collections import OrderedDict
from .exceptions import ( from .exceptions import (
@ -159,11 +161,76 @@ class FakePolicy(BaseModel):
} }
class FakeJob(BaseModel):
JOB_ID_REGEX_PATTERN = "[a-zA-Z0-9_-]"
JOB_ID_REGEX = re.compile(JOB_ID_REGEX_PATTERN)
def __init__(self, job_id, targets, document_source, document, description, presigned_url_config, target_selection,
job_executions_rollout_config, document_parameters, region_name):
if not self._job_id_matcher(self.JOB_ID_REGEX, job_id):
raise InvalidRequestException()
self.region_name = region_name
self.job_id = job_id
self.job_arn = 'arn:aws:iot:%s:1:job/%s' % (self.region_name, job_id)
self.targets = targets
self.document_source = document_source
self.document = document
self.description = description
self.presigned_url_config = presigned_url_config
self.target_selection = target_selection
self.job_executions_rollout_config = job_executions_rollout_config
self.status = None # IN_PROGRESS | CANCELED | COMPLETED
self.comment = None
self.created_at = time.mktime(datetime(2015, 1, 1).timetuple())
self.last_updated_at = time.mktime(datetime(2015, 1, 1).timetuple())
self.completed_at = None
self.job_process_details = {
'processingTargets': targets,
'numberOfQueuedThings': 1,
'numberOfCanceledThings': 0,
'numberOfSucceededThings': 0,
'numberOfFailedThings': 0,
'numberOfRejectedThings': 0,
'numberOfInProgressThings': 0,
'numberOfRemovedThings': 0
}
self.document_parameters = document_parameters
def to_dict(self):
obj = {
'jobArn': self.job_arn,
'jobId': self.job_id,
'targets': self.targets,
'description': self.description,
'presignedUrlConfig': self.presigned_url_config,
'targetSelection': self.target_selection,
'jobExecutionsRolloutConfig': self.job_executions_rollout_config,
'status': self.status,
'comment': self.comment,
'createdAt': self.created_at,
'lastUpdatedAt': self.last_updated_at,
'completedAt': self.completedAt,
'jobProcessDetails': self.job_process_details,
'documentParameters': self.document_parameters,
'document': self.document,
'documentSource': self.document_source
}
return obj
def _job_id_matcher(self, regex, argument):
regex_match = regex.match(argument)
length_match = len(argument) <= 64
return regex_match and length_match
class IoTBackend(BaseBackend): class IoTBackend(BaseBackend):
def __init__(self, region_name=None): def __init__(self, region_name=None):
super(IoTBackend, self).__init__() super(IoTBackend, self).__init__()
self.region_name = region_name self.region_name = region_name
self.things = OrderedDict() self.things = OrderedDict()
self.jobs = OrderedDict()
self.thing_types = OrderedDict() self.thing_types = OrderedDict()
self.thing_groups = OrderedDict() self.thing_groups = OrderedDict()
self.certificates = OrderedDict() self.certificates = OrderedDict()
@ -507,6 +574,16 @@ class IoTBackend(BaseBackend):
thing.thing_name, None thing.thing_name, None
) )
def create_job(self, job_id, targets, document_source, document, description, presigned_url_config,
target_selection, job_executions_rollout_config, document_parameters):
job = FakeJob(job_id, targets, document_source, document, description, presigned_url_config, target_selection,
job_executions_rollout_config, document_parameters, self.region_name)
self.jobs[job_id] = job
return job.job_arn, job_id, description
def describe_job(self, job_id):
return self.jobs[job_id]
available_regions = boto3.session.Session().get_available_regions("iot") available_regions = boto3.session.Session().get_available_regions("iot")
iot_backends = {region: IoTBackend(region) for region in available_regions} iot_backends = {region: IoTBackend(region) for region in available_regions}

View File

@ -102,6 +102,42 @@ class IoTResponse(BaseResponse):
) )
return json.dumps(dict()) return json.dumps(dict())
def create_job(self):
job_arn, job_id, description = self.iot_backend.create_job(
job_id=self._get_param("jobId"),
targets=self._get_param("targets"),
description=self._get_param("description"),
document_source=self._get_param("documentSource"),
document=self._get_param("document"),
presigned_url_config=self._get_param("presignedUrlConfig"),
target_selection=self._get_param("targetSelection"),
job_executions_rollout_config=self._get_param("jobExecutionsRolloutConfig"),
document_parameters=self._get_param("documentParameters")
)
return json.dumps(dict(jobArn=job_arn, jobId=job_id, description=description))
def describe_job(self):
job = self.iot_backend.describe_job(job_id=self._get_param("jobId"))
return json.dumps(dict(
documentSource=job.document_source,
job=dict(
comment=job.comment,
completedAt=job.completed_at,
createdAt=job.created_at,
description=job.description,
documentParameters=job.document_parameters,
jobArn=job.job_arn,
jobExecutionsRolloutConfig=job.job_executions_rollout_config,
jobId=job.job_id,
jobProcessDetails=job.job_process_details,
lastUpdatedAt=job.last_updated_at,
presignedUrlConfig=job.presigned_url_config,
status=job.status,
targets=job.targets,
targetSelection=job.target_selection
)))
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")
cert, key_pair = self.iot_backend.create_keys_and_certificate( cert, key_pair = self.iot_backend.create_keys_and_certificate(

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
import moto import moto
import os
from botocore import xform_name from botocore import xform_name
from botocore.session import Session from botocore.session import Session
import boto3 import boto3
@ -42,8 +43,7 @@ def calculate_implementation_coverage():
return coverage return coverage
def print_implementation_coverage(): def print_implementation_coverage(coverage):
coverage = calculate_implementation_coverage()
for service_name in sorted(coverage): for service_name in sorted(coverage):
implemented = coverage.get(service_name)['implemented'] implemented = coverage.get(service_name)['implemented']
not_implemented = coverage.get(service_name)['not_implemented'] not_implemented = coverage.get(service_name)['not_implemented']
@ -65,5 +65,37 @@ def print_implementation_coverage():
print("- [ ] {}".format(op)) print("- [ ] {}".format(op))
def write_implementation_coverage_to_file(coverage):
# try deleting the implementation coverage file
try:
os.remove("../IMPLEMENTATION_COVERAGE.md")
except OSError:
pass
for service_name in sorted(coverage):
implemented = coverage.get(service_name)['implemented']
not_implemented = coverage.get(service_name)['not_implemented']
operations = sorted(implemented + not_implemented)
if implemented and not_implemented:
percentage_implemented = int(100.0 * len(implemented) / (len(implemented) + len(not_implemented)))
elif implemented:
percentage_implemented = 100
else:
percentage_implemented = 0
# rewrite the implementation coverage file with updated values
with open("../IMPLEMENTATION_COVERAGE.md", "a+") as file:
file.write("\n")
file.write("## {} - {}% implemented\n".format(service_name, percentage_implemented))
for op in operations:
if op in implemented:
file.write("- [X] {}\n".format(op))
else:
file.write("- [ ] {}\n".format(op))
if __name__ == '__main__': if __name__ == '__main__':
print_implementation_coverage() cov = calculate_implementation_coverage()
write_implementation_coverage_to_file(cov)
print_implementation_coverage(cov)

View File

@ -418,7 +418,7 @@ def test_get_authorization_token_assume_region():
auth_token_response.should.contain('ResponseMetadata') auth_token_response.should.contain('ResponseMetadata')
auth_token_response['authorizationData'].should.equal([ auth_token_response['authorizationData'].should.equal([
{ {
'authorizationToken': 'QVdTOnVzLWVhc3QtMS1hdXRoLXRva2Vu', 'authorizationToken': 'QVdTOjAxMjM0NTY3ODkxMC1hdXRoLXRva2Vu',
'proxyEndpoint': 'https://012345678910.dkr.ecr.us-east-1.amazonaws.com', 'proxyEndpoint': 'https://012345678910.dkr.ecr.us-east-1.amazonaws.com',
'expiresAt': datetime(2015, 1, 1, tzinfo=tzlocal()) 'expiresAt': datetime(2015, 1, 1, tzinfo=tzlocal())
}, },
@ -428,19 +428,19 @@ def test_get_authorization_token_assume_region():
@mock_ecr @mock_ecr
def test_get_authorization_token_explicit_regions(): def test_get_authorization_token_explicit_regions():
client = boto3.client('ecr', region_name='us-east-1') client = boto3.client('ecr', region_name='us-east-1')
auth_token_response = client.get_authorization_token(registryIds=['us-east-1', 'us-west-1']) auth_token_response = client.get_authorization_token(registryIds=['10987654321', '878787878787'])
auth_token_response.should.contain('authorizationData') auth_token_response.should.contain('authorizationData')
auth_token_response.should.contain('ResponseMetadata') auth_token_response.should.contain('ResponseMetadata')
auth_token_response['authorizationData'].should.equal([ auth_token_response['authorizationData'].should.equal([
{ {
'authorizationToken': 'QVdTOnVzLWVhc3QtMS1hdXRoLXRva2Vu', 'authorizationToken': 'QVdTOjEwOTg3NjU0MzIxLWF1dGgtdG9rZW4=',
'proxyEndpoint': 'https://012345678910.dkr.ecr.us-east-1.amazonaws.com', 'proxyEndpoint': 'https://10987654321.dkr.ecr.us-east-1.amazonaws.com',
'expiresAt': datetime(2015, 1, 1, tzinfo=tzlocal()), 'expiresAt': datetime(2015, 1, 1, tzinfo=tzlocal()),
}, },
{ {
'authorizationToken': 'QVdTOnVzLXdlc3QtMS1hdXRoLXRva2Vu', 'authorizationToken': 'QVdTOjg3ODc4Nzg3ODc4Ny1hdXRoLXRva2Vu',
'proxyEndpoint': 'https://012345678910.dkr.ecr.us-west-1.amazonaws.com', 'proxyEndpoint': 'https://878787878787.dkr.ecr.us-east-1.amazonaws.com',
'expiresAt': datetime(2015, 1, 1, tzinfo=tzlocal()) 'expiresAt': datetime(2015, 1, 1, tzinfo=tzlocal())
} }

View File

@ -2,6 +2,7 @@ from __future__ import unicode_literals
import boto3 import boto3
import sure # noqa import sure # noqa
import json
from moto import mock_iot from moto import mock_iot
@ -96,6 +97,7 @@ def test_certs():
res = client.list_certificates() res = client.list_certificates()
res.should.have.key('certificates').which.should.have.length_of(0) res.should.have.key('certificates').which.should.have.length_of(0)
@mock_iot @mock_iot
def test_certs_create_inactive(): def test_certs_create_inactive():
client = boto3.client('iot', region_name='ap-northeast-1') client = boto3.client('iot', region_name='ap-northeast-1')
@ -113,6 +115,7 @@ def test_certs_create_inactive():
cert_desc = cert['certificateDescription'] cert_desc = cert['certificateDescription']
cert_desc.should.have.key('status').which.should.equal('ACTIVE') cert_desc.should.have.key('status').which.should.equal('ACTIVE')
@mock_iot @mock_iot
def test_policy(): def test_policy():
client = boto3.client('iot', region_name='ap-northeast-1') client = boto3.client('iot', region_name='ap-northeast-1')
@ -239,9 +242,9 @@ def test_thing_groups():
thing_group.should.have.key('thingGroupArn') thing_group.should.have.key('thingGroupArn')
thing_group = client.describe_thing_group(thingGroupName=group_name) thing_group = client.describe_thing_group(thingGroupName=group_name)
thing_group.should.have.key('thingGroupProperties')\ thing_group.should.have.key('thingGroupProperties') \
.which.should.have.key('attributePayload')\ .which.should.have.key('attributePayload') \
.which.should.have.key('attributes') .which.should.have.key('attributes')
res_props = thing_group['thingGroupProperties']['attributePayload']['attributes'] res_props = thing_group['thingGroupProperties']['attributePayload']['attributes']
res_props.should.have.key('key1').which.should.equal('val01') 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('Key02').which.should.equal('VAL2')
@ -260,9 +263,9 @@ def test_thing_groups():
thingGroupProperties=new_props thingGroupProperties=new_props
) )
thing_group = client.describe_thing_group(thingGroupName=group_name) thing_group = client.describe_thing_group(thingGroupName=group_name)
thing_group.should.have.key('thingGroupProperties')\ thing_group.should.have.key('thingGroupProperties') \
.which.should.have.key('attributePayload')\ .which.should.have.key('attributePayload') \
.which.should.have.key('attributes') .which.should.have.key('attributes')
res_props = thing_group['thingGroupProperties']['attributePayload']['attributes'] res_props = thing_group['thingGroupProperties']['attributePayload']['attributes']
res_props.should.have.key('key1').which.should.equal('val01') 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('Key02').which.should.equal('VAL2')
@ -282,9 +285,9 @@ def test_thing_groups():
thingGroupProperties=new_props thingGroupProperties=new_props
) )
thing_group = client.describe_thing_group(thingGroupName=group_name) thing_group = client.describe_thing_group(thingGroupName=group_name)
thing_group.should.have.key('thingGroupProperties')\ thing_group.should.have.key('thingGroupProperties') \
.which.should.have.key('attributePayload')\ .which.should.have.key('attributePayload') \
.which.should.have.key('attributes') .which.should.have.key('attributes')
res_props = thing_group['thingGroupProperties']['attributePayload']['attributes'] res_props = thing_group['thingGroupProperties']['attributePayload']['attributes']
res_props.should.have.key('k4').which.should.equal('v4') res_props.should.have.key('k4').which.should.equal('v4')
res_props.should_not.have.key('key1') res_props.should_not.have.key('key1')
@ -383,3 +386,135 @@ def test_thing_group_relations():
) )
things.should.have.key('things') things.should.have.key('things')
things['things'].should.have.length_of(0) things['things'].should.have.length_of(0)
@mock_iot
def test_create_job():
client = boto3.client('iot', region_name='eu-west-1')
name = "my-thing"
job_id = "TestJob"
# thing
thing = client.create_thing(thingName=name)
thing.should.have.key('thingName').which.should.equal(name)
thing.should.have.key('thingArn')
# job document
job_document = {
"field": "value"
}
job = client.create_job(
jobId=job_id,
targets=[thing["thingArn"]],
document=json.dumps(job_document),
description="Description",
presignedUrlConfig={
'roleArn': 'arn:aws:iam::1:role/service-role/iot_job_role',
'expiresInSec': 123
},
targetSelection="CONTINUOUS",
jobExecutionsRolloutConfig={
'maximumPerMinute': 10
}
)
job.should.have.key('jobId').which.should.equal(job_id)
job.should.have.key('jobArn')
job.should.have.key('description')
@mock_iot
def test_describe_job():
client = boto3.client('iot', region_name='eu-west-1')
name = "my-thing"
job_id = "TestJob"
# thing
thing = client.create_thing(thingName=name)
thing.should.have.key('thingName').which.should.equal(name)
thing.should.have.key('thingArn')
job = client.create_job(
jobId=job_id,
targets=[thing["thingArn"]],
documentSource="https://s3-eu-west-1.amazonaws.com/bucket-name/job_document.json",
presignedUrlConfig={
'roleArn': 'arn:aws:iam::1:role/service-role/iot_job_role',
'expiresInSec': 123
},
targetSelection="CONTINUOUS",
jobExecutionsRolloutConfig={
'maximumPerMinute': 10
}
)
job.should.have.key('jobId').which.should.equal(job_id)
job.should.have.key('jobArn')
job = client.describe_job(jobId=job_id)
job.should.have.key('documentSource')
job.should.have.key('job')
job.should.have.key('job').which.should.have.key("jobArn")
job.should.have.key('job').which.should.have.key("jobId").which.should.equal(job_id)
job.should.have.key('job').which.should.have.key("targets")
job.should.have.key('job').which.should.have.key("jobProcessDetails")
job.should.have.key('job').which.should.have.key("lastUpdatedAt")
job.should.have.key('job').which.should.have.key("createdAt")
job.should.have.key('job').which.should.have.key("jobExecutionsRolloutConfig")
job.should.have.key('job').which.should.have.key("targetSelection").which.should.equal("CONTINUOUS")
job.should.have.key('job').which.should.have.key("presignedUrlConfig")
job.should.have.key('job').which.should.have.key("presignedUrlConfig").which.should.have.key(
"roleArn").which.should.equal('arn:aws:iam::1:role/service-role/iot_job_role')
job.should.have.key('job').which.should.have.key("presignedUrlConfig").which.should.have.key(
"expiresInSec").which.should.equal(123)
job.should.have.key('job').which.should.have.key("jobExecutionsRolloutConfig").which.should.have.key(
"maximumPerMinute").which.should.equal(10)
@mock_iot
def test_describe_job_1():
client = boto3.client('iot', region_name='eu-west-1')
name = "my-thing"
job_id = "TestJob"
# thing
thing = client.create_thing(thingName=name)
thing.should.have.key('thingName').which.should.equal(name)
thing.should.have.key('thingArn')
# job document
job_document = {
"field": "value"
}
job = client.create_job(
jobId=job_id,
targets=[thing["thingArn"]],
document=json.dumps(job_document),
presignedUrlConfig={
'roleArn': 'arn:aws:iam::1:role/service-role/iot_job_role',
'expiresInSec': 123
},
targetSelection="CONTINUOUS",
jobExecutionsRolloutConfig={
'maximumPerMinute': 10
}
)
job.should.have.key('jobId').which.should.equal(job_id)
job.should.have.key('jobArn')
job = client.describe_job(jobId=job_id)
job.should.have.key('job')
job.should.have.key('job').which.should.have.key("jobArn")
job.should.have.key('job').which.should.have.key("jobId").which.should.equal(job_id)
job.should.have.key('job').which.should.have.key("targets")
job.should.have.key('job').which.should.have.key("jobProcessDetails")
job.should.have.key('job').which.should.have.key("lastUpdatedAt")
job.should.have.key('job').which.should.have.key("createdAt")
job.should.have.key('job').which.should.have.key("jobExecutionsRolloutConfig")
job.should.have.key('job').which.should.have.key("targetSelection").which.should.equal("CONTINUOUS")
job.should.have.key('job').which.should.have.key("presignedUrlConfig")
job.should.have.key('job').which.should.have.key("presignedUrlConfig").which.should.have.key(
"roleArn").which.should.equal('arn:aws:iam::1:role/service-role/iot_job_role')
job.should.have.key('job').which.should.have.key("presignedUrlConfig").which.should.have.key(
"expiresInSec").which.should.equal(123)
job.should.have.key('job').which.should.have.key("jobExecutionsRolloutConfig").which.should.have.key(
"maximumPerMinute").which.should.equal(10)