Skip to content

Commit

Permalink
Merge pull request #505 from valory-xyz/fix/misc
Browse files Browse the repository at this point in the history
[v1.27.0] chore: miscellaneous fixes
  • Loading branch information
DavidMinarsch authored Dec 28, 2022
2 parents 860c6e0 + 4b53ad6 commit 00c0671
Show file tree
Hide file tree
Showing 49 changed files with 401 additions and 195 deletions.
21 changes: 21 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Release History - open AEA

## 1.27.0 (2022-12-27)

AEA:
- Adds auto-generated protobuf `*_pb2.py` and `*_pb2_*.py` files to `coveragerc` ignore template for aea test command.
- Fixes comparison operators ` __eq__`, `__ne__`, `__lt__`, `__le__`, `__gt__`, `__ge__` for multiple classes including `PackageVersion`.
- Adds support to `test packages` command for the `--all` flag and switches default behaviour to only run tests on `dev` packages.
- Fixes miscellaneous issues on base test classes and adds consistency checks via meta classes.

Plugins:
- Updates `open-aea-cli-ipfs` to retry in case an IPFS download fails

Tests:
- Fills coverage gaps on core `aea`
- Fills coverage gaps on multiple packages
- Fills coverage gaps on all plugins

Chores:
- Merges the coverage checks with unit tests and removes the extra test coverage CI run.
- Cleans up release flow.
- Adds workflow for image building.

## 1.26.0 (2022-12-15)

AEA:
Expand Down
6 changes: 0 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,6 @@ test-sub-p:
pytest -rfE --doctest-modules aea packages/valory/connections packages/valory/protocols packages/fetchai/connections packages/fetchai/protocols packages/fetchai/skills tests/test_packages/test_$(tdir) --cov=packages.fetchai.$(dir) --cov-report=html --cov-report=xml --cov-report=term-missing --cov-report=term --cov-config=.coveragerc
find . -name ".coverage*" -not -name ".coveragerc" -exec rm -fr "{}" \;

.PHONY: hashes
hashes:
python -m aea.cli packages lock
python -m aea.cli --registry-path=./tests/data/packages packages lock

.PHONY: test-all
test-all:
tox
Expand Down Expand Up @@ -167,7 +162,6 @@ security:
generators:
rm -rf packages/fetchai/connections/stub/input_file
tox -e fix-copyright
tox -e hash-all
tox -e lock-packages
tox -e generate-all-protocols
tox -e generate-api-documentation
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ The following table shows which versions of `open-aea` are currently being suppo

| Version | Supported |
| --------- | ------------------ |
| `1.26.x` | :white_check_mark: |
| `< 1.26.0` | :x: |
| `1.27.x` | :white_check_mark: |
| `< 1.27.0` | :x: |

## Reporting a Vulnerability

Expand Down
2 changes: 1 addition & 1 deletion aea/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
__title__ = "open-aea"
__description__ = "Open Autonomous Economic Agent framework (without vendor lock-in)"
__url__ = "https://github.com/valory-xyz/open-aea.git"
__version__ = "1.26.0"
__version__ = "1.27.0"
__author__ = "Valory AG"
__license__ = "Apache-2.0"
__copyright__ = "2021 Valory AG, 2019 Fetch.AI Limited"
14 changes: 10 additions & 4 deletions aea/test_tools/click_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import subprocess # nosec
import sys
import tempfile
from abc import ABC
from contextlib import nullcontext, redirect_stderr
from pathlib import Path
from typing import Any, ContextManager, Optional, Sequence, cast
Expand Down Expand Up @@ -147,12 +148,12 @@ def invoke( # type: ignore
)


class CliTest:
class CliTest(ABC):
"""Test cli commands."""

t: Path
cli_options: Sequence[str] = ()

_t: Path
__cwd: Path
__cli: click.core.Group = aea_cli
__cli_runner: CliRunner
Expand All @@ -163,6 +164,11 @@ def set_capfd_on_cli_runner(self, capfd: CaptureFixture) -> None:

self.__cli_runner.capfd = capfd

@property
def t(self) -> Path:
"""Get t."""
return self._t

@classmethod
def setup_class(cls, mix_stderr: bool = True) -> None:
"""Setup test class."""
Expand All @@ -179,12 +185,12 @@ def teardown_class(cls) -> None:
def setup(self) -> None:
"""Setup test."""

self.t = Path(tempfile.mkdtemp()).resolve()
self._t = Path(tempfile.mkdtemp()).resolve()

def teardown(self) -> None:
"""Teardown test."""

remove_test_directory(self.t)
remove_test_directory(self._t)

def run_cli(
self,
Expand Down
84 changes: 62 additions & 22 deletions aea/test_tools/test_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
"""This module contains test case classes based on pytest for AEA contract testing."""

import time
from abc import ABC, abstractmethod
from abc import ABC, ABCMeta, abstractmethod
from pathlib import Path
from typing import Any, Dict, List, Optional, cast
from typing import Any, Dict, List, Optional, Tuple, Type, cast

from aea.common import JSONLike
from aea.configurations.loader import (
Expand All @@ -39,11 +39,52 @@
)


class BaseContractTestCase(ABC):
class _MetaBaseContractTestCase(ABCMeta):
"""A metaclass that validates BaseContractTestCase's class."""

def __new__( # type: ignore # pylint: disable=bad-mcs-classmethod-argument # type: ignore
mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any
) -> Type:
"""Initialize the class."""
new_cls = super().__new__(mcs, name, bases, namespace, **kwargs)

if ABC in bases:
# abstract class, return
return new_cls
if not issubclass(new_cls, BaseContractTestCase):
# the check only applies to BaseContractTestCase subclasses
return new_cls

mcs._check_consistency(cast(Type[BaseContractTestCase], new_cls))
return new_cls

@classmethod
def _check_consistency( # pylint: disable=bad-mcs-classmethod-argument
mcs, base_contract_test_case_cls: Type["BaseContractTestCase"]
) -> None:
"""Check consistency of class."""
mcs._check_required_class_attributes(base_contract_test_case_cls)

@classmethod
def _check_required_class_attributes( # pylint: disable=bad-mcs-classmethod-argument
mcs, base_contract_test_case_cls: Type["BaseContractTestCase"]
) -> None:
"""Check that required class attributes are set."""
if not hasattr(base_contract_test_case_cls, "path_to_contract"):
raise ValueError(
f"'path_to_contract' not set on {base_contract_test_case_cls}"
)
if not hasattr(base_contract_test_case_cls, "ledger_identifier"):
raise ValueError(
f"'ledger_identifier' not set on {base_contract_test_case_cls}"
)


class BaseContractTestCase(ABC, metaclass=_MetaBaseContractTestCase):
"""A class to test a contract."""

path_to_contract: Path = Path(".")
ledger_identifier: str = ""
path_to_contract: Path
ledger_identifier: str
fund_from_faucet: bool = False
_deployment_gas: int = 5000000
_contract: Contract
Expand All @@ -65,20 +106,32 @@ def contract(self) -> Contract:
raise ValueError("Ensure the contract is set during setup.")
return value

@classmethod
def setup_class(cls) -> None:
"""Set up the contract test case class."""
# register contract
configuration = cast(
ContractConfig,
load_component_configuration(ComponentType.CONTRACT, cls.path_to_contract),
)
configuration._directory = ( # pylint: disable=protected-access
cls.path_to_contract
)
if str(configuration.public_id) not in contract_registry.specs:
# load contract into sys modules
Contract.from_config(configuration) # pragma: nocover
cls._contract = contract_registry.make(str(configuration.public_id))

@classmethod
def setup(cls, **kwargs: Any) -> None:
"""Set up the contract test case."""
if cls.ledger_identifier == "":
raise ValueError("ledger_identifier not set!") # pragma: nocover

_ledger_config: Dict[str, str] = kwargs.pop("ledger_config", {})
_deployer_private_key_path: Optional[str] = kwargs.pop(
"deployer_private_key_path", None
)
_item_owner_private_key_path: Optional[str] = kwargs.pop(
"item_owner_private_key_path", None
)

cls.ledger_api = ledger_apis_registry.make(
cls.ledger_identifier, **_ledger_config
)
Expand All @@ -102,19 +155,6 @@ def setup(cls, **kwargs: Any) -> None:
cls.ledger_api, cls.faucet_api, cls.item_owner_crypto.address
)

# register contract
configuration = cast(
ContractConfig,
load_component_configuration(ComponentType.CONTRACT, cls.path_to_contract),
)
configuration._directory = ( # pylint: disable=protected-access
cls.path_to_contract
)
if str(configuration.public_id) not in contract_registry.specs:
# load contract into sys modules
Contract.from_config(configuration) # pragma: nocover
cls._contract = contract_registry.make(str(configuration.public_id))

# deploy contract
cls.deployment_tx_receipt = cls._deploy_contract(
cls._contract, cls.ledger_api, cls.deployer_crypto, gas=cls._deployment_gas
Expand Down
40 changes: 38 additions & 2 deletions aea/test_tools/test_skill.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"""This module contains test case classes based on pytest for AEA skill testing."""
import asyncio
import os
from abc import ABC, ABCMeta
from pathlib import Path
from queue import Queue
from types import SimpleNamespace
Expand All @@ -43,10 +44,45 @@
COUNTERPARTY_SKILL_ADDRESS = "some_author/some_skill:0.1.0"


class BaseSkillTestCase:
class _MetaBaseSkillTestCase(ABCMeta):
"""A metaclass that validates BaseSkillTestCase's class."""

def __new__( # type: ignore # pylint: disable=bad-mcs-classmethod-argument
mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any
) -> Type:
"""Initialize the class."""
new_cls = super().__new__(mcs, name, bases, namespace, **kwargs)

if ABC in bases:
# abstract class, return
return new_cls
if not issubclass(new_cls, BaseSkillTestCase):
# the check only applies to BaseSkillTestCase subclasses
return new_cls

mcs._check_consistency(cast(Type[BaseSkillTestCase], new_cls))
return new_cls

@classmethod
def _check_consistency( # pylint: disable=bad-mcs-classmethod-argument
mcs, base_skill_test_case_cls: Type["BaseSkillTestCase"]
) -> None:
"""Check consistency of class."""
mcs._check_required_class_attributes(base_skill_test_case_cls)

@classmethod
def _check_required_class_attributes( # pylint: disable=bad-mcs-classmethod-argument
mcs, base_skill_test_case_cls: Type["BaseSkillTestCase"]
) -> None:
"""Check that required class attributes are set."""
if not hasattr(base_skill_test_case_cls, "path_to_skill"):
raise ValueError(f"'path_to_skill' not set on {base_skill_test_case_cls}")


class BaseSkillTestCase(ABC, metaclass=_MetaBaseSkillTestCase):
"""A class to test a skill."""

path_to_skill: Path = Path(".")
path_to_skill: Path
is_agent_to_agent_messages: bool = True
_skill: Skill
_multiplexer: AsyncMultiplexer
Expand Down
2 changes: 1 addition & 1 deletion deploy-image/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ RUN apk add --no-cache go

# aea installation
RUN pip install --upgrade pip
RUN pip install --upgrade --force-reinstall open-aea[all]==1.26.0 "open-aea-cli-ipfs<2.0.0,>=1.26.0"
RUN pip install --upgrade --force-reinstall open-aea[all]==1.27.0 "open-aea-cli-ipfs<2.0.0,>=1.27.0"

# directories and aea cli config
WORKDIR /home/agents
Expand Down
2 changes: 1 addition & 1 deletion deploy-image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The example uses the `fetchai/my_first_aea` project. You will likely want to mod
Install subversion, then download the example directory to your local working directory

``` bash
svn checkout https://github.com/valory-xyz/open-aea/tags/v1.26.0/packages packages
svn checkout https://github.com/valory-xyz/open-aea/tags/v1.27.0/packages packages
```

### Modify scripts
Expand Down
2 changes: 1 addition & 1 deletion develop-image/docker-env.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash

# Swap the following lines if you want to work with 'latest'
DOCKER_IMAGE_TAG=valory/open-aea-develop:1.26.0
DOCKER_IMAGE_TAG=valory/open-aea-develop:1.27.0
# DOCKER_IMAGE_TAG=valory/open-aea-develop:latest

DOCKER_BUILD_CONTEXT_DIR=..
Expand Down
11 changes: 11 additions & 0 deletions docs/api/configurations/data_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ Initialize a package version.

- `version_like`: a string, os a semver.VersionInfo object.

<a id="aea.configurations.data_types.PackageVersion.is_any"></a>

#### is`_`any

```python
@property
def is_any() -> bool
```

Check whether the version is 'any'.

<a id="aea.configurations.data_types.PackageVersion.is_latest"></a>

#### is`_`latest
Expand Down
11 changes: 11 additions & 0 deletions docs/api/package_manager/v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ def third_party_packages() -> PackageIdToHashMapping

Returns mappings of package ids -> package hash

<a id="aea.package_manager.v1.PackageManagerV1.all_packages"></a>

#### all`_`packages

```python
@property
def all_packages() -> PackageIdToHashMapping
```

Return all packages.

<a id="aea.package_manager.v1.PackageManagerV1.get_package_hash"></a>

#### get`_`package`_`hash
Expand Down
17 changes: 17 additions & 0 deletions docs/api/plugins/aea_ledger_fetchai/test_tools/fixture_helpers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<a id="plugins.aea-ledger-fetchai.aea_ledger_fetchai.test_tools.fixture_helpers"></a>

# plugins.aea-ledger-fetchai.aea`_`ledger`_`fetchai.test`_`tools.fixture`_`helpers

Fixture helpers

<a id="plugins.aea-ledger-fetchai.aea_ledger_fetchai.test_tools.fixture_helpers.fetchd"></a>

#### fetchd

```python
@pytest.fixture(scope="class")
def fetchd(fetchd_configuration=FETCHD_CONFIGURATION, timeout: float = 2.0, max_attempts: int = 20)
```

Launch the Fetch ledger image.

Loading

0 comments on commit 00c0671

Please sign in to comment.