mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 17:36:29 +03:00
- rework running of liveconfig tests
- better README reflecting how to use things, don't advertise run-integration-tests to only have one documented way and use less tools for rust-devs that just want to run python tests - fix test skipping and get circle-ci to play along - update docker related docs as well
This commit is contained in:
@@ -16,7 +16,7 @@ export BRANCH=${CIRCLE_BRANCH:-test7}
|
|||||||
#fi
|
#fi
|
||||||
|
|
||||||
# run everything else inside docker (TESTS, DOCS, WHEELS)
|
# run everything else inside docker (TESTS, DOCS, WHEELS)
|
||||||
docker run -e BRANCH -e TESTS -e DOCS \
|
docker run -e DCC_PY_LIVECONFIG -e BRANCH -e TESTS -e DOCS \
|
||||||
--rm -it -v $(pwd):/mnt -w /mnt \
|
--rm -it -v $(pwd):/mnt -w /mnt \
|
||||||
deltachat/coredeps ci_scripts/run_all.sh
|
deltachat/coredeps ci_scripts/run_all.sh
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
set -e -x
|
set -e -x
|
||||||
|
|
||||||
# Install Rust
|
# Install Rust
|
||||||
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2019-04-19 -y
|
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2019-07-10 -y
|
||||||
export PATH=/root/.cargo/bin:$PATH
|
export PATH=/root/.cargo/bin:$PATH
|
||||||
rustc --version
|
rustc --version
|
||||||
|
|
||||||
# remove some 300-400 MB that we don't need for automated builds
|
# remove some 300-400 MB that we don't need for automated builds
|
||||||
rm -rf /root/.rustup/toolchains/nightly-2019-04-19-x86_64-unknown-linux-gnu/share/
|
rm -rf /root/.rustup/toolchains/nightly-2019-07-10-x86_64-unknown-linux-gnu/share/
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ if [ -n "$TESTS" ]; then
|
|||||||
export PYTHONDONTWRITEBYTECODE=1
|
export PYTHONDONTWRITEBYTECODE=1
|
||||||
|
|
||||||
# run tox
|
# run tox
|
||||||
|
# XXX we don't run liveconfig tests because they hang sometimes
|
||||||
|
# see https://github.com/deltachat/deltachat-core-rust/issues/331
|
||||||
|
unset DCC_PY_LIVECONFIG
|
||||||
|
|
||||||
tox --workdir "$TOXWORKDIR" -e lint,py27,py35,py36,py37,auditwheels
|
tox --workdir "$TOXWORKDIR" -e lint,py27,py35,py36,py37,auditwheels
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -39,6 +39,12 @@ and push them to a python package index. To install the latest github ``master``
|
|||||||
|
|
||||||
pip install -i https://m.devpi.net/dc/master deltachat
|
pip install -i https://m.devpi.net/dc/master deltachat
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If you can help to automate the building of wheels for Mac or Windows,
|
||||||
|
that'd be much appreciated! please then get
|
||||||
|
`in contact with us <https://delta.chat/en/contribute>`_.
|
||||||
|
|
||||||
|
|
||||||
Installing bindings from source
|
Installing bindings from source
|
||||||
===============================
|
===============================
|
||||||
@@ -48,34 +54,56 @@ to core deltachat library::
|
|||||||
|
|
||||||
git clone https://github.com/deltachat/deltachat-core-rust
|
git clone https://github.com/deltachat/deltachat-core-rust
|
||||||
cd deltachat-core-rust
|
cd deltachat-core-rust
|
||||||
cargo build -p deltachat_ffi --release
|
|
||||||
|
|
||||||
This will result in a ``libdeltachat.so`` and ``libdeltachat.a`` files
|
|
||||||
in the ``target/release`` directory. These files are needed for
|
|
||||||
creating the python bindings for deltachat::
|
|
||||||
|
|
||||||
cd python
|
cd python
|
||||||
DCC_RS_DEV=`pwd`/.. pip install -e .
|
|
||||||
|
|
||||||
Now test if the bindings find the correct library::
|
It is always a good idea to create a python "virtualenv".
|
||||||
|
Install "virtualenv" on your system and run::
|
||||||
|
|
||||||
python -c 'import deltachat ; print(deltachat.__version__)'
|
virtualenv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
This should print your deltachat bindings version.
|
Afterwards ``which python`` tells you that it comes out of the "venv"
|
||||||
|
directory that contains all python install artifacts. Let's first
|
||||||
|
install test tools::
|
||||||
|
|
||||||
|
pip install pytest pytest-timeout pytest-faulthandler requests
|
||||||
|
|
||||||
|
then cargo-build and install the deltachat bindings::
|
||||||
|
|
||||||
|
python install_python_bindings.py
|
||||||
|
|
||||||
|
The bindings will be installed in release mode but with debug symbols.
|
||||||
|
The release mode is neccessary because some tests generate RSA keys
|
||||||
|
which is prohibitively slow in debug mode.
|
||||||
|
|
||||||
|
After succcessul binding installation you can finally run the tests::
|
||||||
|
|
||||||
|
pytest -v tests
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
If you can help to automate the building of wheels for Mac or Windows,
|
Some tests are sometimes failing/hanging because of
|
||||||
that'd be much appreciated! please then get
|
https://github.com/deltachat/deltachat-core-rust/issues/331
|
||||||
`in contact with us <https://delta.chat/en/contribute>`_.
|
and
|
||||||
|
https://github.com/deltachat/deltachat-core-rust/issues/326
|
||||||
|
|
||||||
Using a system-installed deltachat-core-rust
|
|
||||||
--------------------------------------------
|
|
||||||
|
|
||||||
When calling ``pip`` without specifying the ``DCC_RS_DEV`` environment
|
running "live" tests (experimental)
|
||||||
variable cffi will try to use a ``deltachat.h`` from a system location
|
-----------------------------------
|
||||||
like ``/usr/local/include`` and will try to dynamically link against a
|
|
||||||
``libdeltachat.so`` in a similar location (e.g. ``/usr/local/lib``).
|
If you want to run "liveconfig" functional tests you can set
|
||||||
|
``DCC_PY_LIVECONFIG`` to:
|
||||||
|
|
||||||
|
- a particular https-url that you can ask for from the delta
|
||||||
|
chat devs.
|
||||||
|
|
||||||
|
- or the path of a file that contains two lines, each describing
|
||||||
|
via "addr=... mail_pwd=..." a test account login that will
|
||||||
|
be used for the live tests.
|
||||||
|
|
||||||
|
With ``DCC_PY_LIVECONFIG`` set pytest invocations will use real
|
||||||
|
e-mail accounts and run through all functional "liveconfig" tests.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Code examples
|
Code examples
|
||||||
@@ -84,68 +112,34 @@ Code examples
|
|||||||
You may look at `examples <https://py.delta.chat/examples.html>`_.
|
You may look at `examples <https://py.delta.chat/examples.html>`_.
|
||||||
|
|
||||||
|
|
||||||
Running tests
|
|
||||||
=============
|
|
||||||
|
|
||||||
Get a checkout of the `deltachat-core-rust github repository`_ and type::
|
|
||||||
|
|
||||||
pip install tox
|
|
||||||
./run-integration-tests.sh
|
|
||||||
|
|
||||||
If you want to run functional tests with real
|
|
||||||
e-mail test accounts, generate a "liveconfig" file where each
|
|
||||||
lines contains test account settings, for example::
|
|
||||||
|
|
||||||
# 'liveconfig' file specifying imap/smtp accounts
|
|
||||||
addr=some-email@example.org mail_pw=password
|
|
||||||
addr=other-email@example.org mail_pw=otherpassword
|
|
||||||
|
|
||||||
The "keyword=value" style allows to specify any
|
|
||||||
`deltachat account config setting <https://c.delta.chat/classdc__context__t.html#aff3b894f6cfca46cab5248fdffdf083d>`_ so you can also specify smtp or imap servers, ports, ssl modes etc.
|
|
||||||
Typically DC's automatic configuration allows to not specify these settings.
|
|
||||||
|
|
||||||
The ``run-integration-tests.sh`` script will automatically use
|
|
||||||
``python/liveconfig`` if it exists, to manually run tests with this
|
|
||||||
``liveconfig`` file use::
|
|
||||||
|
|
||||||
tox -- --liveconfig liveconfig
|
|
||||||
|
|
||||||
|
|
||||||
.. _`deltachat-core-rust github repository`: https://github.com/deltachat/deltachat-core-rust
|
.. _`deltachat-core-rust github repository`: https://github.com/deltachat/deltachat-core-rust
|
||||||
.. _`deltachat-core`: https://github.com/deltachat/deltachat-core-rust
|
.. _`deltachat-core`: https://github.com/deltachat/deltachat-core-rust
|
||||||
|
|
||||||
Running test using a debug build
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
If you need to examine e.g. a coredump you may want to run the tests
|
|
||||||
using a debug build::
|
|
||||||
|
|
||||||
DCC_RS_TARGET=debug ./run-integration-tests.sh -e py37 -- -x -v -k failing_test
|
|
||||||
|
|
||||||
|
|
||||||
Building manylinux1 wheels
|
Building manylinux1 wheels
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This section may not fully work.
|
||||||
|
|
||||||
Building portable manylinux1 wheels which come with libdeltachat.so
|
Building portable manylinux1 wheels which come with libdeltachat.so
|
||||||
and all it's dependencies is easy using the provided docker tooling.
|
and all it's dependencies is easy using the provided docker tooling.
|
||||||
|
|
||||||
using docker pull / premade images
|
using docker pull / premade images
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
We publish a build environment under the ``deltachat/wheel`` tag so
|
We publish a build environment under the ``deltachat/coredeps`` tag so
|
||||||
that you can pull it from the ``hub.docker.com`` site's "deltachat"
|
that you can pull it from the ``hub.docker.com`` site's "deltachat"
|
||||||
organization::
|
organization::
|
||||||
|
|
||||||
$ docker pull deltachat/wheel
|
$ docker pull deltachat/coredeps
|
||||||
|
|
||||||
The ``deltachat/wheel`` image can be used to build both libdeltachat.so
|
This docker image can be used to run tests and build Python wheels for all interpreters::
|
||||||
and the Python wheels::
|
|
||||||
|
|
||||||
$ docker run --rm -it -v $(pwd):/io/ deltachat/wheel /io/python/wheelbuilder/build-wheels.sh
|
$ bash ci_scripts/ci_run.sh
|
||||||
|
|
||||||
This command runs a script within the image, after mounting ``$(pwd)`` as ``/io`` within
|
This command runs tests and build-wheel scripts in a docker container.
|
||||||
the docker image. The script is specified as a path within the docker image's filesystem.
|
|
||||||
The resulting wheel files will be in ``python/wheelhouse``.
|
|
||||||
|
|
||||||
|
|
||||||
Optionally build your own docker image
|
Optionally build your own docker image
|
||||||
@@ -154,10 +148,10 @@ Optionally build your own docker image
|
|||||||
If you want to build your own custom docker image you can do this::
|
If you want to build your own custom docker image you can do this::
|
||||||
|
|
||||||
$ cd deltachat-core # cd to deltachat-core checkout directory
|
$ cd deltachat-core # cd to deltachat-core checkout directory
|
||||||
$ docker build -t deltachat/wheel python/wheelbuilder/
|
$ docker build -t deltachat/coredeps ci_scripts/docker_coredeps
|
||||||
|
|
||||||
This will use the ``python/wheelbuilder/Dockerfile`` to build
|
This will use the ``ci_scripts/docker_coredeps/Dockerfile`` to build
|
||||||
up docker image called ``deltachat/wheel``. You can afterwards
|
up docker image called ``deltachat/coredeps``. You can afterwards
|
||||||
find it with::
|
find it with::
|
||||||
|
|
||||||
$ docker images
|
$ docker images
|
||||||
|
|||||||
@@ -6,29 +6,18 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import os
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
os.environ["DCC_RS_TARGET"] = target = "release"
|
os.environ["DCC_RS_TARGET"] = target = "release"
|
||||||
|
if "DCC_RS_DEV" not in os.environ:
|
||||||
|
dn = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
os.environ["DCC_RS_DEV"] = dn
|
||||||
|
|
||||||
toml = os.path.join(os.getcwd(), "..", "Cargo.toml")
|
os.environ["RUSTFLAGS"] = "-g"
|
||||||
assert os.path.exists(toml)
|
|
||||||
with open(toml) as f:
|
|
||||||
s = orig = f.read()
|
|
||||||
s += "\n"
|
|
||||||
s += "[profile.release]\n"
|
|
||||||
s += "debug = true\n"
|
|
||||||
with open(toml, "w") as f:
|
|
||||||
f.write(s)
|
|
||||||
print("temporarily modifying Cargo.toml to provide release build with debug symbols ")
|
|
||||||
try:
|
|
||||||
subprocess.check_call([
|
subprocess.check_call([
|
||||||
"cargo", "build", "-p", "deltachat_ffi", "--" + target
|
"cargo", "build", "-p", "deltachat_ffi", "--" + target
|
||||||
])
|
])
|
||||||
finally:
|
|
||||||
with open(toml, "w") as f:
|
|
||||||
f.write(orig)
|
|
||||||
print("\nreseted Cargo.toml to previous original state")
|
|
||||||
|
|
||||||
subprocess.check_call("rm -rf build/ src/deltachat/*.so" , shell=True)
|
subprocess.check_call("rm -rf build/ src/deltachat/*.so" , shell=True)
|
||||||
|
|
||||||
subprocess.check_call([
|
subprocess.check_call([
|
||||||
|
|||||||
@@ -6,10 +6,15 @@ import platform
|
|||||||
import os
|
import os
|
||||||
import cffi
|
import cffi
|
||||||
import shutil
|
import shutil
|
||||||
|
from os.path import dirname as dn
|
||||||
|
from os.path import abspath
|
||||||
|
|
||||||
|
|
||||||
def ffibuilder():
|
def ffibuilder():
|
||||||
projdir = os.environ.get('DCC_RS_DEV')
|
projdir = os.environ.get('DCC_RS_DEV')
|
||||||
|
if not projdir:
|
||||||
|
p = dn(dn(dn(dn(abspath(__file__)))))
|
||||||
|
projdir = os.environ["DCC_RS_DEV"] = p
|
||||||
target = os.environ.get('DCC_RS_TARGET', 'release')
|
target = os.environ.get('DCC_RS_TARGET', 'release')
|
||||||
if projdir:
|
if projdir:
|
||||||
if platform.system() == 'Darwin':
|
if platform.system() == 'Darwin':
|
||||||
|
|||||||
@@ -50,8 +50,9 @@ class Account(object):
|
|||||||
self._configkeys = self.get_config("sys.config_keys").split()
|
self._configkeys = self.get_config("sys.config_keys").split()
|
||||||
self._imex_completed = threading.Event()
|
self._imex_completed = threading.Event()
|
||||||
|
|
||||||
def __del__(self):
|
# XXX this can cause "illegal instructions" at test ends so we omit it for now
|
||||||
self.shutdown()
|
# def __del__(self):
|
||||||
|
# self.shutdown()
|
||||||
|
|
||||||
def _check_config_key(self, name):
|
def _check_config_key(self, name):
|
||||||
if name not in self._configkeys:
|
if name not in self._configkeys:
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import os
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
|
import requests
|
||||||
import time
|
import time
|
||||||
from deltachat import Account
|
from deltachat import Account
|
||||||
from deltachat import props
|
|
||||||
from deltachat.capi import lib
|
from deltachat.capi import lib
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
@@ -36,6 +36,8 @@ def pytest_runtest_call(item):
|
|||||||
|
|
||||||
|
|
||||||
def pytest_report_header(config, startdir):
|
def pytest_report_header(config, startdir):
|
||||||
|
summary = []
|
||||||
|
|
||||||
t = tempfile.mktemp()
|
t = tempfile.mktemp()
|
||||||
try:
|
try:
|
||||||
ac = Account(t, eventlogging=False)
|
ac = Account(t, eventlogging=False)
|
||||||
@@ -43,13 +45,18 @@ def pytest_report_header(config, startdir):
|
|||||||
ac.shutdown()
|
ac.shutdown()
|
||||||
finally:
|
finally:
|
||||||
os.remove(t)
|
os.remove(t)
|
||||||
summary = ['Deltachat core={} sqlite={}'.format(
|
summary.extend(['Deltachat core={} sqlite={}'.format(
|
||||||
info['deltachat_core_version'],
|
info['deltachat_core_version'],
|
||||||
info['sqlite_version'],
|
info['sqlite_version'],
|
||||||
)]
|
)])
|
||||||
cfg = config.getoption('--liveconfig')
|
|
||||||
|
cfg = config.option.liveconfig
|
||||||
if cfg:
|
if cfg:
|
||||||
summary.append('Liveconfig: {}'.format(os.path.abspath(cfg)))
|
if "#" in cfg:
|
||||||
|
url, token = cfg.split("#", 1)
|
||||||
|
summary.append('Liveconfig provider: {}#<token ommitted>'.format(url))
|
||||||
|
else:
|
||||||
|
summary.append('Liveconfig file: {}'.format(cfg))
|
||||||
return summary
|
return summary
|
||||||
|
|
||||||
|
|
||||||
@@ -66,9 +73,56 @@ def data():
|
|||||||
return Data()
|
return Data()
|
||||||
|
|
||||||
|
|
||||||
|
class SessionLiveConfigFromFile:
|
||||||
|
def __init__(self, fn):
|
||||||
|
self.fn = fn
|
||||||
|
self.configlist = []
|
||||||
|
for line in open(fn):
|
||||||
|
if line.strip() and not line.strip().startswith('#'):
|
||||||
|
d = {}
|
||||||
|
for part in line.split():
|
||||||
|
name, value = part.split("=")
|
||||||
|
d[name] = value
|
||||||
|
self.configlist.append(d)
|
||||||
|
|
||||||
|
def get(self, index):
|
||||||
|
return self.configlist[index]
|
||||||
|
|
||||||
|
def exists(self):
|
||||||
|
return bool(self.configlist)
|
||||||
|
|
||||||
|
|
||||||
|
class SessionLiveConfigFromURL:
|
||||||
|
def __init__(self, url, create_token):
|
||||||
|
self.configlist = []
|
||||||
|
for i in range(2):
|
||||||
|
res = requests.post(url, json={"token_create_user": int(create_token)})
|
||||||
|
if res.status_code != 200:
|
||||||
|
pytest.skip("creating newtmpuser failed {!r}".format(res))
|
||||||
|
d = res.json()
|
||||||
|
config = dict(addr=d["email"], mail_pw=d["password"])
|
||||||
|
self.configlist.append(config)
|
||||||
|
|
||||||
|
def get(self, index):
|
||||||
|
return self.configlist[index]
|
||||||
|
|
||||||
|
def exists(self):
|
||||||
|
return bool(self.configlist)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def session_liveconfig(request):
|
||||||
|
liveconfig_opt = request.config.option.liveconfig
|
||||||
|
if liveconfig_opt:
|
||||||
|
if liveconfig_opt.startswith("http"):
|
||||||
|
url, create_token = liveconfig_opt.split("#", 1)
|
||||||
|
return SessionLiveConfigFromURL(url, create_token)
|
||||||
|
else:
|
||||||
|
return SessionLiveConfigFromFile(liveconfig_opt)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def acfactory(pytestconfig, tmpdir, request):
|
def acfactory(pytestconfig, tmpdir, request, session_liveconfig):
|
||||||
fn = pytestconfig.getoption("--liveconfig")
|
|
||||||
|
|
||||||
class AccountMaker:
|
class AccountMaker:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -82,18 +136,6 @@ def acfactory(pytestconfig, tmpdir, request):
|
|||||||
fin = self._finalizers.pop()
|
fin = self._finalizers.pop()
|
||||||
fin()
|
fin()
|
||||||
|
|
||||||
@props.cached
|
|
||||||
def configlist(self):
|
|
||||||
configlist = []
|
|
||||||
for line in open(fn):
|
|
||||||
if line.strip() and not line.strip().startswith('#'):
|
|
||||||
d = {}
|
|
||||||
for part in line.split():
|
|
||||||
name, value = part.split("=")
|
|
||||||
d[name] = value
|
|
||||||
configlist.append(d)
|
|
||||||
return configlist
|
|
||||||
|
|
||||||
def get_unconfigured_account(self):
|
def get_unconfigured_account(self):
|
||||||
self.offline_count += 1
|
self.offline_count += 1
|
||||||
tmpdb = tmpdir.join("offlinedb%d" % self.offline_count)
|
tmpdb = tmpdir.join("offlinedb%d" % self.offline_count)
|
||||||
@@ -116,10 +158,10 @@ def acfactory(pytestconfig, tmpdir, request):
|
|||||||
return ac
|
return ac
|
||||||
|
|
||||||
def get_online_configuring_account(self):
|
def get_online_configuring_account(self):
|
||||||
if not fn:
|
if not session_liveconfig:
|
||||||
pytest.skip("specify a --liveconfig file to run tests with real accounts")
|
pytest.skip("specify DCC_PY_LIVECONFIG or --liveconfig")
|
||||||
|
configdict = session_liveconfig.get(self.live_count)
|
||||||
self.live_count += 1
|
self.live_count += 1
|
||||||
configdict = self.configlist.pop(0)
|
|
||||||
if "e2ee_enabled" not in configdict:
|
if "e2ee_enabled" not in configdict:
|
||||||
configdict["e2ee_enabled"] = "1"
|
configdict["e2ee_enabled"] = "1"
|
||||||
tmpdb = tmpdir.join("livedb%d" % self.live_count)
|
tmpdb = tmpdir.join("livedb%d" % self.live_count)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ envlist =
|
|||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
commands =
|
commands =
|
||||||
pytest -v -rsXx {posargs:tests}
|
pytest -s -v -rsXx {posargs:tests}
|
||||||
python tests/package_wheels.py {toxworkdir}/wheelhouse
|
python tests/package_wheels.py {toxworkdir}/wheelhouse
|
||||||
passenv =
|
passenv =
|
||||||
TRAVIS
|
TRAVIS
|
||||||
@@ -19,6 +19,7 @@ deps =
|
|||||||
pytest
|
pytest
|
||||||
pytest-faulthandler
|
pytest-faulthandler
|
||||||
pdbpp
|
pdbpp
|
||||||
|
requests
|
||||||
|
|
||||||
[testenv:auditwheels]
|
[testenv:auditwheels]
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
@@ -51,6 +52,7 @@ commands =
|
|||||||
|
|
||||||
|
|
||||||
[pytest]
|
[pytest]
|
||||||
|
addopts = -v -rs
|
||||||
python_files = tests/test_*.py
|
python_files = tests/test_*.py
|
||||||
norecursedirs = .tox
|
norecursedirs = .tox
|
||||||
xfail_strict=true
|
xfail_strict=true
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ if [ $? != 0 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
pushd python
|
pushd python
|
||||||
if [ -e "./liveconfig" ]; then
|
if [ -e "./liveconfig" && -z "$DCC_PY_LIVECONFIG" ]; then
|
||||||
export DCC_PY_LIVECONFIG=liveconfig
|
export DCC_PY_LIVECONFIG=liveconfig
|
||||||
fi
|
fi
|
||||||
tox "$@"
|
tox "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user