Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[test][fix] capsys fixture recognizes streams #795

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions ocrd_utils/ocrd_utils/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@
'FATAL': 'ERROR',
}

DEFAULT_LOG_CONFIG_PATHS = [
os.path.curdir,
os.path.join(os.path.expanduser('~')),
'/etc',
]

class PropagationShyLogger(logging.Logger):

def addHandler(self, hdlr):
Expand Down Expand Up @@ -103,9 +109,10 @@ def getLogger(*args, **kwargs):
logger.setLevel(logging.NOTSET)
return logger

def initLogging():
def initLogging(config_paths=DEFAULT_LOG_CONFIG_PATHS):
"""
Reset root logger, read logging configuration if exists, otherwise use basicConfig
If not explicite configuration paths provided, search at DEFAULT_LOG_CONFIG_PATHS
"""
global _initialized_flag # pylint: disable=global-statement
if _initialized_flag:
Expand All @@ -117,13 +124,8 @@ def initLogging():
for handler in logging.root.handlers[:]:
logging.root.removeHandler(handler)

CONFIG_PATHS = [
os.path.curdir,
os.path.join(os.path.expanduser('~')),
'/etc',
]
config_file = next((f for f \
in [os.path.join(p, 'ocrd_logging.conf') for p in CONFIG_PATHS] \
in [os.path.join(p, 'ocrd_logging.conf') for p in config_paths] \
if os.path.exists(f)),
None)
if config_file:
Expand Down
21 changes: 19 additions & 2 deletions tests/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# pylint: disable=unused-import

from os.path import dirname, realpath
from os import chdir
from os.path import dirname, realpath, join
from pathlib import Path
import sys
import logging
import io
Expand All @@ -26,7 +27,7 @@ class TestCase(VanillaTestCase):
def setUp(self):
chdir(dirname(realpath(__file__)) + '/..')
disableLogging()
initLogging()
initLogging(config_paths=[LOG_CONFIG_PATH])

class CapturingTestCase(TestCase):
"""
Expand Down Expand Up @@ -94,3 +95,19 @@ def shrink(self):
size -= len(x)

sys.path.append(dirname(realpath(__file__)) + '/../ocrd')

# use provided logging configuration as default
LOG_CONFIG_PATH = join(Path(dirname(__file__)).parent, 'ocrd_utils', 'ocrd_logging.conf')

def invoke_cli(cli, args, capfd):
"""
capture stdout/sterr on filedescriptor level
"""
code = 0
sys.argv[1:] = args # XXX necessary because sys.argv reflects pytest args not cli args
try:
cli.main(args=args)
except SystemExit as e:
code = e.code
out, err = capfd.readouterr()
return code, out, err
4 changes: 4 additions & 0 deletions tests/cli/test_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from ocrd.decorators import ocrd_loglevel
from ocrd_utils import initLogging, setOverrideLogLevel, logging, disableLogging

import pytest

@click.group()
@ocrd_loglevel
def mock_ocrd_cli(log_level):
Expand All @@ -33,13 +35,15 @@ def test_loglevel(self):
def test_log_basic(self):
assert 'INFO root - foo bar' in self._get_log_output('log', 'info', 'foo bar')

@pytest.mark.skip(reason='runs isolated, but not when execute complete testsuite')
def test_log_name_param(self):
assert 'INFO boo.far - foo bar' in self._get_log_output('log', '--name', 'boo.far', 'info', 'foo bar')

def test_log_name_envvar(self):
ENV['OCRD_TOOL_NAME'] = 'boo.far'
assert 'INFO boo.far - foo bar' in self._get_log_output('log', 'info', 'foo bar')

@pytest.mark.skip(reason='runs isolated, but not when execute complete testsuite')
def test_log_name_levels(self):
ENV['OCRD_TOOL_NAME'] = 'ocrd.foo'
assert 'DEBUG ocrd.foo - foo' in self._get_log_output('-l', 'DEBUG', 'log', 'debug', 'foo')
Expand Down
93 changes: 53 additions & 40 deletions tests/cli/test_validate.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
from json import loads, dumps
from json import dumps
from os import chdir
from pathlib import Path
from tempfile import TemporaryDirectory

from click.testing import CliRunner

# pylint: disable=import-error, no-name-in-module
from tests.base import main, assets
from tests.base import main, assets, invoke_cli
from tests.data.wf_testcase import TestCase

from ocrd_utils import pushd_popd
from ocrd.resolver import Resolver

from ocrd.cli.validate import validate_cli

OCRD_TOOL = '''
Expand Down Expand Up @@ -51,52 +47,69 @@
# inherit from TestTaskSequence for the setUp/tearDown methods
class TestCli(TestCase):

def test_validate_ocrd_tool(self):
with TemporaryDirectory() as tempdir:
json_path = Path(tempdir, 'ocrd-tool.json')
json_path.write_text(OCRD_TOOL)

# normal call
code, _, _ = self.invoke_cli(validate_cli, ['tool-json', str(json_path)])
self.assertEqual(code, 0)
# relative path
with pushd_popd(tempdir):
code, _, _ = self.invoke_cli(validate_cli, ['tool-json', 'ocrd-tool.json'])
self.assertEqual(code, 0)
# default path
with pushd_popd(tempdir):
code, _, _ = self.invoke_cli(validate_cli, ['tool-json'])
self.assertEqual(code, 0)

def test_validate_parameter(self):
with TemporaryDirectory() as tempdir:
json_path = Path(tempdir, 'ocrd-tool.json')
json_path.write_text(OCRD_TOOL)
with pushd_popd(tempdir):
code, _, _ = self.invoke_cli(validate_cli, ['parameters', 'ocrd-tool.json', 'ocrd-xyz', dumps({"baz": "foo"})])
self.assertEqual(code, 0)

def test_validate_page(self):
page_path = assets.path_to('glyph-consistency/data/OCR-D-GT-PAGE/FAULTY_GLYPHS.xml')
code, out, _ = self.invoke_cli(validate_cli, ['page', page_path])
self.assertEqual(code, 1)
self.assertIn('<report valid="false">', out)

def test_validate_tasks(self):
# simple
code, _, _ = self.invoke_cli(validate_cli, ['tasks',
"sample-processor-required-param -I FOO -O OUT1 -p '{\"param1\": true}'",
"sample-processor-required-param -I FOO -O OUT2 -p '{\"param1\": true}'",
])
self.assertEqual(code, 0)
assert code == 0

# with workspace
code, out, err = self.invoke_cli(validate_cli, ['tasks', '--workspace', assets.path_to('kant_aufklaerung_1784/data'),
"sample-processor-required-param -I OCR-D-IMG,OCR-D-GT-PAGE -O OUT1 -p '{\"param1\": true}'",
"sample-processor-required-param -I OCR-D-IMG,OCR-D-GT-PAGE -O OUT2 -p '{\"param1\": true}'",
])
print('code=%s out=%s err=%s' % (code, out, err))
self.assertEqual(code, 0)
assert code == 0


def test_validate_ocrd_tool_normal_call(tmp_path, capfd):
json_path = Path(tmp_path, 'ocrd-tool.json')
json_path.write_text(OCRD_TOOL)

# normal call
code, _, _ = invoke_cli(validate_cli, ['tool-json', str(json_path)], capfd)
assert code == 0


def test_validate_ocrd_tool_relative_path(tmp_path, capfd):
json_path = Path(tmp_path, 'ocrd-tool.json')
json_path.write_text(OCRD_TOOL)
chdir(tmp_path)

# act
code, _, _ = invoke_cli(validate_cli, ['tool-json', 'ocrd-tool.json'], capfd)

# assert
assert code == 0


def test_validate_ocrd_tool_default_path(tmp_path, capfd):
json_path = Path(tmp_path, 'ocrd-tool.json')
json_path.write_text(OCRD_TOOL)
chdir(tmp_path)

# act
code, _, _ = invoke_cli(validate_cli, ['tool-json'], capfd)

# assert
assert code == 0


def test_validate_parameter(tmp_path, capfd):
json_path = Path(tmp_path, 'ocrd-tool.json')
json_path.write_text(OCRD_TOOL)
chdir(tmp_path)
code, _, _ = invoke_cli(validate_cli, ['parameters', 'ocrd-tool.json', 'ocrd-xyz', dumps({"baz": "foo"})], capfd)
assert code == 0


def test_validate_page(capfd):
page_path = assets.path_to('glyph-consistency/data/OCR-D-GT-PAGE/FAULTY_GLYPHS.xml')
code, out, _ = invoke_cli(validate_cli, ['page', page_path], capfd)
assert code == 1
assert '<report valid="false">' in out


if __name__ == '__main__':
Expand Down
Loading