Files
dvc/tests/remotes/hdfs.py
T
Saugat PachhaiandRuslan Kuprieiev fc6999ad17 Run CI for Python3.9 (#4647)
* Run CI for Python3.9, skips hdfs tests for 3.9

Also, `dvc[hdfs]` install will be a no-op till we have
a pyarrow wheel for 3.9.

Note that this does not add an entry to the classifier
claiming it supports 3.9, that will be added when 3.9
gets released (or, wait for pyarrow to be released).

* Skip HDFS related tests on Python3.9

Also, fix the python version regex for `3.9.0b5` like versions.

* Exclude python3.9 for Windows

libxml does not have wheels for Python39.
We do compile them on Linux and Mac

* Update tests/unit/test_info.py

* Use realpath for gitignore

Windows tests for Python3.8 was failing
intermittently.

Note: Also removed the realpath wrap around self.root_dir as it's already a
realpath when `Git` is instantiated.

Co-authored-by: Ruslan Kuprieiev <[email protected]>
2020-10-01 10:41:39 +03:00

147 lines
4.1 KiB
Python

import locale
import os
import platform
import uuid
from contextlib import contextmanager
import pytest
from dvc.path_info import URLInfo
from tests import PY39, PYARROW_NOT_AVAILABLE
from .base import Base
class HDFS(Base, URLInfo): # pylint: disable=abstract-method
@contextmanager
def _hdfs(self):
import pyarrow
conn = pyarrow.hdfs.connect(self.host, self.port)
try:
yield conn
finally:
conn.close()
def is_file(self):
with self._hdfs() as _hdfs:
return _hdfs.isfile(self.path)
def is_dir(self):
with self._hdfs() as _hdfs:
return _hdfs.isfile(self.path)
def exists(self):
with self._hdfs() as _hdfs:
return _hdfs.exists(self.path)
def mkdir(self, mode=0o777, parents=False, exist_ok=False):
assert mode == 0o777
assert parents
assert not exist_ok
with self._hdfs() as _hdfs:
# NOTE: hdfs.mkdir always creates parents
_hdfs.mkdir(self.path)
def write_bytes(self, contents):
with self._hdfs() as _hdfs:
# NOTE: hdfs.open only supports 'rb', 'wb' or 'ab'
with _hdfs.open(self.path, "wb") as fobj:
fobj.write(contents)
def write_text(self, contents, encoding=None, errors=None):
if not encoding:
encoding = locale.getpreferredencoding(False)
assert errors is None
self.write_bytes(contents.encode(encoding))
def read_bytes(self):
with self._hdfs() as _hdfs:
# NOTE: hdfs.open only supports 'rb', 'wb' or 'ab'
with _hdfs.open(self.path, "rb") as fobj:
return fobj.read()
def read_text(self, encoding=None, errors=None):
if not encoding:
encoding = locale.getpreferredencoding(False)
assert errors is None
return self.read_bytes().decode(encoding)
@pytest.fixture(scope="session")
def hadoop():
if platform.system() != "Linux":
pytest.skip("only supported on Linux")
if PY39:
pytest.skip(PYARROW_NOT_AVAILABLE)
import wget
from appdirs import user_cache_dir
hadoop_name = "hadoop-2.7.2.tar.gz"
java_name = "openjdk-7u75-b13-linux-x64-18_dec_2014.tar.gz"
base_url = "https://s3-us-east-2.amazonaws.com/dvc-public/dvc-test/"
hadoop_url = base_url + hadoop_name
java_url = base_url + java_name
(cache_dir,) = (user_cache_dir("dvc-test", "iterative"),)
dname = os.path.join(cache_dir, "hdfs")
java_tar = os.path.join(dname, java_name)
hadoop_tar = os.path.join(dname, hadoop_name)
java_home = os.path.join(dname, "java-se-7u75-ri")
hadoop_home = os.path.join(dname, "hadoop-2.7.2")
def _get(url, tar, target):
if os.path.isdir(target):
return
if not os.path.exists(tar):
wget.download(url, out=tar)
assert os.system(f"tar -xvf {tar} -C {dname}") == 0
assert os.path.isdir(target)
os.makedirs(dname, exist_ok=True)
_get(hadoop_url, hadoop_tar, hadoop_home)
_get(java_url, java_tar, java_home)
os.environ["JAVA_HOME"] = java_home
os.environ["HADOOP_HOME"] = hadoop_home
os.environ["PATH"] += f":{hadoop_home}/bin:{hadoop_home}/sbin"
@pytest.fixture(scope="session")
def hdfs_server(hadoop, docker_compose, docker_services):
import pyarrow
port = docker_services.port_for("hdfs", 8020)
def _check():
try:
# NOTE: just connecting or even opening something is not enough,
# we need to make sure that we are able to write something.
conn = pyarrow.hdfs.connect("127.0.0.1", port)
try:
with conn.open(str(uuid.uuid4()), "wb") as fobj:
fobj.write(b"test")
finally:
conn.close()
return True
except (pyarrow.ArrowException, OSError):
return False
docker_services.wait_until_responsive(timeout=30.0, pause=5, check=_check)
return port
@pytest.fixture
def hdfs(hdfs_server):
port = hdfs_server
url = f"hdfs://127.0.0.1:{port}/{uuid.uuid4()}"
yield HDFS(url)