Repository: getmoto/moto

Issue:
route53.list_resource_record_sets() with StartRecordName= behaves different from real service
Hi,

I believe I have found a bug in Moto concerning Route53: the mocked call behaves differently from the real Route53 service.

Step to reproduce:
```python
import boto3
import moto

mock = moto.mock_route53()
mock.start()

route53_client = boto3.client('route53')
hosted_zone = route53_client.create_hosted_zone(
    Name="github.com",  # I'd like to use example.org, but Route53 refuses that
    CallerReference="whatever",
)
hosted_zone_id = hosted_zone['HostedZone']['Id']

route53_client.change_resource_record_sets(
    HostedZoneId=hosted_zone_id,
    ChangeBatch={'Changes': [
        {
            'Action': 'CREATE',
            'ResourceRecordSet': {
                'Name': 'www.github.com',
                'Type': 'A',
                'TTL': 5,
                'ResourceRecords': [
                    {'Value': "127.0.0.1"},
                ],
            },
        },
        {
            'Action': 'CREATE',
            'ResourceRecordSet': {
                'Name': 'sub.www.github.com',
                'Type': 'A',
                'TTL': 5,
                'ResourceRecords': [
                    {'Value': "127.0.0.1"},
                ],
            },
        },
    ]},
)

records = route53_client.list_resource_record_sets(
    HostedZoneId=hosted_zone_id,
    StartRecordName="www.github.com.",
)

print("\n".join([_['Name'] for _ in records['ResourceRecordSets']]))

mock.stop()
```

When running this code mocked, it returns:
```
www.github.com.
```

The expected result (and the actual result when running against the actual Route53) is:
```
www.github.com.
sub.www.github.com.
```

The relevant [API documentation](https://docs.aws.amazon.com/Route53/latest/APIReference/API_ListResourceRecordSets.html) states:

>  `ListResourceRecordSets` sorts results first by DNS name with the labels reversed, for example: `com.example.www.`

>  name: The first name in the lexicographic ordering of resource record sets that you want to list.

I understand this to mean that `ListResourceRecordSets` will return all records that are lexicographically sorted at/after the given `StartRecordName` (possibly truncated by the page limit). This interpretation is supported by the actual Route53 service, which also returns records sorted after the given `StartRecordName`.


Discussion:

Resolving patch:
diff --git a/moto/route53/models.py b/moto/route53/models.py
--- a/moto/route53/models.py
+++ b/moto/route53/models.py
@@ -165,6 +165,12 @@ def delete(self, *args, **kwargs):
         hosted_zone.delete_rrset_by_name(self.name)
 
 
+def reverse_domain_name(domain_name):
+    if domain_name.endswith('.'):  # normalize without trailing dot
+        domain_name = domain_name[:-1]
+    return '.'.join(reversed(domain_name.split('.')))
+
+
 class FakeZone(BaseModel):
 
     def __init__(self, name, id_, private_zone, comment=None):
@@ -200,12 +206,15 @@ def delete_rrset_by_id(self, set_identifier):
 
     def get_record_sets(self, start_type, start_name):
         record_sets = list(self.rrsets)  # Copy the list
+        if start_name:
+            record_sets = [
+                record_set
+                for record_set in record_sets
+                if reverse_domain_name(record_set.name) >= reverse_domain_name(start_name)
+            ]
         if start_type:
             record_sets = [
                 record_set for record_set in record_sets if record_set.type_ >= start_type]
-        if start_name:
-            record_sets = [
-                record_set for record_set in record_sets if record_set.name >= start_name]
 
         return record_sets
 


Test patch:
diff --git a/tests/test_route53/test_route53.py b/tests/test_route53/test_route53.py
--- a/tests/test_route53/test_route53.py
+++ b/tests/test_route53/test_route53.py
@@ -123,12 +123,12 @@ def test_rrset():
     rrsets.should.have.length_of(2)
 
     rrsets = conn.get_all_rrsets(
-        zoneid, name="foo.bar.testdns.aws.com", type="A")
+        zoneid, name="bar.foo.testdns.aws.com", type="A")
     rrsets.should.have.length_of(1)
-    rrsets[0].resource_records[0].should.equal('1.2.3.4')
+    rrsets[0].resource_records[0].should.equal('5.6.7.8')
 
     rrsets = conn.get_all_rrsets(
-        zoneid, name="bar.foo.testdns.aws.com", type="A")
+        zoneid, name="foo.bar.testdns.aws.com", type="A")
     rrsets.should.have.length_of(2)
     resource_records = [rr for rr_set in rrsets for rr in rr_set.resource_records]
     resource_records.should.contain('1.2.3.4')