Repository: getmoto/moto
Pull request #6044 (2023-03-09 10:28:51)

Techdebt: Sure - Dax
- Removing sure: #6035
- Combined some tests using parametrize
- Small cosmetic changes to make tests more consistent and readable


Patch:
diff --git a/moto/glue/models.py b/moto/glue/models.py
index a0b3566aa..6abbf4aa9 100644
--- a/moto/glue/models.py
+++ b/moto/glue/models.py
@@ -324,6 +324,9 @@ class GlueBackend(BaseBackend):
         glue_version,
         number_of_workers,
         worker_type,
+        code_gen_configuration_nodes,
+        execution_class,
+        source_control_details,
     ):
         self.jobs[name] = FakeJob(
             name,
@@ -345,6 +348,9 @@ class GlueBackend(BaseBackend):
             glue_version,
             number_of_workers,
             worker_type,
+            code_gen_configuration_nodes,
+            execution_class,
+            source_control_details,
             backend=self,
         )
         return name
@@ -1070,6 +1076,9 @@ class FakeJob:
         glue_version=None,
         number_of_workers=None,
         worker_type=None,
+        code_gen_configuration_nodes=None,
+        execution_class=None,
+        source_control_details=None,
         backend=None,
     ):
         self.name = name
@@ -1090,6 +1099,9 @@ class FakeJob:
         self.glue_version = glue_version
         self.number_of_workers = number_of_workers
         self.worker_type = worker_type
+        self.code_gen_configuration_nodes = code_gen_configuration_nodes
+        self.execution_class = execution_class or "STANDARD"
+        self.source_control_details = source_control_details
         self.created_on = datetime.utcnow()
         self.last_modified_on = datetime.utcnow()
         self.arn = (
@@ -1125,6 +1137,9 @@ class FakeJob:
             "SecurityConfiguration": self.security_configuration,
             "NotificationProperty": self.notification_property,
             "GlueVersion": self.glue_version,
+            "CodeGenConfigurationNodes": self.code_gen_configuration_nodes,
+            "ExecutionClass": self.execution_class,
+            "SourceControlDetails": self.source_control_details,
         }
 
     def start_job_run(self):
diff --git a/moto/glue/responses.py b/moto/glue/responses.py
index 7439dbbd7..934b1ed76 100644
--- a/moto/glue/responses.py
+++ b/moto/glue/responses.py
@@ -309,6 +309,9 @@ class GlueResponse(BaseResponse):
         glue_version = self._get_param("GlueVersion")
         number_of_workers = self._get_int_param("NumberOfWorkers")
         worker_type = self._get_param("WorkerType")
+        code_gen_configuration_nodes = self._get_param("CodeGenConfigurationNodes")
+        execution_class = self._get_param("ExecutionClass")
+        source_control_details = self._get_param("SourceControlDetails")
         name = self.glue_backend.create_job(
             name=name,
             description=description,
@@ -329,6 +332,9 @@ class GlueResponse(BaseResponse):
             glue_version=glue_version,
             number_of_workers=number_of_workers,
             worker_type=worker_type,
+            code_gen_configuration_nodes=code_gen_configuration_nodes,
+            execution_class=execution_class,
+            source_control_details=source_control_details,
         )
         return json.dumps(dict(Name=name))
 
diff --git a/moto/s3/responses.py b/moto/s3/responses.py
index 5285cd975..f10bd6500 100644
--- a/moto/s3/responses.py
+++ b/moto/s3/responses.py
@@ -1319,7 +1319,10 @@ class S3Response(BaseResponse):
             response_headers["x-amz-version-id"] = key.version_id
 
         if key.storage_class in ARCHIVE_STORAGE_CLASSES:
-            raise InvalidObjectState(storage_class=key.storage_class)
+            if 'ongoing-request="false"' not in key.response_dict.get(
+                "x-amz-restore", ""
+            ):
+                raise InvalidObjectState(storage_class=key.storage_class)
         if if_unmodified_since:
             if_unmodified_since = str_to_rfc_1123_datetime(if_unmodified_since)
             if key.last_modified.replace(microsecond=0) > if_unmodified_since:


Test patch:
diff --git a/tests/test_dax/test_dax.py b/tests/test_dax/test_dax.py
index 4722f8ae3..32af80020 100644
--- a/tests/test_dax/test_dax.py
+++ b/tests/test_dax/test_dax.py
@@ -1,12 +1,12 @@
 """Unit tests for dax-supported APIs."""
 import boto3
 import pytest
-import sure  # noqa # pylint: disable=unused-import
-
 from botocore.exceptions import ClientError
+
 from moto import mock_dax
 from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
 
+
 # See our Development Tips on writing tests for hints on how to write good tests:
 # http://docs.getmoto.org/en/latest/docs/contributing/development_tips/tests.html
 
@@ -21,31 +21,28 @@ def test_create_cluster_minimal():
         ReplicationFactor=3,
         IamRoleArn=iam_role_arn,
     )["Cluster"]
-
     described_cluster = client.describe_clusters(ClusterNames=["daxcluster"])[
         "Clusters"
     ][0]
 
     for cluster in [created_cluster, described_cluster]:
-        cluster["ClusterName"].should.equal("daxcluster")
-        cluster["ClusterArn"].should.equal(
-            f"arn:aws:dax:us-east-2:{ACCOUNT_ID}:cache/daxcluster"
+        assert cluster["ClusterName"] == "daxcluster"
+        assert (
+            cluster["ClusterArn"]
+            == f"arn:aws:dax:us-east-2:{ACCOUNT_ID}:cache/daxcluster"
         )
-        cluster["TotalNodes"].should.equal(3)
-        cluster["ActiveNodes"].should.equal(0)
-        cluster["NodeType"].should.equal("dax.t3.small")
-        cluster["Status"].should.equal("creating")
-        cluster["ClusterDiscoveryEndpoint"].should.equal({"Port": 8111})
-        cluster["PreferredMaintenanceWindow"].should.equal("thu:23:30-fri:00:30")
-        cluster["SubnetGroup"].should.equal("default")
-        cluster["SecurityGroups"].should.have.length_of(1)
-        cluster["IamRoleArn"].should.equal(iam_role_arn)
-        cluster.should.have.key("ParameterGroup")
-        cluster["ParameterGroup"].should.have.key("ParameterGroupName").equals(
-            "default.dax1.0"
-        )
-        cluster["SSEDescription"].should.equal({"Status": "DISABLED"})
-        cluster.should.have.key("ClusterEndpointEncryptionType").equals("NONE")
+        assert cluster["TotalNodes"] == 3
+        assert cluster["ActiveNodes"] == 0
+        assert cluster["NodeType"] == "dax.t3.small"
+        assert cluster["Status"] == "creating"
+        assert cluster["ClusterDiscoveryEndpoint"] == {"Port": 8111}
+        assert cluster["PreferredMaintenanceWindow"] == "thu:23:30-fri:00:30"
+        assert cluster["SubnetGroup"] == "default"
+        assert len(cluster["SecurityGroups"]) == 1
+        assert cluster["IamRoleArn"] == iam_role_arn
+        assert cluster["ParameterGroup"]["ParameterGroupName"] == "default.dax1.0"
+        assert cluster["SSEDescription"] == {"Status": "DISABLED"}
+        assert cluster["ClusterEndpointEncryptionType"] == "NONE"
 
 
 @mock_dax
@@ -59,14 +56,13 @@ def test_create_cluster_description():
         ReplicationFactor=3,
         IamRoleArn=iam_role_arn,
     )["Cluster"]
-
     described_cluster = client.describe_clusters(ClusterNames=["daxcluster"])[
         "Clusters"
     ][0]
 
     for cluster in [created_cluster, described_cluster]:
-        cluster["ClusterName"].should.equal("daxcluster")
-        cluster["Description"].should.equal("my cluster")
+        assert cluster["ClusterName"] == "daxcluster"
+        assert cluster["Description"] == "my cluster"
 
 
 @mock_dax
@@ -81,94 +77,46 @@ def test_create_cluster_with_sse_enabled():
         SSESpecification={"Enabled": True},
         ClusterEndpointEncryptionType="TLS",
     )["Cluster"]
-
     described_cluster = client.describe_clusters(ClusterNames=["daxcluster"])[
         "Clusters"
     ][0]
 
     for cluster in [created_cluster, described_cluster]:
-        cluster["ClusterName"].should.equal("daxcluster")
-        cluster["SSEDescription"].should.equal({"Status": "ENABLED"})
-        cluster["ClusterEndpointEncryptionType"].should.equal("TLS")
-
-
-@mock_dax
-def test_create_cluster_invalid_arn():
-    client = boto3.client("dax", region_name="eu-west-1")
-    with pytest.raises(ClientError) as exc:
-        client.create_cluster(
-            ClusterName="1invalid",
-            NodeType="dax.t3.small",
-            ReplicationFactor=3,
-            IamRoleArn="n/a",
-        )
-    err = exc.value.response["Error"]
-    err["Code"].should.equal("InvalidParameterValueException")
-    err["Message"].should.equal("ARNs must start with 'arn:': n/a")
-
-
-@mock_dax
-def test_create_cluster_invalid_arn_no_partition():
-    client = boto3.client("dax", region_name="eu-west-1")
-    with pytest.raises(ClientError) as exc:
-        client.create_cluster(
-            ClusterName="1invalid",
-            NodeType="dax.t3.small",
-            ReplicationFactor=3,
-            IamRoleArn="arn:sth",
-        )
-    err = exc.value.response["Error"]
-    err["Code"].should.equal("InvalidParameterValueException")
-    err["Message"].should.equal("Second colon partition not found: arn:sth")
+        assert cluster["ClusterName"] == "daxcluster"
+        assert cluster["SSEDescription"] == {"Status": "ENABLED"}
+        assert cluster["ClusterEndpointEncryptionType"] == "TLS"
 
 
 @mock_dax
-def test_create_cluster_invalid_arn_no_vendor():
+@pytest.mark.parametrize(
+    "iam_role,expected",
+    (
+        ("n/a", "ARNs must start with 'arn:': n/a"),
+        ("arn:sth", "Second colon partition not found: arn:sth"),
+        ("arn:sth:aws", "Third colon vendor not found: arn:sth:aws"),
+        (
+            "arn:sth:aws:else",
+            "Fourth colon (region/namespace delimiter) not found: arn:sth:aws:else",
+        ),
+        (
+            "arn:sth:aws:else:eu-west-1",
+            "Fifth colon (namespace/relative-id delimiter) not found: arn:sth:aws:else:eu-west-1",
+        ),
+    ),
+)
+def test_create_cluster_invalid_arn(iam_role: str, expected: str):
     client = boto3.client("dax", region_name="eu-west-1")
     with pytest.raises(ClientError) as exc:
         client.create_cluster(
             ClusterName="1invalid",
             NodeType="dax.t3.small",
             ReplicationFactor=3,
-            IamRoleArn="arn:sth:aws",
+            IamRoleArn=iam_role,
         )
     err = exc.value.response["Error"]
-    err["Code"].should.equal("InvalidParameterValueException")
-    err["Message"].should.equal("Third colon vendor not found: arn:sth:aws")
 
-
-@mock_dax
-def test_create_cluster_invalid_arn_no_region():
-    client = boto3.client("dax", region_name="eu-west-1")
-    with pytest.raises(ClientError) as exc:
-        client.create_cluster(
-            ClusterName="1invalid",
-            NodeType="dax.t3.small",
-            ReplicationFactor=3,
-            IamRoleArn="arn:sth:aws:else",
-        )
-    err = exc.value.response["Error"]
-    err["Code"].should.equal("InvalidParameterValueException")
-    err["Message"].should.equal(
-        "Fourth colon (region/namespace delimiter) not found: arn:sth:aws:else"
-    )
-
-
-@mock_dax
-def test_create_cluster_invalid_arn_no_namespace():
-    client = boto3.client("dax", region_name="eu-west-1")
-    with pytest.raises(ClientError) as exc:
-        client.create_cluster(
-            ClusterName="1invalid",
-            NodeType="dax.t3.small",
-            ReplicationFactor=3,
-            IamRoleArn="arn:sth:aws:else:eu-west-1",
-        )
-    err = exc.value.response["Error"]
-    err["Code"].should.equal("InvalidParameterValueException")
-    err["Message"].should.equal(
-        "Fifth colon (namespace/relative-id delimiter) not found: arn:sth:aws:else:eu-west-1"
-    )
+    assert err["Code"] == "InvalidParameterValueException"
+    assert err["Message"] == expected
 
 
 @mock_dax
@@ -177,7 +125,6 @@ def test_create_cluster_invalid_arn_no_namespace():
 )
 def test_create_cluster_invalid_name(name):
     client = boto3.client("dax", region_name="eu-west-1")
-
     with pytest.raises(ClientError) as exc:
         client.create_cluster(
             ClusterName=name,
@@ -186,8 +133,9 @@ def test_create_cluster_invalid_name(name):
             IamRoleArn="arn:aws:iam::486285699788:role/apigatewayrole",
         )
     err = exc.value.response["Error"]
-    err["Code"].should.equal("InvalidParameterValueException")
-    err["Message"].should.equal(
+
+    assert err["Code"] == "InvalidParameterValueException"
+    assert err["Message"] == (
         "Cluster ID specified is not a valid identifier. Identifiers must begin with a letter; must contain only ASCII letters, digits, and hyphens; and must not end with a hyphen or contain two consecutive hyphens."
     )
 
@@ -198,7 +146,6 @@ def test_create_cluster_invalid_name(name):
 )
 def test_describe_clusters_invalid_name(name):
     client = boto3.client("dax", region_name="eu-west-1")
-
     with pytest.raises(ClientError) as exc:
         client.describe_clusters(ClusterNames=[name])
     err = exc.value.response["Error"]
@@ -211,19 +158,17 @@ def test_describe_clusters_invalid_name(name):
 @mock_dax
 def test_delete_cluster_unknown():
     client = boto3.client("dax", region_name="eu-west-1")
-
     with pytest.raises(ClientError) as exc:
         client.delete_cluster(ClusterName="unknown")
-
     err = exc.value.response["Error"]
-    err["Code"].should.equals("ClusterNotFoundFault")
-    err["Message"].should.equal("Cluster not found.")
+
+    assert err["Code"] == "ClusterNotFoundFault"
+    assert err["Message"] == "Cluster not found."
 
 
 @mock_dax
 def test_delete_cluster():
     client = boto3.client("dax", region_name="eu-west-1")
-
     iam_role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
     client.create_cluster(
         ClusterName="daxcluster",
@@ -231,32 +176,33 @@ def test_delete_cluster():
         ReplicationFactor=2,
         IamRoleArn=iam_role_arn,
     )
-
     client.delete_cluster(ClusterName="daxcluster")
 
     for _ in range(0, 3):
         # Cluster takes a while to delete...
         cluster = client.describe_clusters(ClusterNames=["daxcluster"])["Clusters"][0]
-        cluster["Status"].should.equal("deleting")
-        cluster["TotalNodes"].should.equal(2)
-        cluster["ActiveNodes"].should.equal(0)
-        cluster.shouldnt.have.key("Nodes")
+
+        assert cluster["Status"] == "deleting"
+        assert cluster["TotalNodes"] == 2
+        assert cluster["ActiveNodes"] == 0
+        assert "Nodes" not in cluster
 
     with pytest.raises(ClientError) as exc:
         client.describe_clusters(ClusterNames=["daxcluster"])
     err = exc.value.response["Error"]
-    err["Code"].should.equal("ClusterNotFoundFault")
+
+    assert err["Code"] == "ClusterNotFoundFault"
 
 
 @mock_dax
 def test_describe_cluster_unknown():
     client = boto3.client("dax", region_name="eu-west-1")
-
     with pytest.raises(ClientError) as exc:
         client.describe_clusters(ClusterNames=["unknown"])
     err = exc.value.response["Error"]
-    err["Code"].should.equal("ClusterNotFoundFault")
-    err["Message"].should.equal("Cluster unknown not found.")
+
+    assert err["Code"] == "ClusterNotFoundFault"
+    assert err["Message"] == "Cluster unknown not found."
 
 
 @mock_dax
@@ -271,8 +217,7 @@ def test_describe_clusters_returns_all():
             IamRoleArn=iam_role_arn,
         )
 
-    clusters = client.describe_clusters()["Clusters"]
-    clusters.should.have.length_of(50)
+    assert len(client.describe_clusters()["Clusters"]) == 50
 
 
 @mock_dax
@@ -288,99 +233,81 @@ def test_describe_clusters_paginates():
         )
 
     resp = client.describe_clusters(MaxResults=10)
-    resp["Clusters"].should.have.length_of(10)
-    resp.should.have.key("NextToken")
+    assert len(resp["Clusters"]) == 10
+    assert "NextToken" in resp
 
     resp = client.describe_clusters(MaxResults=10, NextToken=resp["NextToken"])
-    resp["Clusters"].should.have.length_of(10)
-    resp.should.have.key("NextToken")
+    assert len(resp["Clusters"]) == 10
+    assert "NextToken" in resp
 
     resp = client.describe_clusters(NextToken=resp["NextToken"])
-    resp["Clusters"].should.have.length_of(30)
-    resp.shouldnt.have.key("NextToken")
+    assert len(resp["Clusters"]) == 30
+    assert "NextToken" not in resp
 
 
 @mock_dax
 def test_describe_clusters_returns_nodes_after_some_time():
     client = boto3.client("dax", region_name="us-east-2")
+    iam_role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
     client.create_cluster(
         ClusterName="daxcluster",
         NodeType="dax.t3.small",
         ReplicationFactor=3,
-        IamRoleArn=f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX",
-    )["Cluster"]
+        IamRoleArn=iam_role_arn,
+    )
 
     for _ in range(0, 3):
         # Cluster takes a while to load...
         cluster = client.describe_clusters(ClusterNames=["daxcluster"])["Clusters"][0]
-        cluster["Status"].should.equal("creating")
-        cluster.shouldnt.have.key("Nodes")
+        assert cluster["Status"] == "creating"
+        assert "Nodes" not in cluster
 
     # Finished loading by now
     cluster = client.describe_clusters(ClusterNames=["daxcluster"])["Clusters"][0]
 
-    cluster["ClusterName"].should.equal("daxcluster")
-    cluster["ClusterArn"].should.equal(
-        f"arn:aws:dax:us-east-2:{ACCOUNT_ID}:cache/daxcluster"
-    )
-    cluster["TotalNodes"].should.equal(3)
-    cluster["ActiveNodes"].should.equal(0)
-    cluster["NodeType"].should.equal("dax.t3.small")
-    cluster["Status"].should.equal("available")
+    assert cluster["TotalNodes"].should.equal(3)
+    assert cluster["ActiveNodes"].should.equal(0)
+    assert cluster["Status"].should.equal("available")
 
     # Address Info is only available when the cluster is ready
-    cluster.should.have.key("ClusterDiscoveryEndpoint")
     endpoint = cluster["ClusterDiscoveryEndpoint"]
-    endpoint.should.have.key("Address")
     address = endpoint["Address"]
     cluster_id = address.split(".")[1]
-    address.should.equal(
-        f"daxcluster.{cluster_id}.dax-clusters.us-east-2.amazonaws.com"
-    )
-    endpoint.should.have.key("Port").equal(8111)
-    endpoint.should.have.key("URL").equal(f"dax://{address}")
+
+    assert address == f"daxcluster.{cluster_id}.dax-clusters.us-east-2.amazonaws.com"
+    assert endpoint["Port"] == 8111
+    assert endpoint["URL"] == f"dax://{address}"
 
     # Nodes are only shown when the cluster is ready
-    cluster.should.have.key("Nodes").length_of(3)
+    assert len(cluster["Nodes"]) == 3
+
     for idx, a in enumerate(["a", "b", "c"]):
         node = cluster["Nodes"][idx]
-        node.should.have.key("NodeId").equals(f"daxcluster-{a}")
-        node.should.have.key("Endpoint")
-        node_address = (
+        expected_node_address = (
             f"daxcluster-{a}.{cluster_id}.nodes.dax-clusters.us-east-2.amazonaws.com"
         )
-        node["Endpoint"].should.have.key("Address").equals(node_address)
-        node["Endpoint"].should.have.key("Port").equals(8111)
-        node.should.contain("AvailabilityZone")
-        node.should.have.key("NodeStatus").equals("available")
-        node.should.have.key("ParameterGroupStatus").equals("in-sync")
-
-    cluster["PreferredMaintenanceWindow"].should.equal("thu:23:30-fri:00:30")
-    cluster["SubnetGroup"].should.equal("default")
-    cluster["SecurityGroups"].should.have.length_of(1)
-    cluster.should.have.key("ParameterGroup")
-    cluster["ParameterGroup"].should.have.key("ParameterGroupName").equals(
-        "default.dax1.0"
-    )
-    cluster["SSEDescription"].should.equal({"Status": "DISABLED"})
-    cluster.should.have.key("ClusterEndpointEncryptionType").equals("NONE")
+
+        assert node["NodeId"] == f"daxcluster-{a}"
+        assert node["Endpoint"]["Address"] == expected_node_address
+        assert node["Endpoint"]["Port"] == 8111
+        assert "AvailabilityZone" in node
+        assert node["NodeStatus"] == "available"
+        assert node["ParameterGroupStatus"] == "in-sync"
 
 
 @mock_dax
 def test_list_tags_unknown():
     client = boto3.client("dax", region_name="ap-southeast-1")
-
     with pytest.raises(ClientError) as exc:
         client.list_tags(ResourceName="unknown")
-
     err = exc.value.response["Error"]
-    err["Code"].should.equal("ClusterNotFoundFault")
+
+    assert err["Code"] == "ClusterNotFoundFault"
 
 
 @mock_dax
 def test_list_tags():
     client = boto3.client("dax", region_name="ap-southeast-1")
-
     cluster = client.create_cluster(
         ClusterName="daxcluster",
         NodeType="dax.t3.small",
@@ -396,8 +323,8 @@ def test_list_tags():
     for name in ["daxcluster", cluster["ClusterArn"]]:
         resp = client.list_tags(ResourceName=name)
 
-        resp.shouldnt.have.key("NextToken")
-        resp.should.have.key("Tags").equals(
+        assert "NextToken" not in resp
+        assert resp["Tags"] == (
             [
                 {"Key": "tag1", "Value": "value1"},
                 {"Key": "tag2", "Value": "value2"},
@@ -409,20 +336,18 @@ def test_list_tags():
 @mock_dax
 def test_increase_replication_factor_unknown():
     client = boto3.client("dax", region_name="ap-southeast-1")
-
     with pytest.raises(ClientError) as exc:
         client.increase_replication_factor(
             ClusterName="unknown", NewReplicationFactor=2
         )
-
     err = exc.value.response["Error"]
-    err["Code"].should.equal("ClusterNotFoundFault")
+
+    assert err["Code"] == "ClusterNotFoundFault"
 
 
 @mock_dax
 def test_increase_replication_factor():
     client = boto3.client("dax", region_name="ap-southeast-1")
-
     name = "daxcluster"
     cluster = client.create_cluster(
         ClusterName=name,
@@ -435,23 +360,25 @@ def test_increase_replication_factor():
             {"Key": "tag3", "Value": "value3"},
         ],
     )["Cluster"]
-    cluster["TotalNodes"].should.equal(2)
 
-    new_cluster = client.increase_replication_factor(
+    assert cluster["TotalNodes"] == 2
+
+    adjusted_cluster = client.increase_replication_factor(
         ClusterName=name, NewReplicationFactor=5
     )["Cluster"]
-    new_cluster["TotalNodes"].should.equal(5)
+    described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
 
-    new_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
-    new_cluster["TotalNodes"].should.equal(5)
+    assert adjusted_cluster["TotalNodes"] == 5
+    assert described_cluster["TotalNodes"] == 5
 
     # Progress cluster until it's available
-    client.describe_clusters(ClusterNames=[name])["Clusters"][0]
-    client.describe_clusters(ClusterNames=[name])["Clusters"][0]
+    for _ in range(0, 3):
+        client.describe_clusters(ClusterNames=[name])
+
+    described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
+    node_ids = set([node["NodeId"] for node in described_cluster["Nodes"]])
 
-    cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
-    node_ids = set([n["NodeId"] for n in cluster["Nodes"]])
-    node_ids.should.equal(
+    assert node_ids == (
         {f"{name}-a", f"{name}-b", f"{name}-c", f"{name}-d", f"{name}-e"}
     )
 
@@ -459,81 +386,70 @@ def test_increase_replication_factor():
 @mock_dax
 def test_decrease_replication_factor_unknown():
     client = boto3.client("dax", region_name="ap-southeast-1")
-
     with pytest.raises(ClientError) as exc:
         client.decrease_replication_factor(
             ClusterName="unknown", NewReplicationFactor=2
         )
-
     err = exc.value.response["Error"]
-    err["Code"].should.equal("ClusterNotFoundFault")
+
+    assert err["Code"] == "ClusterNotFoundFault"
 
 
 @mock_dax
 def test_decrease_replication_factor():
     client = boto3.client("dax", region_name="eu-west-1")
-
     name = "daxcluster"
     client.create_cluster(
         ClusterName=name,
         NodeType="dax.t3.small",
         ReplicationFactor=5,
         IamRoleArn=f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX",
-        Tags=[
-            {"Key": "tag1", "Value": "value1"},
-            {"Key": "tag2", "Value": "value2"},
-            {"Key": "tag3", "Value": "value3"},
-        ],
     )
 
-    new_cluster = client.decrease_replication_factor(
+    adjusted_cluster = client.decrease_replication_factor(
         ClusterName=name, NewReplicationFactor=3
     )["Cluster"]
-    new_cluster["TotalNodes"].should.equal(3)
+    described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
 
-    new_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
-    new_cluster["TotalNodes"].should.equal(3)
+    assert adjusted_cluster["TotalNodes"] == 3
+    assert described_cluster["TotalNodes"] == 3
 
     # Progress cluster until it's available
-    client.describe_clusters(ClusterNames=[name])["Clusters"][0]
-    client.describe_clusters(ClusterNames=[name])["Clusters"][0]
+    for _ in range(0, 3):
+        client.describe_clusters(ClusterNames=[name])
 
-    cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
-    node_ids = set([n["NodeId"] for n in cluster["Nodes"]])
-    node_ids.should.equal({f"{name}-a", f"{name}-b", f"{name}-c"})
+    described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
+    node_ids = set([node["NodeId"] for node in described_cluster["Nodes"]])
+
+    assert node_ids == ({f"{name}-a", f"{name}-b", f"{name}-c"})
 
 
 @mock_dax
 def test_decrease_replication_factor_specific_nodeids():
     client = boto3.client("dax", region_name="ap-southeast-1")
-
     name = "daxcluster"
     client.create_cluster(
         ClusterName=name,
         NodeType="dax.t3.small",
         ReplicationFactor=5,
         IamRoleArn=f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX",
-        Tags=[
-            {"Key": "tag1", "Value": "value1"},
-            {"Key": "tag2", "Value": "value2"},
-            {"Key": "tag3", "Value": "value3"},
-        ],
     )
 
-    new_cluster = client.decrease_replication_factor(
+    adjusted_cluster = client.decrease_replication_factor(
         ClusterName=name,
         NewReplicationFactor=3,
         NodeIdsToRemove=["daxcluster-b", "daxcluster-c"],
     )["Cluster"]
-    new_cluster["TotalNodes"].should.equal(3)
+    described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
 
-    new_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
-    new_cluster["TotalNodes"].should.equal(3)
+    assert adjusted_cluster["TotalNodes"] == 3
+    assert described_cluster["TotalNodes"] == 3
 
     # Progress cluster until it's available
-    client.describe_clusters(ClusterNames=[name])["Clusters"][0]
-    client.describe_clusters(ClusterNames=[name])["Clusters"][0]
+    for _ in range(0, 3):
+        client.describe_clusters(ClusterNames=[name])
+
+    described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
+    node_ids = set([node["NodeId"] for node in described_cluster["Nodes"]])
 
-    cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
-    node_ids = set([n["NodeId"] for n in cluster["Nodes"]])
-    node_ids.should.equal({f"{name}-a", f"{name}-d", f"{name}-e"})
+    assert node_ids == ({f"{name}-a", f"{name}-d", f"{name}-e"})
diff --git a/tests/test_dax/test_server.py b/tests/test_dax/test_server.py
index f0fc9aefa..3f2d2453f 100644
--- a/tests/test_dax/test_server.py
+++ b/tests/test_dax/test_server.py
@@ -1,5 +1,4 @@
 import json
-import sure  # noqa # pylint: disable=unused-import
 
 import moto.server as server
 
@@ -7,9 +6,9 @@ import moto.server as server
 def test_dax_list():
     backend = server.create_backend_app("dax")
     test_client = backend.test_client()
-
     resp = test_client.post(
         "/", headers={"X-Amz-Target": "AmazonDAXV3.DescribeClusters"}, data="{}"
     )
-    resp.status_code.should.equal(200)
-    json.loads(resp.data).should.equal({"Clusters": [], "NextToken": None})
+
+    assert resp.status_code == 200
+    assert json.loads(resp.data) == {"Clusters": [], "NextToken": None}
diff --git a/tests/test_glue/test_glue.py b/tests/test_glue/test_glue.py
index 820bbc14e..03d7a54e8 100644
--- a/tests/test_glue/test_glue.py
+++ b/tests/test_glue/test_glue.py
@@ -83,30 +83,36 @@ def test_get_job_exists():
         "SecurityConfiguration": "test_config",
         "NotificationProperty": {"NotifyDelayAfter": 123},
         "GlueVersion": "string",
+        "CodeGenConfigurationNodes": {},
+        "ExecutionClass": "string",
+        "SourceControlDetails": {},
     }
     job_name = create_test_job_w_all_attributes(client, **job_attributes)
     job = client.get_job(JobName=job_name)["Job"]
-    job.should.have.key("Name").equals(job_name)
-    job.should.have.key("Description")
-    job.should.have.key("LogUri")
-    job.should.have.key("Role")
-    job.should.have.key("ExecutionProperty").equals({"MaxConcurrentRuns": 123})
-    job.should.have.key("CreatedOn")
-    job.should.have.key("LastModifiedOn")
-    job.should.have.key("ExecutionProperty")
-    job.should.have.key("Command")
-    job.should.have.key("DefaultArguments")
-    job.should.have.key("NonOverridableArguments")
-    job.should.have.key("Connections")
-    job.should.have.key("MaxRetries")
-    job.should.have.key("AllocatedCapacity")
-    job.should.have.key("Timeout")
-    job.should.have.key("MaxCapacity")
-    job.should.have.key("WorkerType")
-    job.should.have.key("NumberOfWorkers")
-    job.should.have.key("SecurityConfiguration")
-    job.should.have.key("NotificationProperty")
-    job.should.have.key("GlueVersion")
+    assert job["Name"] == job_name
+    assert "Description" in job
+    assert "LogUri" in job
+    assert "Role" in job
+    assert job["ExecutionProperty"] == {"MaxConcurrentRuns": 123}
+    assert "CreatedOn" in job
+    assert "LastModifiedOn" in job
+    assert "ExecutionProperty" in job
+    assert "Command" in job
+    assert "DefaultArguments" in job
+    assert "NonOverridableArguments" in job
+    assert "Connections" in job
+    assert "MaxRetries" in job
+    assert "AllocatedCapacity" in job
+    assert "Timeout" in job
+    assert "MaxCapacity" in job
+    assert "WorkerType" in job
+    assert "NumberOfWorkers" in job
+    assert "SecurityConfiguration" in job
+    assert "NotificationProperty" in job
+    assert "GlueVersion" in job
+    assert "CodeGenConfigurationNodes" in job
+    assert "ExecutionClass" in job
+    assert "SourceControlDetails" in job
 
 
 @mock_glue
diff --git a/tests/test_s3/test_s3_storageclass.py b/tests/test_s3/test_s3_storageclass.py
index 4c71a6b33..c0fa60cd6 100644
--- a/tests/test_s3/test_s3_storageclass.py
+++ b/tests/test_s3/test_s3_storageclass.py
@@ -231,8 +231,18 @@ def test_s3_copy_object_for_deep_archive_storage_class_restored():
         Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="DEEP_ARCHIVE"
     )
 
+    with pytest.raises(ClientError) as exc:
+        s3.get_object(Bucket="Bucket", Key="First_Object")
+    err = exc.value.response["Error"]
+    err["Code"].should.equal("InvalidObjectState")
+    err["Message"].should.equal(
+        "The operation is not valid for the object's storage class"
+    )
+    err["StorageClass"].should.equal("DEEP_ARCHIVE")
+
     s3.create_bucket(Bucket="Bucket2")
     s3.restore_object(Bucket="Bucket", Key="First_Object", RestoreRequest={"Days": 123})
+    s3.get_object(Bucket="Bucket", Key="First_Object")
 
     s3.copy_object(
         CopySource={"Bucket": "Bucket", "Key": "First_Object"},