Repository: aws-quickstart/taskcat (python)

Issue:
Boto3Cache._get_account_info determines incorrect partition due to unexpected upstream behavior.
**Describe the bug**
The `Boto3Cache._get_account_info` function relies on `boto3.Session.get_available_regions('s3')`; However this function defaults to the 'commerical' partition, even when the session is created in another partition. See below. 

** Logic used in taskcat **
https://github.com/aws-quickstart/taskcat/blob/ca4bfe765d92203e5ca58b3ea89313431dc30001/taskcat/_client_factory.py#L105-L118

**To Reproduce**
```
>>> import pprint as pp
>>> import boto3
>>> from taskcat._client_factory import Boto3Cache
>>> boto3_cache = Boto3Cache()
>>> s = boto3_cache.session(profile='govcloud')
>>> s
Session(region_name='us-gov-west-1')
>>>
>>>
>>> s.get_available_regions('s3')
['ap-east-1',
 'ap-northeast-1',
 'ap-northeast-2',
 'ap-south-1',
 'ap-southeast-1',
 'ap-southeast-2',
 'ca-central-1',
 'eu-central-1',
 'eu-north-1',
 'eu-west-1',
 'eu-west-2',
 'eu-west-3',
 'me-south-1',
 'sa-east-1',
 'us-east-1',
 'us-east-2',
 'us-west-1',
 'us-west-2']
>>>
>>>
>>>
```

**Expected behavior**
The partition is correctly identified.

**Screenshots**
[ERROR  ] : ClientError An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid

**Version (Please make sure you are running the latest version of taskcat)
0.9.13



Pull request description:
Accurately determine the appropriate partition for an account. Closes #503
## Overview

This PR changes how we determine what the partition for an account is. Old method relied on boto3.client.get_available_regions('s3'); which does not implicitly return cross-partition data. 

new method is to iterate over partition and default region until an `sts.get_caller_identity()` call succeeds. 

Unit tests are included. 

## Testing/Steps taken to ensure quality

Unit tests
actual live testing.

Patch:
diff --git a/taskcat/_client_factory.py b/taskcat/_client_factory.py
index 3d06905..e46b702 100644
--- a/taskcat/_client_factory.py
+++ b/taskcat/_client_factory.py
@@ -100,17 +100,8 @@ class Boto3Cache:
         )["account_id"]
 
     def _get_account_info(self, profile):
-        region = self._get_region(None, profile)
+        partition, region = self._get_partition(profile)
         session = self.session(profile, region)
-        avail_regions = session.get_available_regions("s3")
-        partition = "aws"
-        region = "us-east-1"
-        if "us-gov-east-1" in avail_regions:
-            partition = "aws-us-gov"
-            region = "us-gov-east-1"
-        elif "cn-north-1" in avail_regions:
-            partition = "aws-cn"
-            region = "cn-north-1"
         sts_client = session.client("sts", region_name=region)
         try:
             account_id = sts_client.get_caller_identity()["Account"]
@@ -186,6 +177,24 @@ class Boto3Cache:
             region = self.get_default_region(profile)
         return region
 
+    def _get_partition(self, profile):
+        partition_regions = [
+            ("aws", "us-east-1"),
+            ("aws-cn", "cn-north-1"),
+            ("aws-us-gov", "us-gov-west-1"),
+        ]
+        for partition, region in partition_regions:
+            try:
+                self.session(profile, region).client(
+                    "sts", region_name=region
+                ).get_caller_identity()
+                return (partition, region)
+            except ClientError as e:
+                if "InvalidClientTokenId" in str(e):
+                    continue
+                raise
+        raise ValueError("cannot find suitable AWS partition")
+
     def get_default_region(self, profile_name="default") -> str:
         try:
             region = self._boto3.session.Session(profile_name=profile_name).region_name
@@ -194,6 +203,8 @@ class Boto3Cache:
                 raise
             region = self._boto3.session.Session().region_name
         if not region:
-            LOG.warning("Region not set in credential chain, defaulting to us-east-1")
-            region = "us-east-1"
+            _, region = self._get_partition(profile_name)
+            LOG.warning(
+                "Region not set in credential chain, defaulting to {}".format(region)
+            )
         return region
diff --git a/taskcat/_common_utils.py b/taskcat/_common_utils.py
index 6ef778e..3ea4a56 100644
--- a/taskcat/_common_utils.py
+++ b/taskcat/_common_utils.py
@@ -1,7 +1,9 @@
 import collections
 import logging
 import os
+import random
 import re
+import string
 import sys
 from collections import OrderedDict
 from functools import reduce
@@ -140,6 +142,17 @@ def pascal_to_snake(pascal):
     return ALL_CAP_RE.sub(r"\1_\2", sub).lower()
 
 
+def generate_bucket_name(project: str, prefix: str = "tcat"):
+    if len(prefix) > 8 or len(prefix) < 1:  # pylint: disable=len-as-condition
+        raise TaskCatException("prefix must be between 1 and 8 characters long")
+    alnum = string.ascii_lowercase + string.digits
+    suffix = "".join(random.choice(alnum) for i in range(8))  # nosec: B311
+    mid = f"-{project}-"
+    avail_len = 63 - len(mid)
+    mid = mid[:avail_len]
+    return f"{prefix}{mid}{suffix}"
+
+
 def merge_nested_dict(old, new):
     for k, v in new.items():
         if isinstance(old.get(k), dict) and isinstance(v, collections.Mapping):
diff --git a/taskcat/_config.py b/taskcat/_config.py
index 75499bc..905eec2 100644
--- a/taskcat/_config.py
+++ b/taskcat/_config.py
@@ -8,6 +8,7 @@ import yaml
 
 from taskcat._cfn.template import Template
 from taskcat._client_factory import Boto3Cache
+from taskcat._common_utils import generate_bucket_name
 from taskcat._dataclasses import (
     BaseConfig,
     RegionObj,
@@ -15,8 +16,6 @@ from taskcat._dataclasses import (
     Tag,
     TestObj,
     TestRegion,
-    generate_bucket_name,
-    generate_regional_bucket_name,
 )
 from taskcat._legacy_config import legacy_overrides, parse_legacy_config
 from taskcat._template_params import ParamGen
@@ -245,21 +244,12 @@ class Config:
         for test_name, test in self.config.tests.items():
             bucket_mappings[test_name] = {}
             for region_name, region in regions[test_name].items():
-                if test.s3_regional_buckets:
-                    bucket_obj = self._create_regional_bucket_obj(
-                        bucket_objects, region, test
-                    )
-                    bucket_objects[f"{region.account_id}{region.name}"] = bucket_obj
-                else:
-                    bucket_obj = self._create_legacy_bucket_obj(
-                        bucket_objects, region, test
-                    )
-                    bucket_objects[region.account_id] = bucket_obj
+                bucket_obj = self._create_bucket_obj(bucket_objects, region, test)
+                bucket_objects[region.account_id] = bucket_obj
                 bucket_mappings[test_name][region_name] = bucket_obj
-
         return bucket_mappings
 
-    def _create_legacy_bucket_obj(self, bucket_objects, region, test):
+    def _create_bucket_obj(self, bucket_objects, region, test):
         new = False
         object_acl = (
             self.config.project.s3_object_acl
@@ -288,42 +278,6 @@ class Config:
             sigv4=sigv4,
             taskcat_id=self.uid,
             partition=region.partition,
-            regional_buckets=test.s3_regional_buckets,
-        )
-        if new:
-            bucket_obj.create()
-        return bucket_obj
-
-    def _create_regional_bucket_obj(self, bucket_objects, region, test):
-        _bucket_obj_key = f"{region.account_id}{region.name}"
-        new = False
-        object_acl = (
-            self.config.project.s3_object_acl
-            if self.config.project.s3_object_acl
-            else "private"
-        )
-        sigv4 = not self.config.project.s3_enable_sig_v2
-        if not test.s3_bucket and not bucket_objects.get(_bucket_obj_key):
-            name = generate_regional_bucket_name(region)
-            auto_generated = True
-            new = True
-        elif bucket_objects.get(_bucket_obj_key):
-            name = bucket_objects[_bucket_obj_key].name
-            auto_generated = bucket_objects[_bucket_obj_key].auto_generated
-        else:
-            name = test.s3_bucket
-            auto_generated = False
-        bucket_obj = S3BucketObj(
-            name=name,
-            region=region.name,
-            account_id=region.account_id,
-            s3_client=region.session.client("s3", region_name=region.name),
-            auto_generated=auto_generated,
-            object_acl=object_acl,
-            sigv4=sigv4,
-            taskcat_id=self.uid,
-            partition=region.partition,
-            regional_buckets=test.s3_regional_buckets,
         )
         if new:
             bucket_obj.create()
diff --git a/taskcat/_dataclasses.py b/taskcat/_dataclasses.py
index 22adef5..48bb942 100644
--- a/taskcat/_dataclasses.py
+++ b/taskcat/_dataclasses.py
@@ -1,11 +1,9 @@
 import json
 import logging
-import random
-import string
+import uuid
 from dataclasses import dataclass, field
 from pathlib import Path
 from typing import Any, Dict, List, NewType, Optional, Union
-from uuid import UUID, uuid5
 
 import boto3
 
@@ -36,7 +34,6 @@ METADATA = {
         "description": "Package Lambda functions into zips before uploading to s3, "
         "set to false to disable"
     },
-    "s3_regional_buckets": {"description": "Enable regional auto-buckets."},
     "lambda_zip_path": {
         "description": "Path relative to the project root to place Lambda zip "
         "files, default is 'lambda_functions/zips'"
@@ -178,7 +175,7 @@ class RegionObj:
     account_id: str
     partition: str
     profile: str
-    taskcat_id: UUID
+    taskcat_id: uuid.UUID
     _boto3_cache: Boto3Cache
 
     def client(self, service: str):
@@ -198,9 +195,8 @@ class S3BucketObj:
     s3_client: boto3.client
     sigv4: bool
     auto_generated: bool
-    regional_buckets: bool
     object_acl: str
-    taskcat_id: UUID
+    taskcat_id: uuid.UUID
 
     @property
     def sigv4_policy(self):
@@ -231,13 +227,12 @@ class S3BucketObj:
         try:
             self.s3_client.get_waiter("bucket_exists").wait(Bucket=self.name)
 
-            if not self.regional_buckets:
-                self.s3_client.put_bucket_tagging(
-                    Bucket=self.name,
-                    Tagging={
-                        "TagSet": [{"Key": "taskcat-id", "Value": self.taskcat_id.hex}]
-                    },
-                )
+            self.s3_client.put_bucket_tagging(
+                Bucket=self.name,
+                Tagging={
+                    "TagSet": [{"Key": "taskcat-id", "Value": self.taskcat_id.hex}]
+                },
+            )
             if self.sigv4:
                 self.s3_client.put_bucket_policy(
                     Bucket=self.name, Policy=self.sigv4_policy
@@ -306,12 +301,10 @@ class S3BucketObj:
                 f"the expected region {self.region}, expected {location}"
             )
         if location:
-            if self.regional_buckets:
-                return True
             tags = self.s3_client.get_bucket_tagging(Bucket=self.name)["TagSet"]
             tags = {t["Key"]: t["Value"] for t in tags}
             uid = tags.get("taskcat-id")
-            uid = UUID(uid) if uid else uid
+            uid = uuid.UUID(uid) if uid else uid
             if uid != self.taskcat_id:
                 raise TaskCatException(
                     f"bucket {self.name} already exists, but does not have a matching"
@@ -365,9 +358,6 @@ class GeneralConfig(JsonSchemaMixin, allow_additional_props=False):  # type: ign
     )
     auth: Optional[Dict[Region, str]] = field(default=None, metadata=METADATA["auth"])
     s3_bucket: Optional[str] = field(default=None, metadata=METADATA["s3_bucket"])
-    s3_regional_buckets: Optional[bool] = field(
-        default=None, metadata=METADATA["s3_regional_buckets"]
-    )
 
 
 @dataclass
@@ -386,9 +376,6 @@ class TestConfig(JsonSchemaMixin, allow_additional_props=False):  # type: ignore
     s3_bucket: Optional[S3BucketName] = field(
         default=None, metadata=METADATA["s3_bucket"]
     )
-    s3_regional_buckets: Optional[bool] = field(
-        default=None, metadata=METADATA["s3_regional_buckets"]
-    )
     az_blacklist: Optional[List[AzId]] = field(
         default=None, metadata=METADATA["az_ids"]
     )
@@ -420,9 +407,6 @@ class ProjectConfig(JsonSchemaMixin, allow_additional_props=False):  # type: ign
     s3_bucket: Optional[S3BucketName] = field(
         default=None, metadata=METADATA["s3_bucket"]
     )
-    s3_regional_buckets: Optional[bool] = field(
-        default=None, metadata=METADATA["s3_regional_buckets"]
-    )
     parameters: Optional[Dict[ParameterKey, ParameterValue]] = field(
         default=None, metadata=METADATA["parameters"]
     )
@@ -445,33 +429,7 @@ class ProjectConfig(JsonSchemaMixin, allow_additional_props=False):  # type: ign
 
 
 PROPAGATE_KEYS = ["tags", "parameters", "auth"]
-PROPOGATE_ITEMS = [
-    "regions",
-    "s3_bucket",
-    "template",
-    "az_blacklist",
-    "s3_regional_buckets",
-]
-
-
-def generate_regional_bucket_name(region_obj: RegionObj, prefix: str = "tcat"):
-    if len(prefix) > 8 or len(prefix) < 1:  # pylint: disable=len-as-condition
-        raise TaskCatException("prefix must be between 1 and 8 characters long")
-    hashed_account_id = uuid5(
-        name=str(region_obj.account_id), namespace=UUID(int=0)
-    ).hex
-    return f"{prefix}-{hashed_account_id}-{region_obj.name}"
-
-
-def generate_bucket_name(project: str, prefix: str = "tcat"):
-    if len(prefix) > 8 or len(prefix) < 1:  # pylint: disable=len-as-condition
-        raise TaskCatException("prefix must be between 1 and 8 characters long")
-    alnum = string.ascii_lowercase + string.digits
-    suffix = "".join(random.choice(alnum) for i in range(8))  # nosec: B311
-    mid = f"-{project}-"
-    avail_len = 63 - len(mid)
-    mid = mid[:avail_len]
-    return f"{prefix}{mid}{suffix}"
+PROPOGATE_ITEMS = ["regions", "s3_bucket", "template", "az_blacklist"]
 
 
 # pylint raises false positive due to json-dataclass
diff --git a/taskcat/cfg/config_schema.json b/taskcat/cfg/config_schema.json
index 497ebbb..a7a493f 100644
--- a/taskcat/cfg/config_schema.json
+++ b/taskcat/cfg/config_schema.json
@@ -47,10 +47,6 @@
                     "description": "Name of S3 bucket to upload project to, if left out a bucket will be auto-generated",
                     "type": "string"
                 },
-                "s3_regional_buckets": {
-                    "description": "Enable regional auto-buckets.",
-                    "type": "boolean"
-                },
                 "tags": {
                     "additionalProperties": {
                         "type": "string"
@@ -159,10 +155,6 @@
                     "pattern": "^(bucket-owner-full-control|bucket-owner-read|authenticated-read|aws-exec-read|public-read-write|public-read|private)$",
                     "type": "string"
                 },
-                "s3_regional_buckets": {
-                    "description": "Enable regional auto-buckets.",
-                    "type": "boolean"
-                },
                 "shorten_stack_name": {
                     "description": "Shorten stack names generated for tests, set to true to enable",
                     "type": "boolean"
@@ -246,10 +238,6 @@
                     "pattern": "^[a-z0-9-]*$",
                     "type": "string"
                 },
-                "s3_regional_buckets": {
-                    "description": "Enable regional auto-buckets.",
-                    "type": "boolean"
-                },
                 "tags": {
                     "additionalProperties": {
                         "type": "string"
@@ -273,7 +261,6 @@
                 "auth": null,
                 "parameters": null,
                 "s3_bucket": null,
-                "s3_regional_buckets": null,
                 "tags": null
             }
         },
@@ -293,7 +280,6 @@
                 "s3_bucket": null,
                 "s3_enable_sig_v2": null,
                 "s3_object_acl": null,
-                "s3_regional_buckets": null,
                 "shorten_stack_name": null,
                 "tags": null,
                 "template": null


Test patch:
diff --git a/taskcat/_cli_modules/test.py b/taskcat/_cli_modules/test.py
index 3753b6d..73f57b0 100644
--- a/taskcat/_cli_modules/test.py
+++ b/taskcat/_cli_modules/test.py
@@ -113,12 +113,11 @@ class Test:
         # TODO: summarise stack statusses (did they complete/delete ok) and print any
         #  error events
         # 8. delete buckets
-
         if not no_delete or (keep_failed is True and len(status["FAILED"]) == 0):
             deleted: ListType[str] = []
             for test in buckets.values():
                 for bucket in test.values():
-                    if (bucket.name not in deleted) and not bucket.regional_buckets:
+                    if bucket.name not in deleted:
                         bucket.delete(delete_objects=True)
                         deleted.append(bucket.name)
         # 9. raise if something failed
diff --git a/tests/data/config_inheritance/.taskcat_global.yml b/tests/data/config_inheritance/.taskcat_global.yml
index 6ffd065..e4907e3 100644
--- a/tests/data/config_inheritance/.taskcat_global.yml
+++ b/tests/data/config_inheritance/.taskcat_global.yml
@@ -1,6 +1,5 @@
 general:
   s3_bucket: "set-in-global"
-  s3_regional_buckets: False
   parameters:
     GlobalVar: set_in_global
     OverridenVar: set_in_global
diff --git a/tests/data/regional_client_and_bucket/.taskcat_global_regional_bucket.yml b/tests/data/regional_client_and_bucket/.taskcat_global_regional_bucket.yml
deleted file mode 100644
index e667efa..0000000
--- a/tests/data/regional_client_and_bucket/.taskcat_global_regional_bucket.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-general:
-  s3_regional_buckets: True
-  parameters:
-    GlobalOverrideTest: success
diff --git a/tests/test_client_factory.py b/tests/test_client_factory.py
index 094bc58..de5fd16 100644
--- a/tests/test_client_factory.py
+++ b/tests/test_client_factory.py
@@ -40,10 +40,14 @@ class TestBoto3Cache(unittest.TestCase):
             x, x._session_cache, ["imported_session_foobar", "us-east-1"], mock_boto3
         )
 
+    @mock.patch("taskcat._client_factory.Boto3Cache._get_partition", autospec=True)
     @mock.patch("taskcat._client_factory.Boto3Cache._cache_set", autospec=True)
     @mock.patch("taskcat._client_factory.Boto3Cache._cache_lookup", autospec=True)
     @mock.patch("taskcat._client_factory.boto3.Session", autospec=True)
-    def test_session_no_profile(self, mock_boto3, mock_cache_lookup, mock_cache_set):
+    def test_session_no_profile(
+        self, mock_boto3, mock_cache_lookup, mock_cache_set, mock_get_partition
+    ):
+        mock_get_partition.return_value = (None, "us-east-1")
         mock_cache_lookup.side_effect = ProfileNotFound(profile="non-existent-profile")
         Boto3Cache().session()  # default value should be "default" profile
         self.assertEqual(mock_boto3.called, True)
@@ -92,9 +96,13 @@ class TestBoto3Cache(unittest.TestCase):
         Boto3Cache().account_id()
         self.assertEqual(mock_cache_lookup.called, True)
 
+    @mock.patch("taskcat._client_factory.boto3", autospec=True)
+    @mock.patch("taskcat._client_factory.Boto3Cache._get_partition", autospec=True)
     @mock.patch("taskcat._client_factory.Boto3Cache._get_region", autospec=True)
     @mock.patch("taskcat._client_factory.Boto3Cache.session")
-    def test__get_account_info(self, mock_session, mock__get_region):
+    def test__get_account_info(
+        self, mock_session, mock__get_region, mock__get_partition, mock_boto3
+    ):
         mock__get_region.return_value = "us-east-1"
         session = boto3.Session()
         session.get_available_regions = mock.Mock()
@@ -103,22 +111,23 @@ class TestBoto3Cache(unittest.TestCase):
         sts.get_caller_identity.return_value = {"Account": "123412341234"}
         session.client.return_value = sts
         mock_session.return_value = session
-        cache = Boto3Cache()
+        mock_boto3.session.Session = mock.Mock()
+        mock_boto3.session.Session.return_value = session
+        cache = Boto3Cache(_boto3=mock_boto3)
 
-        session.get_available_regions.return_value = ["us-gov-east-1"]
+        mock__get_partition.return_value = ("aws-us-gov", "us-gov-east-1")
         partition = cache._get_account_info("default")["partition"]
         self.assertEqual(partition, "aws-us-gov")
 
-        session.get_available_regions.return_value = ["cn-north-1"]
+        mock__get_partition.return_value = ("aws-cn", "cn-north-1")
         partition = cache._get_account_info("default")["partition"]
         self.assertEqual(partition, "aws-cn")
 
-        session.get_available_regions.return_value = ["us-east-1"]
+        mock__get_partition.return_value = ("aws", "us-east-1")
         partition = cache._get_account_info("default")["partition"]
         self.assertEqual(partition, "aws")
 
-        self.assertEqual(mock_session.call_count, 3)
-        self.assertEqual(sts.get_caller_identity.call_count, 3)
+        self.assertEqual(3, sts.get_caller_identity.call_count)
 
         sts.get_caller_identity.side_effect = ClientError(
             error_response={"Error": {"Code": "test"}}, operation_name="test"
@@ -141,3 +150,38 @@ class TestBoto3Cache(unittest.TestCase):
         )
         with self.assertRaises(TaskCatException):
             cache._get_account_info("default")
+
+    @mock.patch("taskcat._client_factory.boto3", autospec=True)
+    @mock.patch("taskcat._client_factory.Boto3Cache.session")
+    def test__get_partition(self, mock_session, mock_boto3):
+        session = boto3.Session()
+        session.client = mock.Mock()
+        sts = mock.Mock()
+        sts.get_caller_identity.return_value = {"Account": "123412341234"}
+        session.client.return_value = sts
+        mock_session.return_value = session
+        mock_boto3.session.Session = mock.Mock()
+        mock_boto3.session.Session.return_value = session
+        cache = Boto3Cache(_boto3=mock_boto3)
+
+        invalid_token_exception = ClientError(
+            error_response={"Error": {"Code": "InvalidClientTokenId"}},
+            operation_name="test",
+        )
+
+        sts.get_caller_identity.side_effect = [True]
+        result = cache._get_partition("default")
+        self.assertEqual(result, ("aws", "us-east-1"))
+
+        sts.get_caller_identity.side_effect = [invalid_token_exception, True]
+        result = cache._get_partition("default")
+        self.assertEqual(result, ("aws-cn", "cn-north-1"))
+
+        sts.get_caller_identity.side_effect = [
+            invalid_token_exception,
+            invalid_token_exception,
+            True,
+        ]
+        result = cache._get_partition("default")
+        self.assertEqual(result, ("aws-us-gov", "us-gov-west-1"))
+        self.assertEqual(sts.get_caller_identity.call_count, 6)
diff --git a/tests/test_config.py b/tests/test_config.py
index ea40350..0562e98 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -28,7 +28,6 @@ class TestNewConfig(unittest.TestCase):
                     "OverridenVar": "set_in_global",
                 },
                 "s3_bucket": "set-in-global",
-                "s3_regional_buckets": False,
             },
             "project": {
                 "regions": ["us-east-1"],
@@ -45,7 +44,6 @@ class TestNewConfig(unittest.TestCase):
                 "s3_bucket": "set-in-global",
                 "s3_enable_sig_v2": False,
                 "shorten_stack_name": False,
-                "s3_regional_buckets": False,
             },
             "tests": {
                 "default": {
@@ -58,7 +56,6 @@ class TestNewConfig(unittest.TestCase):
                     "regions": ["us-west-2"],
                     "s3_bucket": "set-in-global",
                     "template": "template1.yaml",
-                    "s3_regional_buckets": False,
                 },
                 "other": {
                     "template": "other_template.yaml",
@@ -69,7 +66,6 @@ class TestNewConfig(unittest.TestCase):
                     },
                     "regions": ["us-east-1"],
                     "s3_bucket": "set-in-global",
-                    "s3_regional_buckets": False,
                 },
             },
         }
@@ -81,12 +77,10 @@ class TestNewConfig(unittest.TestCase):
                     "GlobalVar": str(base_path / ".taskcat_global.yml"),
                     "OverridenVar": str(base_path / ".taskcat_global.yml"),
                 },
-                "s3_regional_buckets": str(base_path / ".taskcat_global.yml"),
             },
             "project": {
                 "s3_bucket": str(base_path / ".taskcat_global.yml"),
                 "s3_enable_sig_v2": "TASKCAT_DEFAULT",
-                "s3_regional_buckets": str(base_path / ".taskcat_global.yml"),
                 "shorten_stack_name": "TASKCAT_DEFAULT",
                 "package_lambda": "EnvoronmentVariable",
                 "lambda_zip_path": "TASKCAT_DEFAULT",
@@ -103,7 +97,6 @@ class TestNewConfig(unittest.TestCase):
             "tests": {
                 "default": {
                     "s3_bucket": str(base_path / ".taskcat_global.yml"),
-                    "s3_regional_buckets": str(base_path / ".taskcat_global.yml"),
                     "template": str(base_path / ".taskcat.yml"),
                     "parameters": {
                         "GlobalVar": str(base_path / ".taskcat_global.yml"),
@@ -115,7 +108,6 @@ class TestNewConfig(unittest.TestCase):
                 },
                 "other": {
                     "s3_bucket": str(base_path / ".taskcat_global.yml"),
-                    "s3_regional_buckets": str(base_path / ".taskcat_global.yml"),
                     "template": str(base_path / ".taskcat.yml"),
                     "parameters": {
                         "GlobalVar": str(base_path / ".taskcat_global.yml"),
@@ -127,8 +119,8 @@ class TestNewConfig(unittest.TestCase):
             },
         }
 
-        self.assertEqual(expected, config.config.to_dict())
-        self.assertEqual(expected_source, config.config._source)
+        self.assertEqual(config.config.to_dict(), expected)
+        self.assertEqual(config.config._source, expected_source)
 
     def test_legacy_config(self):
 
@@ -235,36 +227,6 @@ class TestNewConfig(unittest.TestCase):
                         )
                         region_obj.delete()
 
-    @mock.patch("taskcat._config.Boto3Cache.account_id", return_value="123412341234")
-    @mock.patch("taskcat._config.Boto3Cache.partition", return_value="aws")
-    @mock.patch("taskcat._config.S3BucketObj.create", return_value=None)
-    @mock.patch("taskcat._client_factory.boto3", autospec=True)
-    def test_get_buckets_regional(self, _, __, ___, m_boto):
-        base_path = "./" if os.getcwd().endswith("/tests") else "./tests/"
-        base_path = Path(base_path + "data/regional_client_and_bucket").resolve()
-
-        config = Config.create(
-            args={},
-            global_config_path=base_path / ".taskcat_global_regional_bucket.yml",
-            project_config_path=base_path / "./.taskcat.yml",
-            overrides_path=base_path / "./.taskcat_overrides.yml",
-            env_vars={},
-        )
-        mock_boto_cache = Boto3Cache(_boto3=m_boto)
-        buckets = config.get_buckets(boto3_cache=mock_boto_cache)
-        for test_name, regions in buckets.items():
-            with self.subTest(test=test_name):
-                for region_name, bucket_obj in regions.items():
-                    self.assertEqual(bucket_obj.account_id, "123412341234")
-                    self.assertEqual(bucket_obj.region, region_name)
-                    self.assertTrue(bucket_obj.auto_generated)
-                    self.assertTrue(bucket_obj.sigv4, True)
-                    self.assertEqual(bucket_obj.partition, "aws")
-                    self.assertEqual(
-                        bucket_obj.name,
-                        f"tcat-13725204b43e5bf5a37800c23614ee21-{region_name}",
-                    )
-
     @mock.patch("taskcat._config.Boto3Cache.account_id", return_value="123412341234")
     @mock.patch("taskcat._config.Boto3Cache.partition", return_value="aws")
     @mock.patch("taskcat._config.S3BucketObj.create", return_value=None)