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

Rewrite test_filter.py using pytest #328

Merged
merged 1 commit into from
Jan 17, 2024

Conversation

git-hyagi
Copy link
Contributor

fixes: #324

Comment on lines 107 to 121
@pytest.fixture()
def setup_filter(
repo,
remote,
ostree_repository_version,
ostree_repositories_api,
ostree_remotes_api,
):
"""Setup for ostree filter tests"""
delete_orphans()

yield ostree_repository_version
ostree_repositories_api.delete(repo.pulp_href)
ostree_remotes_api.delete(remote.pulp_href)
delete_orphans()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a special setup code for a few tests in one module, the fixture should live there too.
Instead of calling delete_orphans, use the delete_orphans_pre fixture (I always suppose to check if it's needed at all...).

Comment on lines 3 to 4
from pulp_smash.pulp3.bindings import delete_orphans, monitor_task
from pulp_smash.pulp3.utils import gen_repo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the rewrite goals is to stop using pulp-smash...
Both delete_orphans (as delete_orphans_pre) and monitor_task are provided by fixtures.
gen_repo is not doing much more than creating a dict with a "name" key.

@git-hyagi git-hyagi force-pushed the pytest-refactor-filter branch from c267c5e to cd02c5a Compare January 15, 2024 18:17
Copy link
Member

@lubosmj lubosmj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening this PR! I have added a couple of suggestions.

Comment on lines +17 to +23
def ostree_client(_api_client_set, bindings_cfg):
"""Fixture to provide a client to Pulp API"""
api_client = ApiClient(bindings_cfg)
_api_client_set.add(api_client)
yield api_client
_api_client_set.remove(api_client)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to keep this simple?

from pulpcore.client.pulp_ostree import ApiClient as OstreeApiClient

@pytest.fixture(scope="session")
def ostree_client(bindings_cfg):
    """Fixture for an OSTree client."""
    return OstreeApiClient(bindings_cfg)

Note that in this case I am using the session scope which means that the fixture is destroyed at the end of the test session. This is what we usually want when dealing with generic fixtures that are used from multiple test modules. In case we want to execute the fixture each time being requested, we leave the scope unfilled. Would you mind using the session scope across all the relevant fixtures, please?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the session scope. However registering this client with the _api_client_set what provides our tests with a unique correlation id per test. It proved to be helpful in debugging.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. We do not use such a thing in pulp-rpm.

Comment on lines 49 to 52
@pytest.fixture()
def ostree_repository_sync_url(ostree_client):
"""Fixture that returns an instance of RepositorySyncURL"""
return RepositorySyncURL(ostree_client)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a fixture for RepositorySyncURL is not necessary because this class is a wrapper for the body of a request sent to sync remote content. Usually, we use it in the following way: https://github.com/pulp/pulp_rpm/blob/6d331892b3688b5eea574d7b594c92a5227b8674/pulp_rpm/tests/functional/api/test_publish.py#L435-L438.

Comment on lines 62 to 65
def remote(ostree_remotes_api):
"""Fixture that creates an ostree Remote and returns the object created"""
body = gen_ostree_remote(depth=0, policy="immediate")
return ostree_remotes_api.create(body)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of writing this, you may want to implement a factory that will handle the setup and cleanup of resources by itself by leveraging gen_object_with_cleanup, like so: https://github.com/pulp/pulp_gem/blob/4de8c2adf1be973958d95b16f0c4137dab7ba066/pulp_gem/tests/functional/conftest.py#L105-L116. At the moment, we do not support domains, so you can skip that part.

Do you think it makes sense to follow the same concept for the corresponding repo and distribution fixture?

Comment on lines 68 to 71
@pytest.fixture()
def random_name():
"""Fixture that returns a dictionary with a random uuid for the `name` key"""
return {"name": str(uuid.uuid4())}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am in favour of removing the fixture. From time to time, we want to find a balance between the usability of the fixture and self-explanatory code used directly in a test case.



@pytest.fixture()
def ostree_repository_version(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's clearly describe what the fixture returns.

Suggested change
def ostree_repository_version(
def synced_repo_version(

Furthermore, you may find it useful to call ostree_repo_factory here.

Comment on lines 96 to 105
@pytest.fixture()
def ostree_repositories_delete(ostree_repositories_api, repo):
"""Fixture that deletes an ostree Repository"""
return ostree_repositories_api.delete(repo.pulp_href)


@pytest.fixture()
def ostree_remotes_delete(ostree_remotes_api, remote):
"""Fixture that deletes an ostree Remote"""
return ostree_remotes_api.delete(remote.pulp_href)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With pytest, you do not need to care about cleanups in the old-fashioned way. The procedure is as follows:

def repo_fixture():
    repo = setup_repo()
    yield repo
    delete_repo(repo)

Thus, by following the logic implemented here: https://github.com/pulp/pulp_gem/blob/4de8c2adf1be973958d95b16f0c4137dab7ba066/pulp_gem/tests/functional/conftest.py#L105-L116, we can clearly get rid of these two cleanup fixtures.

@git-hyagi git-hyagi force-pushed the pytest-refactor-filter branch from cd02c5a to 2ca657b Compare January 17, 2024 14:04
@git-hyagi git-hyagi marked this pull request as draft January 17, 2024 14:17
@git-hyagi git-hyagi force-pushed the pytest-refactor-filter branch from 2ca657b to eba23fd Compare January 17, 2024 15:43
@git-hyagi git-hyagi marked this pull request as ready for review January 17, 2024 15:53
Copy link
Member

@lubosmj lubosmj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left two more comments. Please, review them.

In addition to that, have you tried dropping delete_orphans_pre? In my opinion, it is not required.

delete_orphans_pre,
):
"""Check if refs can be filtered by their names and related commits' checksums."""
repo = synced_repo()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this fixture be ever called with other than non-default parameters? How about making it a regular fixture that returns an object instead of a function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! I see!
Good point!

):
"""Check if commits can be filtered by their checksums."""
repo = synced_repo()
assert repo.latest_version_href == f"{repo.pulp_href}versions/1/"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We know that the repository is synced. There is no need to assert on the version number.

@git-hyagi
Copy link
Contributor Author

In addition to that, have you tried dropping delete_orphans_pre?

Hum… I didn't. I'll do some tests without it before updating the PR.

@git-hyagi git-hyagi force-pushed the pytest-refactor-filter branch from eba23fd to 0ac19cd Compare January 17, 2024 17:35
Copy link
Member

@lubosmj lubosmj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you believe it makes sense to run these tests in parallel?

pytest -v -r sx --color=yes --suppress-no-test-exit-code --pyargs pulp_ostree.tests.functional -m parallel -n 8

https://github.com/pulp/pulp_gem/blob/4de8c2adf1be973958d95b16f0c4137dab7ba066/pulp_gem/tests/functional/api/test_sync.py#L36

Comment on lines 16 to 22
def _synced_repo():
repo = ostree_repository_factory()
remote = ostree_remote_factory(url=OSTREE_FIXTURE_URL, policy="immediate")
result = ostree_repositories_api_client.sync(repo.pulp_href, {"remote": remote.pulp_href})
monitor_task(result.task)
return ostree_repositories_api_client.read(repo.pulp_href)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need for having an inner function anymore. We can simply return ostree_repositories_api_client.read(repo.pulp_href) from synced_repo.

@git-hyagi
Copy link
Contributor Author

Do you believe it makes sense to run these tests in parallel?

Hum... I guess it does.
From what I could understand, the filter_refs and filter_commits work in different repositories (each one creates its own repository), therefore it should be fine to run them in parallel.

@git-hyagi git-hyagi force-pushed the pytest-refactor-filter branch from 0ac19cd to afd04ee Compare January 17, 2024 18:00
@lubosmj lubosmj merged commit 4273c0f into pulp:main Jan 17, 2024
16 checks passed
@git-hyagi git-hyagi deleted the pytest-refactor-filter branch January 17, 2024 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rewrite test_filter.py to pytest
3 participants