Added unit test for validating quota exception behavior, fixed up the validation write within the driver itself.
This commit is contained in:
Родитель
5f22817673
Коммит
86ca235ae2
|
@ -35,8 +35,6 @@ from requests import Session
|
|||
|
||||
executor = concurrent.futures.ThreadPoolExecutor(multiprocessing.cpu_count())
|
||||
|
||||
_prior_write_failure = False;
|
||||
|
||||
#import ptvsd
|
||||
#ptvsd.enable_attach(secret='my_secret')
|
||||
|
||||
|
@ -101,8 +99,10 @@ class WriteInfo:
|
|||
#logger.debug('updating %s range %d to %d', path, self.offset, self.offset+data_length-1)
|
||||
self.files._files_service.update_range(self.files._azure_file_share_name, self.directory, self.filename, self.data, start_range=self.offset, end_range=self.offset+data_length-1)
|
||||
|
||||
except AzureHttpError as ahe:
|
||||
self.files._prior_write_failure = True
|
||||
raise
|
||||
except Exception as e:
|
||||
_prior_write_failure = True
|
||||
logger.warning('error writing %s', str(e))
|
||||
|
||||
class FileCache:
|
||||
|
@ -135,6 +135,8 @@ class AzureFiles(LoggingMixIn, Operations):
|
|||
self._sas_token = sas_token.lstrip("?")
|
||||
self._files_service = file.FileService(self._azure_storage_account_name, sas_token=self._sas_token, request_session=Session())
|
||||
|
||||
self._prior_write_failure = False
|
||||
|
||||
self.writes = deque()
|
||||
|
||||
self.dir_cache = {}
|
||||
|
@ -500,7 +502,7 @@ class AzureFiles(LoggingMixIn, Operations):
|
|||
# Take the write lock to see if we can coalesce
|
||||
with self.file_cache[orig_path].append_write_lock:
|
||||
found = False
|
||||
if self.file_cache[orig_path].writes and not _prior_write_failure:
|
||||
if self.file_cache[orig_path].writes and not self._prior_write_failure:
|
||||
last = self.file_cache[orig_path].writes[-1]
|
||||
if (not last.processing and
|
||||
(last.offset + len(last.data)) == offset and
|
||||
|
@ -515,16 +517,17 @@ class AzureFiles(LoggingMixIn, Operations):
|
|||
|
||||
# If we failed at some point (potentially in an async write) do this one immediately
|
||||
# to see if the remote FS is functional and not hide the failure from the OS.
|
||||
if _prior_write_failure:
|
||||
wi.write()
|
||||
_prior_write_failure = False
|
||||
return data_length
|
||||
if not self._prior_write_failure:
|
||||
future = executor.submit(wi.write)
|
||||
self.file_cache[orig_path].pending_writes.add(future)
|
||||
def done(future):
|
||||
self.file_cache[orig_path].pending_writes.remove(future)
|
||||
future.add_done_callback(done)
|
||||
|
||||
future = executor.submit(wi.write)
|
||||
self.file_cache[orig_path].pending_writes.add(future)
|
||||
def done(future):
|
||||
self.file_cache[orig_path].pending_writes.remove(future)
|
||||
future.add_done_callback(done)
|
||||
#Gotta do the "validation" write outside the append lock block.
|
||||
if self._prior_write_failure:
|
||||
wi.write()
|
||||
self._prior_write_failure = False
|
||||
|
||||
# TODO: if we ever try to cache attrs, we would have to update the st_mtime.
|
||||
return data_length
|
||||
|
|
|
@ -12,7 +12,6 @@ import azure.storage.file as file
|
|||
from azure.storage.file import models
|
||||
import os
|
||||
|
||||
|
||||
# USEFUL LINKS FOR THESE TESTS:
|
||||
# ERRNO http://man7.org/linux/man-pages/man3/errno.3.html
|
||||
# requests status codes:https://github.com/kennethreitz/requests/blob/5524472cc76ea00d64181505f1fbb7f93f11cc2b/requests/status_codes.py
|
||||
|
@ -55,7 +54,7 @@ with mock.patch.object(ctypes.util, 'find_library', side_effect=find_library_moc
|
|||
class Test_azfilesfuse(unittest.TestCase):
|
||||
STORAGE_ACCOUNT_NAME='crwilcoxmsftplayground'
|
||||
STORAGE_ACCOUNT_SHARE='fusetests'
|
||||
STORAGE_ACCOUNT_SAS_TOKEN=None
|
||||
STORAGE_ACCOUNT_SAS_TOKEN='None'
|
||||
|
||||
def setUp(self):
|
||||
# TODO: Verify Settings provided
|
||||
|
@ -345,6 +344,34 @@ class Test_azfilesfuse(unittest.TestCase):
|
|||
# TODO: verify fails if file handle isn't open for write. (RESPECT
|
||||
# ATTRIBUTES OF OPEN, CURRENTLY WE DON'T
|
||||
|
||||
# For this test, set "quota" to be the size of the quota you've created.
|
||||
def test_quota(self):
|
||||
quota = 1250000000
|
||||
|
||||
delta = int(quota / 5) # an arbitrary amount to go under and then over the quota threshold to test it.
|
||||
size = quota - delta
|
||||
contents = b'a' * size
|
||||
|
||||
self.azure_fs.create_file_from_bytes(
|
||||
self.STORAGE_ACCOUNT_SHARE, '', 'file.txt', b'best file content')
|
||||
fd = self.fuse_driver.open('file.txt', 'w')
|
||||
self.fuse_driver.write('file.txt', b'a', size - 1, fd)
|
||||
self.fuse_driver.flush('file.txt')
|
||||
|
||||
self.assertEqual(
|
||||
len(self.azure_fs.get_file_to_bytes(self.STORAGE_ACCOUNT_SHARE, '', 'file.txt').content),
|
||||
size)
|
||||
|
||||
self.fuse_driver.write('file.txt', b'b', size + delta * 2, fd)
|
||||
time.sleep(1)
|
||||
# We expect the second write to fail visibly once the first async write has exceeded quota and failed silently.
|
||||
with self.assertRaisesRegex(Exception, '\[Errno 28\] No space left on device'):
|
||||
self.fuse_driver.write('file.txt', b'b', size + delta * 2, fd)
|
||||
|
||||
self.assertEqual(
|
||||
len(self.azure_fs.get_file_to_bytes(self.STORAGE_ACCOUNT_SHARE, '', 'file.txt').content),
|
||||
size)
|
||||
|
||||
def test_write_getattr_read(self):
|
||||
# Created after https://github.com/crwilcox/AzureFilesFUSE/issues/10
|
||||
self.fuse_driver.create('file.txt', None)
|
||||
|
|
Загрузка…
Ссылка в новой задаче