From 4683b3856e8af546253bbf8dc88c823b1e0b162f Mon Sep 17 00:00:00 2001 From: Ian Fijolek Date: Tue, 30 Jul 2019 21:17:00 -0700 Subject: [PATCH] Allow building against more Python versions --- .drone.yml | 29 ++++++++++++++ .pre-commit-config.yaml | 2 +- Makefile | 88 ++++++++++++++++++++++++----------------- setup.py | 2 +- tests/__init__.py | 0 tests/alert_test.py | 14 ++++--- tests/monitor_test.py | 5 ++- tests/util.py | 12 ++++++ tox.ini | 2 +- 9 files changed, 107 insertions(+), 47 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/util.py diff --git a/.drone.yml b/.drone.yml index b2ca497..de3d5ef 100644 --- a/.drone.yml +++ b/.drone.yml @@ -53,6 +53,34 @@ steps: when: status: [ changed, failure ] +--- +kind: pipeline +name: test-python3.5 + +workspace: + base: /app + path: . + +steps: + - name: test + image: python:3.5 + commands: + - python -V + - make test-env test + + - name: notify + image: drillster/drone-email + settings: + host: + from_secret: SMTP_HOST + username: + from_secret: SMTP_USER + password: + from_secret: SMTP_PASS + from: drone@iamthefij.com + when: + status: [ changed, failure ] + --- kind: pipeline name: test-python3.6 @@ -148,6 +176,7 @@ name: tests depends_on: - test-python-latest - test-python3.4 + - test-python3.5 - test-python3.6 - test-python3.7 # - test-pypy3.6 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b06f386..d258c56 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: - id: name-tests-test exclude: tests/(common.py|util.py|(helpers|integration/factories)/(.+).py) - repo: https://github.com/asottile/reorder_python_imports - sha: v1.0.1 + rev: v1.0.1 hooks: - id: reorder-python-imports args: diff --git a/Makefile b/Makefile index 70d8177..7e2c989 100644 --- a/Makefile +++ b/Makefile @@ -1,46 +1,62 @@ DOCKER_TAG := minitor-dev OPEN_CMD := $(shell type xdg-open &> /dev/null && echo 'xdg-open' || echo 'open') +ENV := env .PHONY: default default: test -# Builds the python3 venv with all dev requirements -env: - python3 -m venv env - ./env/bin/pip install -r requirements-dev.txt +# Creates virtualenv +$(ENV): + python3 -m venv $(ENV) -# Runs Minitor -.PHONY: run -run: env - ./env/bin/python -m minitor.main -vvv +# Install minitor and dependencies in virtualenv +$(ENV)/bin/minitor: $(ENV) + $(ENV)/bin/pip install -r requirements-dev.txt -# Runs Minitor with metrics -.PHONY: run-metrics -run-metrics: env - ./env/bin/python -m minitor.main --metrics +# Install tox into virtualenv for running tests +$(ENV)/bin/tox: $(ENV) + $(ENV)/bin/pip install tox + +# Install wheel for building packages +$(ENV)/bin/wheel: $(ENV) + $(ENV)/bin/pip install wheel + +# Install twine for uploading packages +$(ENV)/bin/twine: $(ENV) + $(ENV)/bin/pip install twine + +# Installs dev requirements to virtualenv +.PHONY: devenv +devenv: $(ENV)/bin/minitor # Generates a smaller env for running tox, which builds it's own env .PHONY: test-env -test-env: - python3 -m venv env - ./env/bin/pip install tox - -# Runs tests with tox -.PHONY: test -test: env - ./env/bin/tox +test-env: $(ENV)/bin/tox # Generates a small build env for building and uploading dists .PHONY: build-env -build-env: - python3 -m venv env - ./env/bin/pip install twine wheel +build-env: $(ENV)/bin/twine $(ENV)/bin/wheel + +# Runs Minitor +.PHONY: run +run: $(ENV)/bin/minitor + $(ENV)/bin/minitor -vvv + +# Runs Minitor with metrics +.PHONY: run-metrics +run-metrics: $(ENV) + $(ENV)/bin/python -m minitor.main --metrics + +# Runs tests with tox +.PHONY: test +test: $(ENV)/bin/tox + $(ENV)/bin/tox -e py3 # Builds wheel for package to upload .PHONY: build -build: env - ./env/bin/python setup.py sdist - ./env/bin/python setup.py bdist_wheel +build: $(ENV)/bin/wheel + $(ENV)/bin/python setup.py sdist + $(ENV)/bin/python setup.py bdist_wheel # Verify that the python version matches the git tag so we don't push bad shas .PHONY: verify-tag-version @@ -50,13 +66,13 @@ verify-tag-version: # Uses twine to upload to pypi .PHONY: upload -upload: verify-tag-version build - ./env/bin/twine upload dist/* +upload: verify-tag-version build $(ENV)/bin/twine + $(ENV)/bin/twine upload dist/* # Uses twine to upload to test pypi .PHONY: upload-test -upload-test: verify-tag-version build - ./env/bin/twine upload --repository-url https://test.pypi.org/legacy/ dist/* +upload-test: verify-tag-version build $(ENV)/bin/twine + $(ENV)/bin/twine upload --repository-url https://test.pypi.org/legacy/ dist/* # Cleans all build, runtime, and test artifacts .PHONY: clean @@ -68,20 +84,20 @@ clean: # Cleans dist and env .PHONY: dist-clean dist-clean: clean - rm -fr ./dist ./env + rm -fr ./dist $(ENV) # Install pre-commit hooks .PHONY: install-hooks -install-hooks: env - ./env/bin/tox -e pre-commit -- install -f --install-hooks +install-hooks: $(ENV) + $(ENV)/bin/tox -e pre-commit -- install -f --install-hooks # Generates test coverage .coverage: - ./env/bin/tox + $(ENV)/bin/tox # Builds coverage html htmlcov/index.html: .coverage - ./env/bin/coverage html + $(ENV)/bin/coverage html # Opens coverage html in browser (on macOS and some Linux systems) .PHONY: open-coverage @@ -115,7 +131,7 @@ docker-cross-build-arm64: build/qemu-aarch64-static docker build --build-arg REPO=arm64v8 --build-arg ARCH=aarch64 . -t ${DOCKER_TAG}-linux-arm64 # Run on host architechture -.PHONY: run +.PHONY: docker-run docker-run: docker-build docker run ${DOCKER_TAG}-linux-amd64 diff --git a/setup.py b/setup.py index 471796c..e09a9f0 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ with open(path.join(here, 'README.md'), encoding='utf-8') as f: setup( name='minitor', - version='1.0.0', + version='1.0.1', description='A minimal monitoring tool', long_description=long_description, long_description_content_type='text/markdown', diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/alert_test.py b/tests/alert_test.py index b694387..90b9c90 100644 --- a/tests/alert_test.py +++ b/tests/alert_test.py @@ -5,6 +5,7 @@ import pytest from minitor.main import Alert from minitor.main import Monitor +from tests.util import assert_called_once_with class TestAlert(object): @@ -52,9 +53,10 @@ class TestAlert(object): monitor.total_failure_count = 1 with patch.object(echo_alert._logger, 'error') as mock_error: echo_alert.alert('Exception message', monitor) - mock_error.assert_called_once_with( - 'Dummy Monitor has failed 1 time(s)!\n' - 'We have alerted 1 time(s)\n' - 'Last success was ' + expected_success + '\n' - 'Last output was: beep boop' - ) + assert_called_once_with( + mock_error, + 'Dummy Monitor has failed 1 time(s)!\n' + 'We have alerted 1 time(s)\n' + 'Last success was ' + expected_success + '\n' + 'Last output was: beep boop' + ) diff --git a/tests/monitor_test.py b/tests/monitor_test.py index f9d20e5..1c8cfe7 100644 --- a/tests/monitor_test.py +++ b/tests/monitor_test.py @@ -7,6 +7,7 @@ from minitor.main import InvalidMonitorException from minitor.main import MinitorAlert from minitor.main import Monitor from minitor.main import validate_monitor_settings +from tests.util import assert_called_once class TestMonitor(object): @@ -111,14 +112,14 @@ class TestMonitor(object): with patch.object(monitor, 'failure') as mock_failure: monitor.command = ['ls', '--not-real'] assert not monitor.check() - mock_failure.assert_called_once() + assert_called_once(mock_failure) assert monitor.last_output is not None def test_monitor_check_success(self, monitor): assert monitor.last_output is None with patch.object(monitor, 'success') as mock_success: assert monitor.check() - mock_success.assert_called_once() + assert_called_once(mock_success) assert monitor.last_output is not None @pytest.mark.parametrize('failure_count', [0, 1]) diff --git a/tests/util.py b/tests/util.py new file mode 100644 index 0000000..c1a693d --- /dev/null +++ b/tests/util.py @@ -0,0 +1,12 @@ +from unittest import mock + + +def assert_called_once(mocked): + """Safe convenient methods for mock asserts""" + assert mocked.call_count == 1 + + +def assert_called_once_with(mocked, *args, **kwargs): + """Safe convenient methods for mock asserts""" + assert_called_once(mocked) + assert mocked.call_args == mock.call(*args, **kwargs) diff --git a/tox.ini b/tox.ini index 3617a81..8a10321 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py3 +envlist = py3,pypy3 [testenv] deps =