import io import posixpath import time import pytest from ucc import VersionedPath, RetentionMode, InvalidError, PermissionsError OBJECT_WORM_PROVIDERS = ['googlecloudstorage', 'aliyun', 'ibmcloud', 'oraclecloud'] pytestmark = pytest.mark.object_lock @pytest.fixture(scope='module', autouse=True) def set_globals(path_client): global obj_client global container obj_client = path_client._client container = path_client._container @pytest.fixture(scope='session', autouse=True) def test_folder(request, path_client): path = u'/test_object_lock' path_client.mkdir(path) return path def test_upload_with_object_lock_retention_until(path_client, test_folder): path = posixpath.join(test_folder, f'upload_{int(time.time())}') meta = path_client.upload(path, io.BytesIO(b'foo'), object_lock_retention_until=int( time.time() + 10)) assert meta.version_id assert meta.lock_retention_until_utc_timestamp def test_get_object_metadata_with_version_id(path_client, test_folder): path = posixpath.join(test_folder, f'upload_{int(time.time())}') upload_meta = path_client.upload(path, io.BytesIO(b'foo'), object_lock_retention_until=int( time.time() + 10)) meta = path_client.get_metadata(path, version_id=upload_meta.version_id) assert meta.version_id assert meta.lock_retention_until_utc_timestamp def test_download_with_version_id(path_client, test_folder): path = posixpath.join(test_folder, f'upload_{int(time.time())}') meta = path_client.upload(path, io.BytesIO(b'foo'), object_lock_retention_until=int( time.time() + 10)) with path_client.download(path, version_id=meta.version_id) as fp: assert b'foo' == fp.read() def test_delete_version(path_client, test_folder): version_ids = [] path = posixpath.join(test_folder, f'upload_{int(time.time())}') expire_timestamp = None for i in range(3): meta = path_client.upload(path, io.BytesIO(b'foo'), object_lock_retention_until=int( time.time() + 2)) version_ids.append(meta.version_id) expire_timestamp = meta.lock_retention_until_utc_timestamp versioned_paths = [VersionedPath(path, version_id) for version_id in version_ids] try: result = path_client.delete_multi_with_version(versioned_paths) for versioned_path in result['deleted']: assert path == versioned_path['path'] deleted_version_ids = [d['version_id'] for d in result['deleted']] error_version_ids = [d['version_id'] for d in result['error']] assert set(version_ids) == set(deleted_version_ids + error_version_ids) except NotImplementedError: for version_id in version_ids: try: path_client.delete_with_version(path, version_id) except PermissionsError: pass def test_iter_object_versions(path_client, test_folder): version_ids = [] path = posixpath.join(test_folder, f'upload_{int(time.time())}') for i in range(3): meta = path_client.upload(path, io.BytesIO(b'foo')) version_ids.append(meta.version_id) abspath = path_client._abs_path(path) prefix = abspath.rstrip('/') actual_version_ids = [m.version_id for m in obj_client.iter_object_versions(container, prefix)] assert sorted(version_ids) == sorted(actual_version_ids) def test_set_retention_date(path_client, test_folder): 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.lock_retention_until_utc_timestamp if not retention_until: retention_until = int(time.time()) until = retention_until + 10 meta = path_client.set_retention_date(path, RetentionMode.COMPLIANCE, version_id, until) if not meta: meta = path_client.get_metadata(path, version_id) assert until == meta.lock_retention_until_utc_timestamp else: # WORM would return new version_id and retention timestamp assert meta.lock_retention_until_utc_timestamp assert meta.version_id def test_set_retention_date_twice(path_client, test_folder): 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.lock_retention_until_utc_timestamp if not retention_until: retention_until = int(time.time()) until = retention_until + 10 path_client.set_retention_date(path, RetentionMode.COMPLIANCE, version_id, until) meta = path_client.set_retention_date(path, RetentionMode.COMPLIANCE, version_id, until + 10) if not meta: meta = path_client.get_metadata(path, version_id) assert until + 10 == meta.lock_retention_until_utc_timestamp else: assert meta.lock_retention_until_utc_timestamp assert meta.version_id def test_set_retention_date_earlier_than_previous(path_client, test_folder): if path_client.provider_type in OBJECT_WORM_PROVIDERS: pytest.skip('Object worm does not support set retention date earlier than previous') path = posixpath.join(test_folder, f'upload_{int(time.time())}') version_id = path_client.upload(path, io.BytesIO(b'foo')).version_id until = int(time.time() + 10) path_client.set_retention_date(path, RetentionMode.COMPLIANCE, version_id, until) with pytest.raises(InvalidError): path_client.set_retention_date(path, RetentionMode.COMPLIANCE, version_id, until - 10) def test_is_object_lock_enabled(path_client): if path_client.provider_type in OBJECT_WORM_PROVIDERS: pytest.skip( 'Object Worm does not support checking whether object locking is enabled') assert True is obj_client.is_object_lock_enabled(container) def test_create_container_with_enable_object_lock(path_client): if path_client.provider_type in OBJECT_WORM_PROVIDERS: pytest.skip('Object worm does not support enabling object lock') obj_lock_container = f'61520utility{int(time.time())}' obj_client.create_container(obj_lock_container, enable_object_lock=True) assert True is obj_client.is_object_lock_enabled(obj_lock_container) obj_client.delete_container(obj_lock_container)