diff --git a/dvc/remote/azure.py b/dvc/remote/azure.py index 38ee994bf..ba6023f70 100644 --- a/dvc/remote/azure.py +++ b/dvc/remote/azure.py @@ -28,10 +28,10 @@ class Callback(object): class RemoteAzure(RemoteBase): scheme = 'azure' - REGEX = (r'^azure://((?P[^=;]*)|(' + REGEX = (r'azure://((?P[^=;]*)?|(' # backward compatibility r'(ContainerName=(?P[^;]+);?)?' - r'(?P.+)?))$') + r'(?P.+)?)?)$') REQUIRES = {'azure-storage-blob': BlockBlobService} PARAM_ETAG = 'etag' COPY_POLL_SECONDS = 5 @@ -43,8 +43,9 @@ class RemoteAzure(RemoteBase): self.url = config.get(Config.SECTION_REMOTE_URL) match = re.match(self.REGEX, self.url) # backward compatibility + path = match.group('path') self.bucket = ( - urlparse(self.url).netloc + urlparse(self.url if path else '').netloc or match.group('container_name') # backward compatibility or os.getenv('AZURE_STORAGE_CONTAINER_NAME')) @@ -68,8 +69,11 @@ class RemoteAzure(RemoteBase): @property def blob_service(self): if self.__blob_service is None: + logger.debug('URL {}'.format(self.url)) + logger.debug('Connection string {}'.format(self.connection_string)) self.__blob_service = BlockBlobService( connection_string=self.connection_string) + logger.debug('Container name {}'.format(self.bucket)) self.__blob_service.create_container(self.bucket) return self.__blob_service diff --git a/tests/test_data_cloud.py b/tests/test_data_cloud.py index 35b627de7..66da97551 100644 --- a/tests/test_data_cloud.py +++ b/tests/test_data_cloud.py @@ -144,7 +144,11 @@ def get_gcp_url(): def get_azure_url_compat(): - return 'azure://' + container_name = os.getenv("AZURE_STORAGE_CONTAINER_NAME") + connection_string = os.getenv("AZURE_STORAGE_CONNECTION_STRING") + assert container_name is not None + return 'azure://ContainerName={};{}'.format(container_name, + connection_string) def get_azure_url(): @@ -165,11 +169,9 @@ class TestDataCloud(TestDvc): ('gs://mybucket/', RemoteGS), ('ssh://user@localhost:/', RemoteSSH), ('http://localhost:8000/', RemoteHTTP), + ('azure://ContainerName=mybucket;conn_string;', RemoteAzure), (TestDvc.mkdtemp(), RemoteLOCAL)] - if _should_test_azure(): - clist.append(('azure://ContainerName=', RemoteAzure)) - for scheme, cl in clist: remote_url = scheme + str(uuid.uuid4()) config[TEST_SECTION][Config.SECTION_REMOTE_URL] = remote_url diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/unit/remote/__init__.py b/tests/unit/remote/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/unit/remote/azure.py b/tests/unit/remote/azure.py new file mode 100644 index 000000000..7f00a84d6 --- /dev/null +++ b/tests/unit/remote/azure.py @@ -0,0 +1,36 @@ +from unittest import TestCase + +from dvc.remote.azure import RemoteAzure + + +class TestRemoteAzure(TestCase): + container_name = 'container-name' + connection_string = ( + 'DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;' + 'AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsu' + 'Fq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;' + 'BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;' + ) + + def test_init_compat(self): + url = ( + 'azure://ContainerName={container_name};{connection_string}' + .format(container_name=self.container_name, + connection_string=self.connection_string) + ) + config = {'url': url} + remote = RemoteAzure(None, config) + self.assertEqual(remote.url, url) + self.assertEqual(remote.prefix, '') + self.assertEqual(remote.bucket, self.container_name) + self.assertEqual(remote.connection_string, self.connection_string) + + def test_init(self): + prefix = 'some/prefix' + url = 'azure://{}/{}'.format(self.container_name, prefix) + config = {'url': url, 'connection_string': self.connection_string} + remote = RemoteAzure(None, config) + self.assertEqual(remote.url, url) + self.assertEqual(remote.prefix, prefix) + self.assertEqual(remote.bucket, self.container_name) + self.assertEqual(remote.connection_string, self.connection_string)