Skip to content

Commit

Permalink
Fix #46 We need 100% coverage (#72)
Browse files Browse the repository at this point in the history
This adds a bunch of exception testing to get 100% coverage.

Signed-off-by: David Brown <dmlb2000@gmail.com>
  • Loading branch information
dmlb2000 committed Feb 6, 2019
1 parent 11a37e5 commit 09e3a14
Show file tree
Hide file tree
Showing 10 changed files with 282 additions and 102 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ stages:
- export ARCHIVEINTERFACE_CPCONFIG=$PWD/server.conf
- cd tests
- coverage run --include '*/site-packages/pacifica/archiveinterface/*' --omit '*/site-packages/pacifica/archiveinterface/backends/abstract/*' -m pytest -v
- coverage report -m --fail-under 80
- coverage report -m --fail-under 100
jobs:
include:
- stage: lint
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ test_script:
$env:ARCHIVEINTERFACE_CPCONFIG = "$PWD/server.conf";
cd tests;
coverage run --include='*/site-packages/pacifica/archiveinterface/*' --omit '*/site-packages/pacifica/archiveinterface/backends/abstract/*' -m pytest -v;
coverage report -m --fail-under=80;
coverage report -m --fail-under=100;
5 changes: 1 addition & 4 deletions pacifica/archiveinterface/backends/posix/archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,7 @@ def status(self):
def patch(self, file_id, old_path):
"""Move a posix file."""
try:
if get_config().get('posix', 'use_id2filename') == 'true':
fpath = un_abs_path(id2filename(int(un_abs_path(file_id))))
else:
fpath = un_abs_path(file_id)
fpath = un_abs_path(self._id2filename(file_id))
new_filepath = os.path.join(self._prefix, fpath)
new_directories = os.path.dirname(new_filepath)
if not os.path.exists(new_directories):
Expand Down
6 changes: 3 additions & 3 deletions pacifica/archiveinterface/backends/posix/extendedfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ def extended_file_factory(filepath, mode):
# pylint: disable=undefined-variable
file_obj_cls = file # noqa
# pylint: enable=undefined-variable
elif 'r' in mode:
elif 'r' in mode: # pragma: no cover only one version of python
from io import BufferedReader
file_obj_cls = BufferedReader
else:
else: # pragma: no cover only one version of python
from io import BufferedWriter
file_obj_cls = BufferedWriter

Expand All @@ -37,7 +37,7 @@ def __init__(self, filepath, mode, *args, **kwargs):
if PY2: # pragma: no cover only one version of python
super(ExtendedFile, self).__init__(
filepath, mode, *args, **kwargs)
else:
else: # pragma: no cover only one version of python
from io import FileIO
file_obj = FileIO(filepath, mode)
super(ExtendedFile, self).__init__(file_obj)
Expand Down
2 changes: 1 addition & 1 deletion pacifica/archiveinterface/rest_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def PUT(self, filepath):
try:
content_length = int(
cherrypy.request.headers.get('Content-Length'))
except Exception as ex:
except Exception as ex: # pragma: no cover it's hard to get a client to not do this
raise ArchiveInterfaceError(
"Can't get file content length with error: {}".format(str(ex))
)
Expand Down
4 changes: 2 additions & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-r requirements.txt
codeclimate-test-reporter
coverage>4.0,<4.4
coverage
mock
pep257
pre-commit
pylint<2
Expand Down
11 changes: 11 additions & 0 deletions tests/cherrypy_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ def test_interface(self):
self.assertEqual(resp.raw.read(), bytes_type('The data in 1234'))
resp = requests.head('{}/1234'.format(self.url))
self.assertEqual(resp.status_code, 204)
resp = requests.post('{}/1234'.format(self.url))
self.assertEqual(resp.status_code, 200)

with open('/tmp/cptests/222', 'w') as test_fd:
test_fd.write('this is file 222')
resp = requests.patch(
'{}/1235'.format(self.url),
headers={'Content-Type': 'application/json'},
data='{ "path": "/tmp/cptests/222" }'
)
self.assertEqual(resp.status_code, 200)

def test_error_interface(self):
"""Test some error states."""
Expand Down
59 changes: 59 additions & 0 deletions tests/extended_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""File used to unit test the pacifica archive interface."""
import unittest
import os
from pacifica.archiveinterface.backends.posix.extendedfile import extended_file_factory
from pacifica.archiveinterface.backends.posix.status import PosixStatus


class TestExtendedFile(unittest.TestCase):
"""Test the ExtendedFile Class."""

def test_posix_file_status(self):
"""Test the correct values of a files status."""
filepath = '{}{}'.format(os.path.sep, os.path.join('tmp', '1234'))
my_file = extended_file_factory(filepath, 'w')
status = my_file.status()
self.assertTrue(isinstance(status, PosixStatus))
self.assertEqual(status.filesize, 0)
self.assertEqual(status.file_storage_media, 'disk')
my_file.close()

def test_posix_file_stage(self):
"""Test the correct staging of a posix file."""
filepath = '{}{}'.format(os.path.sep, os.path.join('tmp', '1234'))
mode = 'w'
my_file = extended_file_factory(filepath, mode)
my_file.stage()
# easiest way to unit test is look at class variable
# pylint: disable=protected-access
self.assertTrue(my_file._staged)
# pylint: enable=protected-access
my_file.close()


class TestPosixStatus(unittest.TestCase):
"""Test the POSIXStatus Class."""

def test_posix_status_object(self):
"""Test the correct creation of posix status object."""
status = PosixStatus(0o36, 0o35, 15, 15)
self.assertEqual(status.mtime, 0o36)
self.assertEqual(status.ctime, 0o35)
self.assertEqual(status.bytes_per_level, 15)
self.assertEqual(status.filesize, 15)
self.assertEqual(status.defined_levels, ['disk'])
self.assertEqual(status.file_storage_media, 'disk')

def test_posix_status_storage_media(self):
"""Test the correct finding of posix storage media."""
status = PosixStatus(0o36, 0o35, 15, 15)
value = status.find_file_storage_media()
self.assertEqual(value, 'disk')

def test_posix_status_levels(self):
"""Test the correct setting of file storage levels."""
status = PosixStatus(0o36, 0o35, 15, 15)
value = status.define_levels()
self.assertEqual(value, ['disk'])
195 changes: 195 additions & 0 deletions tests/posix_failure_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""File used to unit test the pacifica archive interface."""
import unittest
import mock
from pacifica.archiveinterface.backends.posix.archive import PosixBackendArchive
from pacifica.archiveinterface.exception import ArchiveInterfaceError


class TestPosixBackendArchive(unittest.TestCase):
"""Test the Posix backend archive."""

def test_posix_backend_error(self):
"""Test opening a file from posix backend."""
with self.assertRaises(ArchiveInterfaceError):
filepath = '1234'
mode = 'w'
backend = PosixBackendArchive('/tmp')
# easiest way to unit test is look at class variable
# pylint: disable=protected-access
backend._file = 'none file object'
backend.open(filepath, mode)
# pylint: enable=protected-access

@mock.patch('os.utime')
def test_posix_file_mod_time_failed(self, mock_utime):
"""Test the correct setting of a file mod time."""
filepath = '1234'
mode = 'w'
backend = PosixBackendArchive('/tmp/')
my_file = backend.open(filepath, mode)
my_file.close()
mock_utime.side_effect = OSError('Unable to set utime.')
hit_exception = False
try:
my_file.set_mod_time(1000000)
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue("Can't set posix file mod time with error" in str(ex))
self.assertTrue(hit_exception)

@mock.patch('os.chmod')
def test_posix_file_perms_failed(self, mock_chmod):
"""Test the correct setting of a file mod time."""
filepath = '1235'
mode = 'w'
backend = PosixBackendArchive('/tmp/')
my_file = backend.open(filepath, mode)
my_file.close()
hit_exception = False
mock_chmod.side_effect = OSError('Unable to chmod.')
try:
my_file.set_file_permissions()
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue("Can't set posix file permissions with error" in str(ex))
self.assertTrue(hit_exception)

def test_posix_backend_failed_write(self):
"""Test writing to a failed file."""
filepath = '1234'
mode = 'w'
backend = PosixBackendArchive('/tmp/')
# test failed write
backend.open(filepath, mode)

# easiest way to unit test is look at class variable
# pylint: disable=protected-access
backend._file.write = mock.MagicMock(side_effect=IOError('Unable to Write!'))
# pylint: enable=protected-access
hit_exception = False
try:
backend.write('write stuff')
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue("Can't write posix file with error" in str(ex))
self.assertTrue(hit_exception)

def test_posix_backend_failed_stat(self):
"""Test status to a failed file."""
filepath = '1234'
mode = 'r'
backend = PosixBackendArchive('/tmp/')
# test failed write
backend.open(filepath, mode)

# easiest way to unit test is look at class variable
# pylint: disable=protected-access
backend._file.status = mock.MagicMock(side_effect=IOError('Unable to Read!'))
# pylint: enable=protected-access
hit_exception = False
try:
backend.status()
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue("Can't get posix file status with error" in str(ex))
self.assertTrue(hit_exception)

def test_posix_backend_failed_read(self):
"""Test reading to a failed file."""
filepath = '1234'
mode = 'r'
backend = PosixBackendArchive('/tmp/')
# test failed write
backend.open(filepath, mode)

# easiest way to unit test is look at class variable
# pylint: disable=protected-access
backend._file.read = mock.MagicMock(side_effect=IOError('Unable to Read!'))
# pylint: enable=protected-access
hit_exception = False
try:
backend.read(1024)
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue("Can't read posix file with error" in str(ex))
self.assertTrue(hit_exception)

def test_posix_backend_failed_fd(self):
"""Test reading to a failed file fd."""
filepath = '1234'
mode = 'w'
backend = PosixBackendArchive('/tmp/')
# test failed write
backend.open(filepath, mode)

# easiest way to unit test is look at class variable
# pylint: disable=protected-access
backend._file = None
# pylint: enable=protected-access
hit_exception = False
try:
backend.write('Something to write')
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue('Internal file handle invalid' in str(ex))
self.assertTrue(hit_exception)
hit_exception = False
try:
backend.read(1024)
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue('Internal file handle invalid' in str(ex))
self.assertTrue(hit_exception)
hit_exception = False
try:
backend.stage()
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue('Internal file handle invalid' in str(ex))
self.assertTrue(hit_exception)
hit_exception = False
try:
backend.status()
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue('Internal file handle invalid' in str(ex))
self.assertTrue(hit_exception)

def test_posix_backend_failed_stage(self):
"""Test reading a file from posix backend."""
filepath = '1234'
mode = 'r'
backend = PosixBackendArchive('/tmp/')
backend.open(filepath, mode)
# easiest way to unit test is look at class variable
# pylint: disable=protected-access
backend._file.stage = mock.MagicMock(side_effect=IOError('Unable to Stage!'))
# pylint: enable=protected-access
hit_exception = False
try:
backend.stage()
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue('Can\'t stage posix file with error' in str(ex))
self.assertTrue(hit_exception)

@mock.patch('shutil.move')
def test_patch_failed(self, mock_move):
"""Test patching file."""
old_path = '/tmp/1234'
new_path = '5678'
mode = 'w'
mock_move.side_effect = OSError('Unable to move')
backend = PosixBackendArchive('/tmp')
my_file = backend.open('1234', mode)
my_file.close()
hit_exception = False
try:
backend.patch(new_path, old_path)
except ArchiveInterfaceError as ex:
hit_exception = True
self.assertTrue('Can\'t move posix file with error' in str(ex))
# Error would be thrown on patch so nothing to assert
self.assertTrue(hit_exception)

0 comments on commit 09e3a14

Please sign in to comment.