diff --git a/.travis.yml b/.travis.yml index b33388b..3d4cee4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: - - "2.7" + - "3.5" install: "pip install -r requirements.txt" # command to run tests diff --git a/cirrus.conf b/cirrus.conf index 85952cb..e2e6457 100644 --- a/cirrus.conf +++ b/cirrus.conf @@ -1,10 +1,10 @@ [package] name = cirrus-cli -version = 2.0.2 +version = 3.0.0 description = cirrus development and build git extensions organization = cloudant version_file = src/cirrus/__init__.py -python_versions = 2 +python_versions = 3 [gitflow] develop_branch = new-development diff --git a/installer.sh b/installer.sh index d7136f3..64e04e5 100644 --- a/installer.sh +++ b/installer.sh @@ -8,9 +8,6 @@ # installs git alias commands # gets token for github access & updates .gitconfig -: ${CIRRUS_PYPI_URL?"is not set! Hint: https://user@us.ibm.com:password@na.artifactory.swg-devops.com/artifactory/api/pypi/wcp-sapi-pypi-virtual/simple)"} - -CIRRUS_PACKAGE="cirrus-cli==2.0.2" CIRRUS_INSTALL_DIR="${HOME}/.cirrus" CIRRUS_DEFAULT_USER="${USER}" @@ -40,7 +37,9 @@ cd ${LOCATION} virtualenv venv . venv/bin/activate -pip install --index-url=${CIRRUS_PYPI_URL} ${CIRRUS_PACKAGE} 1>> ${LOCATION}/install.log +# This depends on a properly configured pip.conf file. +# See https://github.com/cloudant/service_engineering/wiki/Using-JFrog-Artifactory +pip install cirrus-cli${CIRRUS_INSTALL_VERSION} 1>> ${LOCATION}/install.log export CIRRUS_HOME=${LOCATION} export VIRTUALENV_HOME=${LOCATION}/venv diff --git a/requirements.txt b/requirements.txt index acbc1d4..0650d82 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,7 @@ argparse==1.2.1 arrow==0.4.2 -Fabric==1.11.1 +Fabric==2.4.0 GitPython==2.1.9 -mock==1.0.1 nose==1.3.0 pep8==1.5.7 pylint==1.3.0 diff --git a/setup.py b/setup.py index bfa0e9f..951a1a7 100644 --- a/setup.py +++ b/setup.py @@ -5,13 +5,13 @@ Setup script for cirrus. """ -import ConfigParser +import configparser import setuptools # # read the cirrus conf for this package # -config = ConfigParser.RawConfigParser() +config = configparser.RawConfigParser() config.read("cirrus.conf") # diff --git a/src/cirrus/__init__.py b/src/cirrus/__init__.py index a1eb36e..94fb774 100644 --- a/src/cirrus/__init__.py +++ b/src/cirrus/__init__.py @@ -18,5 +18,5 @@ See the License for the specific language governing permissions and limitations under the License. """ -__version__="2.0.2" +__version__="3.0.0" diff --git a/src/cirrus/build.py b/src/cirrus/build.py index 2d098d6..bed38e6 100644 --- a/src/cirrus/build.py +++ b/src/cirrus/build.py @@ -18,7 +18,7 @@ from cirrus.configuration import load_configuration, get_pypi_auth from cirrus.pypirc import PypircFile from cirrus.logger import get_logger -from fabric.operations import local +from invoke import run LOGGER = get_logger() @@ -117,12 +117,12 @@ def execute_build(opts): if opts.clean and os.path.exists(venv_path): cmd = "rm -rf {0}".format(venv_path) LOGGER.info("Removing existing virtualenv: {0}".format(venv_path)) - local(cmd) + run(cmd) if not os.path.exists(venv_bin_path): cmd = "{0} {1}".format(venv_command, venv_path) LOGGER.info("Bootstrapping virtualenv: {0}".format(venv_path)) - local(cmd) + run(cmd) # custom pypi server pypi_server = config.pypi_url() @@ -170,7 +170,7 @@ def execute_build(opts): cmd += " {} ".format(pip_options) try: - local(cmd) + run(cmd) except OSError as ex: msg = ( "Error running pip install command during build\n" @@ -198,7 +198,7 @@ def execute_build(opts): for cmd in commands: LOGGER.info("Installing extra requirements... {}".format(cmd)) try: - local(cmd) + run(cmd) except OSError as ex: msg = ( "Error running pip install command extra " @@ -213,7 +213,7 @@ def execute_build(opts): LOGGER.info(msg) else: LOGGER.info('running python setup.py develop...') - local( + run( '. ./{0}/bin/activate && python setup.py develop'.format( config.venv_name() ) diff --git a/src/cirrus/chef_tools.py b/src/cirrus/chef_tools.py index 4318a36..fd4b2c4 100644 --- a/src/cirrus/chef_tools.py +++ b/src/cirrus/chef_tools.py @@ -86,7 +86,7 @@ def edit_chef_environment(server_url, cert, username, environment, attributes): env = chef.Environment(environment) overrides = env.override_attributes LOGGER.info("Editing Chef Server Environment: {} as {}".format(environment, username)) - for attr, new_value in attributes.iteritems(): + for attr, new_value in attributes.items(): LOGGER.info(" => Setting {}={}".format(attr, new_value)) set_dotted(overrides, attr, new_value) env.save() @@ -104,7 +104,7 @@ def edit_chef_role(server_url, cert, username, rolename, attributes): role = chef.Role(rolename) LOGGER.info("Editing Chef Server Role: {} as {}".format(rolename, username)) overrides = role.override_attributes - for attr, new_value in attributes.iteritems(): + for attr, new_value in attributes.items(): LOGGER.info(" => Setting {}={}".format(attr, new_value)) set_dotted(overrides, attr, new_value) role.save() @@ -191,7 +191,7 @@ def update_chef_environment(server_url, cert, username, environment, attributes, with r.feature_branch(feature_name, push=kwargs.get('push', False)): with r.edit_environment(environment, branch=r.current_branch_name) as env: LOGGER.info("Updating Chef Environment: {}".format(environment)) - for x, y in attributes.iteritems(): + for x, y in attributes.items(): LOGGER.info(" => Setting {}={}".format(x, y)) set_dotted(env['override_attributes'], x, y) diff --git a/src/cirrus/cirrus_setup.py b/src/cirrus/cirrus_setup.py index 35b48ac..84da0be 100644 --- a/src/cirrus/cirrus_setup.py +++ b/src/cirrus/cirrus_setup.py @@ -33,7 +33,7 @@ def ask_question(question, default=None, valid=None): to_ask += " [{0}]: ".format(default) else: to_ask += ": " - result = raw_input(to_ask) + result = input(to_ask) if result.strip() == '': if default is not None: result = default diff --git a/src/cirrus/configuration.py b/src/cirrus/configuration.py index 53e76eb..ed47a13 100644 --- a/src/cirrus/configuration.py +++ b/src/cirrus/configuration.py @@ -15,7 +15,7 @@ from cirrus.gitconfig import load_gitconfig from cirrus.environment import repo_directory import subprocess -import ConfigParser +import configparser import pluggage.registry @@ -52,7 +52,7 @@ def load(self): Reread the cirrus config file """ - self.parser = ConfigParser.RawConfigParser() + self.parser = configparser.RawConfigParser() self.parser.read(self.config_file) for section in self.parser.sections(): self.setdefault(section, {}) @@ -103,7 +103,7 @@ def has_gitconfig_param( return validator(self.gitconfig.get_param(section, param)) def list_gitconfig_params(self, section='cirrus'): - return self.gitconfig[section].keys() + return list(self.gitconfig[section].keys()) def has_section(self, section): return section in self diff --git a/src/cirrus/creds_plugin.py b/src/cirrus/creds_plugin.py index cdaf979..52f8e02 100644 --- a/src/cirrus/creds_plugin.py +++ b/src/cirrus/creds_plugin.py @@ -133,4 +133,4 @@ def credential_map(self): if __name__ == '__main__': p = CredsPlugin() - print p.credential_map() + print(p.credential_map()) diff --git a/src/cirrus/delegate.py b/src/cirrus/delegate.py index b694f91..91b97d6 100644 --- a/src/cirrus/delegate.py +++ b/src/cirrus/delegate.py @@ -80,14 +80,14 @@ def main(): args = sys.argv[1:] if len(args) == 0 or args[0] == '-h': # missing command or help - print format_help(commands) + print(format_help(commands)) exit_code = 0 else: command_path = "{0}/bin/{1}".format(home, args[0]) if not os.path.exists(command_path): msg = "Unknown command: {}".format(args[0]) - print msg - print format_help(commands) + print(msg) + print(format_help(commands)) exit_code = 127 else: exit_code = run_command([command_path, ] + args[1:]) diff --git a/src/cirrus/documentation_utils.py b/src/cirrus/documentation_utils.py index 6e56c57..126acb3 100644 --- a/src/cirrus/documentation_utils.py +++ b/src/cirrus/documentation_utils.py @@ -9,7 +9,7 @@ import sys import tarfile -from fabric.operations import local +from invoke import run import pluggage.registry from cirrus.configuration import load_configuration @@ -81,7 +81,7 @@ def build_docs(make_opts=None): # additional args were passed after --docs. Pass these to make cmd = 'cd {} && make {}'.format(docs_root, ' '.join(make_opts)) - local('. ./{}/bin/activate && {}'.format(config.venv_name(), cmd)) + run('. ./{}/bin/activate && {}'.format(config.venv_name(), cmd)) LOGGER.info('Build command was "{}"'.format(cmd)) diff --git a/src/cirrus/environment.py b/src/cirrus/environment.py index a4a6c37..8dfe6b1 100644 --- a/src/cirrus/environment.py +++ b/src/cirrus/environment.py @@ -31,7 +31,7 @@ def repo_directory(): outp, err = process.communicate() if process.returncode: return None - return outp.strip() + return outp.strip().decode('utf-8') def cirrus_home(): diff --git a/src/cirrus/fabric_helpers.py b/src/cirrus/fabric_helpers.py index 79adf2d..392e275 100644 --- a/src/cirrus/fabric_helpers.py +++ b/src/cirrus/fabric_helpers.py @@ -1,52 +1,36 @@ #!/usr/bin/env python """ -_fabric_helpers_ - Utils/helpers for fabric api - """ -import copy -from fabric.api import env +from fabric.config import Config +from fabric.connection import Connection -class FabricHelper(object): +class FabricHelper(Connection): """ - _FabricHelper_ - - Context helper to set and clear fabric env - to run a command on a given host + Simplified fabric Connection Example usage; - with FabricHelper('pypi.cloudant.com', 'evansde77', '/Users/david/.ssh/id_rsa'): - run('/bin/date') + with FabricHelper('pypi.cloudant.com', 'evansde77', '/Users/david/.ssh/id_rsa') as fh: + fh.run('/bin/date') Will run the date command on pypi.cloudant.com as evansde77 using the key file specified """ def __init__(self, hostname, username, ssh_key): - self.hostname = hostname - self.username = username - self.ssh_key = ssh_key - # save settings - self.hostname_cache = None - self.username_cache = None - self.ssh_key_cache = None - - def __enter__(self): - self.hostname_cache = copy.copy(env.host_string) - self.username_cache = copy.copy(env.user) - self.ssh_key_cache = copy.copy(env.key_filename) - - env.host_string = self.hostname - env.user = self.username - env.key_filename = self.ssh_key - return self - - def __exit__(self, *args): - env.host_string = self.hostname_cache - env.user = self.username_cache - env.key_filename = self.ssh_key_cache - - - + config = Config(key_filename=ssh_key) + super().__init__(hostname, user=username, config=config) + + def put(self, local, remote, use_sudo=False): + """ + Adds sudo implementation that was removed in fabric2 + + :param bool use_sudo: if True, file is first moved to user's home + directory and then moved to the remote location + """ + if use_sudo: + super().put(local) + self.sudo('mv {} {}'.format(local, remote)) + else: + super().put(local, remote) diff --git a/src/cirrus/feature.py b/src/cirrus/feature.py index af9d78f..040eb43 100644 --- a/src/cirrus/feature.py +++ b/src/cirrus/feature.py @@ -113,10 +113,10 @@ def list_feature_branches(opts): list unmerged feature branches """ repo_dir = os.getcwd() - print "unmerged feature branches:" + print("unmerged feature branches:") with GitHubContext(repo_dir) as ghc: for x in ghc.iter_git_feature_branches(merged=False): - print x + print(x) def main(): diff --git a/src/cirrus/git_tools.py b/src/cirrus/git_tools.py index e32042b..ce583a5 100644 --- a/src/cirrus/git_tools.py +++ b/src/cirrus/git_tools.py @@ -185,7 +185,7 @@ def push(repo_dir): # Check to make sure that we haven't errored out. for r in ret: if r.flags >= r.ERROR: - raise RuntimeError(unicode(r.summary)) + raise RuntimeError(str(r.summary)) return ret @@ -329,17 +329,17 @@ def format_commit_messages(rows): --- DATETIME: COMMIT MESSAGE """ - result = [u" - Commit History:"] + result = [" - Commit History:"] for author, commits in itertools.groupby(rows, lambda x: x['committer']): - result.append(u" -- Author: {0}".format(author)) + result.append(" -- Author: {0}".format(author)) sorted_commits = sorted( [ c for c in commits ], key=lambda x: x['date'], reverse=True ) result.extend( - u' --- {0}: {1}'.format(commit['date'],commit['message']) + ' --- {0}: {1}'.format(commit['date'],commit['message']) for commit in sorted_commits ) diff --git a/src/cirrus/gitconfig.py b/src/cirrus/gitconfig.py index cfc58d6..82023f2 100644 --- a/src/cirrus/gitconfig.py +++ b/src/cirrus/gitconfig.py @@ -36,7 +36,7 @@ def shell_command(command): if process.returncode != 0: raise RuntimeError(stdout) else: - return "\n".join(stdout.splitlines()) + return "\n".join(stdout.decode('utf-8').splitlines()) class GitConfigSection(object): @@ -50,15 +50,15 @@ def __init__(self, config, section): def keys(self): """list parameter keys in section""" - return dict(self.config)[self.section].keys() + return list(dict(self.config)[self.section].keys()) def values(self): """return all values in section""" - return dict(self.config)[self.section].values() + return list(dict(self.config)[self.section].values()) def items(self): """return key, value tuples of items in section""" - return dict(self.config)[self.section].items() + return list(dict(self.config)[self.section].items()) def get(self, key, default=None): return dict(self.config)[self.section].get(key, default) @@ -75,7 +75,7 @@ def __delitem__(self, key): def __str__(self): result = [ "{0}.{1}={2}".format(self.section, k, v) - for k, v in self.items() + for k, v in list(self.items()) ] return '\n'.join(result) @@ -108,7 +108,7 @@ def parse(self): @property def sections(self): """list sections in the gitconfig""" - return self.keys() + return list(self.keys()) def __getitem__(self, key): """override getitem operator to wrap section in GitConfigSection""" diff --git a/src/cirrus/github_tools.py b/src/cirrus/github_tools.py index 9618c6f..88491c6 100644 --- a/src/cirrus/github_tools.py +++ b/src/cirrus/github_tools.py @@ -128,7 +128,7 @@ def set_branch_state(self, state, context, branch=None): if branch is None: branch = self.repo.active_branch.name - LOGGER.info(u"Setting CI status for branch {} to {}".format(branch, state)) + LOGGER.info("Setting CI status for branch {} to {}".format(branch, state)) sha = self.repo.head.commit.hexsha @@ -138,7 +138,7 @@ def set_branch_state(self, state, context, branch=None): # probably be to push a detached head. push(self.repo_dir) except RuntimeError as ex: - if "rejected" not in unicode(ex): + if "rejected" not in str(ex): raise url = "https://api.github.com/repos/{org}/{repo}/statuses/{sha}".format( @@ -211,7 +211,7 @@ def push_branch(self, branch_name=None): # Check to make sure that we haven't errored out. for r in ret: if r.flags >= r.ERROR: - raise RuntimeError(unicode(r.summary)) + raise RuntimeError(str(r.summary)) return ret def push_branch_with_retry(self, branch_name=None, attempts=300, cooloff=2): @@ -338,7 +338,7 @@ def iter_git_feature_branches(self, merged=False): """ feature_pfix = "remotes/origin/{}".format(self.config.gitflow_feature_prefix()) branches = self.iter_git_branches(merged) - branches = itertools.ifilter(lambda x: x.startswith(feature_pfix), branches) + branches = filter(lambda x: x.startswith(feature_pfix), branches) return branches def pull_requests(self, user=None): @@ -365,7 +365,7 @@ def pull_requests(self, user=None): data = resp.json() gen = iter(data) if user: - gen = itertools.ifilter(lambda x: x['user']['login'] == user, gen) + gen = filter(lambda x: x['user']['login'] == user, gen) for row in gen: yield row @@ -477,7 +477,7 @@ def current_branch_mark_status(repo_dir, state): """ - LOGGER.info(u"Setting CI status for current branch to {}".format(state)) + LOGGER.info("Setting CI status for current branch to {}".format(state)) config = load_configuration() token = get_github_auth()[1] @@ -489,7 +489,7 @@ def current_branch_mark_status(repo_dir, state): # probably be to push a detached head. push(repo_dir) except RuntimeError as ex: - if "rejected" not in unicode(ex): + if "rejected" not in str(ex): raise url = "https://api.github.com/repos/{org}/{repo}/statuses/{sha}".format( diff --git a/src/cirrus/package.py b/src/cirrus/package.py index fb97aa2..bdbc21a 100644 --- a/src/cirrus/package.py +++ b/src/cirrus/package.py @@ -20,7 +20,7 @@ import sys import pystache -import ConfigParser +import configparser import pluggage.registry import cirrus.templates @@ -62,7 +62,7 @@ def list_plugins(): load_modules=['cirrus.plugins.editors'] ) return [ - k for k in factory.registry.keys() + k for k in list(factory.registry.keys()) if k != "EditorPlugin" ] @@ -332,7 +332,7 @@ def write_cirrus_conf(opts, version_file): cirrus_conf = os.path.join(opts.repo, 'cirrus.conf') LOGGER.info("setting up cirrus.conf: {}".format(cirrus_conf)) backup_file(cirrus_conf) - config = ConfigParser.ConfigParser() + config = configparser.ConfigParser() config.add_section('package') config.set('package', 'name', opts.package) config.set('package', 'version', opts.version) @@ -352,10 +352,10 @@ def write_cirrus_conf(opts, version_file): config.set('gitflow', 'feature_branch_prefix', 'feature/') config.add_section('test-default') - config.set('test-default', 'TESTDIRHERE') + config.set('test-default', 'where', 'TESTDIRHERE') config.add_section('quality') - config.set('quality', 'threshold', 10) + config.set('quality', 'threshold', '10') with open(cirrus_conf, 'w') as handle: config.write(handle) diff --git a/src/cirrus/plugins/creds/__init__.py b/src/cirrus/plugins/creds/__init__.py index 427425a..7061a9d 100644 --- a/src/cirrus/plugins/creds/__init__.py +++ b/src/cirrus/plugins/creds/__init__.py @@ -6,4 +6,4 @@ in flat files and use password managers etc where available """ -import default +from . import default diff --git a/src/cirrus/plugins/creds/keyring.py b/src/cirrus/plugins/creds/keyring.py index a6eaff8..aeeeeb3 100644 --- a/src/cirrus/plugins/creds/keyring.py +++ b/src/cirrus/plugins/creds/keyring.py @@ -3,7 +3,7 @@ keyring module plugin """ -import keyring +from . import keyring from cirrus.creds_plugin import CredsPlugin diff --git a/src/cirrus/plugins/deployers/__init__.py b/src/cirrus/plugins/deployers/__init__.py index 4869de4..07afa8b 100644 --- a/src/cirrus/plugins/deployers/__init__.py +++ b/src/cirrus/plugins/deployers/__init__.py @@ -5,4 +5,4 @@ Plugins for the deploy command """ -import chef +from . import chef diff --git a/src/cirrus/plugins/deployers/chef.py b/src/cirrus/plugins/deployers/chef.py index 5360fa1..4b73cda 100644 --- a/src/cirrus/plugins/deployers/chef.py +++ b/src/cirrus/plugins/deployers/chef.py @@ -21,7 +21,6 @@ """ import os -from fabric.operations import run from cirrus.fabric_helpers import FabricHelper from cirrus.logger import get_logger from cirrus.deploy_plugins import Deployer @@ -120,8 +119,12 @@ def run_chef_client(self, opts, nodes): for node in nodes: LOGGER.info("Running chef-client on {}".format(node)) - with FabricHelper(node, opts['chef_client_user'], opts['chef_client_keyfile']): - run('sudo chef-client') + with FabricHelper( + node, + opts['chef_client_user'], + opts['chef_client_keyfile'] + ) as fh: + fh.run('sudo chef-client') def _find_nodes(self, args): """ diff --git a/src/cirrus/plugins/editors/__init__.py b/src/cirrus/plugins/editors/__init__.py index 49271e1..8a30b91 100644 --- a/src/cirrus/plugins/editors/__init__.py +++ b/src/cirrus/plugins/editors/__init__.py @@ -11,4 +11,4 @@ whatever the hell vi does... """ -import sublime +from . import sublime diff --git a/src/cirrus/plugins/publishers/__init__.py b/src/cirrus/plugins/publishers/__init__.py index cbeba1a..6911b2d 100644 --- a/src/cirrus/plugins/publishers/__init__.py +++ b/src/cirrus/plugins/publishers/__init__.py @@ -5,5 +5,5 @@ Documentation publisher plugins """ -import doc_file_server -import jenkins +from . import doc_file_server +from . import jenkins diff --git a/src/cirrus/plugins/publishers/doc_file_server.py b/src/cirrus/plugins/publishers/doc_file_server.py index 3ee4d04..874c7ee 100644 --- a/src/cirrus/plugins/publishers/doc_file_server.py +++ b/src/cirrus/plugins/publishers/doc_file_server.py @@ -1,11 +1,7 @@ #!/usr/bin/env python """ -_doc_file_server_ - Publisher plugin that uses fabric to do a remote put - """ -from fabric.operations import put from cirrus.fabric_helpers import FabricHelper from cirrus.logger import get_logger from cirrus.publish_plugins import Publisher @@ -68,6 +64,5 @@ def publish(self, doc_artifact): use_sudo = True LOGGER.info("Uploading {0} to {1}".format(doc_artifact, fs_url)) - with FabricHelper(fs_url, fs_username, fs_keyfile): - # fabric put the file onto the file server - put(doc_artifact, fs_upload_path, use_sudo=use_sudo) + with FabricHelper(fs_url, fs_username, fs_keyfile) as fh: + fh.put(doc_artifact, fs_upload_path, use_sudo=use_sudo) diff --git a/src/cirrus/plugins/publishers/jenkins.py b/src/cirrus/plugins/publishers/jenkins.py index 0997345..7d9ee1a 100644 --- a/src/cirrus/plugins/publishers/jenkins.py +++ b/src/cirrus/plugins/publishers/jenkins.py @@ -88,7 +88,7 @@ def publish(self, doc_artifact): # stores values internally as strings if jenkins_config.get('extra_vars', 'False').lower() == 'true': extra_vars = self.package_conf.get('jenkins_docs_extra_vars', {}) - for k, v in extra_vars.iteritems(): + for k, v in extra_vars.items(): build_params['parameter'].append({"name": k, "value": v}) payload = MultipartEncoder( diff --git a/src/cirrus/plugins/uploaders/__init__.py b/src/cirrus/plugins/uploaders/__init__.py index b3c0a86..e467692 100644 --- a/src/cirrus/plugins/uploaders/__init__.py +++ b/src/cirrus/plugins/uploaders/__init__.py @@ -5,5 +5,5 @@ Release uploader plugins """ -import fabric_put -import pypi +from . import fabric_put +from . import pypi diff --git a/src/cirrus/plugins/uploaders/fabric_put.py b/src/cirrus/plugins/uploaders/fabric_put.py index 864f1a2..cb5a7c4 100644 --- a/src/cirrus/plugins/uploaders/fabric_put.py +++ b/src/cirrus/plugins/uploaders/fabric_put.py @@ -36,6 +36,5 @@ def upload(self, opts, build_artifact): package_dir = pypi_conf['pypi_upload_path'] LOGGER.info("Uploading {0} to {1}".format(build_artifact, pypi_url)) - with FabricHelper(pypi_url, pypi_user, pypi_auth['ssh_key']): - # fabric put the file onto the pypi server - put(build_artifact, package_dir, use_sudo=opts.pypi_sudo) + with FabricHelper(pypi_url, pypi_user, pypi_auth['ssh_key']) as fh: + fh.put(build_artifact, package_dir, use_sudo=opts.pypi_sudo) diff --git a/src/cirrus/plugins/uploaders/pypi.py b/src/cirrus/plugins/uploaders/pypi.py index 1d0221a..cb5132d 100644 --- a/src/cirrus/plugins/uploaders/pypi.py +++ b/src/cirrus/plugins/uploaders/pypi.py @@ -6,7 +6,7 @@ """ import os -from fabric.operations import local +from invoke import run from cirrus.upload_plugins import Uploader from cirrus.logger import get_logger @@ -36,4 +36,4 @@ def upload(self, opts, build_artifact): pypi_url = opts.pypi_url command += ' -r {}'.format(pypi_url) LOGGER.info("Executing {} ...".format(command)) - local(command) + run(command) diff --git a/src/cirrus/plusone.py b/src/cirrus/plusone.py index 3bed6d0..befb033 100644 --- a/src/cirrus/plusone.py +++ b/src/cirrus/plusone.py @@ -11,7 +11,7 @@ import json import argparse import requests -from configuration import get_github_auth +from .configuration import get_github_auth class GitHubHelper(object): @@ -182,9 +182,9 @@ def main(): gh = GitHubHelper() if not (opts.id or opts.branch): - print opts.id, opts.branch + print(opts.id, opts.branch) msg = "Must supply either pull request ID or branch name" - print msg + print(msg) sys.exit(1) if opts.branch is not None: diff --git a/src/cirrus/prestage.py b/src/cirrus/prestage.py index 3541d6f..7c266b6 100644 --- a/src/cirrus/prestage.py +++ b/src/cirrus/prestage.py @@ -91,13 +91,13 @@ def main(): reqs[req.name] = versions[0] # prestage section contains a map of package name: repo - for req, repo in prestage_params.iteritems(): + for req, repo in prestage_params.items(): msg = "Prestaging repo for requirement {req} from {repo}" tag = reqs.get(req) if tag is not None: msg += " with tag {tag}" msg.format(req=req, repo=repo, tag=tag) - print msg + print(msg) local_repo = os.path.join(repo_cache, req) git_clone_repo(repo, local_repo, tag=reqs.get(req)) install_from_repo(venv_command, local_repo) diff --git a/src/cirrus/pylint_tools.py b/src/cirrus/pylint_tools.py index 77e0190..4a55ef0 100644 --- a/src/cirrus/pylint_tools.py +++ b/src/cirrus/pylint_tools.py @@ -1,16 +1,12 @@ #!/usr/bin/env python """ -_pylint_tools_ - Wrapper for pylint execution - - """ import os import re import sys -from fabric.operations import local, settings, hide +from invoke import run from cirrus.logger import get_logger @@ -32,14 +28,11 @@ def pylint_file(filenames, **kwargs): command = command + ' '.join(filenames) - # we use fabric to run the pylint command, hiding the normal fab - # output and warnings - with hide('output', 'running', 'warnings'), settings(warn_only=True): - result = local(command, capture=True) - + result = run(command, hide=True, warn=True) + output = result.stdout score = 0.0 # parse the output from pylint for the score - for line in result.split('\n'): + for line in output.split('\n'): if re.match("E....:.", line): LOGGER.info(line) if "Your code has been rated at" in line: @@ -51,20 +44,15 @@ def pylint_file(filenames, **kwargs): def pyflakes_file(filenames, verbose=False): """ - _pyflakes_file_ - - Appyly pyflakes to file specified, + Applies pyflakes to file specified, return (filenames, score) """ command = 'pyflakes ' + ' '.join(filenames) - # we use fabric to run the pyflakes command, hiding the normal fab - # output and warnings - with hide('output', 'running', 'warnings'), settings(warn_only=True): - result = local(command, capture=True) - + result = run(command, hide=True, warn=True) + output = result.stdout flakes = 0 - data = [x for x in result.split('\n') if x.strip()] + data = [x for x in output.split('\n') if x.strip()] if len(data) != 0: #We have at least one flake, find the rest flakes = count_flakes(data, verbose) + 1 diff --git a/src/cirrus/pypirc.py b/src/cirrus/pypirc.py index d957bc3..2153807 100644 --- a/src/cirrus/pypirc.py +++ b/src/cirrus/pypirc.py @@ -4,7 +4,7 @@ """ import os -import ConfigParser +import configparser class PypircFile(dict): @@ -22,7 +22,7 @@ def exists(self): def load(self): """parse config file into self""" - self.parser = ConfigParser.RawConfigParser() + self.parser = configparser.RawConfigParser() self.parser.read(self.config_file) for section in self.parser.sections(): self.setdefault(section, {}) diff --git a/src/cirrus/quality_control.py b/src/cirrus/quality_control.py index 67ec234..8fd9250 100644 --- a/src/cirrus/quality_control.py +++ b/src/cirrus/quality_control.py @@ -6,10 +6,10 @@ import sys from argparse import ArgumentParser -from git_tools import get_diff_files -from pylint_tools import pep8_file -from pylint_tools import pyflakes_file -from pylint_tools import pylint_file +from .git_tools import get_diff_files +from .pylint_tools import pep8_file +from .pylint_tools import pyflakes_file +from .pylint_tools import pylint_file from cirrus.configuration import load_configuration from cirrus.logger import get_logger diff --git a/src/cirrus/release.py b/src/cirrus/release.py index 3b6bce0..db790f6 100644 --- a/src/cirrus/release.py +++ b/src/cirrus/release.py @@ -12,7 +12,7 @@ import itertools import shutil from collections import OrderedDict -from fabric.operations import local +from invoke import run import pluggage.registry import argparse @@ -185,7 +185,7 @@ def release_config(config, opts): if 'release' not in config: release_config = release_config_defaults else: - for key, val in release_config_defaults.iteritems(): + for key, val in release_config_defaults.items(): release_config[key] = config.get_param('release', key, val) release_config['wait_on_ci'] = convert_bool(release_config['wait_on_ci']) @@ -606,18 +606,18 @@ def merge_release(opts): expected_branch = release_branch_name(config) if release_branch != expected_branch: msg = ( - u"Not on the expected release branch according " - u"to cirrus.conf\n Expected:{0} but on {1}" + "Not on the expected release branch according " + "to cirrus.conf\n Expected:{0} but on {1}" ).format(expected_branch, release_branch) LOGGER.error(msg) raise RuntimeError(msg) # merge release branch into master - LOGGER.info(u"Tagging and pushing {0}".format(tag)) + LOGGER.info("Tagging and pushing {0}".format(tag)) if opts.skip_master: - LOGGER.info(u'Skipping merging to {}'.format(master)) + LOGGER.info('Skipping merging to {}'.format(master)) if opts.skip_develop: - LOGGER.info(u'Skipping merging to {}'.format(develop)) + LOGGER.info('Skipping merging to {}'.format(develop)) if opts.log_status: ghc.log_branch_status(master) @@ -628,14 +628,14 @@ def merge_release(opts): # # wait on release branch CI success # - LOGGER.info(u"Waiting on CI build for {0}".format(release_branch)) + LOGGER.info("Waiting on CI build for {0}".format(release_branch)) ghc.wait_on_gh_status( sha, timeout=rel_conf['wait_on_ci_timeout'], interval=rel_conf['wait_on_ci_interval'] ) - LOGGER.info(u"Merging {} into {}".format(release_branch, master)) + LOGGER.info("Merging {} into {}".format(release_branch, master)) ghc.pull_branch(master) ghc.merge_branch(release_branch) sha = ghc.repo.head.ref.commit.hexsha @@ -645,7 +645,7 @@ def merge_release(opts): # # wait on release branch CI success # - LOGGER.info(u"Waiting on CI build for {0}".format(master)) + LOGGER.info("Waiting on CI build for {0}".format(master)) ghc.wait_on_gh_status( sha, timeout=rel_conf['wait_on_ci_timeout'], @@ -653,7 +653,7 @@ def merge_release(opts): ) if rel_conf['update_github_context']: for ctx in rel_conf['github_context_string']: - LOGGER.info(u"Setting {} for {}".format( + LOGGER.info("Setting {} for {}".format( ctx, sha) ) @@ -665,7 +665,7 @@ def merge_release(opts): if rel_conf['update_master_github_context']: for ctx in rel_conf['github_master_context_string']: - LOGGER.info(u"Setting {} for {}".format( + LOGGER.info("Setting {} for {}".format( ctx, sha) ) @@ -678,10 +678,10 @@ def merge_release(opts): attempts=rel_conf['push_retry_attempts'], cooloff=rel_conf['push_retry_cooloff'] ) - LOGGER.info(u"Tagging {} as {}".format(master, tag)) + LOGGER.info("Tagging {} as {}".format(master, tag)) ghc.tag_release(tag, master) - LOGGER.info(u"Merging {} into {}".format(release_branch, develop)) + LOGGER.info("Merging {} into {}".format(release_branch, develop)) if opts.log_status: ghc.log_branch_status(develop) if not opts.skip_develop: @@ -693,7 +693,7 @@ def merge_release(opts): # # wait on release branch CI success # - LOGGER.info(u"Waiting on CI build for {0}".format(develop)) + LOGGER.info("Waiting on CI build for {0}".format(develop)) ghc.wait_on_gh_status( sha, timeout=rel_conf['wait_on_ci_timeout'], @@ -701,7 +701,7 @@ def merge_release(opts): ) if rel_conf['update_github_context']: for ctx in rel_conf['github_context_string']: - LOGGER.info(u"Setting {} for {}".format( + LOGGER.info("Setting {} for {}".format( ctx, sha) ) @@ -713,7 +713,7 @@ def merge_release(opts): if rel_conf['update_develop_github_context']: for ctx in rel_conf['github_develop_context_string']: - LOGGER.info(u"Setting {} for {}".format( + LOGGER.info("Setting {} for {}".format( ctx, sha) ) @@ -742,7 +742,7 @@ def build_release(opts): LOGGER.info("Building release...") config = load_configuration() - local(cmd) + run(cmd) build_artifact = artifact_name(config, tag=tag) if not os.path.exists(build_artifact): msg = "Expected build artifact: {0} Not Found".format(build_artifact) @@ -786,8 +786,16 @@ def build_and_upload(opts): 'bin', 'python' ) - cmd = '{} setup.py egg_info {} bdist_wheel upload -r local' - local(cmd.format(venv_py_path, tag_option), capture=True) + cmd = '{} setup.py egg_info {} bdist_wheel upload -r local'.format( + venv_py_path, + tag_option + ) + result = run(cmd, hide='stdout', echo=True) + try: + submit_msg = result.stdout.split('\n')[-3] + print(submit_msg) + except Exception: + print('Unable to print submit message') LOGGER.info("...Build and upload complete") @@ -817,7 +825,7 @@ def update_requirements(path, versions): # overwrite original requirements.txt with updated version fh.seek(0) fh.writelines(['{}=={}'.format(pkg, version) - for pkg, version in reqs.iteritems()]) + for pkg, version in reqs.items()]) fh.truncate() diff --git a/src/cirrus/review.py b/src/cirrus/review.py index 3334b54..2479ef9 100644 --- a/src/cirrus/review.py +++ b/src/cirrus/review.py @@ -102,9 +102,9 @@ def list_prs(opts): """ repo_dir = os.getcwd() with GitHubContext(repo_dir) as ghc: - print " ID, User, Title" + print(" ID, User, Title") for pr in ghc.pull_requests(user=opts.user): - print pr['number'], pr['user']['login'], pr['title'] + print(pr['number'], pr['user']['login'], pr['title']) def get_pr(opts): diff --git a/src/cirrus/selfupdate.py b/src/cirrus/selfupdate.py index 85d5ca0..bcc6382 100644 --- a/src/cirrus/selfupdate.py +++ b/src/cirrus/selfupdate.py @@ -15,7 +15,7 @@ import inspect import contextlib -from fabric.operations import local +from invoke import run import cirrus from cirrus.configuration import load_configuration @@ -139,11 +139,11 @@ def setup_develop(config): """ LOGGER.info("running setup.py develop...") - local( + run( 'git cirrus build --upgrade' ) - local( + run( ' . ./{0}/bin/activate && python setup.py develop'.format( config.venv_name() ) @@ -156,7 +156,7 @@ def pip_install(version): pip_req = 'cirrus-cli=={0}'.format(version) venv_name = os.path.basename(virtualenv_home()) LOGGER.info("running pip upgrade...") - local( + run( ' . ./{0}/bin/activate && pip install --upgrade {1}'.format( venv_name, pip_req ) diff --git a/src/cirrus/test.py b/src/cirrus/test.py index 50ad9c7..74dc785 100644 --- a/src/cirrus/test.py +++ b/src/cirrus/test.py @@ -5,7 +5,7 @@ ''' import sys -from fabric.operations import local +from invoke import run from argparse import ArgumentParser from cirrus.configuration import load_configuration @@ -49,17 +49,16 @@ def build_parser(argslist): def nose_run(config, opts): """ - _nose_test_ - Locally activate vitrualenv and run tests via nose """ where = config.test_where(opts.suite) - local( + run( '. ./{0}/bin/activate && nosetests -w {1} {2}'.format( config.venv_name(), where, opts.options - ) + ), + warn=True ) @@ -70,7 +69,7 @@ def tox_run(config, opts): activate venv and run tox test suite """ - local( + run( '. ./{0}/bin/activate && tox {1}'.format( config.venv_name(), opts.options diff --git a/src/cirrus/utils.py b/src/cirrus/utils.py index e79ccc4..b19d70b 100644 --- a/src/cirrus/utils.py +++ b/src/cirrus/utils.py @@ -39,7 +39,7 @@ def update_file(filename, sentinel, text): with codecs.open(filename, 'r', encoding='utf-8') as handle: content = handle.read() - replacement = u"{0}\n\n{1}".format(sentinel, text) + replacement = "{0}\n\n{1}".format(sentinel, text) content = content.replace(sentinel, replacement, 1) with codecs.open(filename, 'w', encoding='utf-8') as handle: handle.write(content) diff --git a/tests/unit/cirrus/build_tests.py b/tests/unit/cirrus/build_tests.py index ee046b1..3a7e389 100644 --- a/tests/unit/cirrus/build_tests.py +++ b/tests/unit/cirrus/build_tests.py @@ -3,13 +3,12 @@ build command test coverage """ -import unittest -import mock +from unittest import TestCase, mock from cirrus.build import execute_build, build_parser -class BuildParserTests(unittest.TestCase): +class BuildParserTests(TestCase): """test build_parser""" def test_build_parser(self): @@ -25,7 +24,7 @@ def test_build_parser(self): argv = ['build', '--no-setup-develop'] opts = build_parser(argv) - self.failUnless(opts.nosetupdevelop) + self.assertTrue(opts.nosetupdevelop) argv = [ 'build', @@ -40,12 +39,12 @@ def test_build_parser(self): ) -class BuildCommandTests(unittest.TestCase): +class BuildCommandTests(TestCase): """test coverage for build command code""" def setUp(self): """set up patchers and mocks""" self.conf_patcher = mock.patch('cirrus.build.load_configuration') - self.local_patcher = mock.patch('cirrus.build.local') + self.local_patcher = mock.patch('cirrus.build.run') self.os_path_exists_patcher = mock.patch('cirrus.build.os.path.exists') self.os_cwd_patcher = mock.patch('cirrus.build.os.getcwd') self.pypi_auth_patcher = mock.patch('cirrus.build.get_pypi_auth') @@ -224,7 +223,3 @@ def test_execute_build_with_pypi_upgrade(self): mock.call('CWD/venv/bin/pip install -i https://PYPIUSERNAME:TOKEN@PYPIURL/simple --upgrade -r requirements.txt'), mock.call('. ./venv/bin/activate && python setup.py develop') ]) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unit/cirrus/configuration_test.py b/tests/unit/cirrus/configuration_test.py index 3d6e881..c72673b 100644 --- a/tests/unit/cirrus/configuration_test.py +++ b/tests/unit/cirrus/configuration_test.py @@ -4,9 +4,9 @@ """ import os import unittest -import ConfigParser +import configparser import tempfile -import mock +from unittest import mock from cirrus.plugins.creds.default import Default from cirrus.configuration import load_configuration @@ -23,7 +23,7 @@ def setUp(self): self.test_file = os.path.join(self.dir, 'cirrus.conf') self.gitconfig = os.path.join(self.dir, '.gitconfig') - parser = ConfigParser.RawConfigParser() + parser = configparser.RawConfigParser() parser.add_section('package') parser.add_section('gitflow') parser.set('package', 'name', 'cirrus_tests') @@ -36,7 +36,7 @@ def setUp(self): with open(self.test_file, 'w') as handle: parser.write(handle) - gitconf = ConfigParser.RawConfigParser() + gitconf = configparser.RawConfigParser() gitconf.add_section('cirrus') gitconf.set('cirrus', 'credential-plugin', 'default') with open(self.gitconfig, 'w') as handle: @@ -73,8 +73,8 @@ def test_reading(self, mock_shell): self.assertEqual(config.release_notes(), (None, None)) self.assertEqual(config.version_file(), (None, '__version__')) - self.failUnless(config.credentials is not None) - self.failUnless(isinstance(config.credentials, Default)) + self.assertIsNotNone(config.credentials) + self.assertTrue(isinstance(config.credentials, Default)) # test updating version config.update_package_version('1.2.4') @@ -89,16 +89,18 @@ def test_reading_missing(self, mock_pop, mock_shell): mock_result = mock.Mock() mock_result.communicate = mock.Mock() mock_result.returncode = 0 - mock_result.communicate.return_value = (self.dir, None) + mock_result.communicate.return_value = (self.dir.encode(), None) mock_pop.return_value = mock_result mock_shell.return_value = self.gitconf_str config = load_configuration(package_dir="womp") - self.failUnless(mock_result.communicate.called) - mock_pop.assert_has_calls(mock.call(['git', 'rev-parse', '--show-toplevel'], stdout=-1)) + self.assertTrue(mock_result.communicate.called) + mock_pop.assert_has_calls([ + mock.call(['git', 'rev-parse', '--show-toplevel'], stdout=-1) + ]) self.assertEqual(config.package_version(), '1.2.3') self.assertEqual(config.package_name(), 'cirrus_tests') - self.failUnless(mock_shell.called) + self.assertTrue(mock_shell.called) mock_shell.assert_has_calls([ mock.call('git config --file {} -l'.format(self.gitconfig)) ]) @@ -107,10 +109,10 @@ def test_configuration_map(self): """test building config mapping""" config = load_configuration(package_dir=self.dir, gitconfig_file=self.gitconfig) mapping = config.configuration_map() - self.failUnless('cirrus' in mapping) - self.failUnless('credentials' in mapping['cirrus']) - self.failUnless('configuration' in mapping['cirrus']) - self.failUnless('github_credentials' in mapping['cirrus']['credentials']) + self.assertIn('cirrus', mapping) + self.assertIn('credentials', mapping['cirrus']) + self.assertIn('configuration', mapping['cirrus']) + self.assertIn('github_credentials', mapping['cirrus']['credentials']) self.assertEqual( mapping['cirrus']['credentials']['github_credentials'], {'github_user': None, 'github_token': None} diff --git a/tests/unit/cirrus/creds_plugin_tests.py b/tests/unit/cirrus/creds_plugin_tests.py index 08b1b93..f8504ce 100644 --- a/tests/unit/cirrus/creds_plugin_tests.py +++ b/tests/unit/cirrus/creds_plugin_tests.py @@ -16,11 +16,11 @@ def test_creds_plugin(self): plugin = CredsPlugin() methods = [x[0] for x in plugin.credential_methods()] mapping = plugin.credential_map() - self.failUnless(all(m in mapping for m in methods)) + self.assertTrue(all(m in mapping for m in methods)) gh_defaults = plugin.github_credentials() - self.failUnless('github_user' in gh_defaults) - self.failUnless('github_token' in gh_defaults) + self.assertIn('github_user', gh_defaults) + self.assertIn('github_token', gh_defaults) self.assertEqual(gh_defaults['github_user'], None) self.assertEqual(gh_defaults['github_token'], None) diff --git a/tests/unit/cirrus/default_creds_tests.py b/tests/unit/cirrus/default_creds_tests.py index f6dad34..c41d0f3 100644 --- a/tests/unit/cirrus/default_creds_tests.py +++ b/tests/unit/cirrus/default_creds_tests.py @@ -5,7 +5,7 @@ import os import unittest import tempfile -import ConfigParser +import configparser from cirrus.plugins.creds.default import Default @@ -19,7 +19,7 @@ def setUp(self): self.dir = tempfile.mkdtemp() self.gitconfig = os.path.join(self.dir, '.gitconfig') - gitconf = ConfigParser.RawConfigParser() + gitconf = configparser.RawConfigParser() gitconf.add_section('cirrus') gitconf.set('cirrus', 'credential-plugin', 'default') gitconf.set('cirrus', 'github-user', 'steve') @@ -37,8 +37,8 @@ def test_reading_gitconfig(self): """test reading in the fake gitconfig and accessing data""" plugin = Default(gitconfig_file=self.gitconfig) gh = plugin.github_credentials() - self.failUnless('github_user' in gh) - self.failUnless('github_token' in gh) + self.assertIn('github_user', gh) + self.assertIn('github_token', gh) self.assertEqual(gh['github_user'], 'steve') self.assertEqual(gh['github_token'], 'steves token') diff --git a/tests/unit/cirrus/docker_test.py b/tests/unit/cirrus/docker_test.py index 01488bb..80abbe9 100644 --- a/tests/unit/cirrus/docker_test.py +++ b/tests/unit/cirrus/docker_test.py @@ -2,16 +2,14 @@ """ docker command unittests """ - -import unittest -import mock +from unittest import TestCase, mock import cirrus.docker as dckr from cirrus.configuration import Configuration from subprocess import CalledProcessError -class DockerFunctionTests(unittest.TestCase): +class DockerFunctionTests(TestCase): """ test coverage for docker command module functions """ @@ -58,12 +56,12 @@ def tearDown(self): def test_docker_build(self): """test straight docker build call""" dckr.docker_build(self.opts, self.config) - self.failUnless(self.mock_subp.check_output.called) - self.mock_subp.check_output.assert_has_calls( + self.assertTrue(self.mock_subp.check_output.called) + self.mock_subp.check_output.assert_has_calls([ mock.call( ['docker', 'build', '-t', 'unittesting/unittesting:1.2.3', 'vm/docker_image'] ) - ) + ]) @mock.patch('cirrus.docker.ds') def test_docker_build_template(self, mock_ds): @@ -73,18 +71,18 @@ def test_docker_build_template(self, mock_ds): self.opts.dockerstache_context = 'context' self.opts.dockerstache_defaults = 'defaults' dckr.docker_build(self.opts, self.config) - self.failUnless(mock_ds.run.called) + self.assertTrue(mock_ds.run.called) - mock_ds.run.assert_has_calls( + mock_ds.run.assert_has_calls([ mock.call( output='vm/docker_image', context=None, defaults=None, input='template', extend_context=mock.ANY ) - ) - self.mock_subp.check_output.assert_has_calls( + ]) + self.mock_subp.check_output.assert_has_calls([ mock.call( ['docker', 'build', '-t', 'unittesting/unittesting:1.2.3', 'vm/docker_image'] ) - ) + ]) def test_docker_build_login(self): """test build with login""" @@ -97,7 +95,7 @@ def test_docker_build_login(self): self.config['docker']['docker_login_email'] = 'steve@pbr.com' dckr.docker_build(self.opts, self.config) - self.failUnless(self.mock_subp.check_output.called) + self.assertTrue(self.mock_subp.check_output.called) self.mock_subp.check_output.assert_has_calls( [ mock.call(['docker', 'login', '-u', 'steve', '-e', 'steve@pbr.com', '-p', 'st3v3R0X']), @@ -157,14 +155,15 @@ def test_docker_connection_success(self): def test_docker_connection_error(self): """test failed docker daemon connection""" + # need to unmock CalledProcessError or code raises + # TypeError: catching classes that do not inherit from BaseException is + # not allowed + self.mock_subp.CalledProcessError = CalledProcessError self.mock_subp.check_output.side_effect = CalledProcessError( 1, ['docker', 'info'], - 'Cannot connect to the Docker daemon...') - - with self.assertRaises(CalledProcessError): - result = dckr.is_docker_connected() - self.assertFalse(result) + 'Cannot connect to the Docker daemon...' + ) -if __name__ == '__main__': - unittest.main() + result = dckr.is_docker_connected() + self.assertFalse(result) diff --git a/tests/unit/cirrus/documentation_utils_test.py b/tests/unit/cirrus/documentation_utils_test.py index ffcc319..f229e4a 100644 --- a/tests/unit/cirrus/documentation_utils_test.py +++ b/tests/unit/cirrus/documentation_utils_test.py @@ -2,10 +2,9 @@ documentation utils tests """ -import mock import os import tempfile -import unittest +from unittest import TestCase, mock from requests_toolbelt import MultipartEncoder @@ -14,10 +13,10 @@ from cirrus.documentation_utils import build_doc_artifact from cirrus.documentation_utils import publish_documentation -from harnesses import CirrusConfigurationHarness, write_cirrus_conf +from .harnesses import CirrusConfigurationHarness, write_cirrus_conf -class TestDocumentationUtils(unittest.TestCase): +class TestDocumentationUtils(TestCase): def setUp(self): """set up test files""" self.dir = tempfile.mkdtemp() @@ -38,7 +37,7 @@ def setUp(self): ) self.harness = CirrusConfigurationHarness('cirrus.documentation_utils.load_configuration', self.config) self.harness.setUp() - self.patch_local = mock.patch('cirrus.documentation_utils.local') + self.patch_local = mock.patch('cirrus.documentation_utils.run') self.mock_local = self.patch_local.start() self.doc_artifact_name = doc_artifact_name(self.harness.config) diff --git a/tests/unit/cirrus/environment_test.py b/tests/unit/cirrus/environment_test.py index 7544ffb..de9e19f 100644 --- a/tests/unit/cirrus/environment_test.py +++ b/tests/unit/cirrus/environment_test.py @@ -6,15 +6,14 @@ import os import copy -import unittest -import mock +from unittest import TestCase, mock import tempfile from cirrus.environment import cirrus_home from cirrus.environment import virtualenv_home -class EnvironmentFunctionTests(unittest.TestCase): +class EnvironmentFunctionTests(TestCase): """ test case for environment module functions @@ -53,7 +52,7 @@ def test_venv_home(self): self.assertEqual(home2, 'TESTVALUE/venv') -class CleanEnvironmentTests(unittest.TestCase): +class CleanEnvironmentTests(TestCase): def setUp(self): """save/mock the os.environ settings""" @@ -83,8 +82,8 @@ def test_cirrus_home_in_venv(self, mock_env, mock_repo, mock_srcfile): mock_env.__setitem__ = mock.Mock() mock_srcfile.return_value = self.venv_dir self.assertEqual(cirrus_home(), self.dir) - self.failUnless(not mock_repo.called) - self.failUnless(mock_env.__setitem__.called) + self.assertTrue(not mock_repo.called) + self.assertTrue(mock_env.__setitem__.called) @mock.patch('cirrus.environment.inspect.getsourcefile') @mock.patch('cirrus.environment.repo_directory') @@ -100,7 +99,7 @@ def test_cirrus_home_in_bad_repo(self, mock_env, mock_repo, mock_srcfile): mock_srcfile.return_value = self.venv_dir_2 mock_repo.return_value = None self.assertRaises(RuntimeError, cirrus_home) - self.failUnless(not mock_env.__setitem__.called) + self.assertTrue(not mock_env.__setitem__.called) @mock.patch('cirrus.environment.inspect.getsourcefile') @mock.patch('cirrus.environment.repo_directory') @@ -115,8 +114,8 @@ def test_cirrus_home_in_repo(self, mock_env, mock_repo, mock_srcfile): mock_srcfile.return_value = self.venv_dir_2 mock_repo.return_value = os.path.dirname(self.venv_dir_2) self.assertEqual(cirrus_home(), os.path.dirname(self.venv_dir_2)) - self.failUnless(mock_repo.called) - self.failUnless(mock_env.__setitem__.called) + self.assertTrue(mock_repo.called) + self.assertTrue(mock_env.__setitem__.called) if __name__ == '__main__': diff --git a/tests/unit/cirrus/feature_test.py b/tests/unit/cirrus/feature_test.py index 9299181..c06c576 100644 --- a/tests/unit/cirrus/feature_test.py +++ b/tests/unit/cirrus/feature_test.py @@ -1,18 +1,16 @@ """ feature command tests - """ -import mock import os import tempfile -import unittest +from unittest import TestCase, mock from cirrus.feature import new_feature_branch, new_pr -from harnesses import CirrusConfigurationHarness, write_cirrus_conf +from .harnesses import CirrusConfigurationHarness, write_cirrus_conf -class FeatureCommandTest(unittest.TestCase): +class FeatureCommandTest(TestCase): """ Test Case for new_feature_branch function """ @@ -58,10 +56,10 @@ def test_new_feature_branch(self): opts.push = False new_feature_branch(opts) - self.failUnless(self.mock_pull.called) + self.assertTrue(self.mock_pull.called) self.assertEqual(self.mock_pull.call_args[0][1], 'develop') - self.failUnless(self.mock_branch.called) - self.failIf(self.mock_push.called) + self.assertTrue(self.mock_branch.called) + self.assertFalse(self.mock_push.called) def test_new_feature_branch_push(self): """ @@ -76,10 +74,10 @@ def test_new_feature_branch_push(self): opts.push = True new_feature_branch(opts) - self.failUnless(self.mock_pull.called) + self.assertTrue(self.mock_pull.called) self.assertEqual(self.mock_pull.call_args[0][1], 'develop') - self.failUnless(self.mock_branch.called) - self.failUnless(self.mock_push.called) + self.assertTrue(self.mock_branch.called) + self.assertTrue(self.mock_push.called) def test_new_pr(self): """ @@ -93,9 +91,9 @@ def test_new_pr(self): with mock.patch('cirrus.feature.create_pull_request') as mock_pr: new_pr(opts) - self.failUnless('body' in mock_pr.call_args[0][1]) - self.failUnless('title' in mock_pr.call_args[0][1]) - self.failUnless(mock_pr.called) + self.assertIn('body', mock_pr.call_args[0][1]) + self.assertIn('title', mock_pr.call_args[0][1]) + self.assertTrue(mock_pr.called) if __name__ == '__main__': diff --git a/tests/unit/cirrus/git_tools_test.py b/tests/unit/cirrus/git_tools_test.py index 2a70196..5e2bd65 100644 --- a/tests/unit/cirrus/git_tools_test.py +++ b/tests/unit/cirrus/git_tools_test.py @@ -1,25 +1,27 @@ ''' tests for git_tools ''' -import mock -import unittest +from unittest import TestCase, mock from git.remote import PushInfo -from cirrus.git_tools import branch -from cirrus.git_tools import checkout_and_pull -from cirrus.git_tools import get_active_branch -from cirrus.git_tools import get_diff_files -from cirrus.git_tools import merge -from cirrus.git_tools import push -from cirrus.git_tools import build_release_notes -from cirrus.git_tools import format_commit_messages -from cirrus.git_tools import get_commit_msgs -from cirrus.git_tools import get_tags -from cirrus.git_tools import get_tags_with_sha -from cirrus.git_tools import markdown_format - -class GitToolsTest(unittest.TestCase): +from cirrus.git_tools import ( + branch, + build_release_notes, + checkout_and_pull, + format_commit_messages, + get_active_branch, + get_commit_msgs, + get_diff_files, + get_tags, + get_tags_with_sha, + markdown_format, + merge, + push +) + + +class GitToolsTest(TestCase): def setUp(self): self.mock_commits = [mock.Mock(), mock.Mock()] @@ -74,7 +76,7 @@ def test_checkout_and_pull(self): _test_checkout_and_pull_ """ checkout_and_pull(None, 'master') - self.failUnless(self.mock_git.Repo.called) + self.assertTrue(self.mock_git.Repo.called) def test_branch(self): """ @@ -83,28 +85,28 @@ def test_branch(self): self.mock_repo.heads = [] self.mock_repo.active_branch = 'new_branch' branch(None, self.mock_repo.active_branch, 'master') - self.failUnless(self.mock_git.Repo.called) + self.assertTrue(self.mock_git.Repo.called) def test_push(self): """ _test_push_ """ push(None) - self.failUnless(self.mock_git.Repo.called) + self.assertTrue(self.mock_git.Repo.called) def test_get_active_branch(self): """ _test_get_active_branch_ """ get_active_branch(None) - self.failUnless(self.mock_git.Repo.called) + self.assertTrue(self.mock_git.Repo.called) def test_merge(self): branch1 = 'branch1' branch2 = 'branch2' merge(None, branch1, branch2) - self.failUnless(self.mock_git.Repo.called) + self.assertTrue(self.mock_git.Repo.called) def test_get_diff_files(self): path = "path/to/file/hello.py" @@ -113,8 +115,8 @@ def test_get_diff_files(self): self.mock_repo.index.diff.return_value = [self.mock_blob] diffs = get_diff_files(None) - self.failUnlessEqual(diffs[0], path) - self.failUnless(self.mock_git.Repo.called) + self.assertEqual(diffs[0], path) + self.assertTrue(self.mock_git.Repo.called) def test_build_release_notes(self): """ @@ -133,8 +135,8 @@ def test_build_release_notes(self): None, self.release, 'plaintext') - self.failUnless(mock_get_tags_sha.called) - self.failUnless(mock_get_commit.called) + self.assertTrue(mock_get_tags_sha.called) + self.assertTrue(mock_get_commit.called) def test_commit_messages(self): """ @@ -143,7 +145,7 @@ def test_commit_messages(self): prints plaintext release notes """ msg = format_commit_messages(self.commit_info) - print "Plaintext release notes:\n{0}\n".format(msg) + print("Plaintext release notes:\n{0}\n".format(msg)) def test_markdown_format(self): """ @@ -152,26 +154,26 @@ def test_markdown_format(self): prints markdown release notes """ msg = markdown_format(self.commit_info) - print "Markdown release notes:\n{0}\n".format(msg) + print("Markdown release notes:\n{0}\n".format(msg)) def test_get_commit_msgs(self): """ _test_get_commit_msgs_ """ result = get_commit_msgs(None, 'RANDOM_SHA') - self.failUnless('committer' in result[0]) - self.failUnless('message' in result[0]) - self.failUnless('date' in result[0]) - self.failUnless('committer' in result[1]) - self.failUnless('message' in result[1]) - self.failUnless('date' in result[1]) + self.assertIn('committer', result[0]) + self.assertIn('message', result[0]) + self.assertIn('date', result[0]) + self.assertIn('committer', result[1]) + self.assertIn('message', result[1]) + self.assertIn('date', result[1]) def test_get_tags(self): """ _test_get_tags_ """ result = get_tags(None) - self.failUnlessEqual(result, ['orange', 'banana', 'apple']) + self.assertEqual(result, ['orange', 'banana', 'apple']) def test_get_tags_with_sha(self): """ diff --git a/tests/unit/cirrus/github_tools_test.py b/tests/unit/cirrus/github_tools_test.py index 4dde0bc..fbf1014 100644 --- a/tests/unit/cirrus/github_tools_test.py +++ b/tests/unit/cirrus/github_tools_test.py @@ -2,8 +2,7 @@ tests for github_tools ''' import json -import mock -import unittest +from unittest import TestCase, mock import subprocess from cirrus.github_tools import create_pull_request @@ -11,7 +10,8 @@ from cirrus.github_tools import get_releases from .harnesses import _repo_directory -class GithubToolsTest(unittest.TestCase): + +class GithubToolsTest(TestCase): """ _GithubToolsTest_ """ @@ -67,11 +67,11 @@ def test_create_pull_request(self): self.repo, {'title': 'Test', 'body': 'This is a test'}, 'token') - self.failUnless(mock_config_load.called) - self.failUnless(mock_get_branch.called) - self.failUnless(mock_post.called) - self.failUnless(mock_dumps.called) - self.failUnlessEqual(result, resp_json['html_url']) + self.assertTrue(mock_config_load.called) + self.assertTrue(mock_get_branch.called) + self.assertTrue(mock_post.called) + self.assertTrue(mock_dumps.called) + self.assertEqual(result, resp_json['html_url']) def test_get_releases(self): """ @@ -87,8 +87,8 @@ def test_get_releases(self): mock_req.json.return_value = resp_json self.mock_get.return_value = mock_req result = get_releases(self.owner, self.repo, 'token') - self.failUnless(self.mock_get.called) - self.failUnless('tag_name' in result[0]) + self.assertTrue(self.mock_get.called) + self.assertIn('tag_name', result[0]) @mock.patch('cirrus.github_tools.load_configuration') @mock.patch("cirrus.github_tools.requests.post") @@ -113,7 +113,7 @@ def check_post(url, headers, data): current_branch_mark_status(_repo_directory(), "success") - self.failUnless(mock_post.called) + self.assertTrue(mock_post.called) if __name__ == "__main__": unittest.main() diff --git a/tests/unit/cirrus/harnesses.py b/tests/unit/cirrus/harnesses.py index c3bf6c4..f412328 100644 --- a/tests/unit/cirrus/harnesses.py +++ b/tests/unit/cirrus/harnesses.py @@ -3,16 +3,12 @@ harnesses Common/reusable test harnesses - """ - - import os -import unittest +from unittest import mock import tempfile -import mock import subprocess -import ConfigParser +import configparser from cirrus.configuration import Configuration @@ -21,7 +17,7 @@ def _repo_directory(): command = ['git', 'rev-parse', '--show-toplevel'] process = subprocess.Popen(command, stdout=subprocess.PIPE) outp, err = process.communicate() - return outp.strip() + return outp.strip().decode('utf-8') def write_cirrus_conf(config_file, **sections): @@ -38,10 +34,10 @@ def write_cirrus_conf(config_file, **sections): settings={'package': {'name': 'package_name'} } """ - parser = ConfigParser.RawConfigParser() - for section, settings in sections.iteritems(): + parser = configparser.RawConfigParser() + for section, settings in sections.items(): parser.add_section(section) - for key, value in settings.iteritems(): + for key, value in settings.items(): parser.set(section, key, value) with open(config_file, 'w') as handle: diff --git a/tests/unit/cirrus/keyring_creds_tests.py b/tests/unit/cirrus/keyring_creds_tests.py index e313597..948462d 100644 --- a/tests/unit/cirrus/keyring_creds_tests.py +++ b/tests/unit/cirrus/keyring_creds_tests.py @@ -6,7 +6,7 @@ """ import unittest -import mock +from unittest import mock from cirrus.plugins.creds.keyring import Keyring @@ -26,8 +26,8 @@ def test_keyring_plugin(self, mock_keyring): plugin = Keyring() gh = plugin.github_credentials() - self.failUnless('github_user' in gh) - self.failUnless('github_token' in gh) + self.assertIn('github_user', gh) + self.assertIn('github_token', gh) self.assertEqual(gh['github_user'], 'steve') self.assertEqual(gh['github_token'], 'steves token') @@ -43,7 +43,7 @@ def test_all_methods(self, mock_keyring): plugin = Keyring() for n, m in plugin.credential_methods(): check = m() - self.failUnless(all(v is 'womp' for v in check.values())) + self.assertTrue(all(v is 'womp' for v in list(check.values()))) diff --git a/tests/unit/cirrus/package_tests.py b/tests/unit/cirrus/package_tests.py index c876e7c..d26936a 100644 --- a/tests/unit/cirrus/package_tests.py +++ b/tests/unit/cirrus/package_tests.py @@ -1,11 +1,10 @@ #!/usr/bin/env python """tests for package commands """ -import unittest -import mock +from unittest import TestCase, mock, skip import os import json import tempfile -import ConfigParser +import configparser from cirrus.package import ( create_files, @@ -18,10 +17,10 @@ ) -from harnesses import CirrusConfigurationHarness +from .harnesses import CirrusConfigurationHarness -class BuildParserTest(unittest.TestCase): +class BuildParserTest(TestCase): """test for cli parser""" def test_build_parser(self): argslist = ['init'] @@ -35,7 +34,7 @@ def test_build_parser(self): self.assertEqual(opts.develop, 'develop') -class GitFunctionTests(unittest.TestCase): +class GitFunctionTests(TestCase): """ tests for git util functions """ @@ -62,8 +61,8 @@ def test_backup_file(self): """test backup_file""" backup_file(self.bak_file) files = os.listdir(self.repo) - self.failUnless('backmeup' in files) - self.failUnless('backmeup.BAK' in files) + self.assertIn('backmeup', files) + self.assertIn('backmeup.BAK', files) @mock.patch('cirrus.package.branch') @mock.patch('cirrus.package.push') @@ -77,13 +76,13 @@ def test_setup_branches(self, mock_active, mock_push, mock_branch): setup_branches(opts) self.assertEqual(mock_branch.call_count, 2) - self.failUnless(mock_push.called) - self.failUnless(mock_active.called) + self.assertTrue(mock_push.called) + self.assertTrue(mock_active.called) mock_push.reset_mock() opts.no_remote = True setup_branches(opts) - self.failUnless(not mock_push.called) + self.assertTrue(not mock_push.called) @mock.patch('cirrus.package.commit_files_optional_push') @mock.patch('cirrus.package.get_tags') @@ -100,7 +99,7 @@ def test_commit_and_tag(self, mock_branch, mock_tag_rel, mock_tags, mock_commit) mock_tags.return_value = ['0.0.1'] commit_and_tag(opts, 'file1', 'file2') - self.failUnless(mock_commit.called) + self.assertTrue(mock_commit.called) mock_commit.assert_has_calls([ mock.call( self.repo, @@ -110,17 +109,17 @@ def test_commit_and_tag(self, mock_branch, mock_tag_rel, mock_tags, mock_commit) 'file2' ) ]) - self.failUnless(mock_tags.called) - self.failUnless(mock_tag_rel.called) - self.failUnless(mock_branch.called) + self.assertTrue(mock_tags.called) + self.assertTrue(mock_tag_rel.called) + self.assertTrue(mock_branch.called) # tag exists opts.version = '0.0.1' mock_tag_rel.reset_mock() commit_and_tag(opts, 'file1', 'file2') - self.failUnless(not mock_tag_rel.called) + self.assertTrue(not mock_tag_rel.called) -class CreateFilesTest(unittest.TestCase): +class CreateFilesTest(TestCase): """mocked create_files function tests""" def setUp(self): """ @@ -153,35 +152,38 @@ def test_create_files(self): opts.history_file = 'HISTORY.md' opts.package = 'unittests' opts.create_version_file = False + opts.desc = 'testing123' + opts.org = 'IBM Cloudant' + opts.develop = 'test-develop' create_files(opts) dir_list = os.listdir(self.repo) - self.failUnless('cirrus.conf' in dir_list) - self.failUnless('HISTORY.md' in dir_list) - self.failUnless('MANIFEST.in' in dir_list) - self.failUnless('setup.py' in dir_list) + self.assertIn('cirrus.conf', dir_list) + self.assertIn('HISTORY.md', dir_list) + self.assertIn('MANIFEST.in', dir_list) + self.assertIn('setup.py', dir_list) cirrus_conf = os.path.join(self.repo, 'cirrus.conf') - config = ConfigParser.RawConfigParser() + config = configparser.RawConfigParser() config.read(cirrus_conf) self.assertEqual(config.get('package', 'name'), opts.package) self.assertEqual(config.get('package', 'version'), opts.version) history = os.path.join(self.repo, 'HISTORY.md') with open(history, 'r') as handle: - self.failUnless('CIRRUS_HISTORY_SENTINEL' in handle.read()) + self.assertIn('CIRRUS_HISTORY_SENTINEL', handle.read()) manifest = os.path.join(self.repo, 'MANIFEST.in') with open(manifest, 'r') as handle: content = handle.read() - self.failUnless('include requirements.txt' in content) - self.failUnless('include cirrus.conf' in content) - self.failUnless('include steve/*' in content) + self.assertIn('include requirements.txt', content) + self.assertIn('include cirrus.conf', content) + self.assertIn('include steve/*', content) version = os.path.join(self.repo, 'src', 'unittests', '__init__.py') with open(version, 'r') as handle: - self.failUnless(opts.version in handle.read()) + self.assertTrue(opts.version in handle.read()) def test_create_files_with_version(self): """test create_files call and content of files""" @@ -194,41 +196,44 @@ def test_create_files_with_version(self): opts.templates = ['include steve/*'] opts.history_file = 'HISTORY.md' opts.package = 'unittests' + opts.desc = 'testing123' + opts.org = 'IBM Cloudant' + opts.develop = 'test-develop' version = os.path.join(self.repo, 'src', 'unittests', '__init__.py') os.system('rm -f {}'.format(version)) create_files(opts) dir_list = os.listdir(self.repo) - self.failUnless('cirrus.conf' in dir_list) - self.failUnless('HISTORY.md' in dir_list) - self.failUnless('MANIFEST.in' in dir_list) - self.failUnless('setup.py' in dir_list) + self.assertIn('cirrus.conf', dir_list) + self.assertIn('HISTORY.md', dir_list) + self.assertIn('MANIFEST.in', dir_list) + self.assertIn('setup.py', dir_list) cirrus_conf = os.path.join(self.repo, 'cirrus.conf') - config = ConfigParser.RawConfigParser() + config = configparser.RawConfigParser() config.read(cirrus_conf) self.assertEqual(config.get('package', 'name'), opts.package) self.assertEqual(config.get('package', 'version'), opts.version) history = os.path.join(self.repo, 'HISTORY.md') with open(history, 'r') as handle: - self.failUnless('CIRRUS_HISTORY_SENTINEL' in handle.read()) + self.assertIn('CIRRUS_HISTORY_SENTINEL', handle.read()) manifest = os.path.join(self.repo, 'MANIFEST.in') with open(manifest, 'r') as handle: content = handle.read() - self.failUnless('include requirements.txt' in content) - self.failUnless('include cirrus.conf' in content) - self.failUnless('include steve/*' in content) + self.assertIn('include requirements.txt', content) + self.assertIn('include cirrus.conf', content) + self.assertIn('include steve/*', content) version = os.path.join(self.repo, 'src', 'unittests', '__init__.py') with open(version, 'r') as handle: - self.failUnless(opts.version in handle.read()) + self.assertTrue(opts.version in handle.read()) -@unittest.skip("Integ test not unit test") -class PackageInitCommandIntegTest(unittest.TestCase): +@skip("Integ test not unit test") +class PackageInitCommandIntegTest(TestCase): """test case for package init command """ def setUp(self): @@ -267,7 +272,7 @@ def test_init_command(self): opts = build_parser(argslist) init_package(opts) conf = os.path.join(self.repo, 'cirrus.conf') - self.failUnless(os.path.exists(conf)) + self.assertTrue(os.path.exists(conf)) @mock.patch('cirrus.editor_plugin.load_configuration') def test_project_sublime_command(self, mock_lc): @@ -287,19 +292,19 @@ def test_project_sublime_command(self, mock_lc): opts = build_parser(argslist) build_project(opts) proj = os.path.join(self.repo, 'unittests.sublime-project') - self.failUnless(os.path.exists(proj)) + self.assertTrue(os.path.exists(proj)) with open(proj, 'r') as handle: data = json.load(handle) - self.failUnless('folders' in data) - self.failUnless(data['folders']) - self.failUnless('path' in data['folders'][0]) + self.assertIn('folders', data) + self.assertTrue(data['folders']) + self.assertIn('path', data['folders'][0]) self.assertEqual(data['folders'][0]['path'], self.repo) build = data['build_systems'][0] - self.failUnless('name' in build) + self.assertIn('name', build) self.assertEqual(build['name'], "cirrus virtualenv") - self.failUnless('env' in build) - self.failUnless('PYTHONPATH' in build['env']) + self.assertIn('env', build) + self.assertIn('PYTHONPATH', build['env']) self.assertEqual(build['env']['PYTHONPATH'], self.repo) if __name__ == '__main__': diff --git a/tests/unit/cirrus/publisher_plugins_tests.py b/tests/unit/cirrus/publisher_plugins_tests.py index d7a6f01..edbd427 100644 --- a/tests/unit/cirrus/publisher_plugins_tests.py +++ b/tests/unit/cirrus/publisher_plugins_tests.py @@ -1,17 +1,15 @@ -import __builtin__ -import mock import os import tempfile -import unittest +from unittest import TestCase, mock import pluggage.registry from cirrus.documentation_utils import doc_artifact_name -from harnesses import CirrusConfigurationHarness, write_cirrus_conf +from .harnesses import CirrusConfigurationHarness, write_cirrus_conf -class FileServerPublisherTests(unittest.TestCase): +class FileServerPublisherTests(TestCase): """ Test the doc_file_server publisher plugin. @@ -60,9 +58,8 @@ def tearDown(self): if os.path.exists(self.dir): os.system('rm -rf {0}'.format(self.dir)) - @mock.patch('cirrus.plugins.publishers.doc_file_server.put') @mock.patch('cirrus.plugins.publishers.doc_file_server.FabricHelper') - def test_docs_file_server(self, m_fabric, m_fabric_put): + def test_docs_file_server(self, m_fabric): """ test docs_file_server publisher plugin makes put command with Fabric """ @@ -73,14 +70,15 @@ def test_docs_file_server(self, m_fabric, m_fabric_put): plugin = factory('doc_file_server') plugin.publish(self.doc_artifact_name) - - self.assertTrue(m_fabric.called_once_with( - 'http://localhost:8080', 'username', '/path/to/ssh/keyfile')) - self.assertTrue(m_fabric_put.called_once_with( - self.doc_artifact_name, '/path/to/upload/dir', sudo=False)) + m_fabric.assert_called_once_with( + 'http://localhost:8080', 'username', '/path/to/ssh/keyfile' + ) + m_fabric.return_value.__enter__.return_value.put.assert_called_once_with( + self.doc_artifact_name, '/path/to/upload/dir', use_sudo=False + ) -class JenkinsPublisherTests(unittest.TestCase): +class JenkinsPublisherTests(TestCase): """ Test the jenkins publisher plugin. @@ -148,14 +146,10 @@ def test_jenkins(self, m_encoder, m_auth, m_requests): m_resp.status_code = 201 m_session.post = mock.Mock(return_value=m_resp) - with mock.patch('__builtin__.open') as m_open: + with mock.patch('builtins.open') as m_open: plugin.publish(self.doc_artifact_name) self.assertEqual(m_encoder.call_count, 1) self.assertEqual(m_open.call_count, 1) self.assertEqual(m_session.post.call_count, 1) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unit/cirrus/pylint_tools_test.py b/tests/unit/cirrus/pylint_tools_test.py index 89cd578..cd7c9ba 100644 --- a/tests/unit/cirrus/pylint_tools_test.py +++ b/tests/unit/cirrus/pylint_tools_test.py @@ -1,62 +1,63 @@ ''' pylint_tools tests ''' -import mock -import unittest +from unittest import TestCase, mock + +from pep8 import StyleGuide from cirrus.pylint_tools import pep8_file from cirrus.pylint_tools import pyflakes_file from cirrus.pylint_tools import pylint_file -class PylintToolsTest(unittest.TestCase): +class PylintToolsTest(TestCase): def setUp(self): - """setup mocks""" - self.filename = 'hello.py' - self.patch_local = mock.patch('cirrus.pylint_tools.local') - self.patch_hide = mock.patch('cirrus.pylint_tools.hide') - self.patch_settings = mock.patch('cirrus.pylint_tools.settings') - - self.mock_local = self.patch_local.start() - self.mock_hide = self.patch_hide.start() - self.mock_settings = self.patch_settings.start() + self.filenames = ['hello.py', 'goodbye.py'] + patch_run = mock.patch('cirrus.pylint_tools.run') + self.mock_run = patch_run.start() + patch_pep8 = mock.patch('cirrus.pylint_tools.pep8') + self.mock_pep8 = patch_pep8.start() def tearDown(self): - """teardown mocks""" - self.patch_local.stop() - self.patch_hide.stop() - self.patch_settings.stop() + mock.patch.stopall() def test_pylint_file(self): - """ - _test_pylint_file_ - """ - results = pylint_file(self.filename) - self.failUnless(self.mock_local.called) - self.failUnless(self.mock_hide.called) - self.failUnless(self.mock_settings.called) - self.failUnlessEqual(results[0], self.filename) + results = pylint_file(self.filenames) + self.mock_run.assert_called_with( + 'pylint {}'.format(' '.join(self.filenames)), + hide=True, + warn=True + ) + self.assertEqual(results[0], self.filenames) def test_pyflakes_file(self): - """ - _test_pyflakes_file_ - """ - results = pyflakes_file(self.filename) - self.failUnless(self.mock_local.called) - self.failUnless(self.mock_hide.called) - self.failUnless(self.mock_settings.called) - self.failUnlessEqual(results[0], self.filename) - - def pep8_file(self): - """ - _test_pyflakes_file_ - """ - results = pep8_file(self.filename) - self.failUnless(self.mock_local.called) - self.failUnless(self.mock_hide.called) - self.failUnless(self.mock_settings.called) - self.failUnlessEqual(results[0], self.filename) - -if __name__ == "__main__": - unittest.main() + results = pyflakes_file(self.filenames) + self.mock_run.assert_called_with( + 'pyflakes {}'.format(' '.join(self.filenames)), + hide=True, + warn=True + ) + self.assertEqual(results[0], self.filenames) + + def test_pep8_file(self): + mock_style_guide = mock.Mock(spec=StyleGuide) + self.mock_pep8.StyleGuide.return_value = mock_style_guide + + results = pep8_file(self.filenames) + mock_style_guide.check_files.assert_called_with(self.filenames) + self.assertFalse( + mock_style_guide.check_files.return_value.print_statistics.called + ) + self.assertEqual(results[0], self.filenames) + + def test_pep8_file_verbose(self): + mock_style_guide = mock.Mock(spec=StyleGuide) + self.mock_pep8.StyleGuide.return_value = mock_style_guide + + results = pep8_file(self.filenames, verbose=True) + mock_style_guide.check_files.assert_called_with(self.filenames) + self.assertTrue( + mock_style_guide.check_files.return_value.print_statistics.called + ) + self.assertEqual(results[0], self.filenames) diff --git a/tests/unit/cirrus/pypirc_tests.py b/tests/unit/cirrus/pypirc_tests.py index fca7046..838659e 100644 --- a/tests/unit/cirrus/pypirc_tests.py +++ b/tests/unit/cirrus/pypirc_tests.py @@ -45,10 +45,10 @@ def test_pypircfile(self): """test loading file and accessing data""" pypirc = PypircFile(self.file) - self.failUnless(pypirc.exists()) + self.assertTrue(pypirc.exists()) - self.failUnless('pypi' in pypirc.index_servers) - self.failUnless('devpi' in pypirc.index_servers) + self.assertIn('pypi', pypirc.index_servers) + self.assertIn('devpi', pypirc.index_servers) self.assertEqual( pypirc.get_pypi_url('pypi'), diff --git a/tests/unit/cirrus/quality_control_test.py b/tests/unit/cirrus/quality_control_test.py index 038f07a..6e45fc5 100644 --- a/tests/unit/cirrus/quality_control_test.py +++ b/tests/unit/cirrus/quality_control_test.py @@ -1,15 +1,14 @@ ''' qc command tests ''' -import mock -import unittest +from unittest import TestCase, mock from cirrus.quality_control import run_pep8 from cirrus.quality_control import run_pyflakes from cirrus.quality_control import run_pylint -class QualityControlTest(unittest.TestCase): +class QualityControlTest(TestCase): def setUp(self): """setup mocks""" @@ -22,20 +21,19 @@ def tearDown(self): def test_run_pylint(self): with mock.patch('cirrus.quality_control.pylint_file') as mock_pylint: + self.mock_config.return_value.quality_threshold.return_value = 0 + mock_pylint.return_value = (['hello.py', 'goodbye.py'], 0) run_pylint() - self.failUnless(mock_pylint.called) + self.assertTrue(mock_pylint.called) def test_run_pyflakes(self): with mock.patch( 'cirrus.quality_control.pyflakes_file') as mock_pyflakes: run_pyflakes(False) - self.failUnless(mock_pyflakes.called) + self.assertTrue(mock_pyflakes.called) def test_run_pep8(self): with mock.patch('cirrus.quality_control.pep8_file') as mock_pep8: run_pep8(False) - self.failUnless(mock_pep8.called) - -if __name__ == "__main__": - unittest.main() + self.assertTrue(mock_pep8.called) diff --git a/tests/unit/cirrus/release_test.py b/tests/unit/cirrus/release_test.py index 58e815a..e889afb 100644 --- a/tests/unit/cirrus/release_test.py +++ b/tests/unit/cirrus/release_test.py @@ -1,12 +1,10 @@ #!/usr/bin/env python """ release command tests - """ import os -import unittest +from unittest import TestCase, mock import tempfile -import mock from cirrus.release import ( artifact_name, @@ -18,10 +16,10 @@ from cirrus.configuration import Configuration from pluggage.errors import FactoryError -from harnesses import CirrusConfigurationHarness, write_cirrus_conf +from .harnesses import CirrusConfigurationHarness, write_cirrus_conf -class ReleaseNewCommandTest(unittest.TestCase): +class ReleaseNewCommandTest(TestCase): """ Test Case for new_release function """ @@ -53,19 +51,15 @@ def tearDown(self): os.system('rm -rf {0}'.format(self.dir)) @mock.patch('cirrus.release.has_unstaged_changes') - @mock.patch('cirrus.release.get_active_branch') + @mock.patch('cirrus.release.remote_branch_exists') @mock.patch('cirrus.release.get_active_commit_sha') def test_new_release( self, mock_get_sha, - mock_get_branch, + mock_remote_branch_exists, mock_unstaged ): - """ - _test_new_release_ - - """ - mock_get_branch.return_value = mock.Mock() + mock_remote_branch_exists.return_value = False mock_get_sha.return_value = 'abc123' mock_unstaged.return_value = False opts = mock.Mock() @@ -84,27 +78,25 @@ def test_new_release( new_conf.load() self.assertEqual(new_conf.package_version(), '1.2.4') - self.failUnless(self.mock_pull.called) + self.assertTrue(self.mock_pull.called) self.assertEqual(self.mock_pull.call_args[0][1], 'develop') - self.failUnless(self.mock_branch.called) + self.assertTrue(self.mock_branch.called) self.assertEqual(self.mock_branch.call_args[0][1], 'release/1.2.4') - self.failUnless(self.mock_commit.called) + self.assertTrue(self.mock_commit.called) self.assertEqual(self.mock_commit.call_args[0][2], 'cirrus.conf') @mock.patch('cirrus.release.has_unstaged_changes') - @mock.patch('cirrus.release.get_active_branch') + @mock.patch('cirrus.release.remote_branch_exists') @mock.patch('cirrus.release.get_active_commit_sha') def test_new_release_unstaged( self, mock_get_sha, - mock_get_branch, + mock_branch_exists, mock_unstaged ): """ test new release fails on unstaged changes - """ - mock_get_branch.return_value = mock.Mock() mock_get_sha.return_value = 'abc123' mock_unstaged.return_value = True opts = mock.Mock() @@ -116,7 +108,7 @@ def test_new_release_unstaged( self.assertRaises(RuntimeError, new_release, opts) -class ReleaseBuildCommandTest(unittest.TestCase): +class ReleaseBuildCommandTest(TestCase): """ test case for cirrus release build command @@ -133,12 +125,12 @@ def setUp(self): self.harness = CirrusConfigurationHarness('cirrus.release.load_configuration', self.config) self.harness.setUp() - self.patch_local = mock.patch('cirrus.release.local') - self.mock_local = self.patch_local.start() + self.patch_run = mock.patch('cirrus.release.run') + self.mock_run = self.patch_run.start() def tearDown(self): self.harness.tearDown() - self.patch_local.stop() + self.patch_run.stop() @mock.patch('cirrus.release.artifact_name') @mock.patch('cirrus.release.get_active_commit_sha') @@ -164,11 +156,11 @@ def test_build_command(self): opts.dev = None result = build_release(opts) self.assertEqual(result, 'build_artifact') - self.failUnless(mock_os.path.exists.called) + self.assertTrue(mock_os.path.exists.called) self.assertEqual(mock_os.path.exists.call_args[0][0], 'build_artifact') - self.failUnless(self.mock_local.called) - self.assertEqual(self.mock_local.call_args[0][0], 'python setup.py bdist_wheel') + self.assertTrue(self.mock_run.called) + self.assertEqual(self.mock_run.call_args[0][0], 'python setup.py bdist_wheel') @mock.patch('cirrus.release.get_active_commit_sha') def test_build_command_with_tag(self, mock_git_sha): @@ -185,20 +177,20 @@ def test_build_command_with_tag(self, mock_git_sha): result = build_release(opts) self.assertEqual(result, 'build_artifact') - self.failUnless(mock_os.path.exists.called) + self.assertTrue(mock_os.path.exists.called) self.assertEqual( mock_os.path.exists.call_args[0][0], 'build_artifact' ) - self.failUnless(self.mock_local.called) + self.assertTrue(self.mock_run.called) self.assertEqual( - self.mock_local.call_args[0][0], + self.mock_run.call_args[0][0], "python setup.py egg_info --tag-build '.abc123' bdist_wheel" ) -class ReleaseUploadTest(unittest.TestCase): +class ReleaseUploadTest(TestCase): """unittest coverage for upload command using plugins""" def setUp(self): self.dir = tempfile.mkdtemp() @@ -241,7 +233,7 @@ def test_upload_plugin(self, mock_plugin, mock_exists): opts.test = False opts.target = None self.assertRaises(RuntimeError, upload_release, opts) - self.failIf(plugin.upload.called) + self.assertFalse(plugin.upload.called) @mock.patch('cirrus.release.os.path.exists') @mock.patch('cirrus.release.get_plugin') @@ -265,37 +257,72 @@ def test_upload_bad_plugin(self, mock_exists): self.assertRaises(RuntimeError, upload_release, opts) -class ReleaseBuildAndUploadTest(unittest.TestCase): +class ReleaseBuildAndUploadTest(TestCase): def setUp(self): + self.dir = tempfile.mkdtemp() + self.config = os.path.join(self.dir, 'cirrus.conf') + write_cirrus_conf(self.config, + **{ + 'package' :{'name': 'cirrus_unittest', 'version': '1.2.3'}, + 'github': {'develop_branch': 'develop', 'release_branch_prefix': 'release/'}, + 'pypi': { + 'pypi_upload_path': '/opt/pypi', + 'pypi_url': 'pypi.cloudant.com', + 'pypi_username': 'steve', + 'pypi_ssh_key': 'steves_creds' + } + } + ) + self.harness = CirrusConfigurationHarness('cirrus.release.load_configuration', self.config) + self.harness.setUp() + self.artifact_name = artifact_name(self.harness.config) + self.runner_msg = ( + 'running egg_info\n' + '...' + 'running upload\n' + 'Submitting dist/cirrus_cli-2.0.2.test-py3-none-any.whl to artifactory url\n' + 'Server response (200): OK\n' + ) self.patch_get_active_sha = mock.patch( 'cirrus.release.get_active_commit_sha' ) self.mock_get_active_sha = self.patch_get_active_sha.start() - self.patch_local = mock.patch('cirrus.release.local') - self.mock_local = self.patch_local.start() + self.patch_run = mock.patch('cirrus.release.run') + self.mock_run = self.patch_run.start() def tearDown(self): - self.patch_get_active_sha.stop() - self.patch_local.stop() + mock.patch.stopall() - @mock.patch('cirrus.release.os.getcwd') + @mock.patch('cirrus.release.os') @mock.patch('cirrus.release.get_active_branch') - def test_build_and_upload(self, mock_get_active_branch, mock_cwd): + @mock.patch('builtins.print') + def test_build_and_upload(self, mock_print, mock_get_active_branch, mock_os): """ Ensures the build_and_upload command can be ran """ + self.mock_run.return_value.stdout = self.runner_msg opts = mock.Mock() opts.dev = False mock_head = mock.Mock() mock_head.name = 'release/0.0.0' mock_get_active_branch.return_value = mock_head - mock_cwd.return_value = 'cirrus' + mock_os.getcwd.return_value = 'cirrus' + mock_os.path.join.return_value = 'cirrus/venv/bin/python' + mock_os.path.isdir.return_value = False + build_and_upload(opts) self.assertFalse(self.mock_get_active_sha.called) - self.mock_local.assert_called_with( + self.mock_run.assert_called_with( 'cirrus/venv/bin/python setup.py egg_info bdist_wheel upload -r local', - capture=True + hide='stdout', + echo=True ) + mock_print.assert_has_calls([ + mock.call( + 'Submitting dist/cirrus_cli-2.0.2.test-py3-none-any.whl to' + ' artifactory url' + ) + ]) @mock.patch('cirrus.release.get_active_branch') def test_build_and_upload_not_on_release_branch( @@ -313,27 +340,32 @@ def test_build_and_upload_not_on_release_branch( mock_get_active_branch.return_value = mock_head self.assertRaises(RuntimeError, build_and_upload, opts) self.assertFalse(self.mock_get_active_sha.called) - self.assertFalse(self.mock_local.called) + self.assertFalse(self.mock_run.called) - @mock.patch('cirrus.release.os.getcwd') - def test_build_and_upload_dev(self, mock_cwd): + @mock.patch('cirrus.release.os') + def test_build_and_upload_dev(self, mock_os): """ Ensures the build_and_upload command can be ran with the 'dev' option for creating pre-releases (git sha tagged builds) """ + self.mock_run.return_value.stdout = self.runner_msg self.mock_get_active_sha.return_value = 'deadbee' opts = mock.Mock() opts.dev = True - mock_cwd.return_value = 'cirrus' + mock_os.getcwd.return_value = 'cirrus' + mock_os.path.join.return_value = 'cirrus/venv/bin/python' + mock_os.path.isdir.return_value = False + build_and_upload(opts) self.assertTrue(self.mock_get_active_sha.called) - self.mock_local.assert_called_with( + self.mock_run.assert_called_with( 'cirrus/venv/bin/python setup.py egg_info --tag-build ".deadbee" bdist_wheel upload -r local', - capture=True + hide='stdout', + echo=True ) -class ArtifactNameTests(unittest.TestCase): +class ArtifactNameTests(TestCase): """ Tests for artifact_name """ @@ -386,7 +418,3 @@ def test_tagged_artifact_name(self): 'dist/cirrus_unittest-1.2.3.somesortoftag-py2-none-any.whl', artifact_name(self.harness.config, tag='somesortoftag') ) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unit/cirrus/test_test.py b/tests/unit/cirrus/test_test.py index 304d66a..8e2475e 100644 --- a/tests/unit/cirrus/test_test.py +++ b/tests/unit/cirrus/test_test.py @@ -1,18 +1,17 @@ ''' test command tests ''' -import mock -import unittest +from unittest import TestCase, mock from cirrus.test import nose_run from cirrus.test import tox_run -class TestTest(unittest.TestCase): +class TestTest(TestCase): def test_tox_test(self): """test mox based test call""" - with mock.patch('cirrus.test.local') as mock_local: + with mock.patch('cirrus.test.run') as mock_local: mock_opts = mock.Mock() mock_opts.suite = 'default' mock_opts.options = '-o OPTION' @@ -21,14 +20,14 @@ def test_tox_test(self): mock_config.venv_name.return_value = "VENV" tox_run(mock_config, mock_opts) - self.failUnless(mock_local.called) - self.failUnless(mock_config.venv_name.called) + self.assertTrue(mock_local.called) + self.assertTrue(mock_config.venv_name.called) command = mock_local.call_args[0][0] self.assertEqual(command, '. ./VENV/bin/activate && tox -o OPTION') def test_nose_test(self): """test nose_test call""" - with mock.patch('cirrus.test.local') as mock_local: + with mock.patch('cirrus.test.run') as mock_local: mock_opts = mock.Mock() mock_opts.suite = 'default' mock_opts.options = '-o OPTION' @@ -39,9 +38,9 @@ def test_nose_test(self): mock_config.test_where.return_value = "WHERE" nose_run(mock_config, mock_opts) - self.failUnless(mock_local.called) - self.failUnless(mock_config.venv_name.called) - self.failUnless(mock_config.test_where.called) + self.assertTrue(mock_local.called) + self.assertTrue(mock_config.venv_name.called) + self.assertTrue(mock_config.test_where.called) command = mock_local.call_args[0][0] self.assertEqual(command, '. ./VENV/bin/activate && nosetests -w WHERE -o OPTION')