Repository: getmoto/moto

Issue:
SSM `get_parameter_by_path` should return root parameters when path is just '/'
When you have a parameter with out any path in its name ie: `Name='foo', Description='A test parameter', Value='bar', Type='String'` and you run call get_parameters_by_path and pass in a Path of `'/'` it will return all parameters that don't have a path.

However in Moto it returns only an empty list.

Example Test File:
```python
import boto3
from moto import mock_ssm

ssm = boto3.client('ssm')

parameter = ssm.put_parameter(
    Name='foo',
    Description='a test parameter',
    Value='bar',
    Type='String'
)

parameters = ssm.get_parameters_by_path(
    Path='/'
)

print(parameters)
# {'Parameters': [{'Name': 'foo', 'Type': 'String', 'Value': 'bar', 'Version': 1}], 'ResponseMetadata': {}}

with mock_ssm():
    client = boto3.client('ssm')
    params = client.get_parameters_by_path(Path='/')
    print(params)
    # {'Parameters': [], 'ResponseMetadata': {}}
```


Discussion:

Resolving patch:
diff --git a/moto/ssm/models.py b/moto/ssm/models.py
--- a/moto/ssm/models.py
+++ b/moto/ssm/models.py
@@ -100,7 +100,7 @@ def get_parameters_by_path(self, path, with_decryption, recursive, filters=None)
         # difference here.
         path = path.rstrip('/') + '/'
         for param in self._parameters:
-            if not param.startswith(path):
+            if path != '/' and not param.startswith(path):
                 continue
             if '/' in param[len(path) + 1:] and not recursive:
                 continue


Test patch:
diff --git a/tests/test_ssm/test_ssm_boto3.py b/tests/test_ssm/test_ssm_boto3.py
--- a/tests/test_ssm/test_ssm_boto3.py
+++ b/tests/test_ssm/test_ssm_boto3.py
@@ -95,6 +95,27 @@ def test_get_parameters_by_path():
         Type='SecureString',
         KeyId='alias/aws/ssm')
 
+    client.put_parameter(
+        Name='foo',
+        Description='A test parameter',
+        Value='bar',
+        Type='String')
+
+    client.put_parameter(
+        Name='baz',
+        Description='A test parameter',
+        Value='qux',
+        Type='String')
+
+    response = client.get_parameters_by_path(Path='/', Recursive=False)
+    len(response['Parameters']).should.equal(2)
+    {p['Value'] for p in response['Parameters']}.should.equal(
+        set(['bar', 'qux'])
+    )
+
+    response = client.get_parameters_by_path(Path='/', Recursive=True)
+    len(response['Parameters']).should.equal(9)
+
     response = client.get_parameters_by_path(Path='/foo')
     len(response['Parameters']).should.equal(2)
     {p['Value'] for p in response['Parameters']}.should.equal(
@@ -417,6 +438,7 @@ def test_describe_parameters_filter_keyid():
     response['Parameters'][0]['Type'].should.equal('SecureString')
     ''.should.equal(response.get('NextToken', ''))
 
+
 @mock_ssm
 def test_describe_parameters_attributes():
     client = boto3.client('ssm', region_name='us-east-1')
@@ -445,6 +467,7 @@ def test_describe_parameters_attributes():
     response['Parameters'][1].get('Description').should.be.none
     response['Parameters'][1]['Version'].should.equal(1)
 
+
 @mock_ssm
 def test_get_parameter_invalid():
     client = client = boto3.client('ssm', region_name='us-east-1')