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

Use fixtures instead of finalizers #14568

Closed

Conversation

dosas
Copy link
Collaborator

@dosas dosas commented Mar 28, 2024

Problem Statement

The teardown order was not correct
and host was not deleted before hostgroup
pytest-dev/pytest#10023 (comment)

Solution

Use fixtures

@dosas dosas requested a review from a team as a code owner March 28, 2024 15:12
Copy link
Contributor

@vijaysawant vijaysawant left a comment

Choose a reason for hiding this comment

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

suggested chages as per new modified flow.

tests/foreman/api/test_parameters.py Show resolved Hide resolved
tests/foreman/api/test_parameters.py Show resolved Hide resolved
tests/foreman/api/test_parameters.py Show resolved Hide resolved
tests/foreman/api/test_parameters.py Show resolved Hide resolved
tests/foreman/api/test_parameters.py Show resolved Hide resolved
tests/foreman/api/test_parameters.py Show resolved Hide resolved
The teardown order was not correct
and host was not deleted before hostgroup
pytest-dev/pytest#10023 (comment)
@dosas dosas force-pushed the fix-finalizer-execution-order branch from 8854234 to e931f8d Compare April 2, 2024 07:52
@dosas dosas requested a review from vijaysawant April 2, 2024 07:52
Copy link
Contributor

@vijaysawant vijaysawant left a comment

Choose a reason for hiding this comment

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

non-blocking - just make it more appropriate.

tests/foreman/api/test_parameters.py Show resolved Hide resolved
@vijaysawant
Copy link
Contributor

@dosas , I have unresolved comments, please go into File changed tab and look for suggestions.

@dosas dosas requested a review from vijaysawant April 2, 2024 11:11
Copy link
Contributor

@vijaysawant vijaysawant left a comment

Choose a reason for hiding this comment

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

remove extra/older doc string.

@pytest.fixture
def hostgroup(param_name, param_value, module_org, module_target_sat):
"""Create hostgroup object, yeilds it for test cases, delete object before teardown"""
"""Create hostgroup"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Create hostgroup"""

@pytest.fixture
def host(param_name, param_value, module_org, module_location, module_target_sat, cp, hostgroup):
"""Create host object, yeilds it for test cases, delete object before teardown"""
"""Create host"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Create host"""

@pytest.fixture
def cp(param_name, param_value, module_target_sat):
"""Create common parameter object, yields it for test cases, delete object before teardown"""
"""Create common parameter"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Create common parameter"""

@pytest.fixture
def param_value():
"""Generate value string for common parameter and return to test cases"""
"""Generate value for common parameter"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Generate value for common parameter"""

@pytest.fixture
def param_name():
"""Generate name string for common parameter and return to test cases"""
"""Generate name for common parameter"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Generate name for common parameter"""

@@ -14,44 +14,84 @@
import pytest


@pytest.fixture
def param_name():
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be better to just use parametrization for the test and generate the name and value there. You can pass those variables to your other fixtures using request.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member

@JacobCallahan JacobCallahan left a comment

Choose a reason for hiding this comment

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

I think this change goes a bit too far with fixture use. Keep in mind that fixtures should largely be used for setup/teardown and not test logic itself.
Also, consider breaking fixtures down into smaller components only when it make sense for them to be inherited by another. This helps to reduce the amount of fixtures being written.

@dosas
Copy link
Collaborator Author

dosas commented Apr 3, 2024

@JacobCallahan Before we start having endless iterations, could you be a bit more specific about which fixtures you want to have removed?

@JacobCallahan
Copy link
Member

@dosas at a minimum, the fixtures providing the name and value could be included in another, but you can also take a larger approach. For example, to have test-specific setup/teardown in fixture form we can even do it all at once.

def setup_param_precedence(module_target_sat, module_org, module_location):
    param_name = gen_alpha()
    param_value = gen_alpha()
    cp = module_target_sat.api.CommonParameter(name=param_name, value=param_value).create()
    host = module_target_sat.api.Host(organization=module_org, location=module_location).create()
    hg = module_target_sat.api.HostGroup(
        organization=[module_org],
        group_parameters_attributes=[{'name': param_name, 'value': param_value}],
    ).create()
    yield Box(cp=cp, host=host, hg=hg, param_name=param_name)
    cp.delete()
    host.delete()
    hg.delete()

Then in the test, you can access the values by using

setup_param_precedence.cp
setup_param_precedence.host

or alias setup_param_precedence to something shorter in the test for convenience.

@dosas
Copy link
Collaborator Author

dosas commented Apr 4, 2024

@dosas at a minimum, the fixtures providing the name and value could be included in another, but you can also take a larger approach. For example, to have test-specific setup/teardown in fixture form we can even do it all at once.

def setup_param_precedence(module_target_sat, module_org, module_location):
    param_name = gen_alpha()
    param_value = gen_alpha()
    cp = module_target_sat.api.CommonParameter(name=param_name, value=param_value).create()
    host = module_target_sat.api.Host(organization=module_org, location=module_location).create()
    hg = module_target_sat.api.HostGroup(
        organization=[module_org],
        group_parameters_attributes=[{'name': param_name, 'value': param_value}],
    ).create()
    yield Box(cp=cp, host=host, hg=hg, param_name=param_name)
    cp.delete()
    host.delete()
    hg.delete()

Then in the test, you can access the values by using

setup_param_precedence.cp
setup_param_precedence.host

or alias setup_param_precedence to something shorter in the test for convenience.

I chose the fixture approach to have modularity and ensure that deletion in teardown is independent.
With your approach an error in cp.delete() would prevent the deletion of host and hostgroup.

If there is no need for that I will go for the most simple solution and put the finalizers in the right order so the change will be minimal.

@dosas
Copy link
Collaborator Author

dosas commented Apr 4, 2024

Simpler PR #14620


@pytest.fixture
def host(param_name, param_value, module_org, module_location, module_target_sat, cp, hostgroup):
"""Create host object, yeilds it for test cases, delete object before teardown"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Create host object, yeilds it for test cases, delete object before teardown"""
"""Create host object, yields it for test cases, delete object before teardown"""



@pytest.fixture
def host(param_name, param_value, module_org, module_location, module_target_sat, cp, hostgroup):
Copy link
Contributor

Choose a reason for hiding this comment

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

Many parameters here appear to be unused.

Suggested change
def host(param_name, param_value, module_org, module_location, module_target_sat, cp, hostgroup):
def host(module_org, module_location, module_target_sat):

@JacobCallahan
Copy link
Member

Closing in favor of #14620

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.

5 participants