Skip to content

Commit

Permalink
Non-unix exit codes and non-multiprocess exit code fix (#55)
Browse files Browse the repository at this point in the history
* Allow windows exit codes. Fixes #48

* Fixes tests for fix #49

* change final os.EX_OK

* Simplify exit codes

* Correct exit codes when vladiate fails

* Move tests

* Don't lint ./dist
  • Loading branch information
di committed Feb 23, 2018
1 parent 8c75eda commit fdeffb7
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 83 deletions.
2 changes: 1 addition & 1 deletion setup.cfg
@@ -1,4 +1,4 @@
[flake8]
max-line-length = 80
exclude = *.egg,.state,build,.tox
exclude = *.egg,.state,build,.tox,dist
select = E,W,F,N
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -12,7 +12,7 @@ class PyTest(TestCommand):

def initialize_options(self):
TestCommand.initialize_options(self)
self.pytest_args = ['-x', 'vladiate/test']
self.pytest_args = ['-x', 'tests']

def finalize_options(self):
TestCommand.finalize_options(self)
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions vladiate/test/test_inputs.py → tests/test_inputs.py
@@ -1,9 +1,9 @@
import pytest
from pretend import stub, call, call_recorder

from ..exceptions import MissingExtraException
from ..inputs import S3File, StringIO, String, VladInput
from ..vlad import Vlad
from vladiate.exceptions import MissingExtraException
from vladiate.inputs import S3File, StringIO, String, VladInput
from vladiate.vlad import Vlad


def mock_boto(result):
Expand Down
82 changes: 25 additions & 57 deletions vladiate/test/test_main.py → tests/test_main.py
Expand Up @@ -5,15 +5,15 @@
import pytest
from pretend import stub, call, call_recorder

from ..main import ( # NOQA
from vladiate import exits
from vladiate.examples import vladfile
from vladiate.examples.vladfile import YourFirstFailingValidator
from vladiate.inputs import String
from vladiate.main import (
parse_args, is_vlad, find_vladfile, load_vladfile, _vladiate, main, run,
_is_package
)

from ..vlad import Vlad
from ..inputs import String
from ..examples import vladfile
from ..examples.vladfile import YourFirstFailingValidator
from vladiate.vlad import Vlad


def test_parse_args():
Expand Down Expand Up @@ -100,7 +100,11 @@ def test_run(monkeypatch):
]


def test_main_when_get_nowait_raises(monkeypatch):
@pytest.mark.parametrize('get, expected', [
(lambda: True, exits.OK),
(lambda: False, exits.DATAERR),
])
def test_main_with_multiprocess(monkeypatch, get, expected):
monkeypatch.setattr(
'vladiate.main.parse_args', lambda: stub(
list_commands=False,
Expand All @@ -126,49 +130,13 @@ def test_main_when_get_nowait_raises(monkeypatch):
)
monkeypatch.setattr('vladiate.main.Pool', Pool)

class MockEmpty(BaseException):
pass

def _raise_empty():
raise MockEmpty

result_queue = stub(get_nowait=_raise_empty)
monkeypatch.setattr('vladiate.main.result_queue', result_queue)
monkeypatch.setattr('vladiate.main.Empty', MockEmpty)

assert main() is os.EX_OK


@pytest.mark.parametrize('get_nowait, expected', [
(lambda: stub(), os.EX_OK),
(lambda: False, os.EX_DATAERR),
])
def test_main_with_multiprocess(monkeypatch, get_nowait, expected):
monkeypatch.setattr(
'vladiate.main.parse_args', lambda: stub(
list_commands=False,
show_version=False,
vladfile=stub(),
vlads=['Something'],
processes=2,
)
)
monkeypatch.setattr(
'vladiate.main.find_vladfile', lambda *args, **kwargs: stub()
)
vlad = call_recorder(lambda *args, **kwargs: stub(validate=lambda: stub()))
vlad.source = stub()

monkeypatch.setattr(
'vladiate.main.load_vladfile',
lambda *args, **kwargs: (None, {'Something': vlad})
)
def empty(calls=[]):
if calls:
return True
calls.append(None)
return False

Pool = call_recorder(
lambda *args, **kwargs: stub(map=lambda *args, **kwargs: stub())
)
monkeypatch.setattr('vladiate.main.Pool', Pool)
result_queue = stub(get_nowait=get_nowait)
result_queue = stub(get=get, empty=empty)
monkeypatch.setattr('vladiate.main.result_queue', result_queue)

assert main() is expected
Expand All @@ -194,7 +162,7 @@ def test_main_with_vlads_in_args(monkeypatch):
'vladiate.main.load_vladfile',
lambda *args, **kwargs: (None, {'Something': vlad})
)
assert main() is None
assert main() is exits.OK


def test_main_no_vlads_in_args(monkeypatch):
Expand All @@ -217,7 +185,7 @@ def test_main_no_vlads_in_args(monkeypatch):
'vladiate.main.load_vladfile',
lambda *args, **kwargs: (None, {'Something Else': vlad})
)
assert main() is None
assert main() == exits.OK


def test_main_missing_vlads(monkeypatch):
Expand All @@ -236,7 +204,7 @@ def test_main_missing_vlads(monkeypatch):
'vladiate.main.load_vladfile',
lambda *args, **kwargs: (None, {'Something Else': stub()})
)
assert main() == os.EX_UNAVAILABLE
assert main() == exits.UNAVAILABLE


def test_main_no_vlads_loaded(monkeypatch):
Expand All @@ -254,7 +222,7 @@ def test_main_no_vlads_loaded(monkeypatch):
monkeypatch.setattr(
'vladiate.main.load_vladfile', lambda *args, **kwargs: (None, vlads)
)
assert main() == os.EX_NOINPUT
assert main() == exits.NOINPUT


def test_main_list_commands(monkeypatch):
Expand All @@ -272,26 +240,26 @@ def test_main_list_commands(monkeypatch):
monkeypatch.setattr(
'vladiate.main.load_vladfile', lambda *args, **kwargs: (None, vlads)
)
assert main() == os.EX_OK
assert main() == exits.OK


def test_main_show_version(monkeypatch):
monkeypatch.setattr(
'vladiate.main.parse_args', lambda: stub(show_version=True)
)
assert main() == os.EX_OK
assert main() == exits.OK


def test_main_no_vladfile(monkeypatch):
monkeypatch.setattr(
'vladiate.main.find_vladfile', lambda *args, **kwargs: None
)
assert main() == os.EX_NOINPUT
assert main() == exits.NOINPUT


@pytest.mark.parametrize('path, expected', [
('foo/bar', False),
('vladiate/test', True),
('vladiate/examples', True),
])
def test_is_package(path, expected):
assert _is_package(path) == expected
4 changes: 2 additions & 2 deletions vladiate/test/test_validators.py → tests/test_validators.py
@@ -1,12 +1,12 @@
import pytest
from pretend import stub, call, call_recorder

from ..validators import (
from vladiate.exceptions import BadValidatorException, ValidationException
from vladiate.validators import (
CastValidator, EmptyValidator, FloatValidator, Ignore, IntValidator,
NotEmptyValidator, RangeValidator, RegexValidator, SetValidator,
UniqueValidator, Validator, _stringify_set
)
from ..exceptions import BadValidatorException, ValidationException


class FakeRow(object):
Expand Down
6 changes: 3 additions & 3 deletions vladiate/test/test_vlads.py → tests/test_vlads.py
@@ -1,11 +1,11 @@
import pytest

from ..vlad import Vlad
from ..inputs import LocalFile, String
from ..validators import (
from vladiate.inputs import LocalFile, String
from vladiate.validators import (
EmptyValidator, FloatValidator, NotEmptyValidator, SetValidator,
UniqueValidator,
)
from vladiate.vlad import Vlad


def test_initialize_vlad():
Expand Down
8 changes: 8 additions & 0 deletions vladiate/exits.py
@@ -0,0 +1,8 @@
""" A collection of exit codes that work on non-UNIX systems """

import os

OK = getattr(os, 'EX_OK', 0)
DATAERR = getattr(os, 'EX_DATAERR', 65)
NOINPUT = getattr(os, 'EX_NOINPUT', 66)
UNAVAILABLE = getattr(os, 'EX_UNAVAILABLE', 69)
30 changes: 14 additions & 16 deletions vladiate/main.py
@@ -1,10 +1,7 @@
try:
from Queue import Empty
except ImportError:
from queue import Empty
from multiprocessing import Pool, Queue
from vladiate import Vlad
from vladiate import logs
from vladiate import exits

import os
import sys
Expand Down Expand Up @@ -162,34 +159,34 @@ def main():

if arguments.show_version:
print("Vladiate %s" % (get_distribution('vladiate').version, ))
return os.EX_OK
return exits.OK

vladfile = find_vladfile(arguments.vladfile)
if not vladfile:
logger.error(
"Could not find any vladfile! Ensure file ends in '.py' and see "
"--help for available options."
)
return os.EX_NOINPUT
return exits.NOINPUT

docstring, vlads = load_vladfile(vladfile)

if arguments.list_commands:
logger.info("Available vlads:")
for name in vlads:
logger.info(" " + name)
return os.EX_OK
return exits.OK

if not vlads:
logger.error("No vlad class found!")
return os.EX_NOINPUT
return exits.NOINPUT

# make sure specified vlad exists
if arguments.vlads:
missing = set(arguments.vlads) - set(vlads.keys())
if missing:
logger.error("Unknown vlad(s): %s\n" % (", ".join(missing)))
return os.EX_UNAVAILABLE
return exits.UNAVAILABLE
else:
names = set(arguments.vlads) & set(vlads.keys())
vlad_classes = [vlads[n] for n in names]
Expand All @@ -198,9 +195,11 @@ def main():

# validate all the vlads, and collect the validations for a good exit
# return code
all_passed = True
if arguments.processes == 1:
for vlad in vlad_classes:
vlad(source=vlad.source).validate()
passed = vlad(source=vlad.source).validate()
all_passed = all_passed and passed

else:
proc_pool = Pool(
Expand All @@ -209,12 +208,11 @@ def main():
else len(vlad_classes)
)
proc_pool.map(_vladiate, vlad_classes)
try:
if not result_queue.get_nowait():
return os.EX_DATAERR
except Empty:
pass
return os.EX_OK
while not result_queue.empty():
passed = result_queue.get()
all_passed = all_passed and passed

return exits.OK if all_passed else exits.DATAERR


def run(name):
Expand Down

0 comments on commit fdeffb7

Please sign in to comment.