Skip to content

Commit

Permalink
feature/pre commit updates (#102)
Browse files Browse the repository at this point in the history
* fix pre-commit config and typings
* tests: move registry infos to fixtures

Signed-off-by: Tiziano Müller <[email protected]>
  • Loading branch information
dev-zero authored Sep 27, 2023
1 parent 0bc0db2 commit 07272ea
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 102 deletions.
41 changes: 16 additions & 25 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,38 +1,29 @@
exclude: ".all-contributorsrc|.tributors"
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v4.4.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
- id: check-docstring-first
- id: end-of-file-fixer
- id: trailing-whitespace
- id: mixed-line-ending

- repo: local
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: black
name: black
language: python
types: [python]
entry: black

- id: isort
name: isort
args: [--filter-files]
language: python
types: [python]
entry: isort

- id: mypy
name: mypy
language: python
types: [python]
entry: mypy

- repo: https://github.com/psf/black
rev: 23.9.1
hooks:
- id: black
language_version: python3.11
- repo: https://github.com/pycqa/flake8
rev: 6.1.0
hooks:
- id: flake8
name: flake8
language: python
types: [python]
entry: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.1
hooks:
- id: mypy
additional_dependencies: ["types-requests"]
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and **Merged pull requests**. Critical items to know are:
The versions coincide with releases on pip. Only major versions will be released as tags on Github.

## [0.0.x](https://github.com/oras-project/oras-py/tree/main) (0.0.x)
- refactor tests using fixtures and rework pre-commit configuration (0.1.25)
- eliminate the additional subdirectory creation while pulling an image to a custom output directory (0.1.24)
- updating the exclude string in the pyproject.toml file to match the [data type black expects](https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-format)
- patch fix for pulling artifacts by digest (0.1.23)
Expand Down
2 changes: 1 addition & 1 deletion oras/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ def exit(self, msg: str, return_code: int = 1):
self.handler({"level": "error", "msg": msg})
sys.exit(return_code)

def progress(self, done: int = None, total: int = None):
def progress(self, done: int, total: int):
"""
Show piece of a progress bar
Expand Down
2 changes: 1 addition & 1 deletion oras/oci.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def NewLayer(


def ManifestConfig(
path: str = None, media_type: str = None
path: Optional[str] = None, media_type: Optional[str] = None
) -> Tuple[Dict[str, object], str]:
"""
Write an empty config, if one is not provided
Expand Down
8 changes: 4 additions & 4 deletions oras/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ def pull(self, *args, **kwargs) -> List[str]:

@decorator.ensure_container
def get_manifest(
self, container: container_type, allowed_media_type: list = None
self, container: container_type, allowed_media_type: Optional[list] = None
) -> dict:
"""
Retrieve a manifest for a package.
Expand All @@ -842,9 +842,9 @@ def do_request(
self,
url: str,
method: str = "GET",
data: Union[dict, bytes] = None,
headers: dict = None,
json: dict = None,
data: Optional[Union[dict, bytes]] = None,
headers: Optional[dict] = None,
json: Optional[dict] = None,
stream: bool = False,
):
"""
Expand Down
58 changes: 58 additions & 0 deletions oras/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import os
from dataclasses import dataclass

import pytest


@dataclass
class TestCredentials:
with_auth: bool
user: str
password: str


@pytest.fixture
def registry():
host = os.environ.get("ORAS_HOST")
port = os.environ.get("ORAS_PORT")

if not host or not port:
pytest.skip(
"You must export ORAS_HOST and ORAS_PORT"
" for a running registry before running tests."
)

return f"{host}:{port}"


@pytest.fixture
def credentials(request):
with_auth = os.environ.get("ORAS_AUTH") == "true"
user = os.environ.get("ORAS_USER", "myuser")
pwd = os.environ.get("ORAS_PASS", "mypass")

if with_auth and not user or not pwd:
pytest.skip("To test auth you need to export ORAS_USER and ORAS_PASS")

marks = [m.name for m in request.node.iter_markers()]
if request.node.parent:
marks += [m.name for m in request.node.parent.iter_markers()]

if request.node.get_closest_marker("with_auth"):
if request.node.get_closest_marker("with_auth").args[0] != with_auth:
if with_auth:
pytest.skip("test requires un-authenticated access to registry")
else:
pytest.skip("test requires authenticated access to registry")

return TestCredentials(with_auth, user, pwd)


@pytest.fixture
def target(registry):
return f"{registry}/dinosaur/artifact:v1"


@pytest.fixture
def target_dir(registry):
return f"{registry}/dinosaur/directory:v1"
47 changes: 13 additions & 34 deletions oras/tests/test_oras.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,40 @@

import os
import shutil
import sys

import pytest

import oras.client

here = os.path.abspath(os.path.dirname(__file__))

registry_host = os.environ.get("ORAS_HOST")
registry_port = os.environ.get("ORAS_PORT")
with_auth = os.environ.get("ORAS_AUTH") == "true"
oras_user = os.environ.get("ORAS_USER", "myuser")
oras_pass = os.environ.get("ORAS_PASS", "mypass")


def setup_module(module):
"""
Ensure the registry port and host is in the environment.
"""
if not registry_host or not registry_port:
sys.exit(
"You must export ORAS_HOST and ORAS_PORT for a running registry before running tests."
)
if with_auth and not oras_user or not oras_pass:
sys.exit("To test auth you need to export ORAS_USER and ORAS_PASS")


registry = f"{registry_host}:{registry_port}"
target = f"{registry}/dinosaur/artifact:v1"
target_dir = f"{registry}/dinosaur/directory:v1"


def test_basic_oras():
def test_basic_oras(registry):
"""
Basic tests for oras (without authentication)
"""
client = oras.client.OrasClient(hostname=registry, insecure=True)
assert "Python version" in client.version()


@pytest.mark.skipif(not with_auth, reason="basic auth is needed for login/logout")
def test_login_logout():
@pytest.mark.with_auth(True)
def test_login_logout(registry, credentials):
"""
Login and logout are all we can test with basic auth!
"""
client = oras.client.OrasClient(hostname=registry, insecure=True)
res = client.login(
hostname=registry, username=oras_user, password=oras_pass, insecure=True
hostname=registry,
username=credentials.user,
password=credentials.password,
insecure=True,
)
assert res["Status"] == "Login Succeeded"
client.logout(registry)


@pytest.mark.skipif(with_auth, reason="token auth is needed for push and pull")
def test_basic_push_pull(tmp_path):
@pytest.mark.with_auth(False)
def test_basic_push_pull(tmp_path, registry, credentials, target):
"""
Basic tests for oras (without authentication)
"""
Expand Down Expand Up @@ -88,8 +67,8 @@ def test_basic_push_pull(tmp_path):
assert res.status_code == 201


@pytest.mark.skipif(with_auth, reason="token auth is needed for push and pull")
def test_get_delete_tags(tmp_path):
@pytest.mark.with_auth(False)
def test_get_delete_tags(tmp_path, registry, credentials, target):
"""
Test creationg, getting, and deleting tags.
"""
Expand Down Expand Up @@ -139,8 +118,8 @@ def test_get_many_tags():
assert len(tags) == 10


@pytest.mark.skipif(with_auth, reason="token auth is needed for push and pull")
def test_directory_push_pull(tmp_path):
@pytest.mark.with_auth(False)
def test_directory_push_pull(tmp_path, registry, credentials, target_dir):
"""
Test push and pull for directory
"""
Expand Down
31 changes: 4 additions & 27 deletions oras/tests/test_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
__license__ = "Apache-2.0"

import os
import sys
from pathlib import Path

import pytest
Expand All @@ -15,35 +14,13 @@

here = os.path.abspath(os.path.dirname(__file__))

registry_host = os.environ.get("ORAS_HOST")
registry_port = os.environ.get("ORAS_PORT")
with_auth = os.environ.get("ORAS_AUTH") == "true"
oras_user = os.environ.get("ORAS_USER", "myuser")
oras_pass = os.environ.get("ORAS_PASS", "mypass")


def setup_module(module):
"""
Ensure the registry port and host is in the environment.
"""
if not registry_host or not registry_port:
sys.exit(
"You must export ORAS_HOST and ORAS_PORT for a running registry before running tests."
)
if with_auth and not oras_user or not oras_pass:
sys.exit("To test auth you need to export ORAS_USER and ORAS_PASS")


registry = f"{registry_host}:{registry_port}"
target = f"{registry}/dinosaur/artifact:v1"
target_dir = f"{registry}/dinosaur/directory:v1"


@pytest.mark.skipif(with_auth, reason="token auth is needed for push and pull")
def test_annotated_registry_push(tmp_path):
@pytest.mark.with_auth(False)
def test_annotated_registry_push(tmp_path, registry, credentials, target):
"""
Basic tests for oras push with annotations
"""

# Direct access to registry functions
remote = oras.provider.Registry(hostname=registry, insecure=True)
client = oras.client.OrasClient(hostname=registry, insecure=True)
Expand Down Expand Up @@ -84,7 +61,7 @@ def test_annotated_registry_push(tmp_path):
)


def test_parse_manifest():
def test_parse_manifest(registry):
"""
Test parse manifest function.
Expand Down
2 changes: 1 addition & 1 deletion oras/utils/fileio.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def get_tmpdir(
return tmpdir


def recursive_find(base: str, pattern: str = None) -> Generator:
def recursive_find(base: str, pattern: Optional[str] = None) -> Generator:
"""
Find filenames that match a particular pattern, and yield them.
Expand Down
11 changes: 2 additions & 9 deletions oras/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
__copyright__ = "Copyright The ORAS Authors."
__license__ = "Apache-2.0"

__version__ = "0.1.24"
__version__ = "0.1.25"
AUTHOR = "Vanessa Sochat"
EMAIL = "[email protected]"
NAME = "oras"
Expand All @@ -19,14 +19,7 @@
("requests", {"min_version": None}),
)

TESTS_REQUIRES = (
("pytest", {"min_version": "4.6.2"}),
("mypy", {"min_version": None}),
("pyflakes", {"min_version": None}),
("black", {"min_version": None}),
("types-requests", {"min_version": None}),
("isort", {"min_version": None}),
)
TESTS_REQUIRES = (("pytest", {"min_version": "4.6.2"}),)

DOCKER_REQUIRES = (("docker", {"exact_version": "5.0.1"}),)

Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ skip = []

[tool.mypy]
mypy_path = ["oras", "examples"]

[tool.pytest.ini_options]
markers = ["with_auth: mark for tests requiring authenticated registry access (or not)"]

0 comments on commit 07272ea

Please sign in to comment.