Skip to content

Commit d26a67a

Browse files
authored
Merge branch 'master' into windows-virtualenv-support
2 parents 1905c9a + 5304b1c commit d26a67a

File tree

4 files changed

+170
-31
lines changed

4 files changed

+170
-31
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ install:
1818
before_script:
1919
- export PYTHONPATH=$VIRTUAL_ENV/lib/python$TRAVIS_PYTHON_VERSION/site-packages
2020
- cd tests/unit
21+
2122
script:
2223
nosetests -v --with-coverage --cover-package=jnpr.jsnapy --cover-inclusive -a unit
2324

lib/jnpr/jsnapy/check.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def get_err_mssg(self, path, ele_list):
8282
path_keys = ['err', 'info', 'ignore-null']
8383
value_list = []
8484
for key, value in path.items():
85-
if key not in path_keys:
85+
if key not in path_keys and value:
8686
value_list = self.splitter(value)
8787
val = path.get('err')
8888
regex = r"\$(\d+)"
@@ -106,7 +106,7 @@ def get_info_mssg(self, path, ele_list):
106106
path_keys = ['err', 'info', 'ignore-null']
107107
value_list = []
108108
for key, value in path.items():
109-
if key not in path_keys:
109+
if key not in path_keys and value:
110110
value_list = self.splitter(value)
111111
val = path.get('info')
112112
regex = r"\$(\d+)"
@@ -158,6 +158,11 @@ def get_xml_reply(self, db, snap):
158158
return
159159
return xml_value
160160

161+
def _get_testop(self, elem_list):
162+
exclusion_list = ['err', 'info', 'ignore-null']
163+
testop = [key.lower() for key in elem_list if key.lower() not in exclusion_list]
164+
testop = testop[0] if testop else "Define test operator"
165+
return testop
161166

162167
def expression_evaluator(self, elem_test, op, x_path, id_list, iter, teston,
163168
check, db, snap1, snap2=None, action=None, top_ignore_null=None):
@@ -180,11 +185,8 @@ def expression_evaluator(self, elem_test, op, x_path, id_list, iter, teston,
180185
"""
181186
# analyze individual test case and extract element list, info and
182187
# err message ####
183-
values = ['err', 'info']
184-
testvalues = elem_test.keys()
185-
testop1 = [
186-
tvalue for tvalue in testvalues if tvalue not in values]
187-
testop = testop1[0] if testop1 else "Define test operator"
188+
189+
testop = self._get_testop(elem_test)
188190

189191
ele = elem_test.get(testop)
190192
if ele is not None:
@@ -293,11 +295,8 @@ def expression_builder(self, sub_expr, parent_op=None, **kwargs):
293295
last_test_instance = kwargs['op'].test_details[kwargs['teston']][-1]
294296
res = last_test_instance['result']
295297

296-
values = ['err', 'info']
297-
testvalues = elem.keys()
298-
testop1 = [
299-
tvalue for tvalue in testvalues if tvalue not in values]
300-
testop = testop1[0] if testop1 else "Define test operator"
298+
testop = self._get_testop(elem)
299+
301300
#for skipping cases
302301
if res is None or (last_test_instance['count']['pass'] == 0 and
303302
last_test_instance['count']['fail'] == 0 and
@@ -601,7 +600,7 @@ def generate_test_files(
601600
(val),
602601
extra=self.log_detail)
603602
try:
604-
if tests[val][0].keys()[0] == 'command':
603+
if 'command' in list(tests[val][0].keys()):
605604
command = tests[val][0].get('command').split('|')[0].strip()
606605
reply_format = tests[val][0].get('format', 'xml')
607606
message = self._print_testmssg("Command: "+command, "*")

lib/jnpr/jsnapy/jsnapy.py

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ def __init__(self):
109109
nargs='?',
110110
help="post snapshot filename",
111111
type=str) # make it optional
112+
self.parser.add_argument(
113+
"-T", "--testfiles",
114+
nargs="+",
115+
help="test file paths") # Take test file/files as an argument
112116
self.parser.add_argument(
113117
"-f", "--file",
114118
help="config file to take snapshot",
@@ -312,19 +316,29 @@ def get_hosts(self):
312316
conf_file = self.args.file
313317
check = self.args.check
314318
snap = self.args.snap
315-
if os.path.isfile(conf_file):
316-
config_file = open(conf_file, 'r')
317-
self.main_file = yaml.load(config_file)
318-
elif os.path.isfile(os.path.join(get_path('DEFAULT', 'config_file_path'), conf_file)):
319-
fpath = get_path('DEFAULT', 'config_file_path')
320-
config_file = open(os.path.join(fpath, conf_file), 'r')
321-
self.main_file = yaml.load(config_file)
319+
if conf_file is not None:
320+
if os.path.isfile(conf_file):
321+
config_file = open(conf_file, 'r')
322+
self.main_file = yaml.load(config_file)
323+
elif os.path.isfile(os.path.join(get_path('DEFAULT', 'config_file_path'), conf_file)):
324+
fpath = get_path('DEFAULT', 'config_file_path')
325+
config_file = open(os.path.join(fpath, conf_file), 'r')
326+
self.main_file = yaml.load(config_file)
322327
else:
323-
self.logger.error(
324-
colorama.Fore.RED +
325-
"ERROR!! Config file '%s' is not present " %
326-
conf_file, extra=self.log_detail)
327-
sys.exit(1)
328+
if self.args.hostname and self.args.testfiles:
329+
temp_dict = {'hosts':[{'device':'', 'username':'', 'passwd':''}], 'tests':[]}
330+
temp_dict['hosts'][0]['device'] = self.args.hostname
331+
temp_dict['hosts'][0]['username'] = self.args.login
332+
temp_dict['hosts'][0]['passwd'] = self.args.passwd
333+
for tfile in self.args.testfiles:
334+
temp_dict['tests'].append(tfile)
335+
self.main_file = temp_dict
336+
else:
337+
self.logger.error(
338+
colorama.Fore.RED +
339+
"ERROR!! Config file '%s' is not present " %
340+
conf_file, extra=self.log_detail)
341+
sys.exit(1)
328342

329343
#### if --check option is given for sqlite, then snap file name is not compulsory ####
330344
#### else exit the function saying arguments not correct ####
@@ -1049,9 +1063,10 @@ def check_arguments(self):
10491063
self.parser.print_help()
10501064
sys.exit(1)
10511065

1052-
if((self.args.snap is True and (self.args.pre_snapfile is None or self.args.file is None)) or
1066+
if(((self.args.snap is True and (self.args.pre_snapfile is None or self.args.file is None)) or
10531067
(self.args.snapcheck is True and self.args.file is None) or
1054-
(self.args.check is True and self.args.file is None)
1068+
(self.args.check is True and self.args.file is None)) and
1069+
(self.args.testfiles is None or self.args.hostname is None)
10551070
):
10561071
self.logger.error(colorama.Fore.RED +
10571072
"Arguments not given correctly, Please refer help message", extra=self.log_detail)
@@ -1067,7 +1082,8 @@ def check_arguments(self):
10671082
None)
10681083
sys.exit(1)
10691084
else:
1070-
if self.args.file is None:
1085+
if (self.args.file is None) and (
1086+
self.args.testfiles is None or self.args.hostname is None):
10711087
self.parser.print_help()
10721088
sys.exit(1)
10731089

tests/unit/test_jsnapy.py

Lines changed: 126 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -728,10 +728,133 @@ def test_port_with_include(self,mock_connect,mock_path):
728728

729729
mock_connect.assert_has_calls(expected_calls_made, any_order=True)
730730

731-
732-
733-
731+
@patch('argparse.ArgumentParser.exit')
732+
@patch('jnpr.jsnapy.jsnapy.sys.exit')
733+
@patch('jnpr.jsnapy.SnapAdmin.login')
734+
@patch('jnpr.jsnapy.jsnapy.logging.getLogger')
735+
def test_check_arguments_test_file_1(self, mock_log, mock_login, mock_sys, mock_arg):
736+
js = SnapAdmin()
737+
js.args.snap = False
738+
js.args.file = None
739+
js.args.testfiles = os.path.join(os.path.dirname(__file__),
740+
'configs', 'test_diff.yml')
741+
js.args.check = True
742+
js.args.snapcheck = False
743+
js.args.diff = False
744+
js.args.login = "abc"
745+
js.args.hostname = "10.216.193.114"
746+
js.args.passwd = "xyz"
747+
js.args.post_snapfile = "mock_snap2"
748+
js.args.pre_snapfile = "mock_snap"
749+
with patch('argparse.ArgumentParser.print_help') as mock_parser:
750+
js.check_arguments()
751+
js.get_hosts()
752+
self.assertTrue(js.main_file)
753+
self.assertEqual(js.main_file['hosts'][0]['device'],"10.216.193.114")
754+
self.assertEqual(js.main_file['hosts'][0]['username'],"abc")
755+
self.assertEqual(js.main_file['hosts'][0]['passwd'],"xyz")
756+
self.assertEqual(js.main_file['tests'][0],js.args.testfiles[0])
734757

758+
@patch('argparse.ArgumentParser.exit')
759+
@patch('jnpr.jsnapy.jsnapy.sys.exit')
760+
@patch('jnpr.jsnapy.SnapAdmin.login')
761+
@patch('jnpr.jsnapy.jsnapy.logging.getLogger')
762+
def test_check_arguments_test_file_2(self, mock_log, mock_login, mock_sys, mock_arg):
763+
js = SnapAdmin()
764+
js.args.snap = True
765+
js.args.file = None
766+
js.args.testfiles = os.path.join(os.path.dirname(__file__),
767+
'configs', 'test_diff.yml')
768+
js.args.check = False
769+
js.args.snapcheck = False
770+
js.args.diff = False
771+
js.args.login = "abc"
772+
js.args.hostname = "10.216.193.114"
773+
js.args.passwd = "xyz"
774+
js.args.post_snapfile = None
775+
js.args.pre_snapfile = "mock_snap"
776+
with patch('argparse.ArgumentParser.print_help') as mock_parser:
777+
js.check_arguments()
778+
js.get_hosts()
779+
self.assertTrue(js.main_file)
780+
self.assertEqual(js.main_file['hosts'][0]['device'],"10.216.193.114")
781+
self.assertEqual(js.main_file['hosts'][0]['username'],"abc")
782+
self.assertEqual(js.main_file['hosts'][0]['passwd'],"xyz")
783+
self.assertEqual(js.main_file['tests'][0],js.args.testfiles[0])
784+
785+
@patch('argparse.ArgumentParser.exit')
786+
@patch('jnpr.jsnapy.jsnapy.sys.exit')
787+
@patch('jnpr.jsnapy.SnapAdmin.login')
788+
@patch('jnpr.jsnapy.jsnapy.logging.getLogger')
789+
def test_check_arguments_test_file_3(self, mock_log, mock_login, mock_sys, mock_arg):
790+
js = SnapAdmin()
791+
js.args.snap = False
792+
js.args.file = None
793+
js.args.testfiles = [os.path.join(os.path.dirname(__file__),
794+
'configs', 'test_diff.yml'),os.path.join(os.path.dirname(__file__),
795+
'configs', 'tests.yml')]
796+
js.args.check = False
797+
js.args.snapcheck = True
798+
js.args.diff = False
799+
js.args.login = "abc"
800+
js.args.hostname = "10.216.193.114"
801+
js.args.passwd = "xyz"
802+
js.args.post_snapfile = "mock_snap2"
803+
js.args.pre_snapfile = "mock_snap"
804+
with patch('argparse.ArgumentParser.print_help') as mock_parser:
805+
js.check_arguments()
806+
js.get_hosts()
807+
self.assertTrue(js.main_file)
808+
self.assertEqual(js.main_file['hosts'][0]['device'],"10.216.193.114")
809+
self.assertEqual(js.main_file['hosts'][0]['username'],"abc")
810+
self.assertEqual(js.main_file['hosts'][0]['passwd'],"xyz")
811+
self.assertEqual(js.main_file['tests'][0],js.args.testfiles[0])
812+
self.assertEqual(js.main_file['tests'][1],js.args.testfiles[1])
813+
814+
@patch('argparse.ArgumentParser.exit')
815+
@patch('jnpr.jsnapy.SnapAdmin.get_hosts')
816+
@patch('jnpr.jsnapy.jsnapy.sys.exit')
817+
@patch('jnpr.jsnapy.jsnapy.logging.getLogger')
818+
def test_check_arguments_test_file_4(self, mock_log,mock_sys, mock_get_hosts, mock_arg):
819+
js = SnapAdmin()
820+
js.args.snap = False
821+
js.args.file = None
822+
js.args.testfiles = os.path.join(os.path.dirname(__file__),
823+
'configs', 'test_diff.yml')
824+
js.args.check = False
825+
js.args.snapcheck = False
826+
js.args.diff = True
827+
js.args.login = "abc"
828+
js.args.hostname = "10.216.193.114"
829+
js.args.passwd = "xyz"
830+
js.args.post_snapfile = "mock_snap2"
831+
js.args.pre_snapfile = "mock_snap"
832+
with patch('argparse.ArgumentParser.print_help') as mock_parser:
833+
js.check_arguments()
834+
self.assertFalse(mock_get_hosts.called)
835+
836+
@patch('argparse.ArgumentParser.exit')
837+
@patch('jnpr.jsnapy.SnapAdmin.get_hosts')
838+
@patch('jnpr.jsnapy.jsnapy.sys.exit')
839+
@patch('jnpr.jsnapy.jsnapy.logging.getLogger')
840+
def test_check_arguments_test_file_5(self, mock_log, mock_sys, mock_get_hosts, mock_arg):
841+
js = SnapAdmin()
842+
js.args.snap = False
843+
js.args.file = None
844+
js.args.testfiles = None
845+
js.args.check = True
846+
js.args.snapcheck = False
847+
js.args.diff = False
848+
js.args.login = None
849+
js.args.hostname = "10.216.193.114"
850+
js.args.passwd = "xyz"
851+
js.args.post_snapfile = "mock_snap2"
852+
js.args.pre_snapfile = "mock_snap"
853+
with patch('argparse.ArgumentParser.print_help') as mock_parser:
854+
js.check_arguments()
855+
self.assertFalse(mock_get_hosts.called)
856+
mock_sys.assert_called_with(1)
857+
mock_parser.assert_called_with()
735858

736859
with nested(
737860
patch('sys.exit'),

0 commit comments

Comments
 (0)