import io import math import posixpath import time import pytest from mock import MagicMock from ucc import NotFoundError, PermissionsError, RetentionMode, VersionedObject OBJECT_WORM_CAN_EXTEND_PROVIDERS = ['ibmcloud'] pytestmark = pytest.mark.worm @pytest.fixture(scope='module', autouse=True) def set_globals(path_client): global obj_client global worm_client global container worm_client = path_client._client obj_client = path_client._client._client container = path_client._container @pytest.fixture(scope='session', autouse=True) def test_folder(request, path_client): path = u'/test_worm' c = path_client c.mkdir(path) return path def test_mkdir(path_client, test_folder, path=None): if not path: path = posixpath.join(test_folder, "mkdir%f" % time.time()) m1 = path_client.mkdir(path) assert path == m1.path def test_list_objects(path_client, test_folder): path = posixpath.join(test_folder, f'upload_{int(time.time())}.png') expect_mtime = None for i in range(3): meta = path_client.upload(path, io.BytesIO(b'foo')) expect_mtime = meta.server_mtime abspath = path_client._abs_path(path) prefix = abspath.rstrip('/') for meta in worm_client.list_objects(container, prefix): assert expect_mtime == meta.mtime def test_get_object_metadata_on_normal_file(path_client, test_folder): path = posixpath.join(test_folder, f'upload_{int(time.time())}.png') obj = path_client._abs_path(path) obj_client.upload_object(container, obj, io.BytesIO(b'foo')) meta = path_client.get_metadata(path) assert path == meta.path def test_get_object_metadata_on_missing_normal_file(path_client, test_folder): path = posixpath.join(test_folder, 'not_found') with pytest.raises(NotFoundError): path_client.get_metadata(path) def test_get_object_metadata_on_versioned_file(path_client, test_folder): path = posixpath.join(test_folder, f'upload_{int(time.time())}.png') upload_meta = path_client.upload(path, io.BytesIO(b'foo')) get_meta = path_client.get_metadata(path) assert path == get_meta.path assert upload_meta.version_id == get_meta.version_id def test_get_object_metadata_on_folder(path_client, test_folder): meta = path_client.get_metadata('/') assert '/' == meta.path def test_download_on_normal_file(path_client, test_folder): path = posixpath.join(test_folder, f'upload_{int(time.time())}.png') obj = path_client._abs_path(path) obj_client.upload_object(container, obj, io.BytesIO(b'foo')) with path_client.download(path) as fp: assert b'foo' == fp.read() def test_download_on_versioned_file(path_client, test_folder): path = posixpath.join(test_folder, f'upload_{int(time.time())}.png') path_client.upload(path, io.BytesIO(b'foo')) time.sleep(1) path_client.upload(path, io.BytesIO(b'bar')) with path_client.download(path) as fp: assert b'bar' == fp.read() def test_delete(path_client, test_folder): path = posixpath.join(test_folder, f'upload_{int(time.time())}.png') path_client.upload(path, io.BytesIO(b'foo')) with pytest.raises(PermissionsError): path_client.delete(path) def test_multipart_upload(path_client, test_folder): path = posixpath.join(test_folder, f'upload_{int(time.time())}.png') path_client.upload(path, io.BytesIO(b'a'*10*1024*1024)) def test_upload_same_version_id(path_client, test_folder): old_make_version_id = worm_client._make_version_id mock_make_version_id = MagicMock() mock_make_version_id.side_effect = ['foo', 'bar'] worm_client._make_version_id = mock_make_version_id path = posixpath.join(test_folder, f'upload_{int(time.time())}') obj = path_client._abs_path(path) obj_client.upload_object(container, f'{obj}-foo', io.BytesIO(b'foo')) meta = path_client.upload(path, io.BytesIO(b'foo')) worm_client._make_version_id = old_make_version_id assert 'bar' == meta.version_id def test_set_retention_date_same_version_id(path_client, test_folder): old_make_version_id = worm_client._make_version_id mock_make_version_id = MagicMock() mock_make_version_id.side_effect = ['foo', 'foo', 'bar'] worm_client._make_version_id = mock_make_version_id path = posixpath.join(test_folder, f'upload_{int(time.time())}') first_meta = path_client.upload(path, io.BytesIO(b'foo')) version_id = first_meta.version_id retention_until = first_meta._raw.lock_retention_until_utc_timestamp meta = path_client.set_retention_date(path, RetentionMode.COMPLIANCE, version_id, retention_until + 10) worm_client._make_version_id = old_make_version_id if path_client.provider_type in OBJECT_WORM_CAN_EXTEND_PROVIDERS: assert 'foo' == meta.version_id else: assert 'bar' == meta.version_id def test_is_object_worm_enabled(): assert obj_client.is_object_worm_enabled(container) is True