Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
goanpeca committed Nov 30, 2022
1 parent 550e7d7 commit d4e630a
Show file tree
Hide file tree
Showing 17 changed files with 394 additions and 248 deletions.
37 changes: 26 additions & 11 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ jobs:
test:
name: ${{ matrix.platform }} py${{ matrix.python-version }}
runs-on: ${{ matrix.platform }}
defaults:
run:
shell: bash -el {0}
strategy:
matrix:
platform: [ubuntu-latest, windows-latest, macos-latest]
Expand All @@ -25,21 +28,33 @@ jobs:
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: conda-incubator/setup-miniconda@v2
with:
python-version: ${{ matrix.python-version }}
activate-environment: ""
auto-activate-base: true

- name: Install dependencies cli
- name: Install dependencies on 'base'
run: |
conda install conda-lock mamba packaging requests pyyaml -c conda-forge -y
conda install pytest pytest-cov -c conda-forge -y
cd constructor-manager-cli
python -m pip install --upgrade pip
python -m pip install setuptools tox tox-gh-actions
pip list
pip install -e . --no-deps
# this runs the platform-specific tests declared in tox.ini
- name: Test with tox
- name: Run tests on 'base'
run: |
cd constructor-manager-cli
python -m tox
env:
PLATFORM: ${{ matrix.platform }}
cd src/constructor_manager_cli
pytest constructor_manager_cli --cov=constructor_manager_cli --cov-report term-missing
- name: Install dependencies on 'napari-0.4.15'
run: |
conda create -n napari-0.4.15 napari=0.4.5=*pyside* -c conda-forge -y
conda install -n napari-0.4.15 pytest pytest-cov -c conda-forge -y
conda activate napari-0.4.15
cd constructor-manager
pip install -e . --no-deps
- name: Run tests on 'napari-0.4.15'
run: |
conda activate napari-0.4.15
cd src/constructor_manager
pytest constructor_manager --cov=constructor_manager --cov-report term-missing
7 changes: 7 additions & 0 deletions constructor-manager-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,3 +405,10 @@ This command will install a specified on a fresh environment, deleting the old e
```bash
constructor-manager restore "napari=0.4.16=*pyside*" -c conda-forge
```

### Run tests

```bash
cd constructor-manager-cli/src
pytest constructor_manager_cli --cov=constructor_manager_cli --cov-report term-missing
```
99 changes: 50 additions & 49 deletions constructor-manager-cli/src/constructor_manager_cli/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,10 @@ def _get_args(self, arg0, pkg_list: Sequence[str], prefix: Optional[str]):
for channel in self._channels:
cmd.extend(["-c", channel])

return tuple(cmd + list(pkg_list))
if pkg_list:
cmd.extend(pkg_list)

return tuple(cmd)

# -------------------------- Public API ----------------------------------
def info(self) -> Dict[Any, Any]:
Expand All @@ -253,9 +256,53 @@ def info(self) -> Dict[Any, Any]:
res = cast(dict, self._queue_args(args, block=True))
return res

def create(
self, pkg_list: Sequence[str], *, prefix: Optional[str] = None
def list(self, prefix: str, block=True) -> job_id:
"""List packages for `prefix`.
Parameters
----------
prefix : str
Prefix from which to list packages.
Returns
-------
job_id : int
ID that can be used to cancel the process.
"""
return self._queue_args(
("list", "--prefix", str(prefix), "--json"), block=block
)

def lock(
self,
env_path: str,
platforms: Optional[Tuple[str, ...]] = None,
lockfile: Optional[str] = None,
block: bool = False,
) -> job_id:
"""List packages for `prefix`.
Parameters
----------
prefix : str
Prefix from which to list packages.
Returns
-------
job_id : int
ID that can be used to cancel the process.
"""
args = ["-f", env_path]
if platforms:
for platform in platforms:
args.extend(["-p", platform])

if lockfile:
args.extend(["--lockfile", lockfile])

return self._queue_args(args, bin="conda-lock", block=block)

def create(self, prefix: str, *, pkg_list: Sequence[str] = ()) -> job_id:
"""Create a new conda environment with `pkg_list` in `prefix`.
Parameters
Expand Down Expand Up @@ -324,49 +371,3 @@ def uninstall(
ID that can be used to cancel the process.
"""
return self._queue_args(self._get_uninstall_args(pkg_list, prefix))

def list(self, prefix: str, block=True) -> job_id:
"""List packages for `prefix`.
Parameters
----------
prefix : str
Prefix from which to list packages.
Returns
-------
job_id : int
ID that can be used to cancel the process.
"""
return self._queue_args(
("list", "--prefix", str(prefix), "--json"), block=block
)

def lock(
self,
env_path: str,
platforms: Optional[Tuple[str, ...]] = None,
lockfile: Optional[str] = None,
block: bool = False,
) -> job_id:
"""List packages for `prefix`.
Parameters
----------
prefix : str
Prefix from which to list packages.
Returns
-------
job_id : int
ID that can be used to cancel the process.
"""
args = ["-f", env_path]
if platforms:
for platform in platforms:
args.extend(["-p", platform])

if lockfile:
args.extend(["--lockfile", lockfile])

return self._queue_args(args, bin="conda-lock", block=block)
2 changes: 0 additions & 2 deletions constructor-manager-cli/src/constructor_manager_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,6 @@ def _handle_excecute(args, lock, lock_created=None):
lock_created: bool, optional
Whether the lock was created or not, by default ``None``.
"""
_execute(args, lock, lock_created)
return
try:
_execute(args, lock, lock_created)
except Exception as e:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import shutil
import random
from constructor_manager_cli.installer import CondaInstaller
from constructor_manager_cli.utils.conda import get_base_prefix, get_prefix_by_name


def test_conda_installer_info():
data = CondaInstaller().info()
assert data["conda_prefix"] == str(get_base_prefix())


def test_conda_installer_list():
pkgs = CondaInstaller().list(get_base_prefix())
pkg_names = [pkg["name"] for pkg in pkgs]
assert pkgs
assert "conda" in pkg_names
assert "mamba" in pkg_names


def test_conda_installer_create_remove():
prefix = get_prefix_by_name(
f"test-constructor-manager-{random.randint(1000, 9999)}"
)
if prefix.exists() and prefix.is_dir():
shutil.rmtree(prefix)
shutil.rmtree(prefix, ignore_errors=True)

installer = CondaInstaller()
# Create
job_id = installer.create(prefix=prefix)
assert prefix.exists()
assert installer._exit_codes[job_id] == 0

# Remove
job_id = installer.remove(prefix=prefix)
assert not prefix.exists()
assert installer._exit_codes[job_id] == 0


def test_conda_installer_install_uninstall():
prefix = get_base_prefix()
pkg = "loghub"
installer = CondaInstaller()

# Install
job_id = installer.install([pkg], prefix=prefix)

pkgs = installer.list(prefix=prefix)
pkg_names = [pkg["name"] for pkg in pkgs]
assert pkg in pkg_names
assert installer._exit_codes[job_id] == 0

# Uninstall
job_id = installer.uninstall([pkg], prefix=prefix)
pkgs = installer.list(prefix=prefix)
pkg_names = [pkg["name"] for pkg in pkgs]
assert pkg not in pkg_names
assert installer._exit_codes[job_id] == 0
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

import re
from functools import lru_cache
from typing import List
from typing import List, Optional

from constructor_manager_cli.defaults import DEFAULT_CHANNEL
from constructor_manager_cli.utils.packages import normalized_name
from constructor_manager_cli.utils.request import get_request
from constructor_manager_cli.utils.versions import sort_versions

Expand Down Expand Up @@ -37,7 +36,7 @@ def conda_package_data(
@lru_cache
def conda_package_versions(
package_name: str,
build: str,
build: Optional[str] = None,
channels: List[str] = [DEFAULT_CHANNEL],
reverse: bool = False,
) -> List[str]:
Expand Down Expand Up @@ -85,27 +84,3 @@ def conda_package_versions(
)

return sort_versions(set(versions), reverse=reverse)


@lru_cache
def plugin_versions(
url: str,
) -> List[str]:
"""Return information on package plugins from endpoint in json.
Parameters
----------
url : str
Url to json endpoint.
Returns
-------
list of str
Package versions.
"""
response = get_request(url)
plugins = []
for key in response.json():
plugins.append(normalized_name(key))

return list(sorted(plugins))
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

import sys
from pathlib import Path
from typing import List, Optional, Tuple, Union
from typing import Optional, Tuple

from conda.models.match_spec import MatchSpec # type: ignore
from constructor_manager_cli.installer import CondaInstaller
from constructor_manager_cli.utils.packages import sentinel_file_name


def parse_conda_version_spec(package: str) -> Tuple[str, str, str]:
Expand Down Expand Up @@ -41,35 +39,6 @@ def parse_conda_version_spec(package: str) -> Tuple[str, str, str]:
return package_name, version, build_string


def check_if_constructor_app(package_name, path=None) -> bool:
"""FIXME:"""
if path is None:
path = Path(sys.prefix)

return (path.parent.parent / sentinel_file_name(package_name)).exists()


def check_if_conda_environment(
path: Union[Optional[Path], Optional[str]] = None
) -> bool:
"""Check if path is a conda environment.
Parameters
----------
path : str, optional
If `None` then check if current process is running in a conda
environment.
Returns
-------
bool
"""
if path is None:
path = Path(sys.prefix)

return (Path(path) / "conda-meta" / "history").exists()


def get_base_prefix() -> Path:
"""Get base conda prefix.
Expand Down Expand Up @@ -110,39 +79,3 @@ def get_prefix_by_name(name: Optional[str] = None) -> Path:
return base_prefix
else:
return base_prefix / "envs" / name


def list_packages2(prefix: str, plugins: Optional[List] = None):
"""List packages in a conda environment.
Optionally filter by plugin list.
Parameters
----------
prefix : str
The conda environment prefix.
plugins : list, optional
List of plugins to filter by.
Returns
-------
list
List of packages in the environment.
"""
packages = []
for path in (Path(prefix) / "conda-meta").iterdir():
if path.is_file() and path.name.endswith(".json"):
parts = path.name.rsplit("-")
b, v, name = parts[-1], parts[-2], "-".join(parts[:-2])
b = b.replace(".json", "")
packages.append((name, v, b))

if plugins is not None:
packages = [pkg for pkg in packages if pkg[0] in plugins]

return packages


def list_packages():
installer = CondaInstaller()
print("hello", installer.list(sys.prefix))
Loading

0 comments on commit d4e630a

Please sign in to comment.