Skip to content

Commit 0899b27

Browse files
authored
tests: launch oss/azure containers from fixtures (#4178)
* tests: launch oss/azure containers from fixtures Related to #4054 * ci: hdfs: remove unneeded fix We are using pyarrow 0.17.0 already.
1 parent 253a0ea commit 0899b27

File tree

10 files changed

+106
-85
lines changed

10 files changed

+106
-85
lines changed

scripts/ci/before_install.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ if [[ "$TRAVIS_BUILD_STAGE_NAME" == "test" ]]; then
3232
fi
3333

3434
if [ "$TRAVIS_OS_NAME" == "linux" ]; then
35-
bash "$scriptdir/install_azurite.sh"
36-
bash "$scriptdir/install_oss.sh"
3735
bash "$scriptdir/install_hadoop.sh"
3836
fi
3937

scripts/ci/install_azurite.sh

Lines changed: 0 additions & 14 deletions
This file was deleted.

scripts/ci/install_hadoop.sh

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,6 @@ echo "export HADOOP_HDFS_HOME=/usr/local/hadoop" >>env.sh
2424
echo "export YARN_HOME=/usr/local/hadoop" >>env.sh
2525
echo "export HADOOP_COMMON_LIB_NATIVE_DIR=/usr/local/hadoop/lib/native" >>env.sh
2626

27-
# PyArrow==0.16.0 regression https://issues.apache.org/jira/browse/ARROW-7841
28-
# retrieves native library from $HADOOP_HOME directory instead of
29-
# `$HADOOP_HOME/lib/native`.
30-
# Fix: force search for `libhdfs.so` inside `$HADOOP_HOME/lib/native`.
31-
# Note: not needed for PyArrow==0.17.0.
32-
echo "export ARROW_LIBHDFS_DIR=/usr/local/hadoop/lib/native" >> env.sh
33-
3427
echo "export JAVA_HOME=/usr/" >>env.sh
3528
echo "export PATH=\$PATH:/usr/local/hadoop/sbin:/usr/local/hadoop/bin:$JAVA_PATH/bin" >>env.sh
3629

scripts/ci/install_oss.sh

Lines changed: 0 additions & 10 deletions
This file was deleted.

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ def run(self):
103103
"wheel>=0.31.1",
104104
# Test requirements:
105105
"pytest>=4.6.0",
106+
"pytest-docker>=0.7.2",
106107
"pytest-timeout>=1.3.3",
107108
"pytest-cov>=2.6.1",
108109
"pytest-xdist>=1.26.1",

tests/docker-compose.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
version: '3.2'
3+
services:
4+
azurite:
5+
image: mcr.microsoft.com/azure-storage/azurite:3.3.0-preview
6+
ports:
7+
- "10000"
8+
oss:
9+
image: rkuprieiev/oss-emulator
10+
ports:
11+
- "8880"

tests/remotes/__init__.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import subprocess
2+
13
import pytest
24

3-
from .azure import Azure, azure # noqa: F401
5+
from .azure import Azure, azure, azure_server # noqa: F401
46
from .hdfs import HDFS, hdfs # noqa: F401
57
from .http import HTTP, http, http_server # noqa: F401
68
from .local import Local, local_cloud, local_remote # noqa: F401
7-
from .oss import OSS, TEST_OSS_REPO_BUCKET, oss # noqa: F401
9+
from .oss import OSS, TEST_OSS_REPO_BUCKET, oss, oss_server # noqa: F401
810
from .s3 import S3, TEST_AWS_REPO_BUCKET, real_s3, s3 # noqa: F401
911

1012
TEST_REMOTE = "upstream"
@@ -35,6 +37,14 @@
3537
)
3638

3739

40+
@pytest.fixture(scope="session")
41+
def docker_compose():
42+
try:
43+
subprocess.check_output("docker-compose version", shell=True)
44+
except (subprocess.CalledProcessError, OSError):
45+
pytest.skip("no docker-compose installed")
46+
47+
3848
@pytest.fixture
3949
def remote(tmp_dir, dvc, request):
4050
cloud = request.param

tests/remotes/azure.py

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,61 @@
11
# pylint:disable=abstract-method
22

3-
import os
43
import uuid
54

65
import pytest
76

87
from dvc.path_info import CloudURLInfo
9-
from dvc.utils import env2bool
108

119
from .base import Base
1210

11+
TEST_AZURE_CONTAINER = "tests"
12+
TEST_AZURE_CONNECTION_STRING = (
13+
"DefaultEndpointsProtocol=http;"
14+
"AccountName=devstoreaccount1;"
15+
"AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSR"
16+
"Z6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;"
17+
"BlobEndpoint=http://127.0.0.1:{port}/devstoreaccount1;"
18+
)
19+
1320

1421
class Azure(Base, CloudURLInfo):
15-
@staticmethod
16-
def should_test():
17-
do_test = env2bool("DVC_TEST_AZURE", undefined=None)
18-
if do_test is not None:
19-
return do_test
22+
pass
23+
24+
25+
@pytest.fixture(scope="session")
26+
def azure_server(docker_compose, docker_services):
27+
from azure.storage.blob import ( # pylint: disable=no-name-in-module
28+
BlockBlobService,
29+
)
30+
from azure.common import ( # pylint: disable=no-name-in-module
31+
AzureException,
32+
)
33+
34+
port = docker_services.port_for("azurite", 10000)
35+
connection_string = TEST_AZURE_CONNECTION_STRING.format(port=port)
36+
37+
def _check():
38+
try:
39+
BlockBlobService(
40+
connection_string=connection_string,
41+
).list_containers()
42+
return True
43+
except AzureException:
44+
return False
2045

21-
return os.getenv("AZURE_STORAGE_CONTAINER_NAME") and os.getenv(
22-
"AZURE_STORAGE_CONNECTION_STRING"
23-
)
46+
docker_services.wait_until_responsive(
47+
timeout=60.0, pause=0.1, check=_check
48+
)
2449

25-
@staticmethod
26-
def get_url():
27-
container_name = os.getenv("AZURE_STORAGE_CONTAINER_NAME")
28-
assert container_name is not None
29-
return "azure://{}/{}".format(container_name, str(uuid.uuid4()))
50+
return connection_string
3051

3152

3253
@pytest.fixture
33-
def azure():
34-
if not Azure.should_test():
35-
pytest.skip("no azure running")
36-
yield Azure(Azure.get_url())
54+
def azure(azure_server):
55+
url = f"azure://{TEST_AZURE_CONTAINER}/{uuid.uuid4()}"
56+
ret = Azure(url)
57+
ret.config = {
58+
"url": url,
59+
"connection_string": azure_server,
60+
}
61+
return ret

tests/remotes/oss.py

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,54 @@
11
# pylint:disable=abstract-method
2-
import os
32
import uuid
43

54
import pytest
65

76
from dvc.path_info import CloudURLInfo
8-
from dvc.utils import env2bool
97

108
from .base import Base
119

1210
TEST_OSS_REPO_BUCKET = "dvc-test"
11+
TEST_OSS_ENDPOINT = "127.0.0.1:{port}"
12+
TEST_OSS_ACCESS_KEY_ID = "AccessKeyID"
13+
TEST_OSS_ACCESS_KEY_SECRET = "AccessKeySecret"
1314

1415

1516
class OSS(Base, CloudURLInfo):
16-
@staticmethod
17-
def should_test():
18-
do_test = env2bool("DVC_TEST_OSS", undefined=None)
19-
if do_test is not None:
20-
return do_test
17+
pass
2118

22-
return (
23-
os.getenv("OSS_ENDPOINT")
24-
and os.getenv("OSS_ACCESS_KEY_ID")
25-
and os.getenv("OSS_ACCESS_KEY_SECRET")
26-
)
2719

28-
@staticmethod
29-
def _get_storagepath():
30-
return f"{TEST_OSS_REPO_BUCKET}/{uuid.uuid4()}"
20+
@pytest.fixture(scope="session")
21+
def oss_server(docker_compose, docker_services):
22+
import oss2
3123

32-
@staticmethod
33-
def get_url():
34-
return f"oss://{OSS._get_storagepath()}"
24+
port = docker_services.port_for("oss", 8880)
25+
endpoint = TEST_OSS_ENDPOINT.format(port=port)
26+
27+
def _check():
28+
try:
29+
auth = oss2.Auth(
30+
TEST_OSS_ACCESS_KEY_ID, TEST_OSS_ACCESS_KEY_SECRET
31+
)
32+
oss2.Bucket(auth, endpoint, "mybucket").get_bucket_info()
33+
return True
34+
except oss2.exceptions.NoSuchBucket:
35+
return True
36+
except oss2.exceptions.OssError:
37+
return False
38+
39+
docker_services.wait_until_responsive(timeout=30.0, pause=5, check=_check)
40+
41+
return endpoint
3542

3643

3744
@pytest.fixture
38-
def oss():
39-
if not OSS.should_test():
40-
pytest.skip("no oss running")
41-
yield OSS(OSS.get_url())
45+
def oss(oss_server):
46+
url = f"oss://{TEST_OSS_REPO_BUCKET}/{uuid.uuid4()}"
47+
ret = OSS(url)
48+
ret.config = {
49+
"url": url,
50+
"oss_key_id": TEST_OSS_ACCESS_KEY_ID,
51+
"oss_key_secret": TEST_OSS_ACCESS_KEY_SECRET,
52+
"oss_endpoint": oss_server,
53+
}
54+
return ret

tests/unit/remote/test_azure.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
import pytest
2-
31
from dvc.path_info import PathInfo
42
from dvc.remote.azure import AzureRemoteTree
5-
from tests.remotes import Azure
63

74
container_name = "container-name"
85
connection_string = (
@@ -32,14 +29,11 @@ def test_init(dvc):
3229
assert tree._conn_kwargs["connection_string"] == connection_string
3330

3431

35-
def test_get_file_hash(tmp_dir):
36-
if not Azure.should_test():
37-
pytest.skip("no azurite running")
38-
32+
def test_get_file_hash(tmp_dir, azure):
3933
tmp_dir.gen("foo", "foo")
4034

41-
tree = AzureRemoteTree(None, {})
42-
to_info = tree.PATH_CLS(Azure.get_url())
35+
tree = AzureRemoteTree(None, azure.config)
36+
to_info = azure
4337
tree.upload(PathInfo("foo"), to_info)
4438
assert tree.exists(to_info)
4539
hash_ = tree.get_file_hash(to_info)

0 commit comments

Comments
 (0)