internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: cloudtools/troposphere

Issue:
Add AWS::Elasticsearch::Domain DomainEndpointOptions 
Cloudformation now allows you to specify additional options for the domain endpoint, such as whether to require HTTPS for all traffic, with an Elasticseach Domain.  

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticsearch-domain-domainendpointoptions.html

Adding support for this would be super. 


Discussion:

Resolving patch:
diff --git a/troposphere/elasticsearch.py b/troposphere/elasticsearch.py
--- a/troposphere/elasticsearch.py
+++ b/troposphere/elasticsearch.py
@@ -8,6 +8,10 @@
 from .validators import boolean, integer, integer_range, positive_integer
 
 VALID_VOLUME_TYPES = ('standard', 'gp2', 'io1')
+VALID_TLS_SECURITY_POLICIES = (
+    'Policy-Min-TLS-1-0-2019-07',
+    'Policy-Min-TLS-1-2-2019-07'
+    )
 
 
 def validate_volume_type(volume_type):
@@ -18,6 +22,14 @@ def validate_volume_type(volume_type):
     return volume_type
 
 
+def validate_tls_security_policy(tls_security_policy):
+    """Validate TLS Security Policy for ElasticsearchDomain"""
+    if tls_security_policy not in VALID_TLS_SECURITY_POLICIES:
+        raise ValueError("Minimum TLS Security Policy must be one of: %s" %
+                         ", ".join(VALID_TLS_SECURITY_POLICIES))
+    return tls_security_policy
+
+
 class CognitoOptions(AWSProperty):
     props = {
         'Enabled': (boolean, False),
@@ -27,6 +39,13 @@ class CognitoOptions(AWSProperty):
     }
 
 
+class DomainEndpointOptions(AWSProperty):
+    props = {
+        'EnforceHTTPS': (boolean, False),
+        'TLSSecurityPolicy': (validate_tls_security_policy, False),
+    }
+
+
 class EBSOptions(AWSProperty):
     props = {
         'EBSEnabled': (boolean, False),
@@ -111,6 +130,7 @@ class Domain(AWSObject):
         'AdvancedSecurityOptions': (AdvancedSecurityOptionsInput, False),
         'CognitoOptions': (CognitoOptions, False),
         'DomainName': (basestring, False),
+        'DomainEndpointOptions': (DomainEndpointOptions, False),
         'EBSOptions': (EBSOptions, False),
         'ElasticsearchClusterConfig': (ElasticsearchClusterConfig, False),
         'ElasticsearchVersion': (basestring, False),


Test patch:
Repository: cloudtools/troposphere

Issue:
Add MetadataOptions support for LaunchConfiguration
The [MetadataOptions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-launchconfig.html#cfn-autoscaling-launchconfig-metadataoptions) are currently unsupported for [LaunchConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-launchconfig.html). This is an issue because it prevents the user from [configuring IMDS version](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html) to comply with [security best practices](https://docs.aws.amazon.com/eks/latest/userguide/best-practices-security.html )

- A similar case was found with LaunchTemplateData: [https://github.com/cloudtools/troposphere/issues/1590](https://github.com/cloudtools/troposphere/issues/1590)
- #1590 was solved in #1582 (Similar solution to this issue)


Discussion:

Resolving patch:
diff --git a/troposphere/autoscaling.py b/troposphere/autoscaling.py
--- a/troposphere/autoscaling.py
+++ b/troposphere/autoscaling.py
@@ -60,6 +60,14 @@ def to_dict(self):
         return self.tags
 
 
+class MetadataOptions(AWSProperty):
+    props = {
+        'HttpEndpoint': (basestring, False),
+        'HttpPutResponseHopLimit': (integer, False),
+        'HttpTokens': (basestring, False),
+    }
+
+
 class LifecycleHookSpecification(AWSProperty):
     props = {
         'DefaultResult': (basestring, False),
@@ -259,6 +267,7 @@ class LaunchConfiguration(AWSObject):
         'KeyName': (basestring, False),
         'LaunchConfigurationName': (basestring, False),
         'Metadata': (Metadata, False),
+        'MetadataOptions': (MetadataOptions, False),
         'PlacementTenancy': (basestring, False),
         'RamDiskId': (basestring, False),
         'SecurityGroups': (list, False),


Test patch:
Repository: cloudtools/troposphere

Issue:
Apigateway CanarySettings PercentTraffic definition is wrong
I attempted to use PercentTraffic and it gave an error that it expected a list of doubles:

`TypeError: <class 'troposphere.apigateway.CanarySetting'>: None.PercentTraffic is <class 'float'>, expected [<function double at 0x10e783200>]`

I wrapped the double in a list, and cloudformation gave an error that it must be a string:

`Value of property PercentTraffic must be of type String`.

After cloning and modifying the definition from `"PercentTraffic": ([double], False),` to `"PercentTraffic": (double, False),` my cloudformation stack creates without any issues.


Discussion:
To add, [the documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-deployment-deploymentcanarysettings.html) also specifies the data type as a Double, not a list of Doubles.

Resolving patch:
diff --git a/troposphere/apigateway.py b/troposphere/apigateway.py
--- a/troposphere/apigateway.py
+++ b/troposphere/apigateway.py
@@ -78,7 +78,7 @@ class CanarySetting(AWSProperty):
 
     props = {
         "DeploymentId": (str, False),
-        "PercentTraffic": ([double], False),
+        "PercentTraffic": (double, False),
         "StageVariableOverrides": (dict, False),
         "UseStageCache": (boolean, False),
     }
@@ -103,7 +103,7 @@ class ClientCertificate(AWSObject):
 class DeploymentCanarySettings(AWSProperty):
 
     props = {
-        "PercentTraffic": ([double], False),
+        "PercentTraffic": (double, False),
         "StageVariableOverrides": (dict, False),
         "UseStageCache": (boolean, False),
     }


Test patch:
Repository: cloudtools/troposphere

Issue:
Add support for Application Load Balancer to TargetGroup's valid types
Currently the valid TargetTypes include Instance, IP and Lambda.

ALB should also be added as a valid target group type - [ref](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-targetgroup.html#cfn-elasticloadbalancingv2-targetgroup-targettype).


Discussion:

Resolving patch:
diff --git a/troposphere/elasticloadbalancingv2.py b/troposphere/elasticloadbalancingv2.py
--- a/troposphere/elasticloadbalancingv2.py
+++ b/troposphere/elasticloadbalancingv2.py
@@ -286,13 +286,19 @@ class ListenerRule(AWSObject):
     }
 
 
+TARGET_TYPE_ALB = "alb"
 TARGET_TYPE_INSTANCE = "instance"
 TARGET_TYPE_IP = "ip"
 TARGET_TYPE_LAMBDA = "lambda"
 
 
 def validate_target_type(target_type):
-    valid_types = [TARGET_TYPE_INSTANCE, TARGET_TYPE_IP, TARGET_TYPE_LAMBDA]
+    valid_types = [
+        TARGET_TYPE_ALB,
+        TARGET_TYPE_INSTANCE,
+        TARGET_TYPE_IP,
+        TARGET_TYPE_LAMBDA,
+    ]
     if target_type not in valid_types:
         raise ValueError(
             'TargetGroup.TargetType must be one of: "%s"' % ", ".join(valid_types)


Test patch:
diff --git a/tests/test_elasticloadbalancerv2.py b/tests/test_elasticloadbalancerv2.py
--- a/tests/test_elasticloadbalancerv2.py
+++ b/tests/test_elasticloadbalancerv2.py
@@ -131,7 +131,7 @@ def test_invalid_targettype_is_rejected(self):
                 VpcId="unknown",
             ).to_dict()
         self.assertEqual(
-            'TargetGroup.TargetType must be one of: "instance, ip, lambda"',
+            'TargetGroup.TargetType must be one of: "alb, instance, ip, lambda"',
             str(valueError.exception),
         )
Repository: cloudtools/troposphere

Issue:
WAFv2 AndStatement and OrStatement incorrect validation
Hi guys,

https://github.com/cloudtools/troposphere/blob/f287fa8999ef2a5f5e301ba5c0af6421471e230b/troposphere/validators/wafv2.py#L32-L33

In the validator for WAFv2 statements, there is a check to see if the number of statements if _exactly_ 2 when it should be looking to see if there are _at least_ 2 statements given.  

> "You provide more than one [Statement](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wafv2-webacl-notstatement.html#cfn-wafv2-webacl-notstatement-statement) within the AndStatement."
[Source](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wafv2-rulegroup-andstatement.html)

AWS requires there to be more than one statement, but does not restrict them to only pairs.

A small change in the logic of the `if` statement and the `TypeError` message is all that is needed.

Thank you



Discussion:

Resolving patch:
diff --git a/troposphere/validators/wafv2.py b/troposphere/validators/wafv2.py
--- a/troposphere/validators/wafv2.py
+++ b/troposphere/validators/wafv2.py
@@ -29,8 +29,8 @@ def validate_statements(statements):
     Property: OrStatement.Statements
     """
 
-    if not isinstance(statements, list) or len(statements) != 2:
-        raise TypeError("Statements must be a list of 2 Statement elements")
+    if not isinstance(statements, list) or len(statements) < 2:
+        raise TypeError("Statements must be a list of at least 2 Statement elements")
 
     for s in statements:
         validate_statement(s)


Test patch:
diff --git a/tests/test_wafv2.py b/tests/test_wafv2.py
--- a/tests/test_wafv2.py
+++ b/tests/test_wafv2.py
@@ -61,12 +61,11 @@ def test_statement_validator(self):
 
     def test_statements_validator(self):
         validate_statements([Statement(), Statement()])
+        validate_statements([Statement(), Statement(), Statement()])
         with self.assertRaises(TypeError):
-            validate_statements(
-                [
-                    Statement(),
-                ]
-            )
+            validate_statements([])
+        with self.assertRaises(TypeError):
+            validate_statements([Statement()])
         with self.assertRaises(TypeError):
             validate_statements("foo")
         with self.assertRaises(TypeError):
Repository: cloudtools/troposphere

Issue:
Add support for additional Flink runtimes in Kinesis Data Analytics.
Kinesis supports additional Flink runtimes  (FLINK-1_13, ZEPPELIN-FLINK-1_0, ZEPPELIN-FLINK-2_0), see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-kinesisanalyticsv2-application.html.


Discussion:

Resolving patch:
diff --git a/troposphere/validators/kinesisanalyticsv2.py b/troposphere/validators/kinesisanalyticsv2.py
--- a/troposphere/validators/kinesisanalyticsv2.py
+++ b/troposphere/validators/kinesisanalyticsv2.py
@@ -10,7 +10,15 @@ def validate_runtime_environment(runtime_environment):
     Property: Application.RuntimeEnvironment
     """
 
-    VALID_RUNTIME_ENVIRONMENTS = ("SQL-1_0", "FLINK-1_6", "FLINK-1_8", "FLINK-1_11")
+    VALID_RUNTIME_ENVIRONMENTS = (
+        "FLINK-1_6",
+        "FLINK-1_8",
+        "FLINK-1_11",
+        "FLINK-1_13",
+        "SQL-1_0",
+        "ZEPPELIN-FLINK-1_0",
+        "ZEPPELIN-FLINK-2_0",
+    )
 
     if runtime_environment not in VALID_RUNTIME_ENVIRONMENTS:
         raise ValueError(


Test patch:
Repository: cloudtools/troposphere

Issue:
RDS Validiation: minimum allocated storage for Provisioned IOPS for SQLServer is 20GiB, not 100GiB
Troposphere validates the minimum allocated storage required for provisioned iops at 100
https://github.com/cloudtools/troposphere/blob/main/troposphere/validators/rds.py#L345

For SQLServer, the minimum is 20
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html#USER_PIOPS


Discussion:

Resolving patch:
diff --git a/troposphere/validators/rds.py b/troposphere/validators/rds.py
--- a/troposphere/validators/rds.py
+++ b/troposphere/validators/rds.py
@@ -340,12 +340,18 @@ def validate_dbinstance(self) -> None:
     allocated_storage = self.properties.get("AllocatedStorage")
     iops = self.properties.get("Iops", None)
     if iops and not isinstance(iops, AWSHelperFn):
+        min_storage_size = 100
+        engine = self.properties.get("Engine")
+        if not isinstance(engine, AWSHelperFn) and engine.startswith("sqlserver"):
+            min_storage_size = 20
+
         if (
             not isinstance(allocated_storage, AWSHelperFn)
-            and int(allocated_storage) < 100
+            and int(allocated_storage) < min_storage_size
         ):
             raise ValueError(
-                "AllocatedStorage must be at least 100 when " "Iops is set."
+                f"AllocatedStorage must be at least {min_storage_size} when "
+                "Iops is set."
             )
         if (
             not isinstance(allocated_storage, AWSHelperFn)


Test patch:
diff --git a/tests/test_rds.py b/tests/test_rds.py
--- a/tests/test_rds.py
+++ b/tests/test_rds.py
@@ -205,6 +205,23 @@ def test_storage_to_iops_ratio(self):
         i.Iops = 5000
         i.to_dict()
 
+    def test_storage_sqlserver(self):
+        i = rds.DBInstance(
+            "NoAZAndMultiAZ",
+            MasterUsername="myuser",
+            MasterUserPassword="mypassword",
+            DBInstanceClass="db.m1.small",
+            Engine="sqlserver-ee",
+            StorageType="io1",
+            Iops=1000,
+            AllocatedStorage=10,
+        )
+        with self.assertRaisesRegex(ValueError, " must be at least 20 "):
+            i.to_dict()
+
+        i.AllocatedStorage = 20
+        i.to_dict()
+
     def test_snapshot(self):
         i = rds.DBInstance(
             "MyDB",
Repository: cloudtools/troposphere

Issue:
Serverless Api Function events should use ApiFunctionAuth instead of Api Auth
There is currently only one `Auth` class defined in `serverless.py`. This class is used by both the `Api` class as well as `ApiEvent` class, the expected properties of these objects does not however match.

See https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-api-apiauth.html, versus https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-apifunctionauth.html.

Another class should be created to provide support for the `ApiFunctionAuth` entity.


Discussion:

Resolving patch:
diff --git a/troposphere/serverless.py b/troposphere/serverless.py
--- a/troposphere/serverless.py
+++ b/troposphere/serverless.py
@@ -583,6 +583,16 @@ class DynamoDBEvent(AWSObject):
     }
 
 
+class ApiFunctionAuth(AWSProperty):
+    props: PropsDictType = {
+        "ApiKeyRequired": (bool, False),
+        "AuthorizationScopes": (list, False),
+        "Authorizer": (str, False),
+        "InvokeRole": (str, False),
+        "ResourcePolicy": (ResourcePolicyStatement, False),
+    }
+
+
 class RequestModel(AWSProperty):
     props: PropsDictType = {
         "Model": (str, True),
@@ -596,7 +606,7 @@ class ApiEvent(AWSObject):
     resource_type = "Api"
 
     props: PropsDictType = {
-        "Auth": (Auth, False),
+        "Auth": (ApiFunctionAuth, False),
         "Path": (str, True),
         "Method": (str, True),
         "RequestModel": (RequestModel, False),


Test patch:
Repository: cloudtools/troposphere

Issue:
DeletionPolicy: add RetainExceptOnCreate option
## Ask ##

Request to add the new RetainExceptOnCreate option for the DeletionPolicy attribute. Would reduce effort for failed stack operations by eliminating the need for manual work deleting unused resources before a rollback; those resources already exist and cause failures upon retry since they can not be created again

## Documentation ##

- [RetainExceptOnDelete announcement](https://aws.amazon.com/about-aws/whats-new/2023/07/aws-cloudformation-deletion-policies-dev-test-cycle/)
- [DeletionPolicy attribute options](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html)


Discussion:

Resolving patch:
diff --git a/troposphere/__init__.py b/troposphere/__init__.py
--- a/troposphere/__init__.py
+++ b/troposphere/__init__.py
@@ -46,6 +46,7 @@
 # constants for DeletionPolicy and UpdateReplacePolicy
 Delete: Final = "Delete"
 Retain: Final = "Retain"
+RetainExceptOnCreate: Final = "RetainExceptOnCreate"
 Snapshot: Final = "Snapshot"
 
 # Pseudo Parameters


Test patch:
Repository: cloudtools/troposphere

Issue:
Update DLM Interval Rule Values
Update DLM valid intervals.  `1` has been added.

[DLM interval rule allows ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-createrule.html)


Discussion:

Resolving patch:
diff --git a/troposphere/validators/dlm.py b/troposphere/validators/dlm.py
--- a/troposphere/validators/dlm.py
+++ b/troposphere/validators/dlm.py
@@ -22,7 +22,7 @@ def validate_interval(interval):
     Property: CreateRule.Interval
     """
 
-    VALID_INTERVALS = (2, 3, 4, 6, 8, 12, 24)
+    VALID_INTERVALS = (1, 2, 3, 4, 6, 8, 12, 24)
 
     if interval not in VALID_INTERVALS:
         raise ValueError(


Test patch:
Repository: ivy-llc/ivy

Issue:
tolist



Discussion:
#11760

Resolving patch:
diff --git a/ivy/functional/frontends/numpy/manipulation_routines/changing_kind_of_array.py b/ivy/functional/frontends/numpy/manipulation_routines/changing_kind_of_array.py
--- a/ivy/functional/frontends/numpy/manipulation_routines/changing_kind_of_array.py
+++ b/ivy/functional/frontends/numpy/manipulation_routines/changing_kind_of_array.py
@@ -1 +1 @@
-# local
+
diff --git a/ivy/functional/frontends/numpy/ndarray/ndarray.py b/ivy/functional/frontends/numpy/ndarray/ndarray.py
--- a/ivy/functional/frontends/numpy/ndarray/ndarray.py
+++ b/ivy/functional/frontends/numpy/ndarray/ndarray.py
@@ -291,6 +291,9 @@ def std(
     def tobytes(self, order="C") -> bytes:
         return np_frontend.tobytes(self.data, order=order)
 
+    def tolist(self) -> list:
+        return self._ivy_array.to_list()
+
     def view(self):
         return np_frontend.reshape(self._ivy_array, tuple(self.shape))
 


Test patch:
diff --git a/ivy_tests/test_ivy/test_frontends/test_numpy/test_ndarray/test_ndarray.py b/ivy_tests/test_ivy/test_frontends/test_numpy/test_ndarray/test_ndarray.py
--- a/ivy_tests/test_ivy/test_frontends/test_numpy/test_ndarray/test_ndarray.py
+++ b/ivy_tests/test_ivy/test_frontends/test_numpy/test_ndarray/test_ndarray.py
@@ -2563,7 +2563,39 @@ def test_numpy_instance_tobytes__(
         frontend_method_data=frontend_method_data,
         on_device=on_device,
     )
+#tolist
+@handle_frontend_method(
+    class_tree=CLASS_TREE,
+    init_tree="numpy.array",
+    method_name="tolist",
+    dtype_and_x=helpers.dtype_and_values(
+        available_dtypes=helpers.get_dtypes("valid"),
+    ),
+)
+def test_numpy_instance_tolist__(
+    dtype_and_x,
+    frontend_method_data,
+    init_flags,
+    method_flags,
+    frontend,
+    on_device,
+):
+    input_dtypes, x = dtype_and_x
+    helpers.test_frontend_method(
+        init_input_dtypes=input_dtypes,
+        init_all_as_kwargs_np={
+            "object": x[0],
+        },
+        method_input_dtypes=input_dtypes,
+        method_all_as_kwargs_np={},
+        init_flags=init_flags,
+        method_flags=method_flags,
+        frontend=frontend,
+        frontend_method_data=frontend_method_data,
+        on_device=on_device,
+        test_values=False, #Todo change this after we add __iter__ to ndarray
 
+    )
 
 # __getitem__
 @handle_frontend_method(
Repository: ivy-llc/ivy

Issue:
median



Discussion:
#9561 

Resolving patch:
diff --git a/ivy/functional/frontends/torch/tensor.py b/ivy/functional/frontends/torch/tensor.py
--- a/ivy/functional/frontends/torch/tensor.py
+++ b/ivy/functional/frontends/torch/tensor.py
@@ -607,6 +607,10 @@ def permute(self, *args, dims=None):
     def mean(self, dim=None, keepdim=False):
         return torch_frontend.mean(self._ivy_array, dim=dim, keepdim=keepdim)
 
+    @with_unsupported_dtypes({"1.11.0 and below": ("float16",)}, "torch")
+    def median(self, dim=None, keepdim=False):
+        return torch_frontend.median(self._ivy_array, dim=dim, keepdim=keepdim)
+
     def transpose(self, dim0, dim1):
         return torch_frontend.transpose(self._ivy_array, dim0=dim0, dim1=dim1)
 


Test patch:
diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py
--- a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py
+++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py
@@ -4238,6 +4238,47 @@ def test_torch_instance_mean(
     )
 
 
+# median
+@handle_frontend_method(
+    class_tree=CLASS_TREE,
+    init_tree="torch.tensor",
+    method_name="median",
+    dtype_input_axis=helpers.dtype_values_axis(
+        available_dtypes=helpers.get_dtypes("float"),
+        min_num_dims=1,
+        valid_axis=True,
+        force_int_axis=True,
+    ),
+    keepdim=st.booleans(),
+)
+def test_torch_instance_median(
+    dtype_input_axis,
+    keepdim,
+    frontend,
+    frontend_method_data,
+    init_flags,
+    method_flags,
+    on_device,
+):
+    input_dtype, x, axis = dtype_input_axis
+    helpers.test_frontend_method(
+        init_input_dtypes=input_dtype,
+        init_all_as_kwargs_np={
+            "data": x[0],
+        },
+        method_input_dtypes=input_dtype,
+        method_all_as_kwargs_np={
+            "dim": axis,
+            "keepdim": keepdim,
+        },
+        frontend_method_data=frontend_method_data,
+        init_flags=init_flags,
+        method_flags=method_flags,
+        frontend=frontend,
+        on_device=on_device,
+    )
+
+
 # transpose
 @handle_frontend_method(
     class_tree=CLASS_TREE,
Repository: ivy-llc/ivy

Issue:
atleast_3d



Discussion:

Resolving patch:
diff --git a/ivy/functional/frontends/torch/miscellaneous_ops.py b/ivy/functional/frontends/torch/miscellaneous_ops.py
--- a/ivy/functional/frontends/torch/miscellaneous_ops.py
+++ b/ivy/functional/frontends/torch/miscellaneous_ops.py
@@ -361,3 +361,8 @@ def searchsorted(
     if out_int32:
         ret = ivy.astype(ret, "int32")
     return ret
+
+
+@to_ivy_arrays_and_back
+def atleast_3d(*tensors):
+    return ivy.atleast_3d(*tensors)


Test patch:
diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_miscellaneous_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_miscellaneous_ops.py
--- a/ivy_tests/test_ivy/test_frontends/test_torch/test_miscellaneous_ops.py
+++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_miscellaneous_ops.py
@@ -1194,3 +1194,35 @@ def test_torch_searchsorted(
         right=right,
         sorter=sorter,
     )
+
+
+# atleast_3d
+@handle_frontend_test(
+    fn_tree="torch.atleast_3d",
+    dtype_and_x=helpers.dtype_and_values(
+        available_dtypes=helpers.get_dtypes("valid"),
+        num_arrays=helpers.ints(min_value=1, max_value=10),
+    ),
+    test_with_out=st.just(False),
+)
+def test_torch_atleast_3d(
+    *,
+    dtype_and_x,
+    on_device,
+    fn_tree,
+    frontend,
+    test_flags,
+):
+    input_dtype, arrays = dtype_and_x
+    arys = {}
+    for i, array in enumerate(arrays):
+        arys["arrs{}".format(i)] = array
+    test_flags.num_positional_args = len(arys)
+    helpers.test_frontend_function(
+        input_dtypes=input_dtype,
+        frontend=frontend,
+        test_flags=test_flags,
+        fn_tree=fn_tree,
+        on_device=on_device,
+        **arys,
+    )