<commit_before># pylint: disable=missing-docstring
import os
import yaml

import ooinstall.cli_installer as cli

from test.oo_config_tests import OOInstallFixture
from click.testing import CliRunner

# Substitute in a product name before use:
SAMPLE_CONFIG = """
variant: %s
variant_version: 3.2
master_routingconfig_subdomain: example.com
deployment:
    ansible_ssh_user: root
    hosts:
      - connect_to: 10.0.0.1
        ip: 10.0.0.1
        hostname: master-private.example.com
        public_ip: 172.16.58.3
        public_hostname: master.example.com
        roles:
            - master
            - node
      - connect_to: 10.0.0.2
        ip: 10.0.0.2
        hostname: node1-private.example.com
        public_ip: 192.168.127.12
        public_hostname: node1.example.com
        roles:
            - node
      - connect_to: 10.0.0.3
        ip: 10.0.0.3
        hostname: node2-private.example.com
        public_ip: 192.168.127.12
        public_hostname: node2.example.com
        roles:
            - node
    roles:
        master:
        node:
"""

def read_yaml(config_file_path):
    cfg_f = open(config_file_path, 'r')
    config = yaml.safe_load(cfg_f.read())
    cfg_f.close()
    return config


class OOCliFixture(OOInstallFixture):

    def setUp(self):
        OOInstallFixture.setUp(self)
        self.runner = CliRunner()

        # Add any arguments you would like to test here, the defaults ensure
        # we only do unattended invocations here, and using temporary files/dirs.
        self.cli_args = ["-a", self.work_dir]

    def run_cli(self):
        return self.runner.invoke(cli.cli, self.cli_args)

    def assert_result(self, result, exit_code):
        if result.exit_code != exit_code:
            print "Unexpected result from CLI execution"
            print "Exit code: %s" % result.exit_code
            print "Exception: %s" % result.exception
            print result.exc_info
            import traceback
            traceback.print_exception(*result.exc_info)
            print "Output:\n%s" % result.output
            self.fail("Exception during CLI execution")

    def _verify_load_facts(self, load_facts_mock):
        """ Check that we ran load facts with expected inputs. """
        load_facts_args = load_facts_mock.call_args[0]
        self.assertEquals(os.path.join(self.work_dir, "hosts"),
                          load_facts_args[0])
        self.assertEquals(os.path.join(self.work_dir,
                                       "playbooks/byo/openshift_facts.yml"),
                          load_facts_args[1])
        env_vars = load_facts_args[2]
        self.assertEquals(os.path.join(self.work_dir,
                                       '.ansible/callback_facts.yaml'),
                          env_vars['OO_INSTALL_CALLBACK_FACTS_YAML'])
        self.assertEqual('/tmp/ansible.log', env_vars['ANSIBLE_LOG_PATH'])

    def _verify_run_playbook(self, run_playbook_mock, exp_hosts_len, exp_hosts_to_run_on_len):
        """ Check that we ran playbook with expected inputs. """
        hosts = run_playbook_mock.call_args[0][1]
        hosts_to_run_on = run_playbook_mock.call_args[0][2]
        self.assertEquals(exp_hosts_len, len(hosts))
        self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on))

    def _verify_config_hosts(self, written_config, host_count):
        self.assertEquals(host_count, len(written_config['deployment']['hosts']))
        for host in written_config['deployment']['hosts']:
            self.assertTrue('hostname' in host)
            self.assertTrue('public_hostname' in host)
            if 'preconfigured' not in host:
                if 'roles' in host:
                    self.assertTrue('node' in host['roles'] or 'storage' in host['roles'])
                self.assertTrue('ip' in host)
                self.assertTrue('public_ip' in host)

    #pylint: disable=too-many-arguments
    def _verify_get_hosts_to_run_on(self, mock_facts, load_facts_mock,
                                    run_playbook_mock, cli_input,
                                    exp_hosts_len=None, exp_hosts_to_run_on_len=None,
                                    force=None):
        """
        Tests cli_installer.py:get_hosts_to_run_on.  That method has quite a
        few subtle branches in the logic.  The goal with this method is simply
        to handle all the messy stuff here and allow the main test cases to be
        easily read.  The basic idea is to modify mock_facts to return a
        version indicating OpenShift is already installed on particular hosts.
        """
        load_facts_mock.return_value = (mock_facts, 0)
        run_playbook_mock.return_value = 0

        if cli_input:
            self.cli_args.append("install")
            result = self.runner.invoke(cli.cli,
                                        self.cli_args,
                                        input=cli_input)
        else:
            config_file = self.write_config(
                os.path.join(self.work_dir,
                             'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')

            self.cli_args.extend(["-c", config_file, "install"])
            if force:
                self.cli_args.append("--force")
            result = self.runner.invoke(cli.cli, self.cli_args)
            written_config = read_yaml(config_file)
            self._verify_config_hosts(written_config, exp_hosts_len)

        self.assert_result(result, 0)
        self._verify_load_facts(load_facts_mock)
        self._verify_run_playbook(run_playbook_mock, exp_hosts_len, exp_hosts_to_run_on_len)

        # Make sure we ran on the expected masters and nodes:
        hosts = run_playbook_mock.call_args[0][1]
        hosts_to_run_on = run_playbook_mock.call_args[0][2]
        self.assertEquals(exp_hosts_len, len(hosts))
        self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on))


#pylint: disable=too-many-arguments,too-many-branches,too-many-statements
def build_input(ssh_user=None, hosts=None, variant_num=None,
                add_nodes=None, confirm_facts=None, schedulable_masters_ok=None,
                master_lb=None, storage=None):
    """
    Build an input string simulating a user entering values in an interactive
    attended install.<commit_msg>a-o-i: Fix broken tests from installed hosts check<commit_after># pylint: disable=missing-docstring
import os
import yaml

import ooinstall.cli_installer as cli

from test.oo_config_tests import OOInstallFixture
from click.testing import CliRunner

# Substitute in a product name before use:
SAMPLE_CONFIG = """
variant: %s
variant_version: 3.2
master_routingconfig_subdomain: example.com
deployment:
    ansible_ssh_user: root
    hosts:
      - connect_to: 10.0.0.1
        ip: 10.0.0.1
        hostname: master-private.example.com
        public_ip: 172.16.58.3
        public_hostname: master.example.com
        roles:
            - master
            - node
      - connect_to: 10.0.0.2
        ip: 10.0.0.2
        hostname: node1-private.example.com
        public_ip: 192.168.127.12
        public_hostname: node1.example.com
        roles:
            - node
      - connect_to: 10.0.0.3
        ip: 10.0.0.3
        hostname: node2-private.example.com
        public_ip: 192.168.127.12
        public_hostname: node2.example.com
        roles:
            - node
    roles:
        master:
        node:
"""

def read_yaml(config_file_path):
    cfg_f = open(config_file_path, 'r')
    config = yaml.safe_load(cfg_f.read())
    cfg_f.close()
    return config


class OOCliFixture(OOInstallFixture):

    def setUp(self):
        OOInstallFixture.setUp(self)
        self.runner = CliRunner()

        # Add any arguments you would like to test here, the defaults ensure
        # we only do unattended invocations here, and using temporary files/dirs.
        self.cli_args = ["-a", self.work_dir]

    def run_cli(self):
        return self.runner.invoke(cli.cli, self.cli_args)

    def assert_result(self, result, exit_code):
        if result.exit_code != exit_code:
            print "Unexpected result from CLI execution"
            print "Exit code: %s" % result.exit_code
            print "Exception: %s" % result.exception
            print result.exc_info
            import traceback
            traceback.print_exception(*result.exc_info)
            print "Output:\n%s" % result.output
            self.fail("Exception during CLI execution")

    def _verify_load_facts(self, load_facts_mock):
        """ Check that we ran load facts with expected inputs. """
        load_facts_args = load_facts_mock.call_args[0]
        self.assertEquals(os.path.join(self.work_dir, "hosts"),
                          load_facts_args[0])
        self.assertEquals(os.path.join(self.work_dir,
                                       "playbooks/byo/openshift_facts.yml"),
                          load_facts_args[1])
        env_vars = load_facts_args[2]
        self.assertEquals(os.path.join(self.work_dir,
                                       '.ansible/callback_facts.yaml'),
                          env_vars['OO_INSTALL_CALLBACK_FACTS_YAML'])
        self.assertEqual('/tmp/ansible.log', env_vars['ANSIBLE_LOG_PATH'])

    def _verify_run_playbook(self, run_playbook_mock, exp_hosts_len, exp_hosts_to_run_on_len):
        """ Check that we ran playbook with expected inputs. """
        hosts = run_playbook_mock.call_args[0][1]
        hosts_to_run_on = run_playbook_mock.call_args[0][2]
        self.assertEquals(exp_hosts_len, len(hosts))
        self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on))

    def _verify_config_hosts(self, written_config, host_count):
        self.assertEquals(host_count, len(written_config['deployment']['hosts']))
        for host in written_config['deployment']['hosts']:
            self.assertTrue('hostname' in host)
            self.assertTrue('public_hostname' in host)
            if 'preconfigured' not in host:
                if 'roles' in host:
                    self.assertTrue('node' in host['roles'] or 'storage' in host['roles'])
                self.assertTrue('ip' in host)
                self.assertTrue('public_ip' in host)

    #pylint: disable=too-many-arguments
    def _verify_get_hosts_to_run_on(self, mock_facts, load_facts_mock,
                                    run_playbook_mock, cli_input,
                                    exp_hosts_len=None, exp_hosts_to_run_on_len=None,
                                    force=None):
        """
        Tests cli_installer.py:get_hosts_to_run_on.  That method has quite a
        few subtle branches in the logic.  The goal with this method is simply
        to handle all the messy stuff here and allow the main test cases to be
        easily read.  The basic idea is to modify mock_facts to return a
        version indicating OpenShift is already installed on particular hosts.
        """
        load_facts_mock.return_value = (mock_facts, 0)
        run_playbook_mock.return_value = 0

        if cli_input:
            self.cli_args.append("install")
            result = self.runner.invoke(cli.cli,
                                        self.cli_args,
                                        input=cli_input)
        else:
            config_file = self.write_config(
                os.path.join(self.work_dir,
                             'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')

            self.cli_args.extend(["-c", config_file, "install"])
            if force:
                self.cli_args.append("--force")
            result = self.runner.invoke(cli.cli, self.cli_args)
            written_config = read_yaml(config_file)
            self._verify_config_hosts(written_config, exp_hosts_len)

        if "Uninstalled" in result.output:
            # verify we exited on seeing uninstalled hosts
            self.assertEqual(result.exit_code, 1)
        else:
            self.assert_result(result, 0)
            self._verify_load_facts(load_facts_mock)
            self._verify_run_playbook(run_playbook_mock, exp_hosts_len, exp_hosts_to_run_on_len)

            # Make sure we ran on the expected masters and nodes:
            hosts = run_playbook_mock.call_args[0][1]
            hosts_to_run_on = run_playbook_mock.call_args[0][2]
            self.assertEquals(exp_hosts_len, len(hosts))
            self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on))


#pylint: disable=too-many-arguments,too-many-branches,too-many-statements
def build_input(ssh_user=None, hosts=None, variant_num=None,
                add_nodes=None, confirm_facts=None, schedulable_masters_ok=None,
                master_lb=None, storage=None):
    """
    Build an input string simulating a user entering values in an interactive
    attended install.
{'fraction_non_alphanumeric': 0.08908651220844059, 'fraction_numerical': 0.012715500429050628, 'mean_word_length': 2.2162568991470146, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 18, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7422947', 'n_tokens_mistral': 4015, 'n_tokens_neox': 3788, 'n_words': 804}