Skip to content

Commit ccd3537

Browse files
committed
make cross-core tests work on windows
1 parent 103a558 commit ccd3537

File tree

3 files changed

+57
-27
lines changed

3 files changed

+57
-27
lines changed

deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -222,28 +222,49 @@ def indent(self, msg: str) -> None:
222222
#
223223

224224

225+
def find_path(venv, name):
226+
is_windows = platform.system() == "Windows"
227+
bin = venv / ("bin" if not is_windows else "Scripts")
228+
229+
tryadd = [""]
230+
if is_windows:
231+
tryadd += os.environ["PATHEXT"].split(os.pathsep)
232+
for ext in tryadd:
233+
p = bin.joinpath(name + ext)
234+
if p.exists():
235+
return str(p)
236+
237+
return None
238+
239+
225240
@pytest.fixture(scope="session")
226241
def get_core_python_env(tmp_path_factory):
227-
if platform.system() == "Windows":
228-
pytest.skip("cross-core-version testing not available on Windows")
242+
"""Return a factory to create virtualenv environments with rpc server/client packages
243+
installed.
244+
245+
The factory takes a version and returns a (python_path, rpc_server_path) tuple
246+
of the respective binaries in the virtualenv.
247+
"""
229248

230249
envs = {}
231250

232-
def get_core_python(core_version):
251+
def get_versioned_venv(core_version):
233252
venv = envs.get(core_version)
234-
if venv:
235-
return venv
236-
venv = tmp_path_factory.mktemp(f"temp-{core_version}")
237-
python = sys.executable
238-
subprocess.check_call([python, "-m", "venv", venv])
239-
pip = venv.joinpath("bin", "pip")
240-
pkgs = [f"deltachat-rpc-server=={core_version}", f"deltachat-rpc-client=={core_version}"]
241-
subprocess.check_call([pip, "install", "pytest"] + pkgs)
253+
if not venv:
254+
venv = tmp_path_factory.mktemp(f"temp-{core_version}")
255+
subprocess.check_call([sys.executable, "-m", "venv", venv])
256+
257+
python = find_path(venv, "python")
258+
pkgs = [f"deltachat-rpc-server=={core_version}", f"deltachat-rpc-client=={core_version}", "pytest"]
259+
subprocess.check_call([python, "-m", "pip", "install"] + pkgs)
242260

243-
envs[core_version] = venv
244-
return venv
261+
envs[core_version] = venv
262+
python = find_path(venv, "python")
263+
rpc_server_path = find_path(venv, "deltachat-rpc-server")
264+
print(f"python={python}\nrpc_server={rpc_server_path}")
265+
return python, rpc_server_path
245266

246-
return get_core_python
267+
return get_versioned_venv
247268

248269

249270
@pytest.fixture
@@ -255,16 +276,15 @@ def alice_and_remote_bob(tmp_path, acfactory, get_core_python_env):
255276
"""
256277

257278
def factory(core_version):
258-
venv = get_core_python_env(core_version)
259-
python = venv.joinpath("bin", "python")
279+
python, rpc_server_path = get_core_python_env(core_version)
260280
gw = execnet.makegateway(f"popen//python={python}")
261281

262282
accounts_dir = str(tmp_path.joinpath("account1_venv1"))
263283
channel = gw.remote_exec(remote_bob_loop)
264284
cm = os.environ.get("CHATMAIL_DOMAIN")
265285

266286
# trigger getting an online account on bob's side
267-
channel.send((accounts_dir, str(venv.joinpath("bin", "deltachat-rpc-server")), cm))
287+
channel.send((accounts_dir, str(rpc_server_path), cm))
268288

269289
# meanwhile get a local alice account
270290
alice = acfactory.get_online_account()
@@ -286,18 +306,27 @@ def eval(eval_str):
286306

287307

288308
def remote_bob_loop(channel):
309+
# This function executes with versioned
310+
# deltachat-rpc-client/server packages
311+
# installed into the virtualenv.
312+
#
313+
# The "channel" argument is a send/receive pipe
314+
# to the process that runs the corresponding remote_exec(remote_bob_loop)
315+
289316
import os
290-
import pathlib
291317

292318
from deltachat_rpc_client import DeltaChat, Rpc
293319
from deltachat_rpc_client.pytestplugin import ACFactory
294320

295321
accounts_dir, rpc_server_path, chatmail_domain = channel.receive()
296322
os.environ["CHATMAIL_DOMAIN"] = chatmail_domain
297-
bin_path = str(pathlib.Path(rpc_server_path).parent)
298-
os.environ["PATH"] = bin_path + ":" + os.environ["PATH"]
299323

324+
# older core versions don't support specifying rpc_server_path
325+
# so we can't just pass `rpc_server_path` argument to Rpc constructor
326+
basepath = os.path.dirname(rpc_server_path)
327+
os.environ["PATH"] = os.pathsep.join([basepath, os.environ["PATH"]])
300328
rpc = Rpc(accounts_dir=accounts_dir)
329+
301330
with rpc:
302331
dc = DeltaChat(rpc)
303332
channel.send(dc.rpc.get_system_info()["deltachat_core_version"])

deltachat-rpc-client/src/deltachat_rpc_client/rpc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class Rpc:
5757
def __init__(self, accounts_dir: Optional[str] = None, rpc_server_path="deltachat-rpc-server", **kwargs):
5858
"""Initialize RPC client.
5959
60-
The given arguments will be passed to subprocess.Popen().
60+
The 'kwargs' arguments will be passed to subprocess.Popen().
6161
"""
6262
if accounts_dir:
6363
kwargs["env"] = {

deltachat-rpc-client/tests/test_cross_core.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@
66

77

88
def test_install_venv_and_use_other_core(tmp_path, get_core_python_env):
9-
venv = get_core_python_env("2.20.0")
10-
python = venv / "bin" / "python"
11-
subprocess.check_call([python, "-m", "pip", "install", "deltachat-rpc-server==2.20.0"])
12-
rpc = Rpc(accounts_dir=tmp_path.joinpath("accounts"), rpc_server_path=venv.joinpath("bin", "deltachat-rpc-server"))
9+
python, rpc_server_path = get_core_python_env("2.24.0")
10+
subprocess.check_call([python, "-m", "pip", "install", "deltachat-rpc-server==2.24.0"])
11+
rpc = Rpc(accounts_dir=tmp_path.joinpath("accounts"), rpc_server_path=rpc_server_path)
1312

1413
with rpc:
1514
dc = DeltaChat(rpc)
16-
assert dc.rpc.get_system_info()["deltachat_core_version"] == "v2.20.0"
15+
assert dc.rpc.get_system_info()["deltachat_core_version"] == "v2.24.0"
1716

1817

19-
@pytest.mark.parametrize("version", ["2.20.0", "2.10.0"])
18+
@pytest.mark.parametrize("version", ["2.24.0"])
2019
def test_qr_setup_contact(alice_and_remote_bob, version) -> None:
20+
"""Test other-core Bob profile can do securejoin with Alice on current core."""
2121
alice, alice_contact_bob, remote_eval = alice_and_remote_bob(version)
2222

2323
qr_code = alice.get_qr_code()
@@ -35,6 +35,7 @@ def test_qr_setup_contact(alice_and_remote_bob, version) -> None:
3535

3636

3737
def test_send_and_receive_message(alice_and_remote_bob) -> None:
38+
"""Test other-core Bob profile can send a message to Alice on current core."""
3839
alice, alice_contact_bob, remote_eval = alice_and_remote_bob("2.20.0")
3940

4041
remote_eval("bob_contact_alice.create_chat().send_text('hello')")

0 commit comments

Comments
 (0)