Skip to content
This repository has been archived by the owner on Mar 24, 2022. It is now read-only.

handle empty directory and add mocks fixes #195 #203

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 29 additions & 28 deletions grains/ec2_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,36 @@ def _get_ec2_hostinfo(path=""):
resp = _call_aws("/latest/meta-data/{0}".format(path))
resp_data = resp.read().decode('utf-8').strip()
d = {}
for line in resp_data.split("\n"):
if path == "public-keys/":
line = line.split("=")[0] + "/"
if path == "instance-id/":
return {'instance-id': line}
if line[-1] != "/":
call_response = _call_aws("/latest/meta-data/{0}".format(path + line))
call_response_data = call_response.read().decode('utf-8')
# avoid setting empty grain
if call_response_data == '':
d[line] = None
elif call_response_data is not None:
line = _dash_to_snake_case(line)
try:
data = json.loads(call_response_data)
if isinstance(data, dict):
data = _snake_caseify_dict(data)
d[line] = data
except ValueError:
if "\n" in call_response_data:
d[line] = []
for dline in call_response_data.split("\n"):
d[line].append(dline)
else:
d[line] = call_response_data
if resp_data:
for line in resp_data.split("\n"):
if path == "public-keys/":
line = line.split("=")[0] + "/"
if path == "instance-id/":
return {'instance-id': line}
if line[-1] != "/":
call_response = _call_aws("/latest/meta-data/{0}".format(path + line))
call_response_data = call_response.read().decode('utf-8')
# avoid setting empty grain
if call_response_data == '':
d[line] = None
elif call_response_data is not None:
line = _dash_to_snake_case(line)
try:
data = json.loads(call_response_data)
if isinstance(data, dict):
data = _snake_caseify_dict(data)
d[line] = data
except ValueError:
if "\n" in call_response_data:
d[line] = []
for dline in call_response_data.split("\n"):
d[line].append(dline)
else:
d[line] = call_response_data
else:
return line
else:
return line
else:
d[_dash_to_snake_case(line[:-1])] = _get_ec2_hostinfo(path + line)
d[_dash_to_snake_case(line[:-1])] = _get_ec2_hostinfo(path + line)
return d


Expand Down
74 changes: 74 additions & 0 deletions tests/unit/grains/test_ec2_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Faye Salwin <[email protected]>`
'''

# Import python libs
from __future__ import absolute_import

# Import Salt Testing libs
from salttesting.helpers import ensure_in_syspath
from tests.support.unit import TestCase, skipIf
from tests.support.mock import (
patch,
mock_open,
MagicMock,
NO_MOCK,
NO_MOCK_REASON
)

# Import Salt Libs
import salt.grains.ec2_info as ec2_info

@skipIf(NO_MOCK, NO_MOCK_REASON)

def mock_call_aws(url):
class MockResponse:
def __init__(self, data, status_code):
self.data = data
self.status_code = status_code

def read(self):
return self.data

result = { "latest": { "meta-data": { "first": "value", "second": {}, "third": None}}}
path = url.split("/")
path.pop(0)
val = result
for k in path:
if k:
if isinstance(val, dict):
if k in val:
val = val[k]
else:
return MockResponse("", 404)
else:
return MockResponse("", 404)
else:
if isinstance(val, dict):
# return a slash-terminated value if the value is a dictionary
v = map(lambda k: k+"/" if isinstance(val[k],dict) else k, val)
return MockResponse("\n".join(v), 200)
else:
return MockResponse("", 404)
if val:
return MockResponse(val, 200)
else:
return MockResponse("", 404)

class Ec2InfoTestCase(TestCase):
'''
Test cases for ec2_info
'''

def test_mock_call_aws(self):
self.assertEqual(mock_call_aws("/latest/meta-data/").read(),"second/\nthird\nfirst")
self.assertEqual(mock_call_aws("/latest/meta-data/second/").read(),"")

def test__get_ec2_hostinfo(self):
with patch('salt.grains.ec2_info._call_aws', side_effect=mock_call_aws):
self.assertEqual(ec2_info._get_ec2_hostinfo(""), {"first": "value", "second": {}, "third": None})

if __name__ == '__main__':
from integration import run_tests
run_tests(Ec2InfoTestCase, needs_daemon=False)