-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use multiprocessing to run CLI. This is to ensure we can use monkeypatch and are going through the Python API and not invoking the CLI through a separate Python process. Extend CI to take `server` extra into account. Fix and clean CLI according to tests. Remove cli/options.py. It only contained a single variable definition. This has been moved to cli/run.py. Avoid importing optimade-client package in CLI. Define package version manually in CLI. Add new manual package version number to `update-version` invoke task. Add optimade_client/cli/run.py to Publish on PyPI workflow. Create Jupyter config dir if it doesn't exist.
- Loading branch information
Showing
9 changed files
with
191 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
from multiprocessing import Process | ||
import os | ||
import signal | ||
from time import sleep | ||
from typing import List | ||
|
||
import pytest | ||
|
||
|
||
@pytest.fixture | ||
def run_cli(capfd): | ||
"""Run a command in the `optimade-client` CLI (through the Python API).""" | ||
|
||
def _run_cli(options: List[str] = None, raises: bool = False) -> str: | ||
"""Run a command in the `optimade-client` CLI (through the Python API).""" | ||
from optimade_client.cli import run | ||
|
||
if options is None: | ||
options = [] | ||
|
||
try: | ||
cli = Process(target=run.main, args=(options,)) | ||
cli.start() | ||
sleep(5) # Startup time | ||
output = capfd.readouterr() | ||
finally: | ||
os.kill(cli.pid, signal.SIGINT) | ||
timeout = 10 # seconds | ||
while cli.is_alive() and timeout: | ||
sleep(1) | ||
timeout -= 1 | ||
if cli.is_alive(): | ||
cli.kill() | ||
cli.join() | ||
sleep(1) | ||
|
||
assert not cli.is_alive(), f"Could not stop CLI subprocess <PID={cli.pid}>" | ||
|
||
if raises: | ||
assert ( | ||
cli.exitcode != 0 | ||
), f"\nstdout:\n{output.out}\n\nstderr:\n{output.err}" | ||
else: | ||
assert ( | ||
cli.exitcode == 0 | ||
), f"\nstdout:\n{output.out}\n\nstderr:\n{output.err}" | ||
|
||
return output.out + output.err | ||
|
||
return _run_cli |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import pytest | ||
|
||
try: | ||
import voila as _ # noqa: F401 | ||
except ImportError: | ||
VOILA_INSTALLED = False | ||
else: | ||
VOILA_INSTALLED = True | ||
|
||
pytestmark = pytest.mark.skipif( | ||
VOILA_INSTALLED, | ||
reason="Voilà is installed. Tests in this module are rendered invalid.", | ||
) | ||
|
||
|
||
def test_voila_not_installed(run_cli): | ||
"""Ensure the CLI can handle Voilà not being installed.""" | ||
output = run_cli(raises=True) | ||
exit_text = ( | ||
"Voilà is not installed.\nPlease run:\n\n pip install optimade-client[server]\n\n" | ||
"Or the equivalent, matching the installation in your environment, to install Voilà " | ||
"(and ASE for a larger download format selection)." | ||
) | ||
assert exit_text in output | ||
assert "[Voila]" not in output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,84 @@ | ||
import pytest | ||
|
||
try: | ||
import voila as _ | ||
except ImportError: | ||
VOILA_PACKAGE_EXISTS = False | ||
else: | ||
VOILA_PACKAGE_EXISTS = True | ||
|
||
|
||
@pytest.mark.skipif( | ||
not VOILA_PACKAGE_EXISTS, | ||
reason="Voilà is not installed. This test is rendered invalid.", | ||
) | ||
|
||
_ = pytest.importorskip("voila") | ||
|
||
|
||
def test_default(run_cli): | ||
"""Run `optimade-client` with default settings""" | ||
output = run_cli() | ||
assert "[Voila] Voilà is running at:" in output, f"output:\n{output}" | ||
|
||
|
||
@pytest.mark.skipif( | ||
VOILA_PACKAGE_EXISTS, reason="Voilà is installed. This test is rendered invalid." | ||
) | ||
def test_voila_not_installed(run_cli): | ||
"""Ensure the CLI can handle Voilà not being installed.""" | ||
output = run_cli(raises=True) | ||
exit_text = ( | ||
"Voilà is not installed.\nPlease run:\n\n pip install optimade-client[server]\n\n" | ||
"Or the equivalent, matching the installation in your environment, to install Voilà " | ||
"(and ASE for a larger download format selection)." | ||
) | ||
assert exit_text in output | ||
assert "[Voila]" not in output | ||
def test_version(run_cli): | ||
"""Check `--version` flag""" | ||
from optimade_client import __version__ | ||
|
||
output = run_cli(["--version"]) | ||
assert output == f"OPTIMADE Client version {__version__}\n" | ||
|
||
|
||
def test_log_level(run_cli): | ||
"""Check `--log-level` option | ||
Levels: | ||
- `warning`: Above normal setting (INFO). There shouldn't be any output. | ||
- `info`: Normal setting. There should be minimal output. | ||
- `debug`: Below normal setting (INFO). There should be maximum output. | ||
""" | ||
signed_text = "Notebook already signed: OPTIMADE Client.ipynb\n" | ||
|
||
log_level = "warning" | ||
|
||
output = run_cli(["--log-level", log_level]) | ||
assert output == signed_text | ||
|
||
log_level = "info" | ||
|
||
output = run_cli(["--log-level", log_level]) | ||
assert output != signed_text | ||
assert signed_text in output | ||
assert "[Voila]" in output | ||
assert "[Voila] template paths:" not in output | ||
|
||
log_level = "debug" | ||
output = run_cli(["--log-level", log_level]) | ||
assert output != signed_text | ||
assert signed_text in output | ||
assert "[Voila] template paths:" in output | ||
|
||
|
||
def test_debug(run_cli): | ||
"""Check `--debug` flag | ||
This forcefully sets the log-level to `debug`. | ||
""" | ||
output = run_cli(["--debug"]) | ||
assert "[Voila] template paths:" in output | ||
|
||
log_level = "info" | ||
output = run_cli(["--log-level", log_level, "--debug"]) | ||
assert "[OPTIMADE-Client] Overwriting requested log-level to: 'debug'" not in output | ||
assert "[Voila] template paths:" in output | ||
|
||
log_level = "warning" | ||
output = run_cli(["--log-level", log_level, "--debug"]) | ||
assert "[OPTIMADE-Client] Overwriting requested log-level to: 'debug'" in output | ||
assert "[Voila] template paths:" in output | ||
|
||
log_level = "debug" | ||
output = run_cli(["--log-level", log_level, "--debug"]) | ||
assert "[OPTIMADE-Client] Overwriting requested log-level to: 'debug'" not in output | ||
assert "[Voila] template paths:" in output | ||
|
||
|
||
def test_open_browser(run_cli, monkeypatch): | ||
"""Check `--open-browser` flag""" | ||
check_text = "Testing: webbrowser.get has been overwritten" | ||
monkeypatch.setattr("webbrowser.get", lambda *args, **kwargs: print(check_text)) | ||
|
||
output = run_cli(["--open-browser"]) | ||
assert check_text in output, f"output:\n{output}" | ||
|
||
output = run_cli() | ||
assert check_text not in output, f"output:\n{output}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters