diff options
Diffstat (limited to 'utils')
| -rw-r--r-- | utils/.coveragerc | 5 | ||||
| l--------- | utils/.pylintrc | 1 | ||||
| -rw-r--r-- | utils/Makefile | 68 | ||||
| -rw-r--r-- | utils/README.md | 41 | ||||
| -rw-r--r-- | utils/docs/man/man1/atomic-openshift-installer.1 | 8 | ||||
| -rw-r--r-- | utils/docs/man/man1/atomic-openshift-installer.1.asciidoc.in | 2 | ||||
| -rw-r--r-- | utils/setup.cfg | 18 | ||||
| -rw-r--r-- | utils/setup.py | 2 | ||||
| -rw-r--r-- | utils/src/ooinstall/cli_installer.py | 20 | ||||
| -rw-r--r-- | utils/src/ooinstall/oo_config.py | 27 | ||||
| -rw-r--r-- | utils/src/ooinstall/openshift_ansible.py | 30 | ||||
| -rw-r--r-- | utils/src/ooinstall/utils.py | 3 | ||||
| -rw-r--r-- | utils/src/ooinstall/variants.py | 44 | ||||
| -rw-r--r-- | utils/test-requirements.txt | 7 | ||||
| -rw-r--r-- | utils/test/cli_installer_tests.py | 21 | ||||
| -rw-r--r-- | utils/test/fixture.py | 10 | ||||
| -rw-r--r-- | utils/test/oo_config_tests.py | 7 | ||||
| -rw-r--r-- | utils/test/openshift_ansible_tests.py | 71 | ||||
| -rw-r--r-- | utils/test/test_utils.py | 11 | ||||
| -rw-r--r-- | utils/tox.ini | 16 | 
20 files changed, 294 insertions, 118 deletions
| diff --git a/utils/.coveragerc b/utils/.coveragerc new file mode 100644 index 000000000..e1d918755 --- /dev/null +++ b/utils/.coveragerc @@ -0,0 +1,5 @@ +[run] +omit= +    */lib/python*/site-packages/* +    */lib/python*/* +    /usr/* diff --git a/utils/.pylintrc b/utils/.pylintrc new file mode 120000 index 000000000..30b33b524 --- /dev/null +++ b/utils/.pylintrc @@ -0,0 +1 @@ +../.pylintrc
\ No newline at end of file diff --git a/utils/Makefile b/utils/Makefile index 62f08f74b..038c31fcf 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -22,6 +22,7 @@  NAME := oo-install +VENV := $(NAME)env  TESTPACKAGE := oo-install  SHORTNAME := ooinstall @@ -29,9 +30,12 @@ SHORTNAME := ooinstall  # directory of the target file ($@), kinda like `dirname`.  ASCII2MAN = a2x -D $(dir $@) -d manpage -f manpage $<  MANPAGES := docs/man/man1/atomic-openshift-installer.1 -VERSION := 1.3 +# slipped into the manpage template before a2x processing +VERSION := 1.4 -PEPEXCLUDES := E501,E121,E124 +# YAMLFILES: Skipping all '/files/' folders due to conflicting yaml file definitions +YAMLFILES = $(shell find ../ -name $(VENV) -prune -o -name .tox -prune -o \( -name '*.yml' -o -name '*.yaml' \) ! -path "*/files/*" -print 2>&1) +PYFILES = $(shell find ../ -name $(VENV) -prune -o -name ooinstall.egg-info -prune -o -name test -prune -o -name .tox -prune -o -name "*.py" -print)  sdist: clean  	python setup.py sdist @@ -41,8 +45,8 @@ clean:  	@find . -type f -regex ".*\.py[co]$$" -delete  	@find . -type f \( -name "*~" -or -name "#*" \) -delete  	@rm -fR build dist rpm-build MANIFEST htmlcov .coverage cover ooinstall.egg-info oo-install -	@rm -fR $(NAME)env - +	@rm -fR $(VENV) +	@rm -fR .tox  # To force a rebuild of the docs run 'touch' on any *.in file under  # docs/man/man1/ @@ -61,52 +65,46 @@ docs: $(MANPAGES)  viewcover:  	xdg-open cover/index.html -virtualenv: +# Conditional virtualenv building strategy taken from this great post +# by Marcel Hellkamp: +# http://blog.bottlepy.org/2012/07/16/virtualenv-and-makefiles.html +$(VENV): $(VENV)/bin/activate +$(VENV)/bin/activate: test-requirements.txt  	@echo "#############################################"  	@echo "# Creating a virtualenv"  	@echo "#############################################" -	virtualenv $(NAME)env -	 . $(NAME)env/bin/activate && pip install setuptools==17.1.1 -	. $(NAME)env/bin/activate && pip install -r test-requirements.txt +	test -d $(VENV) || virtualenv $(VENV) +	. $(VENV)/bin/activate && pip install setuptools==17.1.1 +	. $(VENV)/bin/activate && pip install -r test-requirements.txt +	touch $(VENV)/bin/activate  #       If there are any special things to install do it here -#       . $(NAME)env/bin/activate && INSTALL STUFF +#       . $(VENV)/bin/activate && INSTALL STUFF -ci-unittests: +ci-unittests: $(VENV)  	@echo "#############################################"  	@echo "# Running Unit Tests in virtualenv"  	@echo "#############################################" -	. $(NAME)env/bin/activate && nosetests -v --with-coverage --cover-html --cover-min-percentage=70 --cover-package=$(SHORTNAME) test/ +	. $(VENV)/bin/activate && detox -e py27-unit,py35-unit  	@echo "VIEW CODE COVERAGE REPORT WITH 'xdg-open cover/index.html' or run 'make viewcover'" -ci-pylint: +ci-pylint: $(VENV)  	@echo "#############################################"  	@echo "# Running PyLint Tests in virtualenv"  	@echo "#############################################" -	. $(NAME)env/bin/activate && python -m pylint --rcfile ../git/.pylintrc src/ooinstall/cli_installer.py src/ooinstall/oo_config.py src/ooinstall/openshift_ansible.py src/ooinstall/variants.py ../callback_plugins/openshift_quick_installer.py ../roles/openshift_certificate_expiry/library/openshift_cert_expiry.py +	. $(VENV)/bin/activate && detox -e py27-pylint,py35-pylint -ci-list-deps: +ci-flake8: $(VENV)  	@echo "#############################################" -	@echo "# Listing all pip deps" +	@echo "# Running Flake8 Compliance Tests in virtualenv"  	@echo "#############################################" -	. $(NAME)env/bin/activate && pip freeze +	. $(VENV)/bin/activate && detox -e py27-flake8,py35-flake8 -ci-pyflakes: -	@echo "#################################################" -	@echo "# Running Pyflakes Compliance Tests in virtualenv" -	@echo "#################################################" -	. $(NAME)env/bin/activate && pyflakes src/ooinstall/*.py -	. $(NAME)env/bin/activate && pyflakes ../callback_plugins/openshift_quick_installer.py -	. $(NAME)env/bin/activate && pyflakes ../roles/openshift_certificate_expiry/library/openshift_cert_expiry.py +ci-tox: $(VENV) +	. $(VENV)/bin/activate && detox -ci-pep8: -	@echo "#############################################" -	@echo "# Running PEP8 Compliance Tests in virtualenv" -	@echo "#############################################" -	. $(NAME)env/bin/activate && pep8 --ignore=$(PEPEXCLUDES) src/$(SHORTNAME)/ -	. $(NAME)env/bin/activate && pep8 --ignore=$(PEPEXCLUDES) ../callback_plugins/openshift_quick_installer.py -# This one excludes E402 because it is an ansible module and the -# boilerplate import statement is expected to be at the bottom -	. $(NAME)env/bin/activate && pep8 --ignore=$(PEPEXCLUDES),E402 ../roles/openshift_certificate_expiry/library/openshift_cert_expiry.py - -ci: clean virtualenv ci-list-deps ci-pep8 ci-pylint ci-pyflakes ci-unittests -	: +ci: ci-tox +	@echo +	@echo "##################################################################################" +	@echo "VIEW CODE COVERAGE REPORT WITH 'xdg-open cover/index.html' or run 'make viewcover'" +	@echo "To clean your test environment run 'make clean'" +	@echo "Other targets you may run with 'make': 'ci-pylint', 'ci-tox', 'ci-unittests', 'ci-flake8'" diff --git a/utils/README.md b/utils/README.md index 2abf2705e..c37ab41e6 100644 --- a/utils/README.md +++ b/utils/README.md @@ -6,6 +6,47 @@ Run the command:  to run an array of unittests locally. +Underneath the covers, we use [tox](http://readthedocs.org/docs/tox/) to manage virtualenvs and run +tests. Alternatively, tests can be run using [detox](https://pypi.python.org/pypi/detox/) which allows +for running tests in parallel + + +``` +pip install tox detox +``` + +List the test environments available: +``` +tox -l +``` + +Run all of the tests with: +``` +tox +``` + +Run all of the tests in parallel with detox: +``` +detox +``` + +Running a particular test environment (python 2.7 flake8 tests in this case): +``` +tox -e py27-ansible22-flake8 +``` + +Running a particular test environment in a clean virtualenv (python 3.5 pylint +tests in this case): +``` +tox -r -e py35-ansible22-pylint +``` + +If you want to enter the virtualenv created by tox to do additional +testing/debugging (py27-flake8 env in this case): +``` +source .tox/py27-ansible22-flake8/bin/activate +``` +  You will get errors if the log files already exist and can not be  written to by the current user (`/tmp/ansible.log` and  `/tmp/installer.txt`). *We're working on it.* diff --git a/utils/docs/man/man1/atomic-openshift-installer.1 b/utils/docs/man/man1/atomic-openshift-installer.1 index 072833ce8..827ce224b 100644 --- a/utils/docs/man/man1/atomic-openshift-installer.1 +++ b/utils/docs/man/man1/atomic-openshift-installer.1 @@ -2,12 +2,12 @@  .\"     Title: atomic-openshift-installer  .\"    Author: [see the "AUTHOR" section]  .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> -.\"      Date: 10/20/2016 +.\"      Date: 12/28/2016  .\"    Manual: atomic-openshift-installer -.\"    Source: atomic-openshift-utils 1.3 +.\"    Source: atomic-openshift-utils 1.4  .\"  Language: English  .\" -.TH "ATOMIC\-OPENSHIFT\-I" "1" "10/20/2016" "atomic\-openshift\-utils 1\&.3" "atomic\-openshift\-installer" +.TH "ATOMIC\-OPENSHIFT\-I" "1" "12/28/2016" "atomic\-openshift\-utils 1\&.4" "atomic\-openshift\-installer"  .\" -----------------------------------------------------------------  .\" * Define some portability stuff  .\" ----------------------------------------------------------------- @@ -86,7 +86,7 @@ Show the usage help and exit\&.  .RE  .SH "COMMANDS"  .sp -\fBatomic\-openshift\-installer\fR has three modes of operation: +\fBatomic\-openshift\-installer\fR has four modes of operation:  .sp  .RS 4  .ie n \{\ diff --git a/utils/docs/man/man1/atomic-openshift-installer.1.asciidoc.in b/utils/docs/man/man1/atomic-openshift-installer.1.asciidoc.in index 9b02c4d14..2917e9992 100644 --- a/utils/docs/man/man1/atomic-openshift-installer.1.asciidoc.in +++ b/utils/docs/man/man1/atomic-openshift-installer.1.asciidoc.in @@ -68,7 +68,7 @@ Show the usage help and exit.  COMMANDS  -------- -**atomic-openshift-installer** has three modes of operation: +**atomic-openshift-installer** has four modes of operation:  * **install**  * **uninstall** diff --git a/utils/setup.cfg b/utils/setup.cfg index 79bc67848..862dffd7b 100644 --- a/utils/setup.cfg +++ b/utils/setup.cfg @@ -3,3 +3,21 @@  # 3. If at all possible, it is good practice to do this. If you cannot, you  # will need to generate wheels for each Python version that you support.  universal=1 + +[nosetests] +verbosity=2 +with-coverage=1 +cover-html=1 +cover-inclusive=1 +cover-min-percentage=70 +cover-erase=1 +detailed-errors=1 +cover-branches=1 + +[flake8] +max-line-length=120 +exclude=test/*,setup.py,oo-installenv +ignore=E501 + +[lint] +lint_disable=fixme,locally-disabled,file-ignored,duplicate-code diff --git a/utils/setup.py b/utils/setup.py index 7909321c9..3518581e7 100644 --- a/utils/setup.py +++ b/utils/setup.py @@ -47,7 +47,7 @@ setup(      # your project is installed. For an analysis of "install_requires" vs pip's      # requirements files see:      # https://packaging.python.org/en/latest/requirements.html -    install_requires=['click', 'PyYAML'], +    install_requires=['click', 'PyYAML', 'ansible'],      # List additional groups of dependencies here (e.g. development      # dependencies). You can install these using the following syntax, diff --git a/utils/src/ooinstall/cli_installer.py b/utils/src/ooinstall/cli_installer.py index 8470fb527..0bc9aa45e 100644 --- a/utils/src/ooinstall/cli_installer.py +++ b/utils/src/ooinstall/cli_installer.py @@ -318,6 +318,7 @@ hostname.  def set_cluster_hostname(oo_cfg): +    first_master = next((host for host in oo_cfg.deployment.hosts if host.is_master()), None)      message = """  You have chosen to install a single master cluster (non-HA). @@ -329,8 +330,9 @@ If you want to override the cluster host name now to something other than the de  """      click.echo(message)      cluster_hostname = click.prompt('Enter hostname or IP address', -                                    default='') +                                    default=str(first_master))      oo_cfg.deployment.variables['openshift_master_cluster_hostname'] = cluster_hostname +    oo_cfg.deployment.variables['openshift_master_cluster_public_hostname'] = cluster_hostname  def collect_storage_host(hosts): @@ -499,7 +501,7 @@ def get_variant_and_version(multi_master=False):      i = 1      combos = get_variant_version_combos() -    for (variant, version) in combos: +    for (variant, _) in combos:          message = "%s\n(%s) %s" % (message, i, variant.description)          i = i + 1      message = "%s\n" % message @@ -1122,6 +1124,20 @@ def scaleup(ctx, gen_inventory):      click.echo('Welcome to the OpenShift Enterprise 3 Scaleup utility.') +    # Scaleup requires manual data entry. Therefore, we do not support +    # unattended operations. +    if unattended: +        msg = """ +--- + +The 'scaleup' operation does not support unattended +functionality. Re-run the installer without the '-u' or '--unattended' +option to continue. +""" +        click.echo(msg) +        sys.exit(1) + +    # Resume normal scaleup workflow      print_installation_summary(installed_hosts,                                 oo_cfg.settings['variant_version'],                                 verbose=False,) diff --git a/utils/src/ooinstall/oo_config.py b/utils/src/ooinstall/oo_config.py index 64eb340f3..cf14105af 100644 --- a/utils/src/ooinstall/oo_config.py +++ b/utils/src/ooinstall/oo_config.py @@ -1,5 +1,7 @@  # pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name,too-many-instance-attributes,too-few-public-methods +from __future__ import (absolute_import, print_function) +  import os  import sys  import logging @@ -50,7 +52,7 @@ Error loading config. {}.  See https://docs.openshift.com/enterprise/latest/install_config/install/quick_install.html#defining-an-installation-configuration-file  for information on creating a configuration file or delete {} and re-run the installer.  """ -    print message.format(error, path) +    print(message.format(error, path))  class OOConfigFileError(Exception): @@ -103,7 +105,7 @@ class Host(object):              # If the property is defined (not None or False), export it:              if getattr(self, prop):                  d[prop] = getattr(self, prop) -        for variable, value in self.other_variables.iteritems(): +        for variable, value in self.other_variables.items():              d[variable] = value          return d @@ -256,16 +258,16 @@ class OOConfig(object):                  # Parse the hosts into DTO objects:                  for host in host_list:                      host['other_variables'] = {} -                    for variable, value in host.iteritems(): +                    for variable, value in host.items():                          if variable not in HOST_VARIABLES_BLACKLIST:                              host['other_variables'][variable] = value                      self.deployment.hosts.append(Host(**host))                  # Parse the roles into Objects -                for name, variables in role_list.iteritems(): +                for name, variables in role_list.items():                      self.deployment.roles.update({name: Role(name, variables)}) -        except IOError, ferr: +        except IOError as ferr:              raise OOConfigFileError('Cannot open config file "{}": {}'.format(ferr.filename,                                                                                ferr.strerror))          except yaml.scanner.ScannerError: @@ -354,14 +356,13 @@ class OOConfig(object):          self.settings['ansible_inventory_path'] = \              '{}/hosts'.format(os.path.dirname(self.config_path)) -        # pylint: disable=consider-iterating-dictionary -        # Disabled because we shouldn't alter the container we're -        # iterating over -        #          # clean up any empty sets -        for setting in self.settings.keys(): +        empty_keys = [] +        for setting in self.settings:              if not self.settings[setting]: -                self.settings.pop(setting) +                empty_keys.append(setting) +        for key in empty_keys: +            self.settings.pop(key)          installer_log.debug("Updated OOConfig settings: %s", self.settings) @@ -410,7 +411,7 @@ class OOConfig(object):          for host in self.deployment.hosts:              p_settings['deployment']['hosts'].append(host.to_dict()) -        for name, role in self.deployment.roles.iteritems(): +        for name, role in self.deployment.roles.items():              p_settings['deployment']['roles'][name] = role.variables          for setting in self.deployment.variables: @@ -424,7 +425,7 @@ class OOConfig(object):              if self.settings['ansible_inventory_directory'] != self._default_ansible_inv_dir():                  p_settings['ansible_inventory_directory'] = self.settings['ansible_inventory_directory']          except KeyError as e: -            print "Error persisting settings: {}".format(e) +            print("Error persisting settings: {}".format(e))              sys.exit(0)          return p_settings diff --git a/utils/src/ooinstall/openshift_ansible.py b/utils/src/ooinstall/openshift_ansible.py index 764cc1e56..ce6e54664 100644 --- a/utils/src/ooinstall/openshift_ansible.py +++ b/utils/src/ooinstall/openshift_ansible.py @@ -1,5 +1,7 @@  # pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name,global-statement,global-variable-not-assigned +from __future__ import (absolute_import, print_function) +  import socket  import subprocess  import sys @@ -107,12 +109,12 @@ def write_inventory_vars(base_inventory, lb):      global CFG      base_inventory.write('\n[OSEv3:vars]\n') -    for variable, value in CFG.settings.iteritems(): +    for variable, value in CFG.settings.items():          inventory_var = VARIABLES_MAP.get(variable, None)          if inventory_var and value:              base_inventory.write('{}={}\n'.format(inventory_var, value)) -    for variable, value in CFG.deployment.variables.iteritems(): +    for variable, value in CFG.deployment.variables.items():          inventory_var = VARIABLES_MAP.get(variable, variable)          if value:              base_inventory.write('{}={}\n'.format(inventory_var, value)) @@ -152,11 +154,11 @@ def write_inventory_vars(base_inventory, lb):                               "'baseurl': '{}', "                               "'enabled': 1, 'gpgcheck': 0}}]\n".format(os.environ['OO_INSTALL_PUDDLE_REPO'])) -    for name, role_obj in CFG.deployment.roles.iteritems(): +    for name, role_obj in CFG.deployment.roles.items():          if role_obj.variables:              group_name = ROLES_TO_GROUPS_MAP.get(name, name)              base_inventory.write("\n[{}:vars]\n".format(group_name)) -            for variable, value in role_obj.variables.iteritems(): +            for variable, value in role_obj.variables.items():                  inventory_var = VARIABLES_MAP.get(variable, variable)                  if value:                      base_inventory.write('{}={}\n'.format(inventory_var, value)) @@ -193,7 +195,7 @@ def write_host(host, role, inventory, schedulable=None):              facts += ' {}={}'.format(HOST_VARIABLES_MAP.get(prop), getattr(host, prop))      if host.other_variables: -        for variable, value in host.other_variables.iteritems(): +        for variable, value in host.other_variables.items():              facts += " {}={}".format(variable, value)      if host.node_labels and role == 'node': @@ -210,9 +212,9 @@ def write_host(host, role, inventory, schedulable=None):      if installer_host in [host.connect_to, host.hostname, host.public_hostname]:          facts += ' ansible_connection=local'          if os.geteuid() != 0: -            no_pwd_sudo = subprocess.call(['sudo', '-n', 'echo', 'openshift']) +            no_pwd_sudo = subprocess.call(['sudo', '-n', 'echo', '-n'])              if no_pwd_sudo == 1: -                print 'The atomic-openshift-installer requires sudo access without a password.' +                print('The atomic-openshift-installer requires sudo access without a password.')                  sys.exit(1)              facts += ' ansible_become=yes' @@ -245,9 +247,9 @@ def load_system_facts(inventory_file, os_facts_path, env_vars, verbose=False):          installer_log.debug("Going to try to read this file: %s", CFG.settings['ansible_callback_facts_yaml'])          try:              callback_facts = yaml.safe_load(callback_facts_file) -        except yaml.YAMLError, exc: -            print "Error in {}".format(CFG.settings['ansible_callback_facts_yaml']), exc -            print "Try deleting and rerunning the atomic-openshift-installer" +        except yaml.YAMLError as exc: +            print("Error in {}".format(CFG.settings['ansible_callback_facts_yaml']), exc) +            print("Try deleting and rerunning the atomic-openshift-installer")              sys.exit(1)      return callback_facts, 0 @@ -314,6 +316,10 @@ def run_uninstall_playbook(hosts, verbose=False):          facts_env['ANSIBLE_LOG_PATH'] = CFG.settings['ansible_log_path']      if 'ansible_config' in CFG.settings:          facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_config'] +    # override the ansible config for our main playbook run +    if 'ansible_quiet_config' in CFG.settings: +        facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_quiet_config'] +      return run_ansible(playbook, inventory_file, facts_env, verbose) @@ -328,4 +334,8 @@ def run_upgrade_playbook(hosts, playbook, verbose=False):          facts_env['ANSIBLE_LOG_PATH'] = CFG.settings['ansible_log_path']      if 'ansible_config' in CFG.settings:          facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_config'] +    # override the ansible config for our main playbook run +    if 'ansible_quiet_config' in CFG.settings: +        facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_quiet_config'] +      return run_ansible(playbook, inventory_file, facts_env, verbose) diff --git a/utils/src/ooinstall/utils.py b/utils/src/ooinstall/utils.py index 85a77c75e..c9e3e25e5 100644 --- a/utils/src/ooinstall/utils.py +++ b/utils/src/ooinstall/utils.py @@ -1,3 +1,5 @@ +# pylint: disable=missing-docstring,invalid-name +  import logging  import re @@ -8,6 +10,7 @@ installer_log = logging.getLogger('installer')  def debug_env(env):      for k in sorted(env.keys()):          if k.startswith("OPENSHIFT") or k.startswith("ANSIBLE") or k.startswith("OO"): +            # pylint: disable=logging-format-interpolation              installer_log.debug("{key}: {value}".format(                  key=k, value=env[k])) diff --git a/utils/src/ooinstall/variants.py b/utils/src/ooinstall/variants.py index 39772bb2e..a45be98bf 100644 --- a/utils/src/ooinstall/variants.py +++ b/utils/src/ooinstall/variants.py @@ -38,32 +38,24 @@ class Variant(object):  # WARNING: Keep the versions ordered, most recent first: -OSE = Variant('openshift-enterprise', 'OpenShift Container Platform', -              [ -                  Version('3.4', 'openshift-enterprise'), -              ] -) - -REG = Variant('openshift-enterprise', 'Registry', -              [ -                  Version('3.4', 'openshift-enterprise', 'registry'), -              ] -) - -origin = Variant('origin', 'OpenShift Origin', -                 [ -                     Version('1.4', 'origin'), -                 ] -) - -LEGACY = Variant('openshift-enterprise', 'OpenShift Container Platform', -                 [ -                     Version('3.3', 'openshift-enterprise'), -                     Version('3.2', 'openshift-enterprise'), -                     Version('3.1', 'openshift-enterprise'), -                     Version('3.0', 'openshift-enterprise'), -                 ] -) +OSE = Variant('openshift-enterprise', 'OpenShift Container Platform', [ +    Version('3.4', 'openshift-enterprise'), +]) + +REG = Variant('openshift-enterprise', 'Registry', [ +    Version('3.4', 'openshift-enterprise', 'registry'), +]) + +origin = Variant('origin', 'OpenShift Origin', [ +    Version('1.4', 'origin'), +]) + +LEGACY = Variant('openshift-enterprise', 'OpenShift Container Platform', [ +    Version('3.3', 'openshift-enterprise'), +    Version('3.2', 'openshift-enterprise'), +    Version('3.1', 'openshift-enterprise'), +    Version('3.0', 'openshift-enterprise'), +])  # Ordered list of variants we can install, first is the default.  SUPPORTED_VARIANTS = (OSE, REG, origin, LEGACY) diff --git a/utils/test-requirements.txt b/utils/test-requirements.txt index af91ab6a7..f6a7bde10 100644 --- a/utils/test-requirements.txt +++ b/utils/test-requirements.txt @@ -1,7 +1,7 @@ -enum +ansible  configparser  pylint -pep8 +setuptools-lint  nose  coverage  mock @@ -10,3 +10,6 @@ PyYAML  click  backports.functools_lru_cache  pyOpenSSL +yamllint +tox +detox diff --git a/utils/test/cli_installer_tests.py b/utils/test/cli_installer_tests.py index 36dc18034..0cb37eaff 100644 --- a/utils/test/cli_installer_tests.py +++ b/utils/test/cli_installer_tests.py @@ -4,7 +4,8 @@  import copy  import os -import ConfigParser + +from six.moves import configparser  import ooinstall.cli_installer as cli @@ -408,7 +409,7 @@ class UnattendedCliTests(OOCliFixture):          result = self.runner.invoke(cli.cli, self.cli_args)          if result.exception is None or result.exit_code != 1: -            print "Exit code: %s" % result.exit_code +            print("Exit code: %s" % result.exit_code)              self.fail("Unexpected CLI return")      # unattended with config file and all installed hosts (with --force) @@ -523,7 +524,7 @@ class UnattendedCliTests(OOCliFixture):          self.assert_result(result, 0)          # Check the inventory file looks as we would expect: -        inventory = ConfigParser.ConfigParser(allow_no_value=True) +        inventory = configparser.ConfigParser(allow_no_value=True)          inventory.read(os.path.join(self.work_dir, 'hosts'))          self.assertEquals('root',              inventory.get('OSEv3:vars', 'ansible_ssh_user')) @@ -566,7 +567,7 @@ class UnattendedCliTests(OOCliFixture):          self.assertEquals('3.3', written_config['variant_version'])          # Make sure the correct value was passed to ansible: -        inventory = ConfigParser.ConfigParser(allow_no_value=True) +        inventory = configparser.ConfigParser(allow_no_value=True)          inventory.read(os.path.join(self.work_dir, 'hosts'))          self.assertEquals('openshift-enterprise',              inventory.get('OSEv3:vars', 'deployment_type')) @@ -594,7 +595,7 @@ class UnattendedCliTests(OOCliFixture):          # and written to disk:          self.assertEquals('3.3', written_config['variant_version']) -        inventory = ConfigParser.ConfigParser(allow_no_value=True) +        inventory = configparser.ConfigParser(allow_no_value=True)          inventory.read(os.path.join(self.work_dir, 'hosts'))          self.assertEquals('openshift-enterprise',              inventory.get('OSEv3:vars', 'deployment_type')) @@ -830,7 +831,7 @@ class AttendedCliTests(OOCliFixture):          written_config = read_yaml(self.config_file)          self._verify_config_hosts(written_config, 4) -        inventory = ConfigParser.ConfigParser(allow_no_value=True) +        inventory = configparser.ConfigParser(allow_no_value=True)          inventory.read(os.path.join(self.work_dir, 'hosts'))          self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1',                                   'openshift_schedulable=False') @@ -949,7 +950,7 @@ class AttendedCliTests(OOCliFixture):          written_config = read_yaml(self.config_file)          self._verify_config_hosts(written_config, 6) -        inventory = ConfigParser.ConfigParser(allow_no_value=True) +        inventory = configparser.ConfigParser(allow_no_value=True)          inventory.read(os.path.join(self.work_dir, 'hosts'))          self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1',                                         'openshift_schedulable=False') @@ -990,7 +991,7 @@ class AttendedCliTests(OOCliFixture):          written_config = read_yaml(self.config_file)          self._verify_config_hosts(written_config, 5) -        inventory = ConfigParser.ConfigParser(allow_no_value=True) +        inventory = configparser.ConfigParser(allow_no_value=True)          inventory.read(os.path.join(self.work_dir, 'hosts'))          self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1',                                         'openshift_schedulable=True') @@ -1082,7 +1083,7 @@ class AttendedCliTests(OOCliFixture):          written_config = read_yaml(self.config_file)          self._verify_config_hosts(written_config, 1) -        inventory = ConfigParser.ConfigParser(allow_no_value=True) +        inventory = configparser.ConfigParser(allow_no_value=True)          inventory.read(os.path.join(self.work_dir, 'hosts'))          self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1',                                         'openshift_schedulable=True') @@ -1116,7 +1117,7 @@ class AttendedCliTests(OOCliFixture):          written_config = read_yaml(self.config_file)          self._verify_config_hosts(written_config, 4) -        inventory = ConfigParser.ConfigParser(allow_no_value=True) +        inventory = configparser.ConfigParser(allow_no_value=True)          inventory.read(os.path.join(self.work_dir, 'hosts'))          self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1',                                   'openshift_schedulable=False') diff --git a/utils/test/fixture.py b/utils/test/fixture.py index 62135c761..5200d275d 100644 --- a/utils/test/fixture.py +++ b/utils/test/fixture.py @@ -65,13 +65,13 @@ class OOCliFixture(OOInstallFixture):      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 +            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 +            print("Output:\n%s" % result.output)              self.fail("Exception during CLI execution")      def _verify_load_facts(self, load_facts_mock): diff --git a/utils/test/oo_config_tests.py b/utils/test/oo_config_tests.py index 56fd82408..2b4fce512 100644 --- a/utils/test/oo_config_tests.py +++ b/utils/test/oo_config_tests.py @@ -2,13 +2,14 @@  # repo. We will work on these over time.  # pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name -import cStringIO  import os  import unittest  import tempfile  import shutil  import yaml +from six.moves import cStringIO +  from ooinstall.oo_config import OOConfig, Host, OOConfigInvalidHostError  import ooinstall.openshift_ansible @@ -244,7 +245,7 @@ class HostTests(OOInstallFixture):          }          new_node = Host(**yaml_props) -        inventory = cStringIO.StringIO() +        inventory = cStringIO()          # This is what the 'write_host' function generates. write_host          # has no return value, it just writes directly to the file          # 'inventory' which in this test-case is a StringIO object @@ -285,7 +286,7 @@ class HostTests(OOInstallFixture):      #     }      #     new_node = Host(**yaml_props) -    #     inventory = cStringIO.StringIO() +    #     inventory = cStringIO()      #     # This is what the original 'write_host' function will      #     # generate. write_host has no return value, it just writes diff --git a/utils/test/openshift_ansible_tests.py b/utils/test/openshift_ansible_tests.py new file mode 100644 index 000000000..5847fe37b --- /dev/null +++ b/utils/test/openshift_ansible_tests.py @@ -0,0 +1,71 @@ +import os +import unittest +import tempfile +import shutil +import yaml + +from six.moves import configparser + +from ooinstall import openshift_ansible +from ooinstall.oo_config import Host, OOConfig + + +BASE_CONFIG = """ +--- +variant: openshift-enterprise +variant_version: 3.3 +version: v2 +deployment: +    ansible_ssh_user: cloud-user +    hosts: [] +    roles: +        master: +        node: +""" + + +class TestOpenShiftAnsible(unittest.TestCase): + +    def setUp(self): +        self.tempfiles = [] +        self.work_dir = tempfile.mkdtemp(prefix='openshift_ansible_tests') +        self.configfile = os.path.join(self.work_dir, 'ooinstall.config') +        with open(self.configfile, 'w') as config_file: +            config_file.write(BASE_CONFIG) +        self.inventory = os.path.join(self.work_dir, 'hosts') +        config = OOConfig(self.configfile) +        config.settings['ansible_inventory_path'] = self.inventory +        openshift_ansible.set_config(config) + +    def tearDown(self): +        shutil.rmtree(self.work_dir) + +    def generate_hosts(self, num_hosts, name_prefix, roles=None, new_host=False): +        hosts = [] +        for num in range(1, num_hosts + 1): +            hosts.append(Host(connect_to=name_prefix + str(num), +                              roles=roles, new_host=new_host)) +        return hosts + +    def test_generate_inventory_new_nodes(self): +        hosts = self.generate_hosts(1, 'master', roles=(['master', 'etcd'])) +        hosts.extend(self.generate_hosts(1, 'node', roles=['node'])) +        hosts.extend(self.generate_hosts(1, 'new_node', roles=['node'], new_host=True)) +        openshift_ansible.generate_inventory(hosts) +        inventory = configparser.ConfigParser(allow_no_value=True) +        inventory.read(self.inventory) +        self.assertTrue(inventory.has_section('new_nodes')) +        self.assertTrue(inventory.has_option('new_nodes', 'new_node1')) + +    def test_write_inventory_vars_role_vars(self): +        with open(self.inventory, 'w') as inv: +            openshift_ansible.CFG.deployment.roles['master'].variables={'color': 'blue'} +            openshift_ansible.CFG.deployment.roles['node'].variables={'color': 'green'} +            openshift_ansible.write_inventory_vars(inv, None) + +        inventory = configparser.ConfigParser(allow_no_value=True) +        inventory.read(self.inventory) +        self.assertTrue(inventory.has_section('masters:vars')) +        self.assertEquals('blue', inventory.get('masters:vars', 'color')) +        self.assertTrue(inventory.has_section('nodes:vars')) +        self.assertEquals('green', inventory.get('nodes:vars', 'color')) diff --git a/utils/test/test_utils.py b/utils/test/test_utils.py index 2e59d86f2..cbce64f7e 100644 --- a/utils/test/test_utils.py +++ b/utils/test/test_utils.py @@ -2,6 +2,7 @@  Unittests for ooinstall utils.  """ +import six  import unittest  import logging  import sys @@ -28,9 +29,6 @@ class TestUtils(unittest.TestCase):              mock.call('OO_FOO: bar'),          ] -        # python 2.x has assertItemsEqual, python 3.x has assertCountEqual -        if sys.version_info.major > 3: -            self.assertItemsEqual = self.assertCountEqual      ######################################################################      # Validate ooinstall.utils.debug_env functionality @@ -40,7 +38,6 @@ class TestUtils(unittest.TestCase):          with mock.patch('ooinstall.utils.installer_log') as _il:              debug_env(self.debug_all_params) -            print _il.debug.call_args_list              # Debug was called for each item we expect              self.assertEqual( @@ -48,7 +45,8 @@ class TestUtils(unittest.TestCase):                  _il.debug.call_count)              # Each item we expect was logged -            self.assertItemsEqual( +            six.assertCountEqual( +                self,                  self.expected,                  _il.debug.call_args_list) @@ -67,7 +65,8 @@ class TestUtils(unittest.TestCase):                  _il.debug.call_count,                  len(debug_some_params)) -            self.assertItemsEqual( +            six.assertCountEqual( +                self,                  self.expected,                  _il.debug.call_args_list) diff --git a/utils/tox.ini b/utils/tox.ini new file mode 100644 index 000000000..1308f7505 --- /dev/null +++ b/utils/tox.ini @@ -0,0 +1,16 @@ +[tox] +minversion=2.3.1 +envlist = +    py{27,35}-{flake8,unit,pylint} +skipsdist=True +skip_missing_interpreters=True + +[testenv] +usedevelop=True +deps = +    -rtest-requirements.txt +    py35-flake8: flake8-bugbear +commands = +    flake8: python setup.py flake8 +    unit: python setup.py nosetests +    pylint: python setup.py lint | 
