{"id":18524443,"url":"https://github.com/stelligent/potemkin-decorator","last_synced_at":"2025-04-09T11:32:03.862Z","repository":{"id":57454320,"uuid":"231446800","full_name":"stelligent/potemkin-decorator","owner":"stelligent","description":"Potemkin is a decorator to setup initial conditions for a boto \"integration test\" with real AWS services via CloudFormation, and to tear them down as well.","archived":false,"fork":false,"pushed_at":"2020-05-12T16:08:12.000Z","size":76,"stargazers_count":10,"open_issues_count":6,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T05:25:08.635Z","etag":null,"topics":["boto","building-block","integration-testing","pytest","stelligent"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stelligent.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-02T19:32:48.000Z","updated_at":"2024-10-18T08:00:49.000Z","dependencies_parsed_at":"2022-09-04T18:22:19.287Z","dependency_job_id":null,"html_url":"https://github.com/stelligent/potemkin-decorator","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stelligent%2Fpotemkin-decorator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stelligent%2Fpotemkin-decorator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stelligent%2Fpotemkin-decorator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stelligent%2Fpotemkin-decorator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stelligent","download_url":"https://codeload.github.com/stelligent/potemkin-decorator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248031647,"owners_count":21036447,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boto","building-block","integration-testing","pytest","stelligent"],"created_at":"2024-11-06T17:41:41.767Z","updated_at":"2025-04-09T11:32:02.883Z","avatar_url":"https://github.com/stelligent.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"The potemkin decorator facilitates \"integration testing\" boto code by creating AWS resources \nusing Cloudformation or Terraform. This provides a convenient way to setup initial conditions\ninstead of having to develop boto code that is likely as complex as the \"code under test\".\n\n## Basic Usage\n\n### CloudFormation\n\nHere is an example CloudFormation invocation from pytest:\n```\nimport potemkin\nimport boto3\n\n\n@potemkin.CloudFormationStack(\n  'test/integration/test_templates/aes256_bucket.yml',\n  stack_name_stem='TestStack',\n  parameters={'BucketName': 'unclefreddie33388'},\n  aws_profile='myprofile',\n  teardown=False\n)\ndef test_bucket_has_aes256_encryption(stack_outputs, stack_name):\n  full_bucket_name = stack_outputs['BucketNameOut']\n\n  s3 = boto3.Session(profile_name='myprofile').client('s3')\n  get_bucket_encryption_response = s3.get_bucket_encryption(\n    Bucket=full_bucket_name\n  )\n\n  assert get_bucket_encryption_response['ServerSideEncryptionConfiguration']['Rules'][0]['ApplyServerSideEncryptionByDefault']['SSEAlgorithm'] == 'AES256'\n``` \n\nThe CloudFormationStack creates the stack and binds the outputs to stack_outputs.  The pytest method\ncould invoke more boto code to manipulate the resources created by the decorator.  In this case,\nthe test just asserts that the initial condition is what is expected.\n\nThis is basically a python/pytest port of \"aws-int-test-rspec-helper\" that worked with Ruby/RSpec:\n* https://github.com/stelligent/aws-int-test-rspec-helper/\n\n### Terraform\nHere is an example Terraform invocation from pytest:\n```\nimport potemkin\nimport boto3\n\n\n@potemkin.TerraformResources(\n  'test/integration/test_templates/terraform',\n  parameters={'BucketName': 'unclefreddie33388'},\n  aws_profile='myprofile',\n  teardown=False\n)\ndef test_bucket_has_aes256_encryption(tf_outputs):\n  full_bucket_name = tf_outputs['BucketNameOut']\n\n  s3 = boto3.Session(profile_name='myprofile').client('s3')\n  get_bucket_encryption_response = s3.get_bucket_encryption(\n    Bucket=full_bucket_name\n  )\n\n  assert get_bucket_encryption_response['ServerSideEncryptionConfiguration']['Rules'][0]['ApplyServerSideEncryptionByDefault']['SSEAlgorithm'] == 'AES256'\n``` \n\nTerraformResources creates the resources and binds the outputs to tf_outputs.  The pytest method\ncould invoke more boto code to manipulate the resources created by the decorator.  In this case,\nthe test just asserts that the initial condition is what is expected.\n\n\n## Service Specific Usage\n\nThe potemkin decorator has additional functions for interacting with specific AWS services \n\n### AWS Config\nAWS Config initiates evaluations when a resource is created, but the evaluations are completed\nasynchronously. They can take several minutes to complete. The AWS config functions wait until \nthe config rule has an evaluation for the resource, then returns the evaluation.\n\n### config_rule_wait_for_compliance_results\nThis function polls aws config until all resource_ids have evaluations. It then checks those evaluations\nagainst expected results and returns a truthy value. This can be used by both configuration\nchange events and periodic events (by setting evaluate=True)\n\n\n```\n@potemkin.CloudFormationStack('test/integration/test_templates/eip.yml',\n                              stack_name_stem='EipTestStack')\ndef test_wait_for_compliance_results(stack_outputs, stack_name):\n    global expected_results\n    configservice = boto3.Session().client('config')\n\n    expected_results_success = {\n        stack_outputs['EIPOutput']: \"NON_COMPLIANT\",\n        stack_outputs['EIP2Output']: \"NON_COMPLIANT\"\n    }\n\n    assert config_rule_wait_for_compliance_results(\n        configservice,\n        rule_name='eip-attached',\n        expected_results=expected_results_success)\n```\n\n### config_rule_wait_for_absent_resources\nThis function is a companion to config_rule_wait_for_compliance_results and is used to validate that\nonce resources are deleted they are removed from AWS config. \n\n```\ndef test_wait_for_compliance_results_success_results():\n    configservice = boto3.Session().client('config')\n    resource_ids = list(expected_results.keys())\n\n    assert [] == config_rule_wait_for_absent_resources(\n        configservice, rule_name='eip-attached', resource_ids=resource_ids)\n```\n\n#### config_rule_wait_for_resource\nThis function polls aws config until there is an evaluation for the resource, then returns it. Use this \nfunction for config rules with a configuration change trigger. If you are checking more than one \nresource, consider using config_rule_wait_for_compliance_results.\n\n```\nimport potemkin\nimport boto3\n\n\n@potemkin.CloudFormationStack(\n  'test/integration/test_templates/aes256_bucket.yml',\n  stack_name_stem='TestStack',\n  parameters={'BucketName': 'unclefreddie33388'}\n)\ndef test_bucket_encryption_rule(stack_outputs, stack_name):\n  configservice = boto3.Session().client('config')\n\n  results = config_rule_wait_for_resource(configservice, \n                                          resource_id='unclefreddie33388', \n                                          rule_name='config-rule-s3-encryption')\n  \n  assert results['ComplianceType'] == 'NON_COMPLIANT'\n``` \n\n\n#### evaluate_config_rule_and_wait_for_resource\nThis is similar to config_rule_wait_for_resource but it first initiates a config evaluation. Use this \nfor config rules with a periodic trigger. If you are checking more than one \nresource, consider using config_rule_wait_for_compliance_results.\n\n```\nimport potemkin\nimport boto3\n\n\n@potemkin.CloudFormationStack(\n  'test/integration/test_templates/aes256_bucket.yml',\n  stack_name_stem='TestStack',\n  parameters={'BucketName': 'unclefreddie33388'}\n)\ndef test_bucket_encryption_rule(stack_outputs, stack_name):\n  configservice = boto3.Session().client('config')\n\n  results = evaluate_config_rule_and_wait_for_resource(configservice, \n                                                      resource_id='unclefreddie33388', \n                                                      rule_name='config-rule-s3-encryption')\n  \n  assert results['ComplianceType'] == 'NON_COMPLIANT'\n``` ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstelligent%2Fpotemkin-decorator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstelligent%2Fpotemkin-decorator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstelligent%2Fpotemkin-decorator/lists"}