[Piglit] [PATCH 12/49] unittests: port core_tests to pytest

Dylan Baker dylan at pnwbakers.com
Fri Jul 29 18:38:58 UTC 2016


Signed-off-by: Dylan Baker <dylanx.c.baker at intel.com>
---
 tox.ini                          |   5 +-
 unittests/core_tests.py          | 289 ---------------------------------------
 unittests/framework/skip.py      |  47 +++++++
 unittests/framework/test_core.py | 271 ++++++++++++++++++++++++++++++++++++
 4 files changed, 322 insertions(+), 290 deletions(-)
 delete mode 100644 unittests/core_tests.py
 create mode 100644 unittests/framework/skip.py
 create mode 100644 unittests/framework/test_core.py

diff --git a/tox.ini b/tox.ini
index 908a5b1..3f73add 100644
--- a/tox.ini
+++ b/tox.ini
@@ -6,7 +6,9 @@ skipsdist = True
 python_paths = framework/ generated_tests/
 
 [testenv]
-passenv=HOME
+passenv=
+    HOME
+    USERPROFILE
 setenv =
     USERNAME = foo
 deps =
@@ -19,6 +21,7 @@ deps =
     py27-accel-nix: subprocess32
     py35: mako==1.0.2
     pytest
+    pytest-mock
     pytest-pythonpath
     pytest-raises
     pytest-warnings
diff --git a/unittests/core_tests.py b/unittests/core_tests.py
deleted file mode 100644
index 7cb6745..0000000
--- a/unittests/core_tests.py
+++ /dev/null
@@ -1,289 +0,0 @@
-# Copyright (c) 2014 Intel Corporation
-
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-""" Module providing tests for the core module """
-
-from __future__ import (
-    absolute_import, division, print_function, unicode_literals
-)
-import collections
-import errno
-import functools
-import os
-import shutil
-import textwrap
-
-# There is a very high potential that one of these will raise an ImportError
-# pylint: disable=import-error
-try:
-    import mock
-except ImportError:
-    from unittest import mock
-# pylint: enable=import-error
-
-import nose.tools as nt
-import six
-try:
-    from six.moves import getcwd
-except ImportError:
-    # pylint: disable=no-member
-    if six.PY2:
-        getcwd = os.getcwdu
-    elif six.PY3:
-        getcwd = os.getcwd
-    # pylint: enable=no-member
-
-from framework import core, exceptions
-from . import utils
-
-# pylint: disable=line-too-long,invalid-name
-
-_CONF_FILE = textwrap.dedent("""\
-[nose-test]
-; a section for testing behavior
-dir = foo
-""")
-
-
- at utils.nose.no_error
-def test_PiglitConfig_init():
-    """core.PiglitConfig: initializes"""
-    core.PiglitConfig()
-
-
-def test_parse_listfile_return():
-    """core.parse_listfile(): returns a list-like object
-
-    Given a file with a newline separated list of results, parse_listfile
-    should return a list of files with no whitespace
-
-    """
-    contents = "/tmp/foo\n/tmp/bar\n"
-
-    with utils.nose.tempfile(contents) as tfile:
-        results = core.parse_listfile(tfile)
-
-    nt.ok_(isinstance(results, collections.Container))
-
-
-class Test_parse_listfile_TrailingWhitespace(object):
-    """Test that parse_listfile removes whitespace"""
-    @classmethod
-    def setup_class(cls):
-        contents = "/tmp/foo\n/tmp/foo  \n/tmp/foo\t\n"
-        with utils.nose.tempfile(contents) as tfile:
-            cls.results = core.parse_listfile(tfile)
-
-    def test_newlines(self):
-        """core.parse_listfile(): Remove trailing newlines"""
-        nt.assert_equal(self.results[0], "/tmp/foo",
-                        msg="Trailing newline not removed!")
-
-    def test_spaces(self):
-        """core.parse_listfile(): Remove trailing spaces"""
-        nt.assert_equal(self.results[1], "/tmp/foo",
-                        msg="Trailing spaces not removed!")
-
-    def test_tabs(self):
-        """core.parse_listfile(): Remove trailing tabs"""
-        nt.assert_equal(self.results[2], "/tmp/foo",
-                        msg="Trailing tabs not removed!")
-
- at utils.nose.Skip.platform('win32', is_=True)
-def test_parse_listfile_tilde():
-    """core.parse_listfile(): tildes (~) are properly expanded.
-
-    According to the python docs for python 2.7
-    (http://docs.python.org/2/library/os.path.html#module-os.path), both
-    os.path.expanduser and os.path.expandvars work on both *nix systems (Linux,
-    *BSD, OSX) and Windows.
-
-    """
-    contents = "~/foo\n"
-    expected = os.path.expandvars("$HOME/foo")
-
-    with utils.nose.tempfile(contents) as tfile:
-        results = core.parse_listfile(tfile)
-
-    nt.eq_(results[0], expected,
-           msg='expected: {} but got: {}'.format(expected, results[0]))
-
-
- at mock.patch('framework.core.os.environ', {})
-def test_xdg_config_home():
-    """core.get_config() finds $XDG_CONFIG_HOME/piglit.conf"""
-    with utils.nose.tempdir() as tdir:
-        os.environ['XDG_CONFIG_HOME'] = tdir
-        with open(os.path.join(tdir, 'piglit.conf'), 'w') as f:
-            f.write(_CONF_FILE)
-        core.get_config()
-
-    nt.ok_(core.PIGLIT_CONFIG.has_section('nose-test'),
-           msg='$XDG_CONFIG_HOME not found')
-
-
- at mock.patch('framework.core.os.environ', {})
-def test_config_home_fallback():
-    """core.get_config() finds $HOME/.config/piglit.conf"""
-    with utils.nose.tempdir() as tdir:
-        os.environ['HOME'] = tdir
-        os.mkdir(os.path.join(tdir, '.config'))
-        with open(os.path.join(tdir, '.config/piglit.conf'), 'w') as f:
-            f.write(_CONF_FILE)
-        core.get_config()
-
-        nt.ok_(core.PIGLIT_CONFIG.has_section('nose-test'),
-               msg='$HOME/.config/piglit.conf not found')
-
-
- at mock.patch('framework.core.os.environ', {})
- at utils.nose.test_in_tempdir
-def test_local():
-    """core.get_config() finds ./piglit.conf"""
-    with utils.nose.tempdir() as tdir:
-        with utils.nose.chdir(tdir):
-            with open(os.path.join(tdir, 'piglit.conf'), 'w') as f:
-                f.write(_CONF_FILE)
-            core.get_config()
-
-    nt.ok_(core.PIGLIT_CONFIG.has_section('nose-test'),
-           msg='./piglit.conf not found')
-
-
- at mock.patch('framework.core.os.environ', {})
-def test_piglit_root():
-    """core.get_config() finds "piglit root"/piglit.conf"""
-    with open('piglit.conf', 'w') as f:
-        f.write(_CONF_FILE)
-        with utils.nose.chdir('..'):
-            core.get_config()
-    os.unlink('piglit.conf')
-
-    nt.ok_(core.PIGLIT_CONFIG.has_section('nose-test'),
-           msg='$PIGLIT_ROOT not found')
-
-
-class TestPiglitConfig(object):
-    """Tests for PiglitConfig methods."""
-    @classmethod
-    def setup_class(cls):
-        cls.conf = core.PiglitConfig()
-        cls.conf.add_section('set')
-        cls.conf.set('set', 'options', 'bool')
-
-    def test_safe_get_valid(self):
-        """core.PiglitConfig: safe_get returns a value if its in the Config"""
-        nt.assert_equal(self.conf.safe_get('set', 'options'), 'bool')
-
-    def test_PiglitConfig_required_get_valid(self):
-        """core.PiglitConfig: required_get returns a value if its in the Config
-        """
-        nt.assert_equal(self.conf.required_get('set', 'options'), 'bool')
-
-    def test_safe_get_missing_option(self):
-        """core.PiglitConfig: safe_get returns None if the option is missing
-        """
-        nt.assert_equal(self.conf.safe_get('set', 'invalid'), None)
-
-    def test_safe_get_missing_section(self):
-        """core.PiglitConfig: safe_get returns None if the section is missing
-        """
-        nt.assert_equal(self.conf.safe_get('invalid', 'invalid'), None)
-
-    @nt.raises(exceptions.PiglitFatalError)
-    def test_required_get_missing_option(self):
-        """core.PiglitConfig: required_get raises PiglitFatalError if the option is missing
-        """
-        self.conf.required_get('set', 'invalid')
-
-    @nt.raises(exceptions.PiglitFatalError)
-    def test_required_get_missing_section(self):
-        """core.PiglitConfig: required_get raises PiglitFatalError if the section is missing
-        """
-        self.conf.required_get('invalid', 'invalid')
-
-    def test_safe_get_fallback(self):
-        """core.PiglitConfig: safe_get returns the value of fallback when the section or option is missing"""
-        nt.eq_(self.conf.safe_get('invalid', 'invalid', fallback='foo'), 'foo')
-
-
- at utils.nose.capture_stderr
- at nt.raises(exceptions.PiglitException)
-def test_check_dir_exists_fail():
-    """core.check_dir: if the directory exists and failifexsits is True fail"""
-    with mock.patch('framework.core.os.stat', mock.Mock(side_effect=OSError)):
-        core.check_dir('foo', True)
-
-
-def test_check_dir_stat_ENOENT():
-    """core.check_dir: if the directory exists (ENOENT) and failifexsits is False continue"""
-    with mock.patch('framework.core.os.stat',
-                    mock.Mock(side_effect=OSError('foo', errno.ENOENT))):
-        with mock.patch('framework.core.os.makedirs') as makedirs:
-            core.check_dir('foo', False)
-            nt.eq_(makedirs.called, 1)
-
-
-def test_check_dir_stat_ENOTDIR():
-    """core.check_dir: if a file exists (ENOTDIR) and failifexsits is False continue"""
-    with mock.patch('framework.core.os.stat',
-                    mock.Mock(side_effect=OSError('foo', errno.ENOTDIR))):
-        with mock.patch('framework.core.os.makedirs') as makedirs:
-            core.check_dir('foo', False)
-            nt.eq_(makedirs.called, 1)
-
-
- at utils.nose.not_raises(OSError)
-def test_check_dir_makedirs_pass():
-    """core.check_dir: If makedirs fails with EEXIST pass"""
-    with mock.patch('framework.core.os.stat', mock.Mock()):
-        with mock.patch('framework.core.os.makedirs',
-                        mock.Mock(side_effect=OSError(errno.EEXIST, 'foo'))):
-            core.check_dir('foo', False)
-
-
- at nt.raises(OSError)
-def test_check_dir_makedirs_fail():
-    """core.check_dir: If makedirs fails with any other raise"""
-    with mock.patch('framework.core.os.stat', mock.Mock()):
-        with mock.patch('framework.core.os.path.exists',
-                        mock.Mock(return_value=False)):
-            with mock.patch('framework.core.os.makedirs',
-                            mock.Mock(side_effect=OSError)):
-                core.check_dir('foo', False)
-
-
- at nt.raises(utils.nose.SentinalException)
-def test_check_dir_handler():
-    """core.check_dir: Handler is called if not failifexists."""
-    with mock.patch('framework.core.os.stat',
-                    mock.Mock(side_effect=OSError('foo', errno.ENOTDIR))):
-        core.check_dir('foo',
-                       handler=mock.Mock(side_effect=utils.nose.SentinalException))
-
-
- at utils.nose.Skip.py2
-def test_check_dir_stat_FileNotFoundError():
-    """core.check_dir: FileNotFoundError is raised and failifexsits is False continue"""
-    with mock.patch('framework.core.os.stat',
-                    mock.Mock(side_effect=FileNotFoundError)):
-        with mock.patch('framework.core.os.makedirs') as makedirs:
-            core.check_dir('foo', False)
-            nt.eq_(makedirs.called, 1)
diff --git a/unittests/framework/skip.py b/unittests/framework/skip.py
new file mode 100644
index 0000000..4600c7a
--- /dev/null
+++ b/unittests/framework/skip.py
@@ -0,0 +1,47 @@
+# encoding=utf-8
+# Copyright © 2016 Intel corporation
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""Extra pytest skip fixtures.
+
+There are a number of repeated conditions for skipping, python version, os name
+or class, etc.
+"""
+
+from __future__ import (
+    absolute_import, division, print_function, unicode_literals
+)
+import os
+import sys
+
+import pytest
+import six
+
+# pylint: disable=invalid-name
+
+PY2 = pytest.mark.skipif(six.PY2, reason="Test isn't relavent on python 2.x")
+PY3 = pytest.mark.skipif(six.PY3, reason="Test isn't relavent on python 3.x")
+posix = pytest.mark.skipif(
+    os.name != 'posix', reason="Test is only relavent on posix systems.")
+windows = pytest.mark.skipif(
+    os.name != 'nt', reason="Test is only relavent on Microsoft Windows.")
+linux = pytest.mark.skipif(
+    not sys.platform.startswith('linux'),
+    reason="Test is only relavent on Linux OSes.")
diff --git a/unittests/framework/test_core.py b/unittests/framework/test_core.py
new file mode 100644
index 0000000..823e0d4
--- /dev/null
+++ b/unittests/framework/test_core.py
@@ -0,0 +1,271 @@
+# Copyright (c) 2014, 2016 Intel Corporation
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+""" Module providing tests for the core module """
+
+from __future__ import (
+    absolute_import, division, print_function, unicode_literals
+)
+import collections
+import errno
+import os
+import textwrap
+
+import pytest
+import six
+
+from framework import core
+from framework import exceptions
+
+from . import skip
+
+# Making good test names often flies in the face of PEP8 recomendations, ignore
+# those
+# pylint: disable=invalid-name
+#
+# For testing purposes (and to get good names) it's useful to use classes for
+# grouping tests. Often these tests share no state, which would be bad if they
+# were not tests, but that's kind of the way python testing works.
+# pylint: disable=no-self-use
+
+
+class TestParseListfile(object):
+    """Tests for core.parse_listfile."""
+
+    def test_parse_listfile_return(self, tmpdir):
+        """core.parse_listfile(): returns a list-like object.
+
+        Given a file with a newline separated list of results, parse_listfile
+        should return a list of files with no whitespace.
+        """
+        f = tmpdir.join('test.list')
+        f.write("/tmp/foo\n/tmp/bar\n")
+        results = core.parse_listfile(six.text_type(f))
+        assert isinstance(results, collections.Container)
+
+    def test_parse_listfile_whitespace(self, tmpdir):
+        """parse_listfile should remove various kinds of trailing whitespace.
+
+        It is important it doesn't touch whitespace in lines, however.
+        """
+        f = tmpdir.join('test.list')
+        f.write(textwrap.dedent("""\
+            space between
+            tab\t
+            space
+            newline
+        """))
+        results = core.parse_listfile(six.text_type(f))
+
+        assert results[0] == 'space between'
+        assert results[1] == 'tab'
+        assert results[2] == 'space'
+        assert results[3] == 'newline'
+
+    def test_parse_listfile_tilde_posix(self, tmpdir):
+        """core.parse_listfile(): tildes (~) are properly expanded.
+
+        According to the python docs for python 2.7
+        (http://docs.python.org/2/library/os.path.html#module-os.path), both
+        os.path.expanduser and os.path.expandvars work on both *nix systems
+        (Linux, *BSD, OSX) and Windows.
+        """
+        if os.name == 'posix':
+            expected = os.path.expandvars('$HOME')
+        else:
+            expected = os.path.expandvars('%USERPROFILE%')
+        expected = os.path.normpath(os.path.join(expected, 'foo'))
+
+        f = tmpdir.join('test.list')
+        f.write("~/foo\n")
+        results = core.parse_listfile(six.text_type(f))
+        assert os.path.normpath(results[0]) == expected
+
+
+class TestGetConfig(object):
+    """Tests for core.get_config."""
+    _CONF_FILE = textwrap.dedent("""\
+        [nose-test]
+        ; a section for testing behavior
+        dir = foo""")
+
+    @skip.linux
+    def test_config_in_xdg_config_home(self, tmpdir, mocker):
+        """core.get_config() finds $XDG_CONFIG_HOME/piglit.conf"""
+        env = mocker.patch('framework.core.os.environ', new={})
+        env['XDG_CONFIG_HOME'] = six.text_type(tmpdir)
+        conf = tmpdir.join('piglit.conf')
+        conf.write(self._CONF_FILE)
+        core.get_config()
+
+        assert core.PIGLIT_CONFIG.has_section('nose-test')
+
+    @skip.linux
+    def test_config_in_home_dir(self, tmpdir, mocker):
+        """core.get_config() finds $HOME/.config/piglit.conf"""
+        env = mocker.patch('framework.core.os.environ', new={})
+        env['HOME'] = six.text_type(tmpdir)
+        conf = tmpdir.join('piglit.conf')
+        conf.write(self._CONF_FILE)
+        core.get_config()
+
+        assert core.PIGLIT_CONFIG.has_section('nose-test')
+
+    def test_config_in_current(self, tmpdir, mocker):
+        """core.get_config() finds ./piglit.conf"""
+        mocker.patch('framework.core.os.environ', new={})
+        conf = tmpdir.join('piglit.conf')
+        conf.write(self._CONF_FILE)
+
+        ret = tmpdir.chdir()
+        try:
+            core.get_config()
+        finally:
+            os.chdir(six.text_type(ret))
+
+        assert core.PIGLIT_CONFIG.has_section('nose-test')
+
+    def test_config_in_piglit_root(self, mocker, tmpdir):
+        """core.get_config() finds "piglit root"/piglit.conf"""
+        # Mock the __file__ attribute of the core module, since that's how
+        # piglit decides where the root of the piglit directory is.
+        mocker.patch('framework.core.__file__',
+                     six.text_type(tmpdir.join('framework', 'core.py')))
+        mocker.patch('framework.core.os.environ', new={})
+        conf = tmpdir.join('piglit.conf')
+        conf.write(self._CONF_FILE)
+        core.get_config()
+
+        assert core.PIGLIT_CONFIG.has_section('nose-test')
+
+
+class TestPiglitConfig(object):
+    """Tests for PiglitConfig methods."""
+    @classmethod
+    def setup_class(cls):
+        cls.conf = core.PiglitConfig()
+        cls.conf.add_section('set')
+        cls.conf.set('set', 'options', 'bool')
+
+    def test_safe_get_valid(self):
+        """core.PiglitConfig: safe_get returns a value if its in the Config."""
+        assert self.conf.safe_get('set', 'options') == 'bool'
+
+    def test_PiglitConfig_required_get_valid(self):
+        """core.PiglitConfig: required_get returns a value if its in the
+        Config."""
+        assert self.conf.required_get('set', 'options') == 'bool'
+
+    def test_safe_get_missing_option(self):
+        """core.PiglitConfig: safe_get returns None if the option is missing.
+        """
+        assert self.conf.safe_get('set', 'invalid') is None
+
+    def test_safe_get_missing_section(self):
+        """core.PiglitConfig: safe_get returns None if the section is missing.
+        """
+        assert self.conf.safe_get('invalid', 'invalid') is None
+
+    def test_required_get_missing_option(self):
+        """core.PiglitConfig: required_get raises PiglitFatalError if the
+        option is missing."""
+        with pytest.raises(exceptions.PiglitFatalError):
+            self.conf.required_get('set', 'invalid')
+
+    def test_required_get_missing_section(self):
+        """core.PiglitConfig: required_get raises PiglitFatalError if the
+        section is missing."""
+        with pytest.raises(exceptions.PiglitFatalError):
+            self.conf.required_get('invalid', 'invalid')
+
+    def test_safe_get_fallback(self):
+        """core.PiglitConfig: safe_get returns the value of fallback when the
+        section or option is missing."""
+        assert self.conf.safe_get('invalid', 'invalid', fallback='foo') == 'foo'
+
+
+class TestCheckDir(object):
+    """Tests for core.check_dir."""
+
+    def test_exists_fail(self, mocker, tmpdir):
+        """core.check_dir: if the directory exists and failifexsits is True
+        fail."""
+        tmpdir.chdir()
+        mocker.patch('framework.core.os.stat', mocker.Mock(side_effect=OSError))
+        with pytest.raises(exceptions.PiglitException):
+            core.check_dir('foo', True)
+
+    def test_not_exists_and_not_fail(self, mocker, tmpdir):
+        """core.check_dir: if the directory doesn't exists (ENOENT) and
+        failifexists is False continue."""
+        tmpdir.chdir()
+        mocker.patch('framework.core.os.stat',
+                     mocker.Mock(side_effect=OSError('foo', errno.ENOENT)))
+        makedirs = mocker.patch('framework.core.os.makedirs')
+
+        core.check_dir('foo', False)
+
+        assert makedirs.called == 1
+
+    def test_exists_and_not_fail(self, mocker, tmpdir):
+        """core.check_dir: If makedirs fails with EEXIST pass"""
+        tmpdir.chdir()
+        mocker.patch('framework.core.os.stat', mocker.Mock())
+        makedirs = mocker.patch(
+            'framework.core.os.makedirs',
+            mocker.Mock(side_effect=OSError(errno.EEXIST, 'foo')))
+
+        core.check_dir('foo', False)
+
+        assert makedirs.called == 0
+
+    def test_makedirs_fail(self, mocker, tmpdir):
+        """core.check_dir: If makedirs fails with any other raise that error."""
+        tmpdir.chdir()
+        mocker.patch('framework.core.os.makedirs',
+                     mocker.Mock(side_effect=OSError))
+
+        with pytest.raises(OSError):
+            core.check_dir('foo', False)
+
+    def test_handler(self, mocker, tmpdir):
+        """core.check_dir: Handler is called if not failifexists."""
+        class Sentinel(Exception):
+            pass
+
+        tmpdir.chdir()
+
+        mocker.patch('framework.core.os.stat',
+                     mocker.Mock(side_effect=OSError('foo', errno.ENOTDIR)))
+        with pytest.raises(Sentinel):
+            core.check_dir('foo', handler=mocker.Mock(side_effect=Sentinel))
+
+    @skip.PY2
+    def test_stat_FileNotFoundError(self, mocker, tmpdir):
+        """core.check_dir: FileNotFoundError is raised and failifexsits is
+        False continue."""
+        tmpdir.chdir()
+        mocker.patch('framework.core.os.stat',
+                     mocker.Mock(side_effect=FileNotFoundError))
+        makedirs = mocker.patch('framework.core.os.makedirs')
+
+        core.check_dir('foo', False)
+
+        assert makedirs.called == 1
-- 
2.9.0



More information about the Piglit mailing list