Skip to content

Commit

Permalink
Merge pull request #390 from JrGoodle/parallel-coverage
Browse files Browse the repository at this point in the history
Add test coverage for parallel tests and write tests on Circle CI
  • Loading branch information
JrGoodle committed Nov 15, 2017
2 parents ae948a5 + 3b97658 commit 7722305
Show file tree
Hide file tree
Showing 26 changed files with 195 additions and 107 deletions.
77 changes: 77 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
version: 2
jobs:
build:
docker:
- image: circleci/python:3.6.1

working_directory: ~/clowder

steps:
- checkout

# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "clowder/requirements.txt" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-

- run:
name: install dependencies
command: |
python3 -m venv venv
. venv/bin/activate
sudo pip install -r clowder/requirements.txt
- run:
name: run setup scripts
command: |
script/update
script/test
- save_cache:
paths:
- ./venv
key: v1-dependencies-{{ checksum "clowder/requirements.txt" }}

- add_ssh_keys:
fingerprints:
- "3a:38:b7:1e:b7:eb:c5:8f:4a:79:bd:4f:f0:9a:ea:61"

- run:
name: install git 2.13.6
command: |
sudo apt-get remove git
sudo apt-get update -y
sudo apt-get install libcurl4-openssl-dev libexpat1-dev gettext libz-dev libssl-dev build-essential autoconf
mkdir tmp-git-build
pushd tmp-git-build
curl -L --progress https://github.com/git/git/archive/v2.13.6.tar.gz | tar xz
pushd git-2.13.6/
sudo make configure
sudo ./configure
sudo make prefix=/usr/local all
sudo make prefix=/usr/local install
popd
popd
- run:
name: setup git config
command: |
git config --global user.email "circle@circleci.org"
git config --global user.name "CircleCI"
git config --global push.default simple
- run:
name: run write tests
command: clowder-test -c write

- run:
name: upload code coverage results
command: |
coverage combine examples/cats examples/cocos2d-objc examples/llvm-projects examples/swift-projects
codecov
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ script:
- if [ "$TARGET" = "cats" ]; then clowder-test -c cats all; fi
- if [ "$TARGET" = "cocos2d" ]; then clowder-test -c cocos2d all; fi
- if [ "$TARGET" = "llvm" ]; then clowder-test -c llvm all; fi
- if [ "$TARGET" = "parallel" ]; then clowder-test parallel; fi
- if [ "$TARGET" = "parallel" ]; then clowder-test -c parallel; fi
- if [ "$TARGET" = "swift" ]; then clowder-test -c swift all; fi

after_script: script/travis/after_script
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# `clowder`
[![Build Status](https://travis-ci.org/JrGoodle/clowder.svg)](https://travis-ci.org/JrGoodle/clowder)
[![CircleCI](https://circleci.com/gh/JrGoodle/clowder.svg?style=svg)](https://circleci.com/gh/JrGoodle/clowder)
[![Build status](https://ci.appveyor.com/api/projects/status/pmf4h6etnb3bbd9y?svg=true)](https://ci.appveyor.com/project/JrGoodle/clowder)
[![Maintainability](https://api.codeclimate.com/v1/badges/56c92799de08f9ef9258/maintainability)](https://codeclimate.com/github/JrGoodle/clowder/maintainability)
[![codecov](https://codecov.io/gh/JrGoodle/clowder/branch/master/graph/badge.svg)](https://codecov.io/gh/JrGoodle/clowder)
[![Test Coverage](https://api.codeclimate.com/v1/badges/56c92799de08f9ef9258/test_coverage)](https://codeclimate.com/github/JrGoodle/clowder/test_coverage)
[![PyPI version](https://badge.fury.io/py/clowder-repo.svg)](https://badge.fury.io/py/clowder-repo)
[![Python version](https://img.shields.io/pypi/pyversions/clowder-repo.svg)](https://pypi.python.org/pypi/clowder-repo)
Expand Down
17 changes: 12 additions & 5 deletions clowder/clowder/cli/sync_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class Meta:
nargs='+', metavar='PROJECT',
help=options_help_message(CLOWDER_CONTROLLER.get_all_fork_project_names(),
'projects to sync'))),
(['--protocol'], dict(choices=['https', 'ssh'], nargs=1, default=None, metavar='PROTOCOL',
help='Protocol to clone new repos with')),
(['--rebase', '-r'], dict(action='store_true', help='use rebase instead of pull')),
(['--parallel'], dict(action='store_true', help='run commands in parallel'))
]
Expand All @@ -56,29 +58,34 @@ def sync(self):
def _sync(self):
"""Clowder sync command private implementation"""

protocol = None if self.app.pargs.protocol is None else self.app.pargs.protocol[0]

all_fork_projects = CLOWDER_CONTROLLER.get_all_fork_project_names()
if all_fork_projects == '':
cprint(' - No forks to sync\n', 'red')
return
sync(CLOWDER_CONTROLLER, all_fork_projects, rebase=self.app.pargs.rebase, parallel=self.app.pargs.parallel)
sync(CLOWDER_CONTROLLER, all_fork_projects, protocol=protocol,
rebase=self.app.pargs.rebase,
parallel=self.app.pargs.parallel)


def sync(clowder, project_names, rebase=False, parallel=False):
def sync(clowder, project_names, protocol, rebase=False, parallel=False):
"""Sync projects
.. py:function:: sync(clowder, project_names, rebase=False, parallel=False)
.. py:function:: sync(clowder, project_names, protocol, rebase=False, parallel=False)
:param ClowderController clowder: ClowderController instance
:param list[str] project_names: Project names to sync
:param str protocol: Git protocol, 'ssh' or 'https'
:param Optional[bool] rebase: Whether to use rebase instead of pulling latest changes
:param Optional[bool] parallel: Whether command is being run in parallel, affects output
"""

projects = filter_projects(clowder.groups, project_names=project_names)
if parallel:
sync_parallel(projects, rebase=rebase)
sync_parallel(projects, protocol, rebase=rebase)
if os.name == "posix":
return

for project in projects:
project.sync(rebase=rebase)
project.sync(protocol, rebase=rebase)
7 changes: 5 additions & 2 deletions clowder/clowder/model/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def stash(self):
repo = ProjectRepo(self.full_path(), self.remote, self.ref)
repo.stash()

def sync(self, rebase=False, parallel=False):
def sync(self, protocol, rebase=False, parallel=False):
"""Sync fork project with upstream remote
.. py:function:: sync(rebase=False, parallel=False)
Expand All @@ -448,8 +448,11 @@ def sync(self, rebase=False, parallel=False):

self._print_output = not parallel

if protocol is None:
protocol = self._protocol

repo = self._repo(self.full_path(), self.remote, self.ref, self.recursive, parallel=parallel)
self._run_herd_command('herd', repo, self._protocol, rebase=rebase)
self._run_herd_command('herd', repo, protocol, rebase=rebase)
self._print(self.fork.status())
repo.sync(self.fork.remote_name, rebase=rebase)

Expand Down
11 changes: 7 additions & 4 deletions clowder/clowder/util/parallel_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,15 @@ def run_project(project, commands, ignore_errors):

project.run(commands, ignore_errors, parallel=True)

def sync_project(project, rebase):
def sync_project(project, protocol, rebase):
"""Sync command wrapper function for multiprocessing Pool execution
:param Project project: Project instance
:param str protocol: Git protocol, 'ssh' or 'https'
:param bool rebase: Whether to use rebase instead of pulling latest changes
"""

project.sync(rebase, parallel=True)
project.sync(protocol, rebase, parallel=True)

def async_callback(val):
"""Increment async progress bar
Expand Down Expand Up @@ -209,18 +210,20 @@ def reset_parallel(clowder, group_names, **kwargs):
__clowder_results__.append(result)
pool_handler(len(projects))

def sync_parallel(projects, rebase=False):
def sync_parallel(projects, protocol, rebase=False):
"""Sync projects in parallel
:param list[Project] projects: Projects to sync
:param str protocol: Git protocol, 'ssh' or 'https'
:param Optional[bool] rebase: Whether to use rebase instead of pulling latest changes
"""

print(' - Sync forks in parallel\n')
print_parallel_projects_output(projects, [])

for project in projects:
result = __clowder_pool__.apply_async(sync_project, args=(project, rebase), callback=async_callback)
result = __clowder_pool__.apply_async(sync_project, args=(project, protocol, rebase),
callback=async_callback)
__clowder_results__.append(result)
pool_handler(len(projects))

Expand Down
6 changes: 4 additions & 2 deletions clowder/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
argcomplete>=1.9.0
awscli>=1.11.186
cement>=2.10.2
codecov>=2.0.9
colorama>=0.3.9
coverage>=4.4.2
GitPython>=2.1.0
psutil>=5.4.0
PyYAML>=3.12
recommonmark>=0.4.0
sphinx>=1.6.5
sphinx-autobuild>=0.7.0
sphinx-rtd-theme>=0.2.4
termcolor>=1.1.0
psutil>=5.4.0
tqdm>=4.19.0
recommonmark>=0.4.0
38 changes: 16 additions & 22 deletions clowder_test/clowder_test/cli/base_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,28 +80,6 @@ def parallel(self):
debug=self.app.debug,
quiet=self.app.pargs.silent)

@expose(
help='Run tests requiring ssh credentials'
)
def ssh(self):
"""clowder ssh tests"""

execute_test_command('./ssh_protocol.sh', os.path.join(self.path, 'cocos2d'),
parallel=self.app.pargs.parallel,
write=True,
coverage=self.app.pargs.coverage,
debug=self.app.debug,
quiet=self.app.pargs.silent,
ssh=True)

execute_test_command('./ssh_configure_remotes.sh', os.path.join(self.path, 'swift'),
parallel=self.app.pargs.parallel,
write=True,
coverage=self.app.pargs.coverage,
debug=self.app.debug,
quiet=self.app.pargs.silent,
ssh=True)

@expose(
help='Run unit tests',
arguments=[
Expand Down Expand Up @@ -148,3 +126,19 @@ def write(self):
coverage=self.app.pargs.coverage,
debug=self.app.debug,
quiet=self.app.pargs.silent)

execute_test_command('./write_protocol.sh', os.path.join(self.path, 'cocos2d'),
parallel=self.app.pargs.parallel,
write=True,
coverage=self.app.pargs.coverage,
debug=self.app.debug,
quiet=self.app.pargs.silent,
ssh=True)

execute_test_command('./write_configure_remotes.sh', os.path.join(self.path, 'swift'),
parallel=self.app.pargs.parallel,
write=True,
coverage=self.app.pargs.coverage,
debug=self.app.debug,
quiet=self.app.pargs.silent,
ssh=True)
4 changes: 0 additions & 4 deletions clowder_test/clowder_test/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,12 @@ def execute_test_command(command, path, **kwargs):
test_env = kwargs.get('test_env', {})
debug = kwargs.get('debug', False)
quiet = kwargs.get('quiet', False)
ssh = kwargs.get('ssh', False)

test_env['ACCESS_LEVEL'] = 'write' if write else 'read'

if parallel:
test_env['PARALLEL'] = '--parallel'

if ssh:
test_env['PROTOCOL'] = 'ssh'

if coverage:
rc_file = os.path.join(ROOT_DIR, '.coveragerc')
test_env['COVERAGE_PROCESS_START'] = rc_file
Expand Down
8 changes: 4 additions & 4 deletions script/clean
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ clean_examples() {
echo "Removing existing example files"
local examples_path=$REPO_PATH/examples
echo 'Clean repo examples...'
$examples_path/cats/clean.sh
$examples_path/llvm-projects/clean.sh
$examples_path/swift-projects/clean.sh
if [ -z "$TRAVIS_OS_NAME" ]; then
"$examples_path/cats/clean.sh"
"$examples_path/llvm-projects/clean.sh"
"$examples_path/swift-projects/clean.sh"
if [ -z "$TRAVIS_OS_NAME" ] && [ -z "$CIRCLECI" ]; then
echo 'Clean home directory examples...'
rm -rf "$HOME/.clowder_tests"
fi
Expand Down
8 changes: 7 additions & 1 deletion script/test
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,11 @@ fi

script/clean 'test' || exit 1

if [ "$PYVERSION" == 'python2' ]; then
PIP='pip'
else
PIP='pip3'
fi

cd clowder_test || exit 1
sudo -H pip install -e . || exit 1
sudo -H $PIP install -e . || exit 1
15 changes: 6 additions & 9 deletions script/travis/after_script
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
#!/usr/bin/env bash

if [ "$TARGET" != "parallel" ]; then
cd "$TRAVIS_BUILD_DIR" || exit 1

coverage combine examples/cats examples/cocos2d-objc examples/llvm-projects examples/swift-projects
coverage xml
./cc-test-reporter format-coverage --output "coverage/codeclimate.$TRAVIS_JOB_NUMBER.json"
mv .coverage "coverage/.coverage.$TRAVIS_OS_NAME.$TARGET"
aws s3 sync coverage/ "s3://clowder-coverage/coverage/$TRAVIS_BUILD_NUMBER"
fi
cd "$TRAVIS_BUILD_DIR" || exit 1
coverage combine examples/cats examples/cocos2d-objc examples/llvm-projects examples/swift-projects
codecov
./cc-test-reporter format-coverage --output "coverage/codeclimate.$TRAVIS_JOB_NUMBER.json"
mv .coverage "coverage/.coverage.$TRAVIS_OS_NAME.$TARGET.$PYVERSION"
aws s3 sync coverage/ "s3://clowder-coverage/coverage/$TRAVIS_BUILD_NUMBER"
26 changes: 9 additions & 17 deletions script/travis/before_script
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,18 @@ cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/.." || exit 1
./setup "$PYVERSION"
./test

if [ "$TARGET" != "parallel" ]; then
cd "$TRAVIS_BUILD_DIR" || exit 1
cd "$TRAVIS_BUILD_DIR" || exit 1

if [ "$PYVERSION" = 'python2' ]; then
sudo pip install coverage
else
sudo pip3 install coverage
fi

if [ "$TRAVIS_OS_NAME" = "osx" ]; then
PLATFORM='darwin'
elif [ "$TRAVIS_OS_NAME" = "linux" ]; then
PLATFORM='linux'
fi

curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-$PLATFORM-amd64 > ./cc-test-reporter
chmod +x ./cc-test-reporter
./cc-test-reporter before-build
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
PLATFORM='darwin'
elif [ "$TRAVIS_OS_NAME" = "linux" ]; then
PLATFORM='linux'
fi

curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-$PLATFORM-amd64 > ./cc-test-reporter
chmod +x ./cc-test-reporter
./cc-test-reporter before-build

setup_git() {
git config --global user.email "travis@travis-ci.org"
git config --global user.name "Travis CI"
Expand Down
14 changes: 9 additions & 5 deletions script/travis/install
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
#!/usr/bin/env bash

cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/.." || exit 1
cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../.." || exit 1

if [ "$PYVERSION" == 'python2' ]; then
PIP='pip'
else
PIP='pip3'
fi

if [ "$TRAVIS_OS_NAME" = "osx" ]; then
brew install github-release
sudo -H pip3 install twine wheel
sudo -H $PIP install twine wheel
fi

if [ "$TARGET" != "parallel" ]; then
sudo pip install awscli
fi
sudo $PIP install -r clowder/requirements.txt

0 comments on commit 7722305

Please sign in to comment.