From 38c76bfacfa1c7b7ff09f0259143385306e9a778 Mon Sep 17 00:00:00 2001
From: Devan Goodwin <dgoodwin@redhat.com>
Date: Thu, 26 Nov 2015 15:32:46 -0400
Subject: Breakout a test fixture to reduce module size.

---
 utils/test/cli_installer_tests.py | 240 +++-----------------------------------
 utils/test/fixture.py             | 218 ++++++++++++++++++++++++++++++++++
 2 files changed, 236 insertions(+), 222 deletions(-)
 create mode 100644 utils/test/fixture.py

(limited to 'utils')

diff --git a/utils/test/cli_installer_tests.py b/utils/test/cli_installer_tests.py
index 20dd57463..3cf704cd5 100644
--- a/utils/test/cli_installer_tests.py
+++ b/utils/test/cli_installer_tests.py
@@ -1,16 +1,14 @@
 # TODO: Temporarily disabled due to importing old code into openshift-ansible
 # repo. We will work on these over time.
-# pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name,too-many-lines
+# pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name
 
 import copy
 import os
 import ConfigParser
-import yaml
 
 import ooinstall.cli_installer as cli
 
-from click.testing import CliRunner
-from test.oo_config_tests import OOInstallFixture
+from test.fixture import OOCliFixture, SAMPLE_CONFIG, build_input, read_yaml
 from mock import patch
 
 
@@ -76,32 +74,6 @@ MOCK_FACTS_QUICKHA = {
     },
 }
 
-# Substitute in a product name before use:
-SAMPLE_CONFIG = """
-variant: %s
-ansible_ssh_user: root
-hosts:
-  - connect_to: 10.0.0.1
-    ip: 10.0.0.1
-    hostname: master-private.example.com
-    public_ip: 24.222.0.1
-    public_hostname: master.example.com
-    master: true
-    node: true
-  - connect_to: 10.0.0.2
-    ip: 10.0.0.2
-    hostname: node1-private.example.com
-    public_ip: 24.222.0.2
-    public_hostname: node1.example.com
-    node: true
-  - connect_to: 10.0.0.3
-    ip: 10.0.0.3
-    hostname: node2-private.example.com
-    public_ip: 24.222.0.3
-    public_hostname: node2.example.com
-    node: true
-"""
-
 # Missing connect_to on some hosts:
 BAD_CONFIG = """
 variant: %s
@@ -212,107 +184,6 @@ hosts:
     node: true
 """
 
-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.exception is not None or 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 _read_yaml(self, config_file_path):
-        f = open(config_file_path, 'r')
-        config = yaml.safe_load(f.read())
-        f.close()
-        return config
-
-    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, ".ansible/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][0]
-        hosts_to_run_on = run_playbook_mock.call_args[0][1]
-        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['hosts']))
-        for h in written_config['hosts']:
-            self.assertTrue('hostname' in h)
-            self.assertTrue('public_hostname' in h)
-            if 'preconfigured' not in h:
-                self.assertTrue(h['node'])
-                self.assertTrue('ip' in h)
-                self.assertTrue('public_ip' in h)
-
-    #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 = self._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][0]
-        hosts_to_run_on = run_playbook_mock.call_args[0][1]
-        self.assertEquals(exp_hosts_len, len(hosts))
-        self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on))
-
 class UnattendedCliTests(OOCliFixture):
 
     def setUp(self):
@@ -491,7 +362,7 @@ class UnattendedCliTests(OOCliFixture):
         result = self.runner.invoke(cli.cli, self.cli_args)
         self.assert_result(result, 0)
 
-        written_config = self._read_yaml(config_file)
+        written_config = read_yaml(config_file)
 
         self.assertEquals('openshift-enterprise', written_config['variant'])
         # We didn't specify a version so the latest should have been assumed,
@@ -520,7 +391,7 @@ class UnattendedCliTests(OOCliFixture):
         result = self.runner.invoke(cli.cli, self.cli_args)
         self.assert_result(result, 0)
 
-        written_config = self._read_yaml(config_file)
+        written_config = read_yaml(config_file)
 
         self.assertEquals('openshift-enterprise', written_config['variant'])
         # Make sure our older version was preserved:
@@ -695,88 +566,13 @@ class AttendedCliTests(OOCliFixture):
         self.config_file = os.path.join(self.work_dir, 'config.yml')
         self.cli_args.extend(["-c", self.config_file])
 
-    #pylint: disable=too-many-arguments,too-many-branches
-    def _build_input(self, ssh_user=None, hosts=None, variant_num=None,
-        add_nodes=None, confirm_facts=None, scheduleable_masters_ok=None,
-        master_lb=None):
-        """
-        Builds a CLI input string with newline characters to simulate
-        the full run.
-        This gives us only one place to update when the input prompts change.
-        """
-
-        inputs = [
-            'y',  # let's proceed
-        ]
-        if ssh_user:
-            inputs.append(ssh_user)
-
-        if variant_num:
-            inputs.append(str(variant_num))  # Choose variant + version
-
-        num_masters = 0
-        if hosts:
-            i = 0
-            min_masters_for_ha = 3
-            for (host, is_master) in hosts:
-                inputs.append(host)
-                if is_master:
-                    inputs.append('y')
-                    num_masters += 1
-                else:
-                    inputs.append('n')
-                #inputs.append('rpm')
-                if i < len(hosts) - 1:
-                    if num_masters <= 1 or num_masters >= min_masters_for_ha:
-                        inputs.append('y')  # Add more hosts
-                else:
-                    inputs.append('n')  # Done adding hosts
-                i += 1
-
-        # You can pass a single master_lb or a list if you intend for one to get rejected:
-        if master_lb:
-            if isinstance(master_lb[0], list) or isinstance(master_lb[0], tuple):
-                inputs.extend(master_lb[0])
-            else:
-                inputs.append(master_lb[0])
-            inputs.append('y' if master_lb[1] else 'n')
-
-        # TODO: support option 2, fresh install
-        if add_nodes:
-            if scheduleable_masters_ok:
-                inputs.append('y')
-            inputs.append('1')  # Add more nodes
-            i = 0
-            for (host, is_master) in add_nodes:
-                inputs.append(host)
-                #inputs.append('rpm')
-                if i < len(add_nodes) - 1:
-                    inputs.append('y')  # Add more hosts
-                else:
-                    inputs.append('n')  # Done adding hosts
-                i += 1
-
-        if add_nodes is None:
-            total_hosts = hosts
-        else:
-            total_hosts = hosts + add_nodes
-        if total_hosts is not None and num_masters == len(total_hosts):
-            inputs.append('y')
-
-        inputs.extend([
-            confirm_facts,
-            'y',  # lets do this
-        ])
-
-        return '\n'.join(inputs)
-
     @patch('ooinstall.openshift_ansible.run_main_playbook')
     @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_full_run(self, load_facts_mock, run_playbook_mock):
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         run_playbook_mock.return_value = 0
 
-        cli_input = self._build_input(hosts=[
+        cli_input = build_input(hosts=[
             ('10.0.0.1', True),
             ('10.0.0.2', False),
             ('10.0.0.3', False)],
@@ -791,7 +587,7 @@ class AttendedCliTests(OOCliFixture):
         self._verify_load_facts(load_facts_mock)
         self._verify_run_playbook(run_playbook_mock, 3, 3)
 
-        written_config = self._read_yaml(self.config_file)
+        written_config = read_yaml(self.config_file)
         self._verify_config_hosts(written_config, 3)
 
         inventory = ConfigParser.ConfigParser(allow_no_value=True)
@@ -817,7 +613,7 @@ class AttendedCliTests(OOCliFixture):
         load_facts_mock.return_value = (mock_facts, 0)
         run_playbook_mock.return_value = 0
 
-        cli_input = self._build_input(hosts=[
+        cli_input = build_input(hosts=[
             ('10.0.0.1', True),
             ('10.0.0.2', False),
             ],
@@ -834,7 +630,7 @@ class AttendedCliTests(OOCliFixture):
         self._verify_load_facts(load_facts_mock)
         self._verify_run_playbook(run_playbook_mock, 3, 2)
 
-        written_config = self._read_yaml(self.config_file)
+        written_config = read_yaml(self.config_file)
         self._verify_config_hosts(written_config, 3)
 
     @patch('ooinstall.openshift_ansible.run_main_playbook')
@@ -846,7 +642,7 @@ class AttendedCliTests(OOCliFixture):
         config_file = self.write_config(os.path.join(self.work_dir,
                                                      'ooinstall.conf'),
                                         SAMPLE_CONFIG % 'openshift-enterprise')
-        cli_input = self._build_input(confirm_facts='y')
+        cli_input = build_input(confirm_facts='y')
         self.cli_args.extend(["-c", config_file])
         self.cli_args.append("install")
         result = self.runner.invoke(cli.cli,
@@ -857,7 +653,7 @@ class AttendedCliTests(OOCliFixture):
         self._verify_load_facts(load_facts_mock)
         self._verify_run_playbook(run_playbook_mock, 3, 3)
 
-        written_config = self._read_yaml(config_file)
+        written_config = read_yaml(config_file)
         self._verify_config_hosts(written_config, 3)
 
     #interactive with config file and all installed hosts
@@ -868,7 +664,7 @@ class AttendedCliTests(OOCliFixture):
         mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
         mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
 
-        cli_input = self._build_input(hosts=[
+        cli_input = build_input(hosts=[
             ('10.0.0.1', True),
             ],
                                       add_nodes=[('10.0.0.2', False)],
@@ -891,7 +687,7 @@ class AttendedCliTests(OOCliFixture):
         load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
         run_playbook_mock.return_value = 0
 
-        cli_input = self._build_input(hosts=[
+        cli_input = build_input(hosts=[
             ('10.0.0.1', True),
             ('10.0.0.2', True),
             ('10.0.0.3', False),
@@ -908,7 +704,7 @@ class AttendedCliTests(OOCliFixture):
         self._verify_load_facts(load_facts_mock)
         self._verify_run_playbook(run_playbook_mock, 5, 5)
 
-        written_config = self._read_yaml(self.config_file)
+        written_config = read_yaml(self.config_file)
         self._verify_config_hosts(written_config, 5)
 
         inventory = ConfigParser.ConfigParser(allow_no_value=True)
@@ -929,7 +725,7 @@ class AttendedCliTests(OOCliFixture):
         load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
         run_playbook_mock.return_value = 0
 
-        cli_input = self._build_input(hosts=[
+        cli_input = build_input(hosts=[
             ('10.0.0.1', True),
             ('10.0.0.2', True),
             ('10.0.0.3', True)],
@@ -945,7 +741,7 @@ class AttendedCliTests(OOCliFixture):
         self._verify_load_facts(load_facts_mock)
         self._verify_run_playbook(run_playbook_mock, 4, 4)
 
-        written_config = self._read_yaml(self.config_file)
+        written_config = read_yaml(self.config_file)
         self._verify_config_hosts(written_config, 4)
 
         inventory = ConfigParser.ConfigParser(allow_no_value=True)
@@ -964,7 +760,7 @@ class AttendedCliTests(OOCliFixture):
         load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
         run_playbook_mock.return_value = 0
 
-        cli_input = self._build_input(hosts=[
+        cli_input = build_input(hosts=[
                                       ('10.0.0.1', True),
                                       ('10.0.0.2', True),
                                       ('10.0.0.3', False),
@@ -985,7 +781,7 @@ class AttendedCliTests(OOCliFixture):
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         run_playbook_mock.return_value = 0
 
-        cli_input = self._build_input(hosts=[
+        cli_input = build_input(hosts=[
             ('10.0.0.1', True)],
                                       ssh_user='root',
                                       variant_num=1,
@@ -998,7 +794,7 @@ class AttendedCliTests(OOCliFixture):
         self._verify_load_facts(load_facts_mock)
         self._verify_run_playbook(run_playbook_mock, 1, 1)
 
-        written_config = self._read_yaml(self.config_file)
+        written_config = read_yaml(self.config_file)
         self._verify_config_hosts(written_config, 1)
 
         inventory = ConfigParser.ConfigParser(allow_no_value=True)
diff --git a/utils/test/fixture.py b/utils/test/fixture.py
new file mode 100644
index 000000000..ab1c3f12e
--- /dev/null
+++ b/utils/test/fixture.py
@@ -0,0 +1,218 @@
+# 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
+ansible_ssh_user: root
+hosts:
+  - connect_to: 10.0.0.1
+    ip: 10.0.0.1
+    hostname: master-private.example.com
+    public_ip: 24.222.0.1
+    public_hostname: master.example.com
+    master: true
+    node: true
+  - connect_to: 10.0.0.2
+    ip: 10.0.0.2
+    hostname: node1-private.example.com
+    public_ip: 24.222.0.2
+    public_hostname: node1.example.com
+    node: true
+  - connect_to: 10.0.0.3
+    ip: 10.0.0.3
+    hostname: node2-private.example.com
+    public_ip: 24.222.0.3
+    public_hostname: node2.example.com
+    node: true
+"""
+
+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.exception is not None or 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, ".ansible/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][0]
+        hosts_to_run_on = run_playbook_mock.call_args[0][1]
+        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['hosts']))
+        for host in written_config['hosts']:
+            self.assertTrue('hostname' in host)
+            self.assertTrue('public_hostname' in host)
+            if 'preconfigured' not in host:
+                self.assertTrue(host['node'])
+                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][0]
+        hosts_to_run_on = run_playbook_mock.call_args[0][1]
+        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
+def build_input(ssh_user=None, hosts=None, variant_num=None,
+                add_nodes=None, confirm_facts=None, scheduleable_masters_ok=None,
+                master_lb=None):
+    """
+    Build an input string simulating a user entering values in an interactive
+    attended install.
+
+    This is intended to give us one place to update when the CLI prompts change.
+    We should aim to keep this dependent on optional keyword arguments with
+    sensible defaults to keep things from getting too fragile.
+    """
+
+    inputs = [
+        'y',  # let's proceed
+    ]
+    if ssh_user:
+        inputs.append(ssh_user)
+
+    if variant_num:
+        inputs.append(str(variant_num))  # Choose variant + version
+
+    num_masters = 0
+    if hosts:
+        i = 0
+        min_masters_for_ha = 3
+        for (host, is_master) in hosts:
+            inputs.append(host)
+            if is_master:
+                inputs.append('y')
+                num_masters += 1
+            else:
+                inputs.append('n')
+            #inputs.append('rpm')
+            if i < len(hosts) - 1:
+                if num_masters <= 1 or num_masters >= min_masters_for_ha:
+                    inputs.append('y')  # Add more hosts
+            else:
+                inputs.append('n')  # Done adding hosts
+            i += 1
+
+    # You can pass a single master_lb or a list if you intend for one to get rejected:
+    if master_lb:
+        if isinstance(master_lb[0], list) or isinstance(master_lb[0], tuple):
+            inputs.extend(master_lb[0])
+        else:
+            inputs.append(master_lb[0])
+        inputs.append('y' if master_lb[1] else 'n')
+
+    # TODO: support option 2, fresh install
+    if add_nodes:
+        if scheduleable_masters_ok:
+            inputs.append('y')
+        inputs.append('1')  # Add more nodes
+        i = 0
+        for (host, is_master) in add_nodes:
+            inputs.append(host)
+            #inputs.append('rpm')
+            if i < len(add_nodes) - 1:
+                inputs.append('y')  # Add more hosts
+            else:
+                inputs.append('n')  # Done adding hosts
+            i += 1
+
+    if add_nodes is None:
+        total_hosts = hosts
+    else:
+        total_hosts = hosts + add_nodes
+    if total_hosts is not None and num_masters == len(total_hosts):
+        inputs.append('y')
+
+    inputs.extend([
+        confirm_facts,
+        'y',  # lets do this
+    ])
+
+    return '\n'.join(inputs)
+
-- 
cgit v1.2.3