cli_installer_tests.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. # TODO: Temporarily disabled due to importing old code into openshift-ansible
  2. # repo. We will work on these over time.
  3. # pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name
  4. import copy
  5. import os
  6. import ConfigParser
  7. import yaml
  8. import ooinstall.cli_installer as cli
  9. from click.testing import CliRunner
  10. from test.oo_config_tests import OOInstallFixture
  11. from mock import patch
  12. MOCK_FACTS = {
  13. '10.0.0.1': {
  14. 'common': {
  15. 'ip': '10.0.0.1',
  16. 'public_ip': '10.0.0.1',
  17. 'hostname': 'master-private.example.com',
  18. 'public_hostname': 'master.example.com'
  19. }
  20. },
  21. '10.0.0.2': {
  22. 'common': {
  23. 'ip': '10.0.0.2',
  24. 'public_ip': '10.0.0.2',
  25. 'hostname': 'node1-private.example.com',
  26. 'public_hostname': 'node1.example.com'
  27. }
  28. },
  29. '10.0.0.3': {
  30. 'common': {
  31. 'ip': '10.0.0.3',
  32. 'public_ip': '10.0.0.3',
  33. 'hostname': 'node2-private.example.com',
  34. 'public_hostname': 'node2.example.com'
  35. }
  36. },
  37. }
  38. # Substitute in a product name before use:
  39. SAMPLE_CONFIG = """
  40. variant: %s
  41. ansible_ssh_user: root
  42. hosts:
  43. - connect_to: 10.0.0.1
  44. ip: 10.0.0.1
  45. hostname: master-private.example.com
  46. public_ip: 24.222.0.1
  47. public_hostname: master.example.com
  48. master: true
  49. node: true
  50. - connect_to: 10.0.0.2
  51. ip: 10.0.0.2
  52. hostname: node1-private.example.com
  53. public_ip: 24.222.0.2
  54. public_hostname: node1.example.com
  55. node: true
  56. - connect_to: 10.0.0.3
  57. ip: 10.0.0.3
  58. hostname: node2-private.example.com
  59. public_ip: 24.222.0.3
  60. public_hostname: node2.example.com
  61. node: true
  62. """
  63. BAD_CONFIG = """
  64. variant: %s
  65. ansible_ssh_user: root
  66. hosts:
  67. - connect_to: 10.0.0.1
  68. ip: 10.0.0.1
  69. hostname: master-private.example.com
  70. public_ip: 24.222.0.1
  71. public_hostname: master.example.com
  72. master: true
  73. node: true
  74. - ip: 10.0.0.2
  75. hostname: node1-private.example.com
  76. public_ip: 24.222.0.2
  77. public_hostname: node1.example.com
  78. node: true
  79. - connect_to: 10.0.0.3
  80. ip: 10.0.0.3
  81. hostname: node2-private.example.com
  82. public_ip: 24.222.0.3
  83. public_hostname: node2.example.com
  84. node: true
  85. """
  86. class OOCliFixture(OOInstallFixture):
  87. def setUp(self):
  88. OOInstallFixture.setUp(self)
  89. self.runner = CliRunner()
  90. # Add any arguments you would like to test here, the defaults ensure
  91. # we only do unattended invocations here, and using temporary files/dirs.
  92. self.cli_args = ["-a", self.work_dir]
  93. def run_cli(self):
  94. return self.runner.invoke(cli.cli, self.cli_args)
  95. def assert_result(self, result, exit_code):
  96. if result.exception is not None or result.exit_code != exit_code:
  97. print "Unexpected result from CLI execution"
  98. print "Exit code: %s" % result.exit_code
  99. print "Exception: %s" % result.exception
  100. print result.exc_info
  101. import traceback
  102. traceback.print_exception(*result.exc_info)
  103. print "Output:\n%s" % result.output
  104. self.fail("Exception during CLI execution")
  105. def _read_yaml(self, config_file_path):
  106. f = open(config_file_path, 'r')
  107. config = yaml.safe_load(f.read())
  108. f.close()
  109. return config
  110. def _verify_load_facts(self, load_facts_mock):
  111. """ Check that we ran load facts with expected inputs. """
  112. load_facts_args = load_facts_mock.call_args[0]
  113. self.assertEquals(os.path.join(self.work_dir, ".ansible/hosts"),
  114. load_facts_args[0])
  115. self.assertEquals(os.path.join(self.work_dir,
  116. "playbooks/byo/openshift_facts.yml"), load_facts_args[1])
  117. env_vars = load_facts_args[2]
  118. self.assertEquals(os.path.join(self.work_dir,
  119. '.ansible/callback_facts.yaml'),
  120. env_vars['OO_INSTALL_CALLBACK_FACTS_YAML'])
  121. self.assertEqual('/tmp/ansible.log', env_vars['ANSIBLE_LOG_PATH'])
  122. def _verify_run_playbook(self, run_playbook_mock, exp_hosts_len, exp_hosts_to_run_on_len):
  123. """ Check that we ran playbook with expected inputs. """
  124. hosts = run_playbook_mock.call_args[0][0]
  125. hosts_to_run_on = run_playbook_mock.call_args[0][1]
  126. self.assertEquals(exp_hosts_len, len(hosts))
  127. self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on))
  128. def _verify_config_hosts(self, written_config, host_count):
  129. print written_config['hosts']
  130. self.assertEquals(host_count, len(written_config['hosts']))
  131. for h in written_config['hosts']:
  132. self.assertTrue(h['node'])
  133. self.assertTrue('ip' in h)
  134. self.assertTrue('hostname' in h)
  135. self.assertTrue('public_ip' in h)
  136. self.assertTrue('public_hostname' in h)
  137. #pylint: disable=too-many-arguments
  138. def _verify_get_hosts_to_run_on(self, mock_facts, load_facts_mock,
  139. run_playbook_mock, cli_input,
  140. exp_hosts_len=None, exp_hosts_to_run_on_len=None,
  141. force=None):
  142. """
  143. Tests cli_installer.py:get_hosts_to_run_on. That method has quite a
  144. few subtle branches in the logic. The goal with this method is simply
  145. to handle all the messy stuff here and allow the main test cases to be
  146. easily read. The basic idea is to modify mock_facts to return a
  147. version indicating OpenShift is already installed on particular hosts.
  148. """
  149. load_facts_mock.return_value = (mock_facts, 0)
  150. run_playbook_mock.return_value = 0
  151. if cli_input:
  152. self.cli_args.append("install")
  153. result = self.runner.invoke(cli.cli,
  154. self.cli_args,
  155. input=cli_input)
  156. else:
  157. config_file = self.write_config(os.path.join(self.work_dir,
  158. 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
  159. self.cli_args.extend(["-c", config_file, "install"])
  160. if force:
  161. self.cli_args.append("--force")
  162. result = self.runner.invoke(cli.cli, self.cli_args)
  163. written_config = self._read_yaml(config_file)
  164. self._verify_config_hosts(written_config, exp_hosts_len)
  165. self.assert_result(result, 0)
  166. self._verify_load_facts(load_facts_mock)
  167. self._verify_run_playbook(run_playbook_mock, exp_hosts_len, exp_hosts_to_run_on_len)
  168. # Make sure we ran on the expected masters and nodes:
  169. hosts = run_playbook_mock.call_args[0][0]
  170. hosts_to_run_on = run_playbook_mock.call_args[0][1]
  171. self.assertEquals(exp_hosts_len, len(hosts))
  172. self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on))
  173. class UnattendedCliTests(OOCliFixture):
  174. def setUp(self):
  175. OOCliFixture.setUp(self)
  176. self.cli_args.append("-u")
  177. # unattended with config file and all installed hosts (without --force)
  178. @patch('ooinstall.openshift_ansible.run_main_playbook')
  179. @patch('ooinstall.openshift_ansible.load_system_facts')
  180. def test_get_hosts_to_run_on1(self, load_facts_mock, run_playbook_mock):
  181. mock_facts = copy.deepcopy(MOCK_FACTS)
  182. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  183. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  184. mock_facts['10.0.0.3']['common']['version'] = "3.0.0"
  185. load_facts_mock.return_value = (mock_facts, 0)
  186. run_playbook_mock.return_value = 0
  187. config_file = self.write_config(os.path.join(self.work_dir,
  188. 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
  189. self.cli_args.extend(["-c", config_file, "install"])
  190. result = self.runner.invoke(cli.cli, self.cli_args)
  191. if result.exception is None or result.exit_code != 1:
  192. print "Exit code: %s" % result.exit_code
  193. self.fail("Unexpected CLI return")
  194. # unattended with config file and all installed hosts (with --force)
  195. @patch('ooinstall.openshift_ansible.run_main_playbook')
  196. @patch('ooinstall.openshift_ansible.load_system_facts')
  197. def test_get_hosts_to_run_on2(self, load_facts_mock, run_playbook_mock):
  198. mock_facts = copy.deepcopy(MOCK_FACTS)
  199. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  200. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  201. mock_facts['10.0.0.3']['common']['version'] = "3.0.0"
  202. self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock, run_playbook_mock,
  203. cli_input=None,
  204. exp_hosts_len=3,
  205. exp_hosts_to_run_on_len=3,
  206. force=True)
  207. # unattended with config file and no installed hosts (without --force)
  208. @patch('ooinstall.openshift_ansible.run_main_playbook')
  209. @patch('ooinstall.openshift_ansible.load_system_facts')
  210. def test_get_hosts_to_run_on3(self, load_facts_mock, run_playbook_mock):
  211. load_facts_mock.return_value = (MOCK_FACTS, 0)
  212. run_playbook_mock.return_value = 0
  213. self._verify_get_hosts_to_run_on(MOCK_FACTS, load_facts_mock, run_playbook_mock,
  214. cli_input=None,
  215. exp_hosts_len=3,
  216. exp_hosts_to_run_on_len=3,
  217. force=False)
  218. # unattended with config file and no installed hosts (with --force)
  219. @patch('ooinstall.openshift_ansible.run_main_playbook')
  220. @patch('ooinstall.openshift_ansible.load_system_facts')
  221. def test_get_hosts_to_run_on4(self, load_facts_mock, run_playbook_mock):
  222. load_facts_mock.return_value = (MOCK_FACTS, 0)
  223. run_playbook_mock.return_value = 0
  224. self._verify_get_hosts_to_run_on(MOCK_FACTS, load_facts_mock, run_playbook_mock,
  225. cli_input=None,
  226. exp_hosts_len=3,
  227. exp_hosts_to_run_on_len=3,
  228. force=True)
  229. # unattended with config file and some installed some uninstalled hosts (without --force)
  230. @patch('ooinstall.openshift_ansible.run_main_playbook')
  231. @patch('ooinstall.openshift_ansible.load_system_facts')
  232. def test_get_hosts_to_run_on5(self, load_facts_mock, run_playbook_mock):
  233. mock_facts = copy.deepcopy(MOCK_FACTS)
  234. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  235. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  236. self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock, run_playbook_mock,
  237. cli_input=None,
  238. exp_hosts_len=3,
  239. exp_hosts_to_run_on_len=2,
  240. force=False)
  241. # unattended with config file and some installed some uninstalled hosts (with --force)
  242. @patch('ooinstall.openshift_ansible.run_main_playbook')
  243. @patch('ooinstall.openshift_ansible.load_system_facts')
  244. def test_get_hosts_to_run_on6(self, load_facts_mock, run_playbook_mock):
  245. mock_facts = copy.deepcopy(MOCK_FACTS)
  246. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  247. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  248. self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock, run_playbook_mock,
  249. cli_input=None,
  250. exp_hosts_len=3,
  251. exp_hosts_to_run_on_len=3,
  252. force=True)
  253. @patch('ooinstall.openshift_ansible.run_main_playbook')
  254. @patch('ooinstall.openshift_ansible.load_system_facts')
  255. def test_cfg_full_run(self, load_facts_mock, run_playbook_mock):
  256. load_facts_mock.return_value = (MOCK_FACTS, 0)
  257. run_playbook_mock.return_value = 0
  258. config_file = self.write_config(os.path.join(self.work_dir,
  259. 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
  260. self.cli_args.extend(["-c", config_file, "install"])
  261. result = self.runner.invoke(cli.cli, self.cli_args)
  262. self.assert_result(result, 0)
  263. load_facts_args = load_facts_mock.call_args[0]
  264. self.assertEquals(os.path.join(self.work_dir, ".ansible/hosts"),
  265. load_facts_args[0])
  266. self.assertEquals(os.path.join(self.work_dir,
  267. "playbooks/byo/openshift_facts.yml"), load_facts_args[1])
  268. env_vars = load_facts_args[2]
  269. self.assertEquals(os.path.join(self.work_dir,
  270. '.ansible/callback_facts.yaml'),
  271. env_vars['OO_INSTALL_CALLBACK_FACTS_YAML'])
  272. self.assertEqual('/tmp/ansible.log', env_vars['ANSIBLE_LOG_PATH'])
  273. # If user running test has rpm installed, this might be set to default:
  274. self.assertTrue('ANSIBLE_CONFIG' not in env_vars or
  275. env_vars['ANSIBLE_CONFIG'] == cli.DEFAULT_ANSIBLE_CONFIG)
  276. # Make sure we ran on the expected masters and nodes:
  277. hosts = run_playbook_mock.call_args[0][0]
  278. hosts_to_run_on = run_playbook_mock.call_args[0][1]
  279. self.assertEquals(3, len(hosts))
  280. self.assertEquals(3, len(hosts_to_run_on))
  281. @patch('ooinstall.openshift_ansible.run_main_playbook')
  282. @patch('ooinstall.openshift_ansible.load_system_facts')
  283. def test_inventory_write(self, load_facts_mock, run_playbook_mock):
  284. # Add an ssh user so we can verify it makes it to the inventory file:
  285. merged_config = "%s\n%s" % (SAMPLE_CONFIG % 'openshift-enterprise',
  286. "ansible_ssh_user: bob")
  287. load_facts_mock.return_value = (MOCK_FACTS, 0)
  288. run_playbook_mock.return_value = 0
  289. config_file = self.write_config(os.path.join(self.work_dir,
  290. 'ooinstall.conf'), merged_config)
  291. self.cli_args.extend(["-c", config_file, "install"])
  292. result = self.runner.invoke(cli.cli, self.cli_args)
  293. self.assert_result(result, 0)
  294. # Check the inventory file looks as we would expect:
  295. inventory = ConfigParser.ConfigParser(allow_no_value=True)
  296. inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
  297. self.assertEquals('bob',
  298. inventory.get('OSEv3:vars', 'ansible_ssh_user'))
  299. self.assertEquals('openshift-enterprise',
  300. inventory.get('OSEv3:vars', 'deployment_type'))
  301. # Check the masters:
  302. self.assertEquals(1, len(inventory.items('masters')))
  303. self.assertEquals(3, len(inventory.items('nodes')))
  304. for item in inventory.items('masters'):
  305. # ansible host lines do NOT parse nicely:
  306. master_line = item[0]
  307. if item[1] is not None:
  308. master_line = "%s=%s" % (master_line, item[1])
  309. self.assertTrue('openshift_ip' in master_line)
  310. self.assertTrue('openshift_public_ip' in master_line)
  311. self.assertTrue('openshift_hostname' in master_line)
  312. self.assertTrue('openshift_public_hostname' in master_line)
  313. @patch('ooinstall.openshift_ansible.run_main_playbook')
  314. @patch('ooinstall.openshift_ansible.load_system_facts')
  315. def test_variant_version_latest_assumed(self, load_facts_mock,
  316. run_playbook_mock):
  317. load_facts_mock.return_value = (MOCK_FACTS, 0)
  318. run_playbook_mock.return_value = 0
  319. config_file = self.write_config(os.path.join(self.work_dir,
  320. 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
  321. self.cli_args.extend(["-c", config_file, "install"])
  322. result = self.runner.invoke(cli.cli, self.cli_args)
  323. self.assert_result(result, 0)
  324. written_config = self._read_yaml(config_file)
  325. self.assertEquals('openshift-enterprise', written_config['variant'])
  326. # We didn't specify a version so the latest should have been assumed,
  327. # and written to disk:
  328. self.assertEquals('3.1', written_config['variant_version'])
  329. # Make sure the correct value was passed to ansible:
  330. inventory = ConfigParser.ConfigParser(allow_no_value=True)
  331. inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
  332. self.assertEquals('openshift-enterprise',
  333. inventory.get('OSEv3:vars', 'deployment_type'))
  334. @patch('ooinstall.openshift_ansible.run_main_playbook')
  335. @patch('ooinstall.openshift_ansible.load_system_facts')
  336. def test_variant_version_preserved(self, load_facts_mock,
  337. run_playbook_mock):
  338. load_facts_mock.return_value = (MOCK_FACTS, 0)
  339. run_playbook_mock.return_value = 0
  340. config = SAMPLE_CONFIG % 'openshift-enterprise'
  341. config = '%s\n%s' % (config, 'variant_version: 3.0')
  342. config_file = self.write_config(os.path.join(self.work_dir,
  343. 'ooinstall.conf'), config)
  344. self.cli_args.extend(["-c", config_file, "install"])
  345. result = self.runner.invoke(cli.cli, self.cli_args)
  346. self.assert_result(result, 0)
  347. written_config = self._read_yaml(config_file)
  348. self.assertEquals('openshift-enterprise', written_config['variant'])
  349. # Make sure our older version was preserved:
  350. # and written to disk:
  351. self.assertEquals('3.0', written_config['variant_version'])
  352. inventory = ConfigParser.ConfigParser(allow_no_value=True)
  353. inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
  354. self.assertEquals('enterprise',
  355. inventory.get('OSEv3:vars', 'deployment_type'))
  356. @patch('ooinstall.openshift_ansible.run_ansible')
  357. @patch('ooinstall.openshift_ansible.load_system_facts')
  358. def test_no_ansible_config_specified(self, load_facts_mock, run_ansible_mock):
  359. load_facts_mock.return_value = (MOCK_FACTS, 0)
  360. run_ansible_mock.return_value = 0
  361. config = SAMPLE_CONFIG % 'openshift-enterprise'
  362. self._ansible_config_test(load_facts_mock, run_ansible_mock,
  363. config, None, None)
  364. @patch('ooinstall.openshift_ansible.run_ansible')
  365. @patch('ooinstall.openshift_ansible.load_system_facts')
  366. def test_ansible_config_specified_cli(self, load_facts_mock, run_ansible_mock):
  367. load_facts_mock.return_value = (MOCK_FACTS, 0)
  368. run_ansible_mock.return_value = 0
  369. config = SAMPLE_CONFIG % 'openshift-enterprise'
  370. ansible_config = os.path.join(self.work_dir, 'ansible.cfg')
  371. self._ansible_config_test(load_facts_mock, run_ansible_mock,
  372. config, ansible_config, ansible_config)
  373. @patch('ooinstall.openshift_ansible.run_ansible')
  374. @patch('ooinstall.openshift_ansible.load_system_facts')
  375. def test_ansible_config_specified_in_installer_config(self,
  376. load_facts_mock, run_ansible_mock):
  377. load_facts_mock.return_value = (MOCK_FACTS, 0)
  378. run_ansible_mock.return_value = 0
  379. ansible_config = os.path.join(self.work_dir, 'ansible.cfg')
  380. config = SAMPLE_CONFIG % 'openshift-enterprise'
  381. config = "%s\nansible_config: %s" % (config, ansible_config)
  382. self._ansible_config_test(load_facts_mock, run_ansible_mock,
  383. config, None, ansible_config)
  384. #pylint: disable=too-many-arguments
  385. # This method allows for drastically simpler tests to write, and the args
  386. # are all useful.
  387. def _ansible_config_test(self, load_facts_mock, run_ansible_mock,
  388. installer_config, ansible_config_cli=None, expected_result=None):
  389. """
  390. Utility method for testing the ways you can specify the ansible config.
  391. """
  392. load_facts_mock.return_value = (MOCK_FACTS, 0)
  393. run_ansible_mock.return_value = 0
  394. config_file = self.write_config(os.path.join(self.work_dir,
  395. 'ooinstall.conf'), installer_config)
  396. self.cli_args.extend(["-c", config_file])
  397. if ansible_config_cli:
  398. self.cli_args.extend(["--ansible-config", ansible_config_cli])
  399. self.cli_args.append("install")
  400. result = self.runner.invoke(cli.cli, self.cli_args)
  401. self.assert_result(result, 0)
  402. # Test the env vars for facts playbook:
  403. facts_env_vars = load_facts_mock.call_args[0][2]
  404. if expected_result:
  405. self.assertEquals(expected_result, facts_env_vars['ANSIBLE_CONFIG'])
  406. else:
  407. # If user running test has rpm installed, this might be set to default:
  408. self.assertTrue('ANSIBLE_CONFIG' not in facts_env_vars or
  409. facts_env_vars['ANSIBLE_CONFIG'] == cli.DEFAULT_ANSIBLE_CONFIG)
  410. # Test the env vars for main playbook:
  411. env_vars = run_ansible_mock.call_args[0][2]
  412. if expected_result:
  413. self.assertEquals(expected_result, env_vars['ANSIBLE_CONFIG'])
  414. else:
  415. # If user running test has rpm installed, this might be set to default:
  416. self.assertTrue('ANSIBLE_CONFIG' not in env_vars or
  417. env_vars['ANSIBLE_CONFIG'] == cli.DEFAULT_ANSIBLE_CONFIG)
  418. # unattended with bad config file and no installed hosts (without --force)
  419. @patch('ooinstall.openshift_ansible.run_main_playbook')
  420. @patch('ooinstall.openshift_ansible.load_system_facts')
  421. def test_bad_config(self, load_facts_mock, run_playbook_mock):
  422. load_facts_mock.return_value = (MOCK_FACTS, 0)
  423. run_playbook_mock.return_value = 0
  424. config_file = self.write_config(os.path.join(self.work_dir,
  425. 'ooinstall.conf'), BAD_CONFIG % 'openshift-enterprise')
  426. self.cli_args.extend(["-c", config_file, "install"])
  427. self.runner.invoke(cli.cli, self.cli_args)
  428. # proving here that we didn't generate an exception from the bad config
  429. assert True
  430. class AttendedCliTests(OOCliFixture):
  431. def setUp(self):
  432. OOCliFixture.setUp(self)
  433. # Doesn't exist but keeps us from reading the local users config:
  434. self.config_file = os.path.join(self.work_dir, 'config.yml')
  435. self.cli_args.extend(["-c", self.config_file])
  436. #pylint: disable=too-many-arguments
  437. def _build_input(self, ssh_user=None, hosts=None, variant_num=None,
  438. add_nodes=None, confirm_facts=None):
  439. """
  440. Builds a CLI input string with newline characters to simulate
  441. the full run.
  442. This gives us only one place to update when the input prompts change.
  443. """
  444. inputs = [
  445. 'y', # let's proceed
  446. ]
  447. if ssh_user:
  448. inputs.append(ssh_user)
  449. if hosts:
  450. i = 0
  451. for (host, is_master) in hosts:
  452. inputs.append(host)
  453. inputs.append('y' if is_master else 'n')
  454. #inputs.append('rpm')
  455. if i < len(hosts) - 1:
  456. inputs.append('y') # Add more hosts
  457. else:
  458. inputs.append('n') # Done adding hosts
  459. i += 1
  460. if variant_num:
  461. inputs.append(str(variant_num)) # Choose variant + version
  462. # TODO: support option 2, fresh install
  463. if add_nodes:
  464. inputs.append('1') # Add more nodes
  465. i = 0
  466. for (host, is_master) in add_nodes:
  467. inputs.append(host)
  468. inputs.append('y' if is_master else 'n')
  469. #inputs.append('rpm')
  470. if i < len(add_nodes) - 1:
  471. inputs.append('y') # Add more hosts
  472. else:
  473. inputs.append('n') # Done adding hosts
  474. i += 1
  475. inputs.extend([
  476. confirm_facts,
  477. 'y', # lets do this
  478. ])
  479. return '\n'.join(inputs)
  480. @patch('ooinstall.openshift_ansible.run_main_playbook')
  481. @patch('ooinstall.openshift_ansible.load_system_facts')
  482. def test_full_run(self, load_facts_mock, run_playbook_mock):
  483. load_facts_mock.return_value = (MOCK_FACTS, 0)
  484. run_playbook_mock.return_value = 0
  485. cli_input = self._build_input(hosts=[
  486. ('10.0.0.1', True),
  487. ('10.0.0.2', False),
  488. ('10.0.0.3', False)],
  489. ssh_user='root',
  490. variant_num=1,
  491. confirm_facts='y')
  492. self.cli_args.append("install")
  493. result = self.runner.invoke(cli.cli, self.cli_args,
  494. input=cli_input)
  495. self.assert_result(result, 0)
  496. self._verify_load_facts(load_facts_mock)
  497. self._verify_run_playbook(run_playbook_mock, 3, 3)
  498. written_config = self._read_yaml(self.config_file)
  499. self._verify_config_hosts(written_config, 3)
  500. # interactive with config file and some installed some uninstalled hosts
  501. @patch('ooinstall.openshift_ansible.run_main_playbook')
  502. @patch('ooinstall.openshift_ansible.load_system_facts')
  503. def test_add_nodes(self, load_facts_mock, run_playbook_mock):
  504. # Modify the mock facts to return a version indicating OpenShift
  505. # is already installed on our master, and the first node.
  506. mock_facts = copy.deepcopy(MOCK_FACTS)
  507. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  508. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  509. load_facts_mock.return_value = (mock_facts, 0)
  510. run_playbook_mock.return_value = 0
  511. cli_input = self._build_input(hosts=[
  512. ('10.0.0.1', True),
  513. ('10.0.0.2', False),
  514. ],
  515. add_nodes=[('10.0.0.3', False)],
  516. ssh_user='root',
  517. variant_num=1,
  518. confirm_facts='y')
  519. self.cli_args.append("install")
  520. result = self.runner.invoke(cli.cli,
  521. self.cli_args,
  522. input=cli_input)
  523. self.assert_result(result, 0)
  524. self._verify_load_facts(load_facts_mock)
  525. self._verify_run_playbook(run_playbook_mock, 3, 2)
  526. written_config = self._read_yaml(self.config_file)
  527. self._verify_config_hosts(written_config, 3)
  528. @patch('ooinstall.openshift_ansible.run_main_playbook')
  529. @patch('ooinstall.openshift_ansible.load_system_facts')
  530. def test_fresh_install_with_config(self, load_facts_mock, run_playbook_mock):
  531. load_facts_mock.return_value = (MOCK_FACTS, 0)
  532. run_playbook_mock.return_value = 0
  533. config_file = self.write_config(os.path.join(self.work_dir,
  534. 'ooinstall.conf'),
  535. SAMPLE_CONFIG % 'openshift-enterprise')
  536. cli_input = self._build_input(confirm_facts='y')
  537. self.cli_args.extend(["-c", config_file])
  538. self.cli_args.append("install")
  539. result = self.runner.invoke(cli.cli,
  540. self.cli_args,
  541. input=cli_input)
  542. self.assert_result(result, 0)
  543. self._verify_load_facts(load_facts_mock)
  544. self._verify_run_playbook(run_playbook_mock, 3, 3)
  545. written_config = self._read_yaml(config_file)
  546. self._verify_config_hosts(written_config, 3)
  547. #interactive with config file and all installed hosts
  548. @patch('ooinstall.openshift_ansible.run_main_playbook')
  549. @patch('ooinstall.openshift_ansible.load_system_facts')
  550. def test_get_hosts_to_run_on(self, load_facts_mock, run_playbook_mock):
  551. mock_facts = copy.deepcopy(MOCK_FACTS)
  552. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  553. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  554. cli_input = self._build_input(hosts=[
  555. ('10.0.0.1', True),
  556. ],
  557. add_nodes=[('10.0.0.2', False)],
  558. ssh_user='root',
  559. variant_num=1,
  560. confirm_facts='y')
  561. self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock,
  562. run_playbook_mock,
  563. cli_input,
  564. exp_hosts_len=2,
  565. exp_hosts_to_run_on_len=2,
  566. force=False)
  567. # TODO: test with config file, attended add node
  568. # TODO: test with config file, attended new node already in config file
  569. # TODO: test with config file, attended new node already in config file, plus manually added nodes
  570. # TODO: test with config file, attended reject facts