text: import pytest
  
  
  from . import mock_s3
  from library.aws.s3 import S3BucketsPolicyChecker
  from library.aws.utility import Account
  
  
  buckets = {
      "Bucket1": {
          "Description": "Bucket without policy",
          "CheckShouldPass": True,
          "Policy": """"""
      },
      "Bucket2": {
          "Description": "Public bucket",
          "CheckShouldPass": False,
          "Policy": """{
    "Version":"2012-10-17",
    "Statement":[
      {
        "Sid":"AddPerm",
        "Effect":"Allow",
        "Principal": "*",
        "Action":["s3:GetObject"],
        "Resource":["arn:aws:s3:::Bucket1/*"]
      }
    ]
  }"""
      },
      "Bucket3": {
          "Description": "Public bucket with AWS principal",
          "CheckShouldPass": False,
          "Policy": """{
    "Version":"2012-10-17",
    "Statement":[
      {
        "Sid":"AddCannedAcl",
        "Effect":"Allow",
        "Principal": {"AWS": "*"},
        "Action":["s3:PutObject","s3:PutObjectAcl"],
        "Resource":["arn:aws:s3:::Bucket2/*"]
      }
    ]
  }"""
      },
      "Bucket4": {
          "Description": "Restricted bucket with AWS principal",
          "CheckShouldPass": True,
          "Policy": """{
    "Version":"2012-10-17",
    "Statement":[
      {
        "Sid":"AddCannedAcl",
        "Effect":"Allow",
        "Principal": {"AWS": ["arn:aws:iam::111122223333:root","arn:aws:iam::444455556666:root"]},
        "Action":["s3:PutObject","s3:PutObjectAcl"],
        "Resource":["arn:aws:s3:::Bucket2/*"]
      }
    ]
  }"""
      },
      "Bucket5": {
          "Description": "Restricted bucket with IP condition",
          "CheckShouldPass": True,
          "Policy": """{
    "Version": "2012-10-17",
    "Id": "S3PolicyId1",
    "Statement": [
      {
        "Sid": "IPAllow",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::Bucket4/*",
        "Condition": {
           "IpAddress": {"aws:SourceIp": "54.240.143.0/24"}
        }
      }
    ]
  }"""
      },
      "Bucket6": {
          "Description": "Public bucket with IP condition",
          "CheckShouldPass": False,
          "Policy": """{
    "Version": "2012-10-17",
    "Id": "S3PolicyId1",
    "Statement": [
      {
        "Sid": "IPAllow",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::Bucket5/*",
        "Condition": {
           "IpAddress": {"aws:SourceIp": "0.0.0.0/0"}
        }
      }
    ]
  }"""
      },
      "Bucket7": {
          "Description": "Public bucket with list IP condition",
          "CheckShouldPass": False,
          "Policy": """{
    "Version": "2012-10-17",
    "Id": "S3PolicyId1",
    "Statement": [
      {
        "Sid": "IPAllow",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::Bucket5/*",
        "Condition": {
           "IpAddress": {"aws:SourceIp": ["0.0.0.0/0", "54.240.143.0/24"]}
        }
      },
      {
        "Sid":"112",
        "Effect":"Allow",
        "Principal":{"AWS":"*" },
        "Action":"s3:PutObject",
        "Resource":"arn:aws:s3:::Bucket5/*",
        "Condition": {
          "StringNotEquals": {"s3:x-amz-grant-full-control":["emailAddress=xyz@amazon.com"]}
        }
      }
    ]
  }"""
      },
      "Bucket8": {
          "Description": "Restricted bucket with list IP condition",
          "CheckShouldPass": True,
          "Policy": """{
    "Version": "2012-10-17",
    "Id": "S3PolicyId1",
    "Statement": [
      {
        "Sid": "IPAllow",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::Bucket5/*",
        "Condition": {
           "IpAddress": {"aws:SourceIp": ["8.8.8.8/32", "54.240.143.0/24"]}
        }
      }
    ]
  }"""
      },
      "Bucket9": {
          "Description": "Bucket with NotPrincipal",
          "CheckShouldPass": True,
          "Policy": """{
      "Version": "2008-10-17",
      "Statement": [
          {
              "Effect": "Deny",
              "NotPrincipal": {
                  "AWS": [
                      "arn:aws:sts::123456789012:assumed-role/opsworks-service-role/OpsWorks"
                  ]
              },
              "Action": "s3:DeleteBucket",
              "Resource": "arn:aws:s3:::aws-opsworks"
          }
      ]
  }"""
      }
  }
  
  
  def find_rule_prop(bucket, prop, default):
      try:
          return buckets[bucket.name][prop]
      except KeyError:
          return default
  
  def ident_test(arg):
      """
      Used to build identification string for each autogenerated test (for easy recognition of failed tests).
  
      :param arg: dict with information about rules from
      :return: identification string with security group name, rule index number and human-readable description.
      """
      # print(jsonDumps(s3policy_details))
      if isinstance(arg, bool):
          return "remediated" if arg else "original"
      else:
          descr = find_rule_prop(arg, "Description", "default description")
          return f"params: {arg.name} ({descr})"
  
  
  def pytest_generate_tests(metafunc):
      """
      Entrypoint for tests (built-in pytest function for dynamic generation of test cases).
      """
      # Launch EC2 mocking and env preparation
      mock_s3.start()
      mock_s3.create_env(buckets)
  
      account = Account()
  
      checker = S3BucketsPolicyChecker(account)
      checker.check()
  
      for s3_bucket in checker.buckets:
          s3_bucket.restrict_policy()
  
      checker_remediated = S3BucketsPolicyChecker(account)
      checker_remediated.check()
  
      s3_buckets = [(bucket, False) for bucket in checker.buckets]
      s3_buckets += [(bucket, True) for bucket in checker_remediated.buckets]
  
      # create test cases for each response
      metafunc.parametrize("bucket,remediated", s3_buckets, ids=ident_test)
  
  
  @pytest.mark.s3policy
  def test_s3policy(bucket, remediated):
      """
      Actual testing function.
  
      :param bucket: bucket details
      :param remediated: 
      :return: nothing, raises AssertionError if actual test result is not matched with expected
      """
      # print(f"{jsonDumps(s3policy_details)}")
      expected = True if remediated else find_rule_prop(bucket, "CheckShouldPass", True)
      assert expected == (not bucket.public_by_policy)