Allow building against more Python versions
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
IamTheFij 2019-07-30 21:17:00 -07:00
parent e8f7ba6801
commit 4683b3856e
9 changed files with 107 additions and 47 deletions

View File

@ -53,6 +53,34 @@ steps:
when: when:
status: [ changed, failure ] 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 kind: pipeline
name: test-python3.6 name: test-python3.6
@ -148,6 +176,7 @@ name: tests
depends_on: depends_on:
- test-python-latest - test-python-latest
- test-python3.4 - test-python3.4
- test-python3.5
- test-python3.6 - test-python3.6
- test-python3.7 - test-python3.7
# - test-pypy3.6 # - test-pypy3.6

View File

@ -19,7 +19,7 @@ repos:
- id: name-tests-test - id: name-tests-test
exclude: tests/(common.py|util.py|(helpers|integration/factories)/(.+).py) exclude: tests/(common.py|util.py|(helpers|integration/factories)/(.+).py)
- repo: https://github.com/asottile/reorder_python_imports - repo: https://github.com/asottile/reorder_python_imports
sha: v1.0.1 rev: v1.0.1
hooks: hooks:
- id: reorder-python-imports - id: reorder-python-imports
args: args:

View File

@ -1,46 +1,62 @@
DOCKER_TAG := minitor-dev DOCKER_TAG := minitor-dev
OPEN_CMD := $(shell type xdg-open &> /dev/null && echo 'xdg-open' || echo 'open') OPEN_CMD := $(shell type xdg-open &> /dev/null && echo 'xdg-open' || echo 'open')
ENV := env
.PHONY: default .PHONY: default
default: test default: test
# Builds the python3 venv with all dev requirements # Creates virtualenv
env: $(ENV):
python3 -m venv env python3 -m venv $(ENV)
./env/bin/pip install -r requirements-dev.txt
# Runs Minitor # Install minitor and dependencies in virtualenv
.PHONY: run $(ENV)/bin/minitor: $(ENV)
run: env $(ENV)/bin/pip install -r requirements-dev.txt
./env/bin/python -m minitor.main -vvv
# Runs Minitor with metrics # Install tox into virtualenv for running tests
.PHONY: run-metrics $(ENV)/bin/tox: $(ENV)
run-metrics: env $(ENV)/bin/pip install tox
./env/bin/python -m minitor.main --metrics
# 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 # Generates a smaller env for running tox, which builds it's own env
.PHONY: test-env .PHONY: test-env
test-env: test-env: $(ENV)/bin/tox
python3 -m venv env
./env/bin/pip install tox
# Runs tests with tox
.PHONY: test
test: env
./env/bin/tox
# Generates a small build env for building and uploading dists # Generates a small build env for building and uploading dists
.PHONY: build-env .PHONY: build-env
build-env: build-env: $(ENV)/bin/twine $(ENV)/bin/wheel
python3 -m venv env
./env/bin/pip install twine 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 # Builds wheel for package to upload
.PHONY: build .PHONY: build
build: env build: $(ENV)/bin/wheel
./env/bin/python setup.py sdist $(ENV)/bin/python setup.py sdist
./env/bin/python setup.py bdist_wheel $(ENV)/bin/python setup.py bdist_wheel
# Verify that the python version matches the git tag so we don't push bad shas # Verify that the python version matches the git tag so we don't push bad shas
.PHONY: verify-tag-version .PHONY: verify-tag-version
@ -50,13 +66,13 @@ verify-tag-version:
# Uses twine to upload to pypi # Uses twine to upload to pypi
.PHONY: upload .PHONY: upload
upload: verify-tag-version build upload: verify-tag-version build $(ENV)/bin/twine
./env/bin/twine upload dist/* $(ENV)/bin/twine upload dist/*
# Uses twine to upload to test pypi # Uses twine to upload to test pypi
.PHONY: upload-test .PHONY: upload-test
upload-test: verify-tag-version build upload-test: verify-tag-version build $(ENV)/bin/twine
./env/bin/twine upload --repository-url https://test.pypi.org/legacy/ dist/* $(ENV)/bin/twine upload --repository-url https://test.pypi.org/legacy/ dist/*
# Cleans all build, runtime, and test artifacts # Cleans all build, runtime, and test artifacts
.PHONY: clean .PHONY: clean
@ -68,20 +84,20 @@ clean:
# Cleans dist and env # Cleans dist and env
.PHONY: dist-clean .PHONY: dist-clean
dist-clean: clean dist-clean: clean
rm -fr ./dist ./env rm -fr ./dist $(ENV)
# Install pre-commit hooks # Install pre-commit hooks
.PHONY: install-hooks .PHONY: install-hooks
install-hooks: env install-hooks: $(ENV)
./env/bin/tox -e pre-commit -- install -f --install-hooks $(ENV)/bin/tox -e pre-commit -- install -f --install-hooks
# Generates test coverage # Generates test coverage
.coverage: .coverage:
./env/bin/tox $(ENV)/bin/tox
# Builds coverage html # Builds coverage html
htmlcov/index.html: .coverage htmlcov/index.html: .coverage
./env/bin/coverage html $(ENV)/bin/coverage html
# Opens coverage html in browser (on macOS and some Linux systems) # Opens coverage html in browser (on macOS and some Linux systems)
.PHONY: open-coverage .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 docker build --build-arg REPO=arm64v8 --build-arg ARCH=aarch64 . -t ${DOCKER_TAG}-linux-arm64
# Run on host architechture # Run on host architechture
.PHONY: run .PHONY: docker-run
docker-run: docker-build docker-run: docker-build
docker run ${DOCKER_TAG}-linux-amd64 docker run ${DOCKER_TAG}-linux-amd64

View File

@ -12,7 +12,7 @@ with open(path.join(here, 'README.md'), encoding='utf-8') as f:
setup( setup(
name='minitor', name='minitor',
version='1.0.0', version='1.0.1',
description='A minimal monitoring tool', description='A minimal monitoring tool',
long_description=long_description, long_description=long_description,
long_description_content_type='text/markdown', long_description_content_type='text/markdown',

0
tests/__init__.py Normal file
View File

View File

@ -5,6 +5,7 @@ import pytest
from minitor.main import Alert from minitor.main import Alert
from minitor.main import Monitor from minitor.main import Monitor
from tests.util import assert_called_once_with
class TestAlert(object): class TestAlert(object):
@ -52,7 +53,8 @@ class TestAlert(object):
monitor.total_failure_count = 1 monitor.total_failure_count = 1
with patch.object(echo_alert._logger, 'error') as mock_error: with patch.object(echo_alert._logger, 'error') as mock_error:
echo_alert.alert('Exception message', monitor) echo_alert.alert('Exception message', monitor)
mock_error.assert_called_once_with( assert_called_once_with(
mock_error,
'Dummy Monitor has failed 1 time(s)!\n' 'Dummy Monitor has failed 1 time(s)!\n'
'We have alerted 1 time(s)\n' 'We have alerted 1 time(s)\n'
'Last success was ' + expected_success + '\n' 'Last success was ' + expected_success + '\n'

View File

@ -7,6 +7,7 @@ from minitor.main import InvalidMonitorException
from minitor.main import MinitorAlert from minitor.main import MinitorAlert
from minitor.main import Monitor from minitor.main import Monitor
from minitor.main import validate_monitor_settings from minitor.main import validate_monitor_settings
from tests.util import assert_called_once
class TestMonitor(object): class TestMonitor(object):
@ -111,14 +112,14 @@ class TestMonitor(object):
with patch.object(monitor, 'failure') as mock_failure: with patch.object(monitor, 'failure') as mock_failure:
monitor.command = ['ls', '--not-real'] monitor.command = ['ls', '--not-real']
assert not monitor.check() assert not monitor.check()
mock_failure.assert_called_once() assert_called_once(mock_failure)
assert monitor.last_output is not None assert monitor.last_output is not None
def test_monitor_check_success(self, monitor): def test_monitor_check_success(self, monitor):
assert monitor.last_output is None assert monitor.last_output is None
with patch.object(monitor, 'success') as mock_success: with patch.object(monitor, 'success') as mock_success:
assert monitor.check() assert monitor.check()
mock_success.assert_called_once() assert_called_once(mock_success)
assert monitor.last_output is not None assert monitor.last_output is not None
@pytest.mark.parametrize('failure_count', [0, 1]) @pytest.mark.parametrize('failure_count', [0, 1])

12
tests/util.py Normal file
View File

@ -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)

View File

@ -1,5 +1,5 @@
[tox] [tox]
envlist = py3 envlist = py3,pypy3
[testenv] [testenv]
deps = deps =