From 487829810faed0ffae683d2c9cd9bf61058048e0 Mon Sep 17 00:00:00 2001 From: Alex Bainbridge Date: Thu, 2 Jul 2020 13:43:14 -0400 Subject: [PATCH] passes python3 and 2.7. added additional few tests for coverage bump --- moto/ssm/models.py | 25 +++++---- tests/test_ssm/test_ssm_docs.py | 96 +++++++++++++++++++++++++++++---- 2 files changed, 101 insertions(+), 20 deletions(-) diff --git a/moto/ssm/models.py b/moto/ssm/models.py index ad9806e9f..fc9cdd273 100644 --- a/moto/ssm/models.py +++ b/moto/ssm/models.py @@ -169,6 +169,11 @@ class Document(BaseModel): if document_format == "JSON": try: content_json = json.loads(content) + except ValueError: + # Python2 + raise InvalidDocumentContent( + "The content for the document is not valid." + ) except json.decoder.JSONDecodeError: raise InvalidDocumentContent( "The content for the document is not valid." @@ -181,7 +186,7 @@ class Document(BaseModel): "The content for the document is not valid." ) else: - raise ValidationException(f"Invalid document format {document_format}") + raise ValidationException("Invalid document format " + str(document_format)) self.content_json = content_json @@ -379,7 +384,7 @@ class Command(BaseModel): def _validate_document_format(document_format): aws_doc_formats = ["JSON", "YAML"] if document_format not in aws_doc_formats: - raise ValidationException(f"Invalid document format {document_format}") + raise ValidationException("Invalid document format " + str(document_format)) def _validate_document_info(content, name, document_type, document_format, strict=True): @@ -403,14 +408,14 @@ def _validate_document_info(content, name, document_type, document_format, stric raise ValidationException("Content is required") if list(filter(name.startswith, aws_name_reject_list)): - raise ValidationException(f"Invalid document name {name}") + raise ValidationException("Invalid document name " + str(name)) ssm_name_pattern = re.compile(aws_ssm_name_regex) if not ssm_name_pattern.match(name): - raise ValidationException(f"Invalid document name {name}") + raise ValidationException("Invalid document name " + str(name)) if strict and document_type not in aws_doc_types: # Update document doesn't use document type - raise ValidationException(f"Invalid document type {document_type}") + raise ValidationException("Invalid document type " + str(document_type)) def _document_filter_equal_comparator(keyed_value, filter): @@ -524,7 +529,7 @@ class SimpleSystemManagerBackend(BaseBackend): elif document_format == "YAML": base["Content"] = yaml.dump(ssm_document.content_json) else: - raise ValidationException(f"Invalid document format {document_format}") + raise ValidationException("Invalid document format " + str(document_format)) if ssm_document.version_name: base["VersionName"] = ssm_document.version_name @@ -589,7 +594,7 @@ class SimpleSystemManagerBackend(BaseBackend): ) if self._documents.get(ssm_document.name): - raise DocumentAlreadyExists(f"The specified document already exists.") + raise DocumentAlreadyExists("The specified document already exists.") self._documents[ssm_document.name] = { "documents": {ssm_document.document_version: ssm_document}, @@ -663,7 +668,7 @@ class SimpleSystemManagerBackend(BaseBackend): self, name, document_version=None, version_name=None, strict=True ): if not self._documents.get(name): - raise InvalidDocument(f"The specified document does not exist.") + raise InvalidDocument("The specified document does not exist.") documents = self._documents[name]["documents"] ssm_document = None @@ -692,7 +697,7 @@ class SimpleSystemManagerBackend(BaseBackend): break if strict and not ssm_document: - raise InvalidDocument(f"The specified document does not exist.") + raise InvalidDocument("The specified document does not exist.") return ssm_document @@ -751,7 +756,7 @@ class SimpleSystemManagerBackend(BaseBackend): name, version_name=version_name, strict=False ): raise DuplicateDocumentVersionName( - f"The specified version name is a duplicate." + "The specified version name is a duplicate." ) old_ssm_document = self._find_document(name) diff --git a/tests/test_ssm/test_ssm_docs.py b/tests/test_ssm/test_ssm_docs.py index 409a3bf95..d39fa12c6 100644 --- a/tests/test_ssm/test_ssm_docs.py +++ b/tests/test_ssm/test_ssm_docs.py @@ -1,12 +1,9 @@ from __future__ import unicode_literals -import string - import boto3 import botocore.exceptions import sure # noqa import datetime -import uuid import json import pkg_resources import yaml @@ -14,10 +11,7 @@ import hashlib import copy from moto.core import ACCOUNT_ID -from botocore.exceptions import ClientError, ParamValidationError -from nose.tools import assert_raises - -from moto import mock_ssm, mock_cloudformation +from moto import mock_ssm def _get_yaml_template(): @@ -57,6 +51,10 @@ def _validate_document_description( doc_description["DocumentVersion"].should.equal(expected_document_version) doc_description["Description"].should.equal(json_doc["description"]) + doc_description["Parameters"] = sorted( + doc_description["Parameters"], key=lambda doc: doc["Name"] + ) + doc_description["Parameters"][0]["Name"].should.equal("Parameter1") doc_description["Parameters"][0]["Type"].should.equal("Integer") doc_description["Parameters"][0]["Description"].should.equal("Command Duration.") @@ -184,6 +182,63 @@ def test_create_document(): "TestDocument3", doc_description, json_doc, "1", "1", "1", "JSON" ) + try: + client.create_document( + Content=json.dumps(json_doc), + Name="TestDocument3", + DocumentType="Command", + DocumentFormat="JSON", + ) + raise RuntimeError("Should fail") + except botocore.exceptions.ClientError as err: + err.operation_name.should.equal("CreateDocument") + err.response["Error"]["Message"].should.equal( + "The specified document already exists." + ) + + try: + client.create_document( + Content=yaml.dump(json_doc), + Name="TestDocument4", + DocumentType="Command", + DocumentFormat="JSON", + ) + raise RuntimeError("Should fail") + except botocore.exceptions.ClientError as err: + err.operation_name.should.equal("CreateDocument") + err.response["Error"]["Message"].should.equal( + "The content for the document is not valid." + ) + + del json_doc["parameters"] + response = client.create_document( + Content=yaml.dump(json_doc), + Name="EmptyParamDoc", + DocumentType="Command", + DocumentFormat="YAML", + ) + doc_description = response["DocumentDescription"] + + doc_description["Hash"].should.equal( + hashlib.sha256(yaml.dump(json_doc).encode("utf-8")).hexdigest() + ) + doc_description["HashType"].should.equal("Sha256") + doc_description["Name"].should.equal("EmptyParamDoc") + doc_description["Owner"].should.equal(ACCOUNT_ID) + + difference = datetime.datetime.utcnow() - doc_description["CreatedDate"] + if difference.min > datetime.timedelta(minutes=1): + assert False + + doc_description["Status"].should.equal("Active") + doc_description["DocumentVersion"].should.equal("1") + doc_description["Description"].should.equal(json_doc["description"]) + doc_description["DocumentType"].should.equal("Command") + doc_description["SchemaVersion"].should.equal("2.2") + doc_description["LatestVersion"].should.equal("1") + doc_description["DefaultVersion"].should.equal("1") + doc_description["DocumentFormat"].should.equal("YAML") + # Done @mock_ssm @@ -508,6 +563,20 @@ def test_update_document(): VersionName="Base", ) + try: + client.update_document( + Name="TestDocument", + Content=json.dumps(json_doc), + DocumentVersion="2", + DocumentFormat="JSON", + ) + raise RuntimeError("Should fail") + except botocore.exceptions.ClientError as err: + err.operation_name.should.equal("UpdateDocument") + err.response["Error"]["Message"].should.equal( + "The document version is not valid or does not exist." + ) + # Duplicate content throws an error try: client.update_document( @@ -639,6 +708,7 @@ def test_list_documents(): Name="TestDocument3", DocumentType="Command", DocumentFormat="JSON", + TargetType="/AWS::EC2::Instance", ) response = client.list_documents() @@ -682,9 +752,7 @@ def test_list_documents(): DocumentFormat="JSON", ) - response = client.update_document_default_version( - Name="TestDocument", DocumentVersion="2" - ) + client.update_document_default_version(Name="TestDocument", DocumentVersion="2") response = client.list_documents() len(response["DocumentIdentifiers"]).should.equal(3) @@ -697,3 +765,11 @@ def test_list_documents(): response["DocumentIdentifiers"][2]["Name"].should.equal("TestDocument3") response["DocumentIdentifiers"][2]["DocumentVersion"].should.equal("1") response["NextToken"].should.equal("") + + response = client.list_documents(Filters=[{"Key": "Owner", "Values": ["Self"]}]) + len(response["DocumentIdentifiers"]).should.equal(3) + + response = client.list_documents( + Filters=[{"Key": "TargetType", "Values": ["/AWS::EC2::Instance"]}] + ) + len(response["DocumentIdentifiers"]).should.equal(1)