test_netmiko_commit.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. #!/usr/bin/env python
  2. """
  3. test_ssh_connect: verify ssh connectivity
  4. test_config_mode: verify enter config mode
  5. test_commit_base: test std .commit()
  6. test_commit_confirm: test commit with confirm
  7. test_confirm_delay: test commit-confirm with non-std delay
  8. test_no_confirm: test commit-confirm with no confirm
  9. test_commit_check: test commit check
  10. test_commit_comment: test commit with comment
  11. test_commit_andquit: test commit andquit
  12. test_exit_config_mode: verify exit config mode
  13. test_disconnect: cleanly disconnect the SSH session
  14. """
  15. import time
  16. import re
  17. import random
  18. import string
  19. def gen_random(N=6):
  20. return "".join([random.choice(string.ascii_lowercase + string.ascii_uppercase
  21. + string.digits) for x in range(N) ])
  22. def retrieve_commands(commands):
  23. """
  24. Retrieve context needed for a set of commit actions
  25. """
  26. config_commands = commands['config']
  27. support_commit = commands.get('support_commit')
  28. config_verify = commands['config_verification']
  29. return (config_commands, support_commit, config_verify)
  30. def setup_initial_state(net_connect, commands, expected_responses):
  31. '''
  32. Setup initial configuration prior to change so that config change can be verified
  33. '''
  34. # Setup initial state
  35. config_commands, support_commit, config_verify = retrieve_commands(commands)
  36. setup_base_config(net_connect, config_commands[0:1])
  37. cmd_response = expected_responses.get('cmd_response_init', config_commands[0])
  38. initial_state = config_change_verify(net_connect, config_verify, cmd_response)
  39. assert initial_state is True
  40. return config_commands, support_commit, config_verify
  41. def setup_base_config(net_connect, config_changes):
  42. """
  43. Send set of config commands and commit
  44. """
  45. net_connect.send_config_set(config_changes)
  46. net_connect.commit()
  47. def config_change_verify(net_connect, verify_cmd, cmd_response):
  48. '''
  49. Send verify_cmd down channel, verify cmd_response in output
  50. '''
  51. config_commands_output = net_connect.send_command_expect(verify_cmd)
  52. if cmd_response in config_commands_output:
  53. return True
  54. else:
  55. return False
  56. def test_ssh_connect(net_connect, commands, expected_responses):
  57. '''
  58. Verify the connection was established successfully
  59. '''
  60. show_version = net_connect.send_command_expect(commands["version"])
  61. assert expected_responses["version_banner"] in show_version
  62. def test_config_mode(net_connect, commands, expected_responses):
  63. '''
  64. Test enter config mode
  65. '''
  66. net_connect.config_mode()
  67. assert net_connect.check_config_mode() == True
  68. def test_commit_base(net_connect, commands, expected_responses):
  69. '''
  70. Test .commit() with no options
  71. '''
  72. # Setup the initial config state
  73. config_commands, support_commit, config_verify = setup_initial_state(net_connect,
  74. commands, expected_responses)
  75. # Perform commit test
  76. net_connect.send_config_set(config_commands)
  77. net_connect.commit()
  78. cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
  79. final_state = config_change_verify(net_connect, config_verify, cmd_response)
  80. assert final_state is True
  81. def test_commit_confirm(net_connect, commands, expected_responses):
  82. '''
  83. Test confirm with confirm
  84. '''
  85. # Setup the initial config state
  86. config_commands, support_commit, config_verify = setup_initial_state(net_connect,
  87. commands, expected_responses)
  88. # Perform commit-confirm test
  89. net_connect.send_config_set(config_commands)
  90. if net_connect.device_type == 'cisco_xr':
  91. net_connect.commit(confirm=True, confirm_delay=60)
  92. else:
  93. net_connect.commit(confirm=True)
  94. cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
  95. final_state = config_change_verify(net_connect, config_verify, cmd_response)
  96. assert final_state is True
  97. # Perform confirm
  98. net_connect.commit()
  99. def test_confirm_delay(net_connect, commands, expected_responses):
  100. '''
  101. Test commit with confirm and non-default delay
  102. '''
  103. # Setup the initial config state
  104. config_commands, support_commit, config_verify = setup_initial_state(net_connect,
  105. commands, expected_responses)
  106. # Perform commit-confirm test
  107. net_connect.send_config_set(config_commands)
  108. if net_connect.device_type == 'cisco_xr':
  109. net_connect.commit(confirm=True, confirm_delay=60)
  110. else:
  111. net_connect.commit(confirm=True, confirm_delay=5)
  112. cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
  113. final_state = config_change_verify(net_connect, config_verify, cmd_response)
  114. assert final_state is True
  115. # Perform confirm
  116. net_connect.commit()
  117. def test_no_confirm(net_connect, commands, expected_responses):
  118. '''
  119. Perform commit-confirm, but don't confirm (verify rollback)
  120. '''
  121. # Setup the initial config state
  122. config_commands, support_commit, config_verify = setup_initial_state(net_connect,
  123. commands, expected_responses)
  124. # Perform commit-confirm test
  125. net_connect.send_config_set(config_commands)
  126. if net_connect.device_type == 'cisco_xr':
  127. net_connect.commit(confirm=True, confirm_delay=30)
  128. else:
  129. net_connect.commit(confirm=True, confirm_delay=1)
  130. cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
  131. final_state = config_change_verify(net_connect, config_verify, cmd_response)
  132. assert final_state is True
  133. time.sleep(130)
  134. # Verify rolled back to initial state
  135. cmd_response = expected_responses.get('cmd_response_init', config_commands[0])
  136. init_state = config_change_verify(net_connect, config_verify, cmd_response)
  137. assert init_state is True
  138. def test_clear_msg(net_connect, commands, expected_responses):
  139. """
  140. IOS-XR generates the following message upon a failed commit
  141. One or more commits have occurred from other
  142. configuration sessions since this session started
  143. or since the last commit was made from this session.
  144. You can use the 'show configuration commit changes'
  145. command to browse the changes.
  146. Do you wish to proceed with this commit anyway? [no]: yes
  147. Clear it
  148. """
  149. # Setup the initial config state
  150. config_commands, support_commit, config_verify = retrieve_commands(commands)
  151. if net_connect.device_type == 'cisco_xr':
  152. output = net_connect.send_config_set(config_commands)
  153. output += net_connect.send_command_expect('commit', expect_string=r'Do you wish to')
  154. output += net_connect.send_command_expect('yes', auto_find_prompt=False)
  155. assert True is True
  156. def test_commit_check(net_connect, commands, expected_responses):
  157. '''
  158. Test commit check
  159. '''
  160. # IOS-XR does not support commit check
  161. if net_connect.device_type == 'cisco_xr':
  162. assert True is True
  163. else:
  164. # Setup the initial config state
  165. config_commands, support_commit, config_verify = setup_initial_state(net_connect,
  166. commands, expected_responses)
  167. # Perform commit-confirm test
  168. net_connect.send_config_set(config_commands)
  169. net_connect.commit(check=True)
  170. # Verify at initial state
  171. cmd_response = expected_responses.get('cmd_response_init', config_commands[0])
  172. init_state = config_change_verify(net_connect, config_verify, cmd_response)
  173. assert init_state is True
  174. rollback = commands.get('rollback')
  175. net_connect.send_config_set([rollback])
  176. def test_commit_comment(net_connect, commands, expected_responses):
  177. '''
  178. Test commit with comment
  179. '''
  180. # Setup the initial config state
  181. config_commands, support_commit, config_verify = setup_initial_state(net_connect,
  182. commands, expected_responses)
  183. # Perform commit with comment
  184. net_connect.send_config_set(config_commands)
  185. net_connect.commit(comment="Unit test on commit with comment")
  186. # Verify change was committed
  187. cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
  188. final_state = config_change_verify(net_connect, config_verify, cmd_response)
  189. assert final_state is True
  190. # Verify commit comment
  191. commit_verification = commands.get("commit_verification")
  192. tmp_output = net_connect.send_command(commit_verification)
  193. if net_connect.device_type == 'cisco_xr':
  194. commit_comment = tmp_output
  195. else:
  196. commit_comment = tmp_output.split("\n")[2]
  197. assert expected_responses.get("commit_comment") in commit_comment.strip()
  198. def test_commit_andquit(net_connect, commands, expected_responses):
  199. '''
  200. Test commit and immediately quit configure mode
  201. '''
  202. # IOS-XR does not support commit and quit
  203. if net_connect.device_type == 'cisco_xr':
  204. assert True is True
  205. else:
  206. # Setup the initial config state
  207. config_commands, support_commit, config_verify = setup_initial_state(net_connect,
  208. commands, expected_responses)
  209. # Execute change and commit
  210. net_connect.send_config_set(config_commands)
  211. net_connect.commit(and_quit=True)
  212. # Verify change was committed
  213. cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
  214. config_verify = 'show configuration | match archive'
  215. final_state = config_change_verify(net_connect, config_verify, cmd_response)
  216. assert final_state is True
  217. def test_commit_label(net_connect, commands, expected_responses):
  218. """Test commit label for IOS-XR."""
  219. if net_connect.device_type != 'cisco_xr':
  220. assert True is True
  221. else:
  222. # Setup the initial config state
  223. config_commands, support_commit, config_verify = setup_initial_state(net_connect,
  224. commands, expected_responses)
  225. # Execute change and commit
  226. net_connect.send_config_set(config_commands)
  227. label = "test_lbl_" + gen_random()
  228. net_connect.commit(label=label)
  229. # Verify commit label
  230. commit_verification = commands.get("commit_verification")
  231. tmp_output = net_connect.send_command(commit_verification)
  232. match = re.search(r"Label: (.*)", tmp_output)
  233. response_label = match.group(1)
  234. response_label = response_label.strip()
  235. assert label == response_label
  236. def test_commit_label_comment(net_connect, commands, expected_responses):
  237. '''
  238. Test commit label for IOS-XR with comment
  239. '''
  240. # IOS-XR only test
  241. if net_connect.device_type != 'cisco_xr':
  242. assert True is True
  243. else:
  244. # Setup the initial config state
  245. config_commands, support_commit, config_verify = setup_initial_state(net_connect,
  246. commands, expected_responses)
  247. # Execute change and commit
  248. net_connect.send_config_set(config_commands)
  249. label = "test_lbl_" + gen_random()
  250. comment="Test with comment and label"
  251. net_connect.commit(label=label, comment=comment)
  252. # Verify commit label
  253. commit_verification = commands.get("commit_verification")
  254. tmp_output = net_connect.send_command(commit_verification)
  255. match = re.search(r"Label: (.*)", tmp_output)
  256. response_label = match.group(1)
  257. response_label = response_label.strip()
  258. assert label == response_label
  259. match = re.search(r"Comment: (.*)", tmp_output)
  260. response_comment = match.group(1)
  261. response_comment = response_comment.strip()
  262. response_comment = response_comment.strip('"')
  263. assert comment == response_comment
  264. def test_commit_label_confirm(net_connect, commands, expected_responses):
  265. '''
  266. Test commit label for IOS-XR with confirm
  267. '''
  268. # IOS-XR only test
  269. if net_connect.device_type != 'cisco_xr':
  270. assert True is True
  271. else:
  272. # Setup the initial config state
  273. config_commands, support_commit, config_verify = setup_initial_state(net_connect,
  274. commands, expected_responses)
  275. # Execute change and commit
  276. net_connect.send_config_set(config_commands)
  277. label = "test_lbl_" + gen_random()
  278. net_connect.commit(label=label, confirm=True, confirm_delay=120)
  279. cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
  280. final_state = config_change_verify(net_connect, config_verify, cmd_response)
  281. assert final_state is True
  282. # Verify commit label
  283. commit_verification = commands.get("commit_verification")
  284. tmp_output = net_connect.send_command(commit_verification)
  285. match = re.search(r"Label: (.*)", tmp_output)
  286. response_label = match.group(1)
  287. response_label = response_label.strip()
  288. assert label == response_label
  289. net_connect.commit()
  290. def test_exit_config_mode(net_connect, commands, expected_responses):
  291. '''
  292. Test exit config mode
  293. '''
  294. net_connect.exit_config_mode()
  295. time.sleep(1)
  296. assert net_connect.check_config_mode() == False
  297. def test_disconnect(net_connect, commands, expected_responses):
  298. '''
  299. Terminate the SSH session
  300. '''
  301. net_connect.disconnect()