class StorageDirectoryTest(FileTestCase): def setUp(self): super(StorageDirectoryTest, self).setUp() url = self.get_file_url() credential = self.get_shared_key_credential() self.fsc = FileServiceClient(url, credential=credential) self.share_name = self.get_resource_name('utshare') if not self.is_playback(): self.fsc.create_share(self.share_name) def tearDown(self): if not self.is_playback(): try: self.fsc.delete_share(self.share_name, delete_snapshots='include') except: pass return super(StorageDirectoryTest, self).tearDown() # --Helpers----------------------------------------------------------------- # --Test cases for directories ---------------------------------------------- @record def test_create_directories(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) # Act created = share_client.create_directory('dir1') # Assert self.assertTrue(created) @record def test_create_directories_with_metadata(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) metadata = {'hello': 'world', 'number': '42'} # Act directory = share_client.create_directory('dir1', metadata=metadata) # Assert md = directory.get_directory_properties().metadata self.assertDictEqual(md, metadata) @record def test_create_directories_fail_on_exist(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) # Act created = share_client.create_directory('dir1') with self.assertRaises(ResourceExistsError): share_client.create_directory('dir1') # Assert self.assertTrue(created) @record def test_create_subdirectories(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') # Act created = directory.create_subdirectory('dir2') # Assert self.assertTrue(created) self.assertEqual(created.directory_path, 'dir1/dir2') @record def test_create_subdirectories_with_metadata(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') metadata = {'hello': 'world', 'number': '42'} # Act created = directory.create_subdirectory('dir2', metadata=metadata) # Assert self.assertTrue(created) self.assertEqual(created.directory_path, 'dir1/dir2') sub_metadata = created.get_directory_properties().metadata self.assertEqual(sub_metadata, metadata) @record def test_create_file_in_directory(self): # Arrange file_data = b'12345678' * 1024 file_name = self.get_resource_name('file') share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') # Act new_file = directory.upload_file(file_name, file_data) # Assert file_content = new_file.download_file().content_as_bytes() self.assertEqual(file_content, file_data) @record def test_delete_file_in_directory(self): # Arrange file_name = self.get_resource_name('file') share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') new_file = directory.upload_file(file_name, "hello world") # Act deleted = directory.delete_file(file_name) # Assert self.assertIsNone(deleted) with self.assertRaises(ResourceNotFoundError): new_file.get_file_properties() @record def test_delete_subdirectories(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') directory.create_subdirectory('dir2') # Act deleted = directory.delete_subdirectory('dir2') # Assert self.assertIsNone(deleted) subdir = directory.get_subdirectory_client('dir2') with self.assertRaises(ResourceNotFoundError): subdir.get_directory_properties() @record def test_get_directory_properties(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') # Act props = directory.get_directory_properties() # Assert self.assertIsNotNone(props) self.assertIsNotNone(props.etag) self.assertIsNotNone(props.last_modified) @record def test_get_directory_properties_with_snapshot(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) metadata = {"test1": "foo", "test2": "bar"} directory = share_client.create_directory('dir1', metadata=metadata) snapshot1 = share_client.create_snapshot() metadata2 = {"test100": "foo100", "test200": "bar200"} directory.set_directory_metadata(metadata2) # Act share_client = self.fsc.get_share_client(self.share_name, snapshot=snapshot1) snap_dir = share_client.get_directory_client('dir1') props = snap_dir.get_directory_properties() # Assert self.assertIsNotNone(props) self.assertIsNotNone(props.etag) self.assertIsNotNone(props.last_modified) self.assertDictEqual(metadata, props.metadata) @record def test_get_directory_metadata_with_snapshot(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) metadata = {"test1": "foo", "test2": "bar"} directory = share_client.create_directory('dir1', metadata=metadata) snapshot1 = share_client.create_snapshot() metadata2 = {"test100": "foo100", "test200": "bar200"} directory.set_directory_metadata(metadata2) # Act share_client = self.fsc.get_share_client(self.share_name, snapshot=snapshot1) snap_dir = share_client.get_directory_client('dir1') snapshot_metadata = snap_dir.get_directory_properties().metadata # Assert self.assertIsNotNone(snapshot_metadata) self.assertDictEqual(metadata, snapshot_metadata) @record def test_get_directory_properties_with_non_existing_directory(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.get_directory_client('dir1') # Act with self.assertRaises(ResourceNotFoundError): directory.get_directory_properties() # Assert @record def test_directory_exists(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') # Act exists = directory.get_directory_properties() # Assert self.assertTrue(exists) @record def test_directory_not_exists(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.get_directory_client('dir1') # Act with self.assertRaises(ResourceNotFoundError): directory.get_directory_properties() # Assert @record def test_directory_parent_not_exists(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.get_directory_client('missing1/missing2') # Act with self.assertRaises(ResourceNotFoundError) as e: directory.get_directory_properties() # Assert self.assertEqual(e.exception.error_code, StorageErrorCode.parent_not_found) @record def test_directory_exists_with_snapshot(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') snapshot = share_client.create_snapshot() directory.delete_directory() # Act share_client = self.fsc.get_share_client(self.share_name, snapshot=snapshot) snap_dir = share_client.get_directory_client('dir1') exists = snap_dir.get_directory_properties() # Assert self.assertTrue(exists) @record def test_directory_not_exists_with_snapshot(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) snapshot = share_client.create_snapshot() directory = share_client.create_directory('dir1') # Act share_client = self.fsc.get_share_client(self.share_name, snapshot=snapshot) snap_dir = share_client.get_directory_client('dir1') with self.assertRaises(ResourceNotFoundError): snap_dir.get_directory_properties() # Assert @record def test_get_set_directory_metadata(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') metadata = {'hello': 'world', 'number': '43'} # Act directory.set_directory_metadata(metadata) md = directory.get_directory_properties().metadata # Assert self.assertDictEqual(md, metadata) @record def test_list_subdirectories_and_files(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') directory.create_subdirectory("subdir1") directory.create_subdirectory("subdir2") directory.create_subdirectory("subdir3") directory.upload_file("file1", "data1") directory.upload_file("file2", "data2") directory.upload_file("file3", "data3") # Act list_dir = list(directory.list_directories_and_files()) # Assert expected = [ { 'name': 'subdir1', 'is_directory': True }, { 'name': 'subdir2', 'is_directory': True }, { 'name': 'subdir3', 'is_directory': True }, { 'name': 'file1', 'is_directory': False, 'size': 5 }, { 'name': 'file2', 'is_directory': False, 'size': 5 }, { 'name': 'file3', 'is_directory': False, 'size': 5 }, ] self.assertEqual(len(list_dir), 6) self.assertEqual(list_dir, expected) @record def test_list_subdirectories_and_files_with_prefix(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') directory.create_subdirectory("subdir1") directory.create_subdirectory("subdir2") directory.create_subdirectory("subdir3") directory.upload_file("file1", "data1") directory.upload_file("file2", "data2") directory.upload_file("file3", "data3") # Act list_dir = list( directory.list_directories_and_files(name_starts_with="sub")) # Assert expected = [ { 'name': 'subdir1', 'is_directory': True }, { 'name': 'subdir2', 'is_directory': True }, { 'name': 'subdir3', 'is_directory': True }, ] self.assertEqual(len(list_dir), 3) self.assertEqual(list_dir, expected) @record def test_list_subdirectories_and_files_with_snapshot(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') directory.create_subdirectory("subdir1") directory.create_subdirectory("subdir2") directory.upload_file("file1", "data1") snapshot = share_client.create_snapshot() directory.create_subdirectory("subdir3") directory.upload_file("file2", "data2") directory.upload_file("file3", "data3") share_client = self.fsc.get_share_client(self.share_name, snapshot=snapshot) snapshot_dir = share_client.get_directory_client('dir1') # Act list_dir = list(snapshot_dir.list_directories_and_files()) # Assert expected = [ { 'name': 'subdir1', 'is_directory': True }, { 'name': 'subdir2', 'is_directory': True }, { 'name': 'file1', 'is_directory': False, 'size': 5 }, ] self.assertEqual(len(list_dir), 3) self.assertEqual(list_dir, expected) @record def test_list_nested_subdirectories_and_files(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') subdir = directory.create_subdirectory("subdir1") subdir.create_subdirectory("subdir2") subdir.create_subdirectory("subdir3") directory.upload_file("file1", "data1") subdir.upload_file("file2", "data2") subdir.upload_file("file3", "data3") # Act list_dir = list(directory.list_directories_and_files()) # Assert expected = [ { 'name': 'subdir1', 'is_directory': True }, { 'name': 'file1', 'is_directory': False, 'size': 5 }, ] self.assertEqual(len(list_dir), 2) self.assertEqual(list_dir, expected) @record def test_delete_directory_with_existing_share(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') # Act deleted = directory.delete_directory() # Assert self.assertIsNone(deleted) with self.assertRaises(ResourceNotFoundError): directory.get_directory_properties() @record def test_delete_directory_with_non_existing_directory(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.get_directory_client('dir1') # Act with self.assertRaises(ResourceNotFoundError): directory.delete_directory() # Assert @record def test_get_directory_properties_server_encryption(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) directory = share_client.create_directory('dir1') # Act props = directory.get_directory_properties() # Assert self.assertIsNotNone(props) self.assertIsNotNone(props.etag) self.assertIsNotNone(props.last_modified) if self.is_file_encryption_enabled(): self.assertTrue(props.server_encrypted) else: self.assertFalse(props.server_encrypted)
class StorageFileTest(FileTestCase): def setUp(self): super(StorageFileTest, self).setUp() url = self.get_file_url() credential = self.get_shared_key_credential() # test chunking functionality by reducing the threshold # for chunking and the size of each chunk, otherwise # the tests would take too long to execute self.fsc = FileServiceClient(url, credential=credential, max_range_size=4 * 1024) self.share_name = self.get_resource_name('utshare') if not self.is_playback(): self.fsc.create_share(self.share_name) self.short_byte_data = self.get_random_bytes(1024) remote_url = self.get_remote_file_url() remote_credential = self.get_remote_shared_key_credential() self.fsc2 = FileServiceClient(remote_url, credential=remote_credential) self.remote_share_name = None def tearDown(self): if not self.is_playback(): try: self.fsc.delete_share(self.share_name, delete_snapshots='include') except: pass if self.remote_share_name: try: self.fs2.delete_share(self.remote_share_name, delete_snapshots='include') except: pass if os.path.isfile(INPUT_FILE_PATH): try: os.remove(INPUT_FILE_PATH) except: pass if os.path.isfile(OUTPUT_FILE_PATH): try: os.remove(OUTPUT_FILE_PATH) except: pass return super(StorageFileTest, self).tearDown() # --Helpers----------------------------------------------------------------- def _get_file_reference(self): return self.get_resource_name(TEST_FILE_PREFIX) def _create_file(self): file_name = self._get_file_reference() share_client = self.fsc.get_share_client(self.share_name) file_client = share_client.get_file_client(file_name) file_client.upload_file(self.short_byte_data) return file_client def _create_remote_share(self): self.remote_share_name = self.get_resource_name('remoteshare') remote_share = self.fsc2.get_share_client(self.remote_share_name) try: remote_share.create_share() except ResourceExistsError: pass return remote_share def _create_remote_file(self, file_data=None): if not file_data: file_data = b'12345678' * 1024 * 1024 source_file_name = self._get_file_reference() remote_share = self.fsc2.get_share_client(self.remote_share_name) remote_file = remote_share.get_file_client(source_file_name) remote_file.upload_file(file_data) return remote_file def _wait_for_async_copy(self, share_name, file_path): count = 0 share_client = self.fsc.get_share_client(share_name) file_client = share_client.get_file_client(file_path) properties = file_client.get_file_properties() while properties.copy.status != 'success': count = count + 1 if count > 10: self.fail('Timed out waiting for async copy to complete.') self.sleep(6) properties = file_client.get_file_properties() self.assertEqual(properties.copy.status, 'success') def assertFileEqual(self, file_client, expected_data): actual_data = file_client.download_file().content_as_bytes() self.assertEqual(actual_data, expected_data) class NonSeekableFile(object): def __init__(self, wrapped_file): self.wrapped_file = wrapped_file def write(self, data): self.wrapped_file.write(data) def read(self, count): return self.wrapped_file.read(count) # --Test cases for files ---------------------------------------------- @record def test_make_file_url(self): # Arrange share = self.fsc.get_share_client("vhds") file_client = share.get_file_client("vhd_dir/my.vhd") # Act res = file_client.url # Assert self.assertEqual(res, 'https://' + self.settings.STORAGE_ACCOUNT_NAME + '.file.core.windows.net/vhds/vhd_dir/my.vhd') @record def test_make_file_url_no_directory(self): # Arrange share = self.fsc.get_share_client("vhds") file_client = share.get_file_client("my.vhd") # Act res = file_client.url # Assert self.assertEqual(res, 'https://' + self.settings.STORAGE_ACCOUNT_NAME + '.file.core.windows.net/vhds/my.vhd') @record def test_make_file_url_with_protocol(self): # Arrange url = self.get_file_url().replace('https', 'http') fsc = FileServiceClient(url, credential=self.settings.STORAGE_ACCOUNT_KEY) share = fsc.get_share_client("vhds") file_client = share.get_file_client("vhd_dir/my.vhd") # Act res = file_client.url # Assert self.assertEqual(res, 'http://' + self.settings.STORAGE_ACCOUNT_NAME + '.file.core.windows.net/vhds/vhd_dir/my.vhd') @record def test_make_file_url_with_sas(self): # Arrange sas = '?sv=2015-04-05&st=2015-04-29T22%3A18%3A26Z&se=2015-04-30T02%3A23%3A26Z&sr=b&sp=rw&sip=168.1.5.60-168.1.5.70&spr=https&sig=Z%2FRHIX5Xcg0Mq2rqI3OlWTjEg2tYkboXr1P9ZUXDtkk%3D' file_client = FileClient( self.get_file_url(), share="vhds", file_path="vhd_dir/my.vhd", credential=sas ) # Act res = file_client.url # Assert self.assertEqual(res, 'https://' + self.settings.STORAGE_ACCOUNT_NAME + '.file.core.windows.net/vhds/vhd_dir/my.vhd{}'.format(sas)) @record def test_create_file(self): # Arrange file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act resp = file_client.create_file(1024) # Assert props = file_client.get_file_properties() self.assertIsNotNone(props) self.assertEqual(props.etag, resp['etag']) self.assertEqual(props.last_modified, resp['last_modified']) @record def test_create_file_with_metadata(self): # Arrange metadata = {'hello': 'world', 'number': '42'} file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act resp = file_client.create_file(1024, metadata=metadata) # Assert props = file_client.get_file_properties() self.assertIsNotNone(props) self.assertEqual(props.etag, resp['etag']) self.assertEqual(props.last_modified, resp['last_modified']) self.assertDictEqual(props.metadata, metadata) @record def test_file_exists(self): # Arrange file_client = self._create_file() # Act exists = file_client.get_file_properties() # Assert self.assertTrue(exists) @record def test_file_not_exists(self): # Arrange file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path="missingdir/" + file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act with self.assertRaises(ResourceNotFoundError): file_client.get_file_properties() # Assert @record def test_file_exists_with_snapshot(self): # Arrange file_client = self._create_file() share_client = self.fsc.get_share_client(self.share_name) snapshot = share_client.create_snapshot() file_client.delete_file() # Act snapshot_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client.file_name, snapshot=snapshot, credential=self.settings.STORAGE_ACCOUNT_KEY) props = snapshot_client.get_file_properties() # Assert self.assertTrue(props) @record def test_file_not_exists_with_snapshot(self): # Arrange share_client = self.fsc.get_share_client(self.share_name) snapshot = share_client.create_snapshot() file_client = self._create_file() # Act snapshot_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client.file_name, snapshot=snapshot, credential=self.settings.STORAGE_ACCOUNT_KEY) # Assert with self.assertRaises(ResourceNotFoundError): snapshot_client.get_file_properties() @record def test_resize_file(self): # Arrange file_client = self._create_file() # Act file_client.resize_file(5) # Assert props = file_client.get_file_properties() self.assertEqual(props.size, 5) @record def test_set_file_properties(self): # Arrange file_client = self._create_file() # Act content_settings = ContentSettings( content_language='spanish', content_disposition='inline') resp = file_client.set_http_headers(content_settings=content_settings) # Assert properties = file_client.get_file_properties() self.assertEqual(properties.content_settings.content_language, content_settings.content_language) self.assertEqual(properties.content_settings.content_disposition, content_settings.content_disposition) @record def test_get_file_properties(self): # Arrange file_client = self._create_file() # Act properties = file_client.get_file_properties() # Assert self.assertIsNotNone(properties) self.assertEqual(properties.size, len(self.short_byte_data)) @record def test_get_file_properties_with_snapshot(self): # Arrange file_client = self._create_file() metadata = {"test1": "foo", "test2": "bar"} file_client.set_file_metadata(metadata) share_client = self.fsc.get_share_client(self.share_name) snapshot = share_client.create_snapshot() metadata2 = {"test100": "foo100", "test200": "bar200"} file_client.set_file_metadata(metadata2) # Act file_props = file_client.get_file_properties() snapshot_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client.file_name, snapshot=snapshot, credential=self.settings.STORAGE_ACCOUNT_KEY) snapshot_props = snapshot_client.get_file_properties() # Assert self.assertIsNotNone(file_props) self.assertIsNotNone(snapshot_props) self.assertEqual(file_props.size, snapshot_props.size) self.assertDictEqual(metadata, snapshot_props.metadata) @record def test_get_file_metadata_with_snapshot(self): # Arrange file_client = self._create_file() metadata = {"test1": "foo", "test2": "bar"} file_client.set_file_metadata(metadata) share_client = self.fsc.get_share_client(self.share_name) snapshot = share_client.create_snapshot() snapshot_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client.file_name, snapshot=snapshot, credential=self.settings.STORAGE_ACCOUNT_KEY) metadata2 = {"test100": "foo100", "test200": "bar200"} file_client.set_file_metadata(metadata2) # Act file_metadata = file_client.get_file_properties().metadata file_snapshot_metadata = snapshot_client.get_file_properties().metadata # Assert self.assertDictEqual(metadata2, file_metadata) self.assertDictEqual(metadata, file_snapshot_metadata) @record def test_get_file_properties_with_non_existing_file(self): # Arrange file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act with self.assertRaises(ResourceNotFoundError): file_client.get_file_properties() # Assert @record def test_get_file_metadata(self): # Arrange file_client = self._create_file() # Act md = file_client.get_file_properties().metadata # Assert self.assertIsNotNone(md) self.assertEqual(0, len(md)) @record def test_set_file_metadata_with_upper_case(self): # Arrange metadata = {'hello': 'world', 'number': '42', 'UP': 'UPval'} file_client = self._create_file() # Act file_client.set_file_metadata(metadata) # Assert md = file_client.get_file_properties().metadata self.assertEqual(3, len(md)) self.assertEqual(md['hello'], 'world') self.assertEqual(md['number'], '42') self.assertEqual(md['UP'], 'UPval') self.assertFalse('up' in md) @record def test_delete_file_with_existing_file(self): # Arrange file_client = self._create_file() # Act file_client.delete_file() # Assert with self.assertRaises(ResourceNotFoundError): file_client.get_file_properties() @record def test_delete_file_with_non_existing_file(self): # Arrange file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act with self.assertRaises(ResourceNotFoundError): file_client.delete_file() # Assert @record def test_update_range(self): # Arrange file_client = self._create_file() # Act data = b'abcdefghijklmnop' * 32 file_client.upload_range(data, 0, 511) # Assert content = file_client.download_file().content_as_bytes() self.assertEqual(data, content[:512]) self.assertEqual(self.short_byte_data[512:], content[512:]) @record def test_update_range_with_md5(self): # Arrange file_client = self._create_file() # Act data = b'abcdefghijklmnop' * 32 file_client.upload_range(data, 0, 511, validate_content=True) # Assert @record def test_clear_range(self): # Arrange file_client = self._create_file() # Act resp = file_client.clear_range(0, 511) # Assert content = file_client.download_file().content_as_bytes() self.assertEqual(b'\x00' * 512, content[:512]) self.assertEqual(self.short_byte_data[512:], content[512:]) @record def test_update_file_unicode(self): # Arrange file_client = self._create_file() # Act data = u'abcdefghijklmnop' * 32 file_client.upload_range(data, 0, 511) encoded = data.encode('utf-8') # Assert content = file_client.download_file().content_as_bytes() self.assertEqual(encoded, content[:512]) self.assertEqual(self.short_byte_data[512:], content[512:]) # Assert @record def test_list_ranges_none(self): # Arrange file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) file_client.create_file(1024) # Act ranges = file_client.get_ranges() # Assert self.assertIsNotNone(ranges) self.assertEqual(len(ranges), 0) @record def test_list_ranges_2(self): # Arrange file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) file_client.create_file(2048) data = b'abcdefghijklmnop' * 32 resp1 = file_client.upload_range(data, 0, 511) resp2 = file_client.upload_range(data, 1024, 1535) # Act ranges = file_client.get_ranges() # Assert self.assertIsNotNone(ranges) self.assertEqual(len(ranges), 2) self.assertEqual(ranges[0]['start'], 0) self.assertEqual(ranges[0]['end'], 511) self.assertEqual(ranges[1]['start'], 1024) self.assertEqual(ranges[1]['end'], 1535) @record def test_list_ranges_none_from_snapshot(self): # Arrange file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) file_client.create_file(1024) share_client = self.fsc.get_share_client(self.share_name) snapshot = share_client.create_snapshot() snapshot_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client.file_name, snapshot=snapshot, credential=self.settings.STORAGE_ACCOUNT_KEY) file_client.delete_file() # Act ranges = snapshot_client.get_ranges() # Assert self.assertIsNotNone(ranges) self.assertEqual(len(ranges), 0) @record def test_list_ranges_2_from_snapshot(self): # Arrange file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) file_client.create_file(2048) data = b'abcdefghijklmnop' * 32 resp1 = file_client.upload_range(data, 0, 511) resp2 = file_client.upload_range(data, 1024, 1535) share_client = self.fsc.get_share_client(self.share_name) snapshot = share_client.create_snapshot() snapshot_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client.file_name, snapshot=snapshot, credential=self.settings.STORAGE_ACCOUNT_KEY) file_client.delete_file() # Act ranges = snapshot_client.get_ranges() # Assert self.assertIsNotNone(ranges) self.assertEqual(len(ranges), 2) self.assertEqual(ranges[0]['start'], 0) self.assertEqual(ranges[0]['end'], 511) self.assertEqual(ranges[1]['start'], 1024) self.assertEqual(ranges[1]['end'], 1535) @record def test_copy_file_with_existing_file(self): # Arrange source_client = self._create_file() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path='file1copy', credential=self.settings.STORAGE_ACCOUNT_KEY) # Act copy = file_client.start_copy_from_url(source_client.url) # Assert self.assertIsNotNone(copy) self.assertEqual(copy['copy_status'], 'success') self.assertIsNotNone(copy['copy_id']) copy_file = file_client.download_file().content_as_bytes() self.assertEqual(copy_file, self.short_byte_data) @record def test_copy_file_async_private_file(self): # Arrange self._create_remote_share() source_file = self._create_remote_file() # Act target_file_name = 'targetfile' file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=target_file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) with self.assertRaises(HttpResponseError) as e: file_client.start_copy_from_url(source_file.url) # Assert self.assertEqual(e.exception.error_code, StorageErrorCode.cannot_verify_copy_source) @record def test_copy_file_async_private_file_with_sas(self): # Arrange data = b'12345678' * 1024 * 1024 self._create_remote_share() source_file = self._create_remote_file(file_data=data) sas_token = source_file.generate_shared_access_signature( permission=FilePermissions.READ, expiry=datetime.utcnow() + timedelta(hours=1), ) source_url = source_file.url + '?' + sas_token # Act target_file_name = 'targetfile' file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=target_file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) copy_resp = file_client.start_copy_from_url(source_url) # Assert self.assertTrue(copy_resp['copy_status'] in ['success', 'pending']) self._wait_for_async_copy(self.share_name, target_file_name) actual_data = file_client.download_file().content_as_bytes() self.assertEqual(actual_data, data) @record def test_abort_copy_file(self): # Arrange data = b'12345678' * 1024 * 1024 self._create_remote_share() source_file = self._create_remote_file(file_data=data) sas_token = source_file.generate_shared_access_signature( permission=FilePermissions.READ, expiry=datetime.utcnow() + timedelta(hours=1), ) source_url = source_file.url + '?' + sas_token # Act target_file_name = 'targetfile' file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=target_file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) copy_resp = file_client.start_copy_from_url(source_url) self.assertEqual(copy_resp['copy_status'], 'pending') file_client.abort_copy(copy_resp) # Assert target_file = file_client.download_file() self.assertEqual(target_file.content_as_bytes(), b'') self.assertEqual(target_file.properties.copy.status, 'aborted') @record def test_abort_copy_file_with_synchronous_copy_fails(self): # Arrange source_file = self._create_file() # Act target_file_name = 'targetfile' file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=target_file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) copy_resp = file_client.start_copy_from_url(source_file.url) with self.assertRaises(HttpResponseError): file_client.abort_copy(copy_resp) # Assert self.assertEqual(copy_resp['copy_status'], 'success') @record def test_unicode_get_file_unicode_name(self): # Arrange file_name = '啊齄丂狛狜' file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) file_client.upload_file(b'hello world') # Act content = file_client.download_file().content_as_bytes() # Assert self.assertEqual(content, b'hello world') @record def test_file_unicode_data(self): # Arrange file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act data = u'hello world啊齄丂狛狜'.encode('utf-8') file_client.upload_file(data) # Assert content = file_client.download_file().content_as_bytes() self.assertEqual(content, data) @record def test_unicode_get_file_binary_data(self): # Arrange base64_data = 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/wABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/v8AAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3+Dh4uPk5ebn6Onq6+zt7u/w8fLz9PX29/j5+vv8/f7/AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==' binary_data = base64.b64decode(base64_data) file_name = self._get_file_reference() file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) file_client.upload_file(binary_data) # Act content = file_client.download_file().content_as_bytes() # Assert self.assertEqual(content, binary_data) def test_create_file_from_bytes_with_progress(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act progress = [] def callback(response): current = response.context['upload_stream_current'] total = response.context['data_stream_total'] if current is not None: progress.append((current, total)) file_client.upload_file(data, max_connections=2, raw_response_hook=callback) # Assert self.assertFileEqual(file_client, data) def test_create_file_from_bytes_with_index(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) index = 1024 file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act file_client.upload_file(data[index:], max_connections=2) # Assert self.assertFileEqual(file_client, data[1024:]) def test_create_file_from_bytes_with_index_and_count(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) index = 512 count = 1024 file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act file_client.upload_file(data[index:], length=count, max_connections=2) # Assert self.assertFileEqual(file_client, data[index:index + count]) def test_create_file_from_path(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) with open(INPUT_FILE_PATH, 'wb') as stream: stream.write(data) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act with open(INPUT_FILE_PATH, 'rb') as stream: file_client.upload_file(stream, max_connections=2) # Assert self.assertFileEqual(file_client, data) def test_create_file_from_path_with_progress(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) with open(INPUT_FILE_PATH, 'wb') as stream: stream.write(data) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY, max_range_size=4 * 1024) # Act progress = [] def callback(response): current = response.context['upload_stream_current'] total = response.context['data_stream_total'] if current is not None: progress.append((current, total)) with open(INPUT_FILE_PATH, 'rb') as stream: file_client.upload_file(stream, max_connections=2, raw_response_hook=callback) # Assert self.assertFileEqual(file_client, data) self.assert_upload_progress( len(data), self.fsc._config.max_range_size, progress, unknown_size=False) def test_create_file_from_stream(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) with open(INPUT_FILE_PATH, 'wb') as stream: stream.write(data) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act file_size = len(data) with open(INPUT_FILE_PATH, 'rb') as stream: file_client.upload_file(stream, max_connections=2) # Assert self.assertFileEqual(file_client, data[:file_size]) def test_create_file_from_stream_non_seekable(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) with open(INPUT_FILE_PATH, 'wb') as stream: stream.write(data) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY) # Act file_size = len(data) with open(INPUT_FILE_PATH, 'rb') as stream: non_seekable_file = StorageFileTest.NonSeekableFile(stream) file_client.upload_file(non_seekable_file, length=file_size, max_connections=1) # Assert self.assertFileEqual(file_client, data[:file_size]) def test_create_file_from_stream_with_progress(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) with open(INPUT_FILE_PATH, 'wb') as stream: stream.write(data) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY, max_range_size=4 * 1024) # Act progress = [] def callback(response): current = response.context['upload_stream_current'] total = response.context['data_stream_total'] if current is not None: progress.append((current, total)) file_size = len(data) with open(INPUT_FILE_PATH, 'rb') as stream: file_client.upload_file(stream, max_connections=2, raw_response_hook=callback) # Assert self.assertFileEqual(file_client, data[:file_size]) self.assert_upload_progress( len(data), self.fsc._config.max_range_size, progress, unknown_size=False) def test_create_file_from_stream_truncated(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) with open(INPUT_FILE_PATH, 'wb') as stream: stream.write(data) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY, max_range_size=4 * 1024) # Act file_size = len(data) - 512 with open(INPUT_FILE_PATH, 'rb') as stream: file_client.upload_file(stream, length=file_size, max_connections=2) # Assert self.assertFileEqual(file_client, data[:file_size]) def test_create_file_from_stream_with_progress_truncated(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) with open(INPUT_FILE_PATH, 'wb') as stream: stream.write(data) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY, max_range_size=4 * 1024) # Act progress = [] def callback(response): current = response.context['upload_stream_current'] total = response.context['data_stream_total'] if current is not None: progress.append((current, total)) file_size = len(data) - 5 with open(INPUT_FILE_PATH, 'rb') as stream: file_client.upload_file(stream, length=file_size, max_connections=2, raw_response_hook=callback) # Assert self.assertFileEqual(file_client, data[:file_size]) self.assert_upload_progress( file_size, self.fsc._config.max_range_size, progress, unknown_size=False) @record def test_create_file_from_text(self): # Arrange file_name = self._get_file_reference() text = u'hello 啊齄丂狛狜 world' data = text.encode('utf-8') file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY, max_range_size=4 * 1024) # Act file_client.upload_file(text) # Assert self.assertFileEqual(file_client, data) @record def test_create_file_from_text_with_encoding(self): # Arrange file_name = self._get_file_reference() text = u'hello 啊齄丂狛狜 world' data = text.encode('utf-16') file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY, max_range_size=4 * 1024) # Act file_client.upload_file(text, encoding='UTF-16') # Assert self.assertFileEqual(file_client, data) def test_create_file_from_text_chunked_upload(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_text_data(LARGE_FILE_SIZE) encoded_data = data.encode('utf-8') file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY, max_range_size=4 * 1024) # Act file_client.upload_file(data) # Assert self.assertFileEqual(file_client, encoded_data) @record def test_create_file_with_md5_small(self): # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(512) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY, max_range_size=4 * 1024) # Act file_client.upload_file(data, validate_content=True) # Assert def test_create_file_with_md5_large(self): # parallel tests introduce random order of requests, can only run live if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = self._get_file_reference() data = self.get_random_bytes(LARGE_FILE_SIZE) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_name, credential=self.settings.STORAGE_ACCOUNT_KEY, max_range_size=4 * 1024) # Act file_client.upload_file(data, validate_content=True, max_connections=2) # Assert # --Test cases for sas & acl ------------------------------------------------ @record def test_sas_access_file(self): # SAS URL is calculated from storage key, so this test runs live only if TestMode.need_recording_file(self.test_mode): return # Arrange file_client = self._create_file() token = file_client.generate_shared_access_signature( permission=FilePermissions.READ, expiry=datetime.utcnow() + timedelta(hours=1), ) # Act file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client.file_name, credential=token) content = file_client.download_file().content_as_bytes() # Assert self.assertEqual(self.short_byte_data, content) @record def test_sas_signed_identifier(self): # SAS URL is calculated from storage key, so this test runs live only if TestMode.need_recording_file(self.test_mode): return # Arrange file_client = self._create_file() share_client = self.fsc.get_share_client(self.share_name) access_policy = AccessPolicy() access_policy.start = datetime.utcnow() - timedelta(hours=1) access_policy.expiry = datetime.utcnow() + timedelta(hours=1) access_policy.permission = FilePermissions.READ identifiers = {'testid': access_policy} share_client.set_share_access_policy(identifiers) token = file_client.generate_shared_access_signature(policy_id='testid') # Act sas_file = FileClient( file_client.url, credential=token) content = file_client.download_file().content_as_bytes() # Assert self.assertEqual(self.short_byte_data, content) @record def test_account_sas(self): # SAS URL is calculated from storage key, so this test runs live only if TestMode.need_recording_file(self.test_mode): return # Arrange file_client = self._create_file() token = self.fsc.generate_shared_access_signature( ResourceTypes.OBJECT, AccountPermissions.READ, datetime.utcnow() + timedelta(hours=1), ) # Act file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client.file_name, credential=token) response = requests.get(file_client.url) # Assert self.assertTrue(response.ok) self.assertEqual(self.short_byte_data, response.content) @record def test_shared_read_access_file(self): # SAS URL is calculated from storage key, so this test runs live only if TestMode.need_recording_file(self.test_mode): return # Arrange file_client = self._create_file() token = file_client.generate_shared_access_signature( permission=FilePermissions.READ, expiry=datetime.utcnow() + timedelta(hours=1), ) # Act file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client.file_name, credential=token) response = requests.get(file_client.url) # Assert self.assertTrue(response.ok) self.assertEqual(self.short_byte_data, response.content) @record def test_shared_read_access_file_with_content_query_params(self): # SAS URL is calculated from storage key, so this test runs live only if TestMode.need_recording_file(self.test_mode): return # Arrange file_client = self._create_file() token = file_client.generate_shared_access_signature( permission=FilePermissions.READ, expiry=datetime.utcnow() + timedelta(hours=1), cache_control='no-cache', content_disposition='inline', content_encoding='utf-8', content_language='fr', content_type='text', ) # Act file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client.file_name, credential=token) response = requests.get(file_client.url) # Assert self.assertEqual(self.short_byte_data, response.content) self.assertEqual(response.headers['cache-control'], 'no-cache') self.assertEqual(response.headers['content-disposition'], 'inline') self.assertEqual(response.headers['content-encoding'], 'utf-8') self.assertEqual(response.headers['content-language'], 'fr') self.assertEqual(response.headers['content-type'], 'text') @record def test_shared_write_access_file(self): # SAS URL is calculated from storage key, so this test runs live only if TestMode.need_recording_file(self.test_mode): return # Arrange updated_data = b'updated file data' file_client_admin = self._create_file() token = file_client_admin.generate_shared_access_signature( permission=FilePermissions.WRITE, expiry=datetime.utcnow() + timedelta(hours=1), ) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client_admin.file_name, credential=token) # Act headers = {'x-ms-range': 'bytes=0-16', 'x-ms-write': 'update'} response = requests.put(file_client.url + '&comp=range', headers=headers, data=updated_data) # Assert self.assertTrue(response.ok) file_content = file_client_admin.download_file().content_as_bytes() self.assertEqual(updated_data, file_content[:len(updated_data)]) @record def test_shared_delete_access_file(self): # SAS URL is calculated from storage key, so this test runs live only if TestMode.need_recording_file(self.test_mode): return # Arrange file_client_admin = self._create_file() token = file_client_admin.generate_shared_access_signature( permission=FilePermissions.DELETE, expiry=datetime.utcnow() + timedelta(hours=1), ) file_client = FileClient( self.get_file_url(), share=self.share_name, file_path=file_client_admin.file_name, credential=token) # Act response = requests.delete(file_client.url) # Assert self.assertTrue(response.ok) with self.assertRaises(ResourceNotFoundError): file_client_admin.download_file()
class StorageShareTest(FileTestCase): def setUp(self): super(StorageShareTest, self).setUp() file_url = self.get_file_url() credentials = self.get_shared_key_credential() self.fsc = FileServiceClient(account_url=file_url, credential=credentials) self.test_shares = [] def tearDown(self): if not self.is_playback(): for share in self.test_shares: try: self.fsc.delete_share(share, delete_snapshots=True) except Exception as e: print("Delete failed", e) return super(StorageShareTest, self).tearDown() # --Helpers----------------------------------------------------------------- def _get_share_reference(self, prefix=TEST_SHARE_PREFIX): share_name = self.get_resource_name(prefix) share = self.fsc.get_share_client(share_name) self.test_shares.append(share_name) return share def _create_share(self, prefix=TEST_SHARE_PREFIX): share_client = self._get_share_reference(prefix) share = share_client.create_share() return share_client def _delete_shares(self, prefix=TEST_SHARE_PREFIX): for l in self.fsc.list_shares(include_snapshots=True): try: self.fsc.delete_share(l.name, delete_snapshots=True) except: pass # --Test cases for shares ----------------------------------------- @record def test_create_share(self): # Arrange share = self._get_share_reference() # Act created = self._create_share() # Assert self.assertTrue(created) self._delete_shares(share.share_name) @record def test_create_share_snapshot(self): # Arrange share = self._get_share_reference() # Act created = share.create_share() snapshot = share.create_snapshot() # Assert self.assertTrue(created) self.assertIsNotNone(snapshot['snapshot']) self.assertIsNotNone(snapshot['etag']) self.assertIsNotNone(snapshot['last_modified']) self._delete_shares(share.share_name) @record def test_create_snapshot_with_metadata(self): # Arrange share = self._get_share_reference() metadata = {"test1": "foo", "test2": "bar"} metadata2 = {"test100": "foo100", "test200": "bar200"} # Act created = share.create_share(metadata=metadata) snapshot = share.create_snapshot(metadata=metadata2) share_props = share.get_share_properties() snapshot_client = ShareClient( self.get_file_url(), share_name=share.share_name, snapshot=snapshot, credential=self.settings.STORAGE_ACCOUNT_KEY) snapshot_props = snapshot_client.get_share_properties() # Assert self.assertTrue(created) self.assertIsNotNone(snapshot['snapshot']) self.assertIsNotNone(snapshot['etag']) self.assertIsNotNone(snapshot['last_modified']) self.assertEqual(share_props.metadata, metadata) self.assertEqual(snapshot_props.metadata, metadata2) self._delete_shares(share.share_name) @record def test_delete_share_with_snapshots(self): # Arrange share = self._get_share_reference() share.create_share() snapshot = share.create_snapshot() # Act with self.assertRaises(HttpResponseError): share.delete_share() deleted = share.delete_share(delete_snapshots=True) self.assertIsNone(deleted) self._delete_shares() @record def test_delete_snapshot(self): # Arrange share = self._get_share_reference() share.create_share() snapshot = share.create_snapshot() # Act with self.assertRaises(HttpResponseError): share.delete_share() snapshot_client = ShareClient( self.get_file_url(), share_name=share.share_name, snapshot=snapshot, credential=self.settings.STORAGE_ACCOUNT_KEY) deleted = snapshot_client.delete_share() self.assertIsNone(deleted) self._delete_shares() @record def test_create_share_fail_on_exist(self): # Arrange share = self._get_share_reference() # Act created = share.create_share() # Assert self.assertTrue(created) self._delete_shares() @record def test_create_share_with_already_existing_share_fail_on_exist(self): # Arrange share = self._get_share_reference() # Act created = share.create_share() with self.assertRaises(HttpResponseError): share.create_share() # Assert self.assertTrue(created) self._delete_shares() @record def test_create_share_with_metadata(self): # Arrange metadata = {'hello': 'world', 'number': '42'} # Act client = self._get_share_reference() created = client.create_share(metadata=metadata) # Assert self.assertTrue(created) md = client.get_share_properties().metadata self.assertDictEqual(md, metadata) self._delete_shares() @record def test_create_share_with_quota(self): # Arrange # Act client = self._get_share_reference() created = client.create_share(quota=1) # Assert props = client.get_share_properties() self.assertTrue(created) self.assertEqual(props.quota, 1) self._delete_shares() @record def test_share_exists(self): # Arrange share = self._create_share() # Act exists = share.get_share_properties() # Assert self.assertTrue(exists) self._delete_shares() @record def test_share_not_exists(self): # Arrange share = self._get_share_reference() # Act with self.assertRaises(ResourceNotFoundError): share.get_share_properties() # Assert self._delete_shares() @record def test_share_snapshot_exists(self): # Arrange share = self._create_share() snapshot = share.create_snapshot() # Act snapshot_client = self.fsc.get_share_client(share.share_name, snapshot=snapshot) exists = snapshot_client.get_share_properties() # Assert self.assertTrue(exists) self._delete_shares() @record def test_share_snapshot_not_exists(self): # Arrange share = self._create_share() made_up_snapshot = '2017-07-19T06:53:46.0000000Z' # Act snapshot_client = self.fsc.get_share_client(share.share_name, snapshot=made_up_snapshot) with self.assertRaises(ResourceNotFoundError): snapshot_client.get_share_properties() # Assert self._delete_shares() @record def test_unicode_create_share_unicode_name(self): # Arrange share_name = u'啊齄丂狛狜' # Act with self.assertRaises(HttpResponseError): # not supported - share name must be alphanumeric, lowercase client = self.fsc.get_share_client(share_name) client.create_share() # Assert self._delete_shares() @record def test_list_shares_no_options(self): # Arrange share = self._create_share() # Act shares = list(self.fsc.list_shares()) # Assert self.assertIsNotNone(shares) self.assertGreaterEqual(len(shares), 1) self.assertIsNotNone(shares[0]) self.assertNamedItemInContainer(shares, share.share_name) self._delete_shares() @record def test_list_shares_with_snapshot(self): # Arrange #share = self._get_share_reference() share = self._create_share('random') snapshot1 = share.create_snapshot() snapshot2 = share.create_snapshot() # Act shares = self.fsc.list_shares(include_snapshots=True) # Assert self.assertIsNotNone(shares) all_shares = list(shares) self.assertEqual(len(all_shares), 3) self.assertNamedItemInContainer(all_shares, share.share_name) self.assertNamedItemInContainer(all_shares, snapshot1['snapshot']) self.assertNamedItemInContainer(all_shares, snapshot2['snapshot']) share.delete_share(delete_snapshots=True) self._delete_shares() @record def test_list_shares_with_prefix(self): # Arrange share = self._get_share_reference() share.create_share() # Act shares = list(self.fsc.list_shares(name_starts_with=share.share_name)) # Assert self.assertEqual(len(shares), 1) self.assertIsNotNone(shares[0]) self.assertEqual(shares[0].name, share.share_name) self.assertIsNone(shares[0].metadata) self._delete_shares() @record def test_list_shares_with_include_metadata(self): # Arrange metadata = {'hello': 'world', 'number': '42'} share = self._get_share_reference() share.create_share(metadata=metadata) # Act shares = list( self.fsc.list_shares(share.share_name, include_metadata=True)) # Assert self.assertIsNotNone(shares) self.assertGreaterEqual(len(shares), 1) self.assertIsNotNone(shares[0]) self.assertNamedItemInContainer(shares, share.share_name) self.assertDictEqual(shares[0].metadata, metadata) self._delete_shares() @record def test_list_shares_with_num_results_and_marker(self): # Arrange prefix = 'listshare' share_names = [] for i in range(0, 4): share_names.append(self._create_share(prefix + str(i)).share_name) #share_names.sort() # Act generator1 = self.fsc.list_shares(prefix, results_per_page=2).by_page() shares1 = list(next(generator1)) generator2 = self.fsc.list_shares(prefix, results_per_page=2).by_page( continuation_token=generator1.continuation_token) shares2 = list(next(generator2)) # Assert self.assertIsNotNone(shares1) self.assertEqual(len(shares1), 2) self.assertNamedItemInContainer(shares1, share_names[0]) self.assertNamedItemInContainer(shares1, share_names[1]) self.assertIsNotNone(shares2) self.assertEqual(len(shares2), 2) self.assertNamedItemInContainer(shares2, share_names[2]) self.assertNamedItemInContainer(shares2, share_names[3]) self._delete_shares() @record def test_set_share_metadata(self): # Arrange share = self._create_share() metadata = {'hello': 'world', 'number': '42'} # Act share.set_share_metadata(metadata) # Assert md = share.get_share_properties().metadata self.assertDictEqual(md, metadata) self._delete_shares() @record def test_get_share_metadata(self): # Arrange metadata = {'hello': 'world', 'number': '42'} # Act client = self._get_share_reference() created = client.create_share(metadata=metadata) # Assert self.assertTrue(created) md = client.get_share_properties().metadata self.assertDictEqual(md, metadata) self._delete_shares() @record def test_get_share_metadata_with_snapshot(self): # Arrange metadata = {'hello': 'world', 'number': '42'} # Act client = self._get_share_reference() created = client.create_share(metadata=metadata) snapshot = client.create_snapshot() snapshot_client = self.fsc.get_share_client(client.share_name, snapshot=snapshot) # Assert self.assertTrue(created) md = snapshot_client.get_share_properties().metadata self.assertDictEqual(md, metadata) self._delete_shares() @record def test_set_share_properties(self): # Arrange share = self._create_share() share.set_share_quota(1) # Act props = share.get_share_properties() # Assert self.assertIsNotNone(props) self.assertEqual(props.quota, 1) self._delete_shares() @record def test_delete_share_with_existing_share(self): # Arrange share = self._get_share_reference() share.create_share() # Act deleted = share.delete_share() # Assert self.assertIsNone(deleted) self._delete_shares() @record def test_delete_share_with_existing_share_fail_not_exist(self): # Arrange client = self._get_share_reference() # Act with LogCaptured(self) as log_captured: with self.assertRaises(HttpResponseError): client.delete_share() log_as_str = log_captured.getvalue() self._delete_shares() @record def test_delete_share_with_non_existing_share(self): # Arrange client = self._get_share_reference() # Act with LogCaptured(self) as log_captured: with self.assertRaises(HttpResponseError): deleted = client.delete_share() log_as_str = log_captured.getvalue() self.assertTrue('ERROR' not in log_as_str) self._delete_shares() @record def test_delete_share_with_non_existing_share_fail_not_exist(self): # Arrange client = self._get_share_reference() # Act with LogCaptured(self) as log_captured: with self.assertRaises(HttpResponseError): client.delete_share() log_as_str = log_captured.getvalue() self._delete_shares() @record def test_get_share_stats(self): # Arrange share = self._get_share_reference() share.create_share() # Act share_usage = share.get_share_stats() # Assert self.assertEqual(share_usage, 0) self._delete_shares() @record def test_set_share_acl(self): # Arrange share = self._get_share_reference() share.create_share() # Act resp = share.set_share_access_policy(signed_identifiers=dict()) # Assert acl = share.get_share_access_policy() self.assertIsNotNone(acl) self._delete_shares() @record def test_set_share_acl_with_empty_signed_identifiers(self): # Arrange share = self._get_share_reference() share.create_share() # Act resp = share.set_share_access_policy(dict()) # Assert acl = share.get_share_access_policy() self.assertIsNotNone(acl) self.assertEqual(len(acl.get('signed_identifiers')), 0) self._delete_shares() @record def test_set_share_acl_with_signed_identifiers(self): # Arrange share = self._get_share_reference() share.create_share() # Act identifiers = dict() identifiers['testid'] = AccessPolicy( permission=ShareSasPermissions(write=True), expiry=datetime.utcnow() + timedelta(hours=1), start=datetime.utcnow() - timedelta(minutes=1), ) resp = share.set_share_access_policy(identifiers) # Assert acl = share.get_share_access_policy() self.assertIsNotNone(acl) self.assertEqual(len(acl['signed_identifiers']), 1) self.assertEqual(acl['signed_identifiers'][0].id, 'testid') self._delete_shares() @record def test_set_share_acl_too_many_ids(self): # Arrange share = self._get_share_reference() share.create_share() # Act identifiers = dict() for i in range(0, 6): identifiers['id{}'.format(i)] = AccessPolicy() # Assert with self.assertRaises(ValueError) as e: share.set_share_access_policy(identifiers) self.assertEqual( str(e.exception), 'Too many access policies provided. The server does not support setting more than 5 access policies on a single resource.' ) self._delete_shares() @record def test_list_directories_and_files(self): # Arrange share = self._create_share() dir0 = share.get_directory_client() dir0.upload_file('file1', 'data1') dir1 = share.get_directory_client('dir1') dir1.create_directory() dir1.upload_file('file2', 'data2') dir2 = share.get_directory_client('dir2') dir2.create_directory() # Act resp = list(share.list_directories_and_files()) # Assert self.assertIsNotNone(resp) self.assertEqual(len(resp), 3) self.assertIsNotNone(resp[0]) self.assertNamedItemInContainer(resp, 'dir1') self.assertNamedItemInContainer(resp, 'dir2') self.assertNamedItemInContainer(resp, 'file1') self._delete_shares() @record def test_list_directories_and_files_with_snapshot(self): # Arrange share_name = self._create_share() dir1 = share_name.get_directory_client('dir1') dir1.create_directory() dir2 = share_name.get_directory_client('dir2') dir2.create_directory() snapshot1 = share_name.create_snapshot() dir3 = share_name.get_directory_client('dir3') dir3.create_directory() file1 = share_name.get_file_client('file1') file1.upload_file('data') # Act snapshot_client = self.fsc.get_share_client(share_name.share_name, snapshot=snapshot1) resp = list(snapshot_client.list_directories_and_files()) # Assert self.assertIsNotNone(resp) self.assertEqual(len(resp), 2) self.assertIsNotNone(resp[0]) self.assertNamedItemInContainer(resp, 'dir1') self.assertNamedItemInContainer(resp, 'dir2') self._delete_shares() @record def test_list_directories_and_files_with_num_results(self): # Arrange share_name = self._create_share() dir1 = share_name.create_directory('dir1') root = share_name.get_directory_client() root.upload_file('filea1', '1024') root.upload_file('filea2', '1024') root.upload_file('filea3', '1024') root.upload_file('fileb1', '1024') # Act result = share_name.list_directories_and_files( results_per_page=2).by_page() result = list(next(result)) # Assert self.assertIsNotNone(result) self.assertEqual(len(result), 2) self.assertNamedItemInContainer(result, 'dir1') self.assertNamedItemInContainer(result, 'filea1') self._delete_shares() @record def test_list_directories_and_files_with_num_results_and_marker(self): # Arrange share_name = self._create_share() dir1 = share_name.get_directory_client('dir1') dir1.create_directory() dir1.upload_file('filea1', '1024') dir1.upload_file('filea2', '1024') dir1.upload_file('filea3', '1024') dir1.upload_file('fileb1', '1024') # Act generator1 = share_name.list_directories_and_files( 'dir1', results_per_page=2).by_page() result1 = list(next(generator1)) generator2 = share_name.list_directories_and_files( 'dir1', results_per_page=2).by_page( continuation_token=generator1.continuation_token) result2 = list(next(generator2)) # Assert self.assertEqual(len(result1), 2) self.assertEqual(len(result2), 2) self.assertNamedItemInContainer(result1, 'filea1') self.assertNamedItemInContainer(result1, 'filea2') self.assertNamedItemInContainer(result2, 'filea3') self.assertNamedItemInContainer(result2, 'fileb1') self.assertEqual(generator2.continuation_token, None) self._delete_shares() @record def test_list_directories_and_files_with_prefix(self): # Arrange share = self._create_share() dir1 = share.create_directory('dir1') share.create_directory('dir1/pref_dir3') share.create_directory('dir2') root = share.get_directory_client() root.upload_file('file1', '1024') dir1.upload_file('pref_file2', '1025') dir1.upload_file('file3', '1025') # Act resp = list( share.list_directories_and_files('dir1', name_starts_with='pref')) # Assert self.assertIsNotNone(resp) self.assertEqual(len(resp), 2) self.assertIsNotNone(resp[0]) self.assertNamedItemInContainer(resp, 'pref_file2') self.assertNamedItemInContainer(resp, 'pref_dir3') self._delete_shares() @record def test_shared_access_share(self): # SAS URL is calculated from storage key, so this test runs live only if TestMode.need_recording_file(self.test_mode): return # Arrange file_name = 'file1' dir_name = 'dir1' data = b'hello world' share = self._create_share() dir1 = share.create_directory(dir_name) dir1.upload_file(file_name, data) token = generate_share_sas( share.account_name, share.share_name, share.credential.account_key, expiry=datetime.utcnow() + timedelta(hours=1), permission=ShareSasPermissions(read=True), ) sas_client = FileClient( self.get_file_url(), share_name=share.share_name, file_path=dir_name + '/' + file_name, credential=token, ) # Act print(sas_client.url) response = requests.get(sas_client.url) # Assert self.assertTrue(response.ok) self.assertEqual(data, response.content) self._delete_shares() @record def test_create_permission_for_share(self): user_given_permission = "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-" \ "1604012920-1887927527-513D:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;" \ "S-1-5-21-397955417-626881126-188441444-3053964)" share_client = self._create_share() permission_key = share_client.create_permission_for_share( user_given_permission) self.assertIsNotNone(permission_key) server_returned_permission = share_client.get_permission_for_share( permission_key) self.assertIsNotNone(server_returned_permission) permission_key2 = share_client.create_permission_for_share( server_returned_permission) # the permission key obtained from user_given_permission should be the same as the permission key obtained from # server returned permission self.assertEqual(permission_key, permission_key2) @record def test_transport_closed_only_once(self): if TestMode.need_recording_file(self.test_mode): return transport = RequestsTransport() url = self.get_file_url() credential = self.get_shared_key_credential() prefix = TEST_SHARE_PREFIX share_name = self.get_resource_name(prefix) with FileServiceClient(url, credential=credential, transport=transport) as fsc: fsc.get_service_properties() assert transport.session is not None with fsc.get_share_client(share_name) as fc: assert transport.session is not None fsc.get_service_properties() assert transport.session is not None