Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests/reorganise tests#375 #393

Merged
merged 24 commits into from
Feb 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
185e304
Initial reorganisation
Reillyhewitson Nov 16, 2022
aa39a81
Fix linting
Reillyhewitson Nov 16, 2022
7ffc4b8
reorganise new DB tests
Reillyhewitson Nov 22, 2022
4ebeb77
Add panosc mapping to unit tests
Reillyhewitson Dec 1, 2022
c0595ba
Split unit and integration test runs
Reillyhewitson Dec 12, 2022
ebcb7a6
Checkout api earlier
Reillyhewitson Dec 12, 2022
4e275f6
Create config earlier and dependency updates
Reillyhewitson Dec 12, 2022
da66fac
Ignore sqlalchemy vulnerability
Reillyhewitson Dec 13, 2022
b3d0fc5
Use latest codecov action
Reillyhewitson Dec 13, 2022
a6f5d06
Multiple codecov uploads
Reillyhewitson Dec 13, 2022
ebd60b6
update to v1
Reillyhewitson Dec 15, 2022
86b9a11
assert correct values for v1
Reillyhewitson Dec 15, 2022
e7b8794
remove get_icat_entity_name_as_camel_case
Reillyhewitson Dec 15, 2022
24c3bd7
Fix linting
Reillyhewitson Jan 3, 2023
a0e9527
Update python icat to full release
Reillyhewitson Jan 4, 2023
aa4350c
Update readme for new test runners.
Reillyhewitson Jan 4, 2023
985aa02
Remove poetry install and setuptools install
Reillyhewitson Jan 10, 2023
f9eb154
Readd fix for python 3.10
Reillyhewitson Jan 10, 2023
5f11ba2
Poetry install needed for generator
Reillyhewitson Jan 10, 2023
c2e3f77
Remove second checkout
Reillyhewitson Jan 10, 2023
35780bb
Add prep for api for integration tests
Reillyhewitson Jan 10, 2023
fe6b137
Merge branch 'tests/reorganise-tests#375' into tests/python_icatv1
Reillyhewitson Feb 1, 2023
8627dbb
Merge pull request #396 from ral-facilities/tests/python_icatv1
Reillyhewitson Feb 1, 2023
619d3e4
Update for safety
Reillyhewitson Feb 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 46 additions & 20 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,48 @@ jobs:
python-version: ${{ matrix.python-version }}
architecture: x64

- name: Checkout DataGateway API
uses: actions/checkout@v2

# Install Nox, Poetry and API's dependencies
- name: Install Nox
run: pip install nox==2020.8.22
- name: Install Poetry
run: pip install poetry==1.1.9

# This command is a workaround for getting Poetry working with Python 3.10. An
# fix is made in Poetry 1.2.0a2 but there is currently no official release for
# Poetry 1.2 and am apprehensive to moving to a pre-release. Disabling the
# experimental installer is a workaround for Poetry 1.1.x
# See https://github.com/python-poetry/poetry/issues/4210 for more details
- name: Disable Poetry's experimental new installer
if: ${{ matrix.python-version == '3.10' }}
run: poetry config experimental.new-installer false

# Prep for using the API for tests
- name: Create log file
run: touch logs.log
- name: Configure log file location
run: echo "`yq \
'.log_location="${GITHUB_WORKSPACE}/logs.log"' datagateway_api/config.yaml.example | envsubst`" > datagateway_api/config.yaml.example
- name: Configure datagateway extension
run: echo "`yq \
'.datagateway_api.extension="/datagateway_api"' datagateway_api/config.yaml.example`" > datagateway_api/config.yaml.example
- name: Create config.yaml
run: cp datagateway_api/config.yaml.example datagateway_api/config.yaml
- name: Create search_api_mapping.json
run: cp datagateway_api/search_api_mapping.json.example datagateway_api/search_api_mapping.json

# Run Unit tests
- name: Run Nox unit tests session
run: nox -p ${{ matrix.python-version }} -s unit_tests -- --cov=datagateway_api --cov-report=xml
- name: Upload unit test code coverage report
if: matrix.python-version == '3.6'
uses: codecov/codecov-action@v3

# ICAT Ansible clone and install dependencies
- name: Checkout icat-ansible
if: success()
uses: actions/checkout@v2
with:
repository: icatproject-contrib/icat-ansible
Expand Down Expand Up @@ -94,39 +134,25 @@ jobs:
- name: Create search_api_mapping.json
run: cp datagateway_api/search_api_mapping.json.example datagateway_api/search_api_mapping.json

# Install Nox, Poetry and API's dependencies
- name: Install Nox
run: pip install nox==2020.8.22
- name: Install Poetry
run: pip install poetry==1.1.9

# Installing an older version of setuptools for reasons explained at: https://github.com/icatproject/python-icat/issues/99
- name: Uninstall setuptools
run: poetry run pip uninstall -y setuptools
- name: Install older setuptools
run: poetry run pip install 'setuptools<58.0.0'

# This command is a workaround for getting Poetry working with Python 3.10. An
# fix is made in Poetry 1.2.0a2 but there is currently no official release for
# Poetry 1.2 and am apprehensive to moving to a pre-release. Disabling the
# experimental installer is a workaround for Poetry 1.1.x
# See https://github.com/python-poetry/poetry/issues/4210 for more details
- name: Disable Poetry's experimental new installer
run: poetry config experimental.new-installer false

- name: Install dependencies
run: poetry install

- name: Add dummy data to icatdb
run: |
poetry run python -m util.icat_db_generator

# Run Nox tests session, saves and uploads a coverage report to codecov
- name: Run Nox tests session
run: nox -p ${{ matrix.python-version }} -s tests -- --cov=datagateway_api --cov-report=xml
- name: Upload code coverage report
# Run Nox integration tests session, saves and uploads a coverage report to codecov
- name: Run Nox Integration tests session
if: success()
run: nox -p ${{ matrix.python-version }} -s integration_tests -- --cov=datagateway_api --cov-report=xml
- name: Upload integration test code coverage report
if: matrix.python-version == '3.6'
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v3

linting:
runs-on: ubuntu-20.04
Expand Down
39 changes: 26 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,12 @@ Currently, the following Nox sessions have been created:
- `safety` - this uses [safety](https://github.com/pyupio/safety) to check the
dependencies (pulled directly from Poetry) for any known vulnerabilities. This session
gives the output in a full ASCII style report.
- `tests` - this uses [pytest](https://docs.pytest.org/en/stable/) to execute the
automated tests in `test/`, tests for the database and ICAT backends, and non-backend
- `unit_tests` - this uses [pytest](https://docs.pytest.org/en/stable/) to execute the
automated tests in `test/unit`, tests for the database and ICAT backends, and non-backend
specific tests. More details about the tests themselves [here](#running-tests).
- `integration_tests` - this uses [pytest](https://docs.pytest.org/en/stable/) to execute the
automated tests in `test/unit`, tests for the database and ICAT backends, and non-backend
specific tests. Requires an ICAT backend. More details about the tests themselves [here](#running-tests).

Each Nox session builds an environment using the repo's dependencies (defined using
Poetry) using `install_with_constraints()`. This stores the dependencies in a
Expand Down Expand Up @@ -434,9 +437,14 @@ for the Swagger interface to be up to date when using the Python ICAT backend.

# Running Tests

To run the tests use `nox -s tests`. The repository contains a variety of tests, to test
the functionality of the API works as intended. The tests are split into 3 main
sections: non-backend specific (testing features such as the date handler), ICAT backend
There are two seperate test runners provided. The integration tests, and the unit tests.
The unit test do not require an ICAT stack to be setup to run. The integration tests do
require an ICAT stack. In order to cover all the code you will need to run both tests.

To run the unit test use `nox -s unit_tests`, and to run the integration tests use `nox -s integration_tests`
The repository contains a variety of tests, to test the functionality of the API works as intended, for convenience
and quicker action runs these are additionally split into the unit and integration tests.
The tests are split into 3 main sections: non-backend specific (testing features such as the date handler), ICAT backend
tests (containing tests for backend specific components, including tests for the
different types of endpoints) and Database Backend tests (like the ICAT backend tests,
but covering only the most used aspects of the API).
Expand All @@ -450,14 +458,16 @@ Python 3.6, 3.7, 3.8, 3.9 and 3.10. For most cases, running the tests in a singl
version will be sufficient:

```bash
nox -p 3.6 -s tests
nox -p 3.6 -s unit_tests
nox -p 3.6 -s integration
```

This repository also utilises [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/)
to check how much of the codebase is covered by the tests in `test/`:

```bash
nox -p 3.6 -s tests -- --cov-report term --cov=./datagateway_api
nox -p 3.6 -s unit_tests -- --cov-report term --cov=./datagateway_api
nox -p 3.6 -s integration_tests -- --cov-report term --cov=./datagateway_api
```

With `pytest`, you can output the duration for each test, useful for showing the slower
Expand All @@ -466,21 +476,24 @@ into setup, call and teardown to more easily understand where the tests are bein
down:

```bash
nox -p 3.6 -s tests -- --durations=0
nox -p 3.6 -s unit_tests -- --durations=0
nox -p 3.6 -s integration_tests -- --durations=0
```

To test a specific test class (or even a specific test function), use a double colon to
denote a each level down beyond the filename:
To test a specific test class (or even a specific test function), you will
need to use pytest itself through poetry. If you want to change the python
version use `poetry env use 3.6` which will generate a virtual env with that
version.

```bash
# Test a specific file
nox -p 3.6 -s tests -- test/icat/test_query.py
poetry run pytest test/integration/datagateway_api/icat/test_query.py

# Test a specific test class
nox -p 3.6 -s tests -- test/icat/test_query.py::TestICATQuery
poetry run pytest test/integration/datagateway_api/icat/test_query.py::TestICATQuery

# Test a specific test function
nox -p 3.6 -s tests -- test/icat/test_query.py::TestICATQuery::test_valid_query_exeuction
poetry run pytest test/integration/datagateway_api/icat/test_query.py::TestICATQuery::test_valid_query_exeuction
```

# Project Structure
Expand Down
37 changes: 1 addition & 36 deletions datagateway_api/src/datagateway_api/icat/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from cachetools import cached
from dateutil.tz import tzlocal
from icat.entities import getTypeMap
from icat.exception import (
ICATInternalError,
ICATNoObjectError,
Expand Down Expand Up @@ -145,40 +144,6 @@ def refresh_client_session(client):
client.refresh()


def get_icat_entity_name_as_camel_case(client, entity_name):
"""
From the entity name, this function returns a camelCase version of its input

Due to the case sensitivity of Python ICAT, a camelCase version of the entity name
is required for creating ICAT entities in ICAT (e.g. `client.new("parameterType")`).

:param client: ICAT client containing an authenticated user
:type client: :class:`icat.client.Client`
:param entity_name: Entity name to fetch a camelCase version of
:type entity_name: :class:`str`
:return: Entity name (of type string) in the correct casing ready to be passed into
Python ICAT
:raises BadRequestError: If the entity cannot be found
"""

entity_names = getTypeMap(client).keys()
lowercase_entity_name = entity_name.lower()
python_icat_entity_name = None

for entity_name in entity_names:
lowercase_name = entity_name.lower()
if lowercase_name == lowercase_entity_name:
python_icat_entity_name = entity_name

# Raise a 400 if a valid entity cannot be found
if python_icat_entity_name is None:
raise BadRequestError(
f"Bad request made, cannot find {entity_name} entity within Python ICAT",
)

return python_icat_entity_name


def update_attributes(old_entity, new_entity):
"""
Updates the attribute(s) of a given object which is a record of an entity from
Expand Down Expand Up @@ -507,7 +472,7 @@ def create_entities(client, entity_type, data):
data = [data]

for result in data:
new_entity = client.new(get_icat_entity_name_as_camel_case(client, entity_type))
new_entity = client.new(entity_type.lower())

for attribute_name, value in result.items():
log.debug("Preparing data for %s", attribute_name)
Expand Down
35 changes: 32 additions & 3 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ def safety(session):
external=True,
)
# Ignore 50916 as the latest version of pydantic and
# Ignore 51457 as the latest version of pytest does not support
# Ignore 51457 as the latest version of pytest and
# Ignore 51668 as the latest version of SQLAchemy and
# Ignore 52355 and 52518 as the latest version of gitpython
# as they do not support
# python 3.6 which is still used in production
session.run(
"safety",
Expand All @@ -84,6 +87,12 @@ def safety(session):
"50916",
"--ignore",
"51457",
"--ignore",
"51668",
"--ignore",
"52322",
"--ignore",
"52518",
)

try:
Expand All @@ -95,7 +104,27 @@ def safety(session):


@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10"], reuse_venv=True)
def tests(session):
def unit_tests(session):
args = session.posargs
# Installing setuptools that will work with `2to3` which is used when building
# `python-icat` < 1.0. 58.0.0 removes support of this tool during builds:
# https://setuptools.pypa.io/en/latest/history.html#v58-0-0
# Ideally this would be done within `pyproject.toml` but specifying `setuptools` as
# a dependency requires Poetry 1.2:
# https://github.com/python-poetry/poetry/issues/4511#issuecomment-922420457
# Currently, only a pre-release exists for Poetry 1.2. Testing on the pre-release
# version didn't fix the `2to3` issue when building Python ICAT, perhaps because
# Python ICAT isn't built on the downgraded version for some reason?
session.run("pip", "uninstall", "-y", "setuptools")
# Not using `poetry run` as it errors on Windows OS when a version with the '<'
# sign is specified for a package
session.run("pip", "install", "setuptools<58.0.0")
session.run("poetry", "install", external=True)
session.run("pytest", "test/unit", *args)


@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10"], reuse_venv=True)
def integration_tests(session):
args = session.posargs
# Installing setuptools that will work with `2to3` which is used when building
# `python-icat` < 1.0. 58.0.0 removes support of this tool during builds:
Expand All @@ -111,4 +140,4 @@ def tests(session):
# sign is specified for a package
session.run("pip", "install", "setuptools<58.0.0")
session.run("poetry", "install", external=True)
session.run("pytest", *args)
session.run("pytest", "test/integration", *args)
Loading