mirror of
https://github.com/ZwareBear/awx.git
synced 2026-03-19 23:33:37 -05:00
add assertion to test on number of queries made (#9)
* add assertions around access to resulting job there is a problem getting the job w/ the user that launched it add more assertions to bulk tests (#11) dig more into the results and assert on results also, use a fixture that already implemented the "max queries" thing fix ansible collection sanity tests (#12)
This commit is contained in:
@@ -6,23 +6,15 @@ from awx.api.versioning import reverse
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from django.test.utils import CaptureQueriesContext
|
|
||||||
from django.db import connections
|
from django.db import connections
|
||||||
|
|
||||||
from awx.main.models.jobs import JobTemplate
|
from awx.main.models.jobs import JobTemplate
|
||||||
from awx.main.models import Organization, Inventory
|
from awx.main.models import Organization, Inventory, WorkflowJob
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def withAssertNumQueriesLessThan(num_queries):
|
|
||||||
with CaptureQueriesContext(connections['default']) as context:
|
|
||||||
yield
|
|
||||||
fail_msg = f"\r\n{json.dumps(context.captured_queries, indent=4)}"
|
|
||||||
assert len(context.captured_queries) < num_queries, fail_msg
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@pytest.mark.parametrize('num_hosts, num_queries', [(9, 15), (99, 20), (999, 30)])
|
@pytest.mark.parametrize('num_hosts, num_queries', [(9, 15), (99, 20), (999, 30)])
|
||||||
def test_bulk_host_create_num_queries(organization, inventory, post, get, user, num_hosts, num_queries):
|
def test_bulk_host_create_num_queries(organization, inventory, post, get, user, num_hosts, num_queries, django_assert_max_num_queries):
|
||||||
'''
|
'''
|
||||||
If I am a...
|
If I am a...
|
||||||
org admin
|
org admin
|
||||||
@@ -45,7 +37,7 @@ def test_bulk_host_create_num_queries(organization, inventory, post, get, user,
|
|||||||
|
|
||||||
for u in [org_admin, inventory_admin, org_inv_admin, superuser]:
|
for u in [org_admin, inventory_admin, org_inv_admin, superuser]:
|
||||||
hosts = [{'name': uuid4()} for i in range(num_hosts)]
|
hosts = [{'name': uuid4()} for i in range(num_hosts)]
|
||||||
with withAssertNumQueriesLessThan(num_queries):
|
with django_assert_max_num_queries(num_queries):
|
||||||
bulk_host_create_response = post(reverse('api:bulk_host_create'), {'inventory': inventory.id, 'hosts': hosts}, u, expect=201).data
|
bulk_host_create_response = post(reverse('api:bulk_host_create'), {'inventory': inventory.id, 'hosts': hosts}, u, expect=201).data
|
||||||
assert len(bulk_host_create_response['hosts']) == len(hosts), f"unexpected number of hosts created for user {u}"
|
assert len(bulk_host_create_response['hosts']) == len(hosts), f"unexpected number of hosts created for user {u}"
|
||||||
|
|
||||||
@@ -89,20 +81,36 @@ def test_bulk_host_create_rbac(organization, inventory, post, get, user):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_bulk_job_launch(job_template, organization, inventory, project, credential, post, get, user):
|
@pytest.mark.parametrize('num_jobs, num_queries', [(9, 30), (99, 35)])
|
||||||
|
def test_bulk_job_launch_queries(job_template, organization, inventory, project, post, get, user, num_jobs, num_queries, django_assert_max_num_queries):
|
||||||
'''
|
'''
|
||||||
if I have access to the unified job template
|
if I have access to the unified job template
|
||||||
... I can launch the bulk job
|
... I can launch the bulk job
|
||||||
|
... and the number of queries should NOT scale with the number of jobs
|
||||||
'''
|
'''
|
||||||
normal_user = user('normal_user', False)
|
normal_user = user('normal_user', False)
|
||||||
jt = JobTemplate.objects.create(name='my-jt', inventory=inventory, project=project, playbook='helloworld.yml')
|
org_admin = user('org_admin', False)
|
||||||
jt.save()
|
jt = JobTemplate.objects.create(name='my-jt', ask_inventory_on_launch=True, project=project, playbook='helloworld.yml')
|
||||||
organization.member_role.members.add(normal_user)
|
organization.member_role.members.add(normal_user)
|
||||||
|
organization.admin_role.members.add(org_admin)
|
||||||
jt.execute_role.members.add(normal_user)
|
jt.execute_role.members.add(normal_user)
|
||||||
bulk_job_launch_response = post(
|
inventory.use_role.members.add(normal_user)
|
||||||
reverse('api:bulk_job_launch'), {'name': 'Bulk Job Launch', 'jobs': [{'unified_job_template': jt.id}]}, normal_user, expect=201
|
jt.save()
|
||||||
).data
|
inventory.save()
|
||||||
assert bulk_job_launch_response['id'] == 1
|
jobs = [{'unified_job_template': jt.id, 'inventory': inventory.id} for _ in range(num_jobs)]
|
||||||
|
|
||||||
|
# This is not working, we need to figure that out if we want to include tests for more jobs
|
||||||
|
# with mock.patch('awx.api.serializers.settings.BULK_JOB_MAX_LAUNCH', num_jobs + 1):
|
||||||
|
with django_assert_max_num_queries(num_queries):
|
||||||
|
bulk_job_launch_response = post(reverse('api:bulk_job_launch'), {'name': 'Bulk Job Launch', 'jobs': jobs}, normal_user, expect=201).data
|
||||||
|
|
||||||
|
for u in (org_admin,): # TODO normal_user not working because launched_by not getting set in the tests...does happen in real request
|
||||||
|
bulk_job = get(bulk_job_launch_response['url'], u, expect=200).data
|
||||||
|
assert organization.id == bulk_job['summary_fields']['organization']['id']
|
||||||
|
resp = get(bulk_job_launch_response['related']['workflow_nodes'], u)
|
||||||
|
assert resp.data['count'] == num_jobs
|
||||||
|
for item in resp.data['results']:
|
||||||
|
assert item["unified_job_template"] == jt.id
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@@ -167,7 +175,9 @@ def test_bulk_job_launch_specific_org(job_template, organization, inventory, pro
|
|||||||
bulk_job_launch_response = post(
|
bulk_job_launch_response = post(
|
||||||
reverse('api:bulk_job_launch'), {'name': 'Bulk Job Launch', 'jobs': [{'unified_job_template': jt.id}], 'organization': org1.id}, normal_user, expect=201
|
reverse('api:bulk_job_launch'), {'name': 'Bulk Job Launch', 'jobs': [{'unified_job_template': jt.id}], 'organization': org1.id}, normal_user, expect=201
|
||||||
).data
|
).data
|
||||||
assert bulk_job_launch_response['id'] == 1
|
bulk_job_id = bulk_job_launch_response['id']
|
||||||
|
bulk_job_obj = WorkflowJob.objects.filter(id=bulk_job_id, is_bulk_job=True).first()
|
||||||
|
assert org1.id == bulk_job_obj.organization.id
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ Notable releases of the `awx.awx` collection:
|
|||||||
- 7.0.0 is intended to be identical to the content prior to the migration, aside from changes necessary to function as a collection.
|
- 7.0.0 is intended to be identical to the content prior to the migration, aside from changes necessary to function as a collection.
|
||||||
- 11.0.0 has no non-deprecated modules that depend on the deprecated `tower-cli` [PyPI](https://pypi.org/project/ansible-tower-cli/).
|
- 11.0.0 has no non-deprecated modules that depend on the deprecated `tower-cli` [PyPI](https://pypi.org/project/ansible-tower-cli/).
|
||||||
- 19.2.1 large renaming purged "tower" names (like options and module names), adding redirects for old names
|
- 19.2.1 large renaming purged "tower" names (like options and module names), adding redirects for old names
|
||||||
|
- 21.11.0 "tower" modules deprecated and symlinks removed.
|
||||||
- 0.0.1-devel is the version you should see if installing from source, which is intended for development and expected to be unstable.
|
- 0.0.1-devel is the version you should see if installing from source, which is intended for development and expected to be unstable.
|
||||||
|
|
||||||
The following notes are changes that may require changes to playbooks:
|
The following notes are changes that may require changes to playbooks:
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ options:
|
|||||||
description:
|
description:
|
||||||
- The name to use for the host.
|
- The name to use for the host.
|
||||||
type: str
|
type: str
|
||||||
require: True
|
required: True
|
||||||
description:
|
description:
|
||||||
description:
|
description:
|
||||||
- The description to use for the host.
|
- The description to use for the host.
|
||||||
@@ -70,7 +70,7 @@ import json
|
|||||||
def main():
|
def main():
|
||||||
# Any additional arguments that are not fields of the item can be added here
|
# Any additional arguments that are not fields of the item can be added here
|
||||||
argument_spec = dict(
|
argument_spec = dict(
|
||||||
hosts=dict(required=True, type='list'),
|
hosts=dict(required=True, type='list', elements='dict'),
|
||||||
inventory=dict(required=True, type='int'),
|
inventory=dict(required=True, type='int'),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -82,8 +82,8 @@ def main():
|
|||||||
hosts = module.params.get('hosts')
|
hosts = module.params.get('hosts')
|
||||||
|
|
||||||
for h in hosts:
|
for h in hosts:
|
||||||
if 'variables' in h:
|
if 'variables' in h:
|
||||||
h['variables'] = json.dumps(h['variables'])
|
h['variables'] = json.dumps(h['variables'])
|
||||||
# Launch the jobs
|
# Launch the jobs
|
||||||
result = module.post_endpoint("bulk/host_create", data={"inventory": inventory, "hosts": hosts})
|
result = module.post_endpoint("bulk/host_create", data={"inventory": inventory, "hosts": hosts})
|
||||||
|
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ from ..module_utils.controller_api import ControllerAPIModule
|
|||||||
def main():
|
def main():
|
||||||
# Any additional arguments that are not fields of the item can be added here
|
# Any additional arguments that are not fields of the item can be added here
|
||||||
argument_spec = dict(
|
argument_spec = dict(
|
||||||
jobs=dict(required=True, type='list'),
|
jobs=dict(required=True, type='list', elements='dict'),
|
||||||
name=dict(),
|
name=dict(),
|
||||||
description=dict(),
|
description=dict(),
|
||||||
organization=dict(type='int'),
|
organization=dict(type='int'),
|
||||||
@@ -217,7 +217,6 @@ def main():
|
|||||||
skip_tags=dict(),
|
skip_tags=dict(),
|
||||||
wait=dict(required=False, default=True, type='bool'),
|
wait=dict(required=False, default=True, type='bool'),
|
||||||
interval=dict(required=False, default=2.0, type='float'),
|
interval=dict(required=False, default=2.0, type='float'),
|
||||||
timeout=dict(required=False, default=None, type='int'),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a module for ourselves
|
# Create a module for ourselves
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import pytest
|
|||||||
|
|
||||||
from awx.main.models import WorkflowJob
|
from awx.main.models import WorkflowJob
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_bulk_job_launch(run_module, admin_user, job_template):
|
def test_bulk_job_launch(run_module, admin_user, job_template):
|
||||||
jobs = [dict(unified_job_template=job_template.id)]
|
jobs = [dict(unified_job_template=job_template.id)]
|
||||||
@@ -39,4 +40,4 @@ def test_bulk_host_create(run_module, admin_user, inventory):
|
|||||||
)
|
)
|
||||||
resp_hosts = inventory.hosts.all().values_list('name', flat=True)
|
resp_hosts = inventory.hosts.all().values_list('name', flat=True)
|
||||||
for h in hosts:
|
for h in hosts:
|
||||||
assert h['name'] in resp_hosts
|
assert h['name'] in resp_hosts
|
||||||
|
|||||||
Reference in New Issue
Block a user