Merge pull request #3842 from ryanpetrello/instance-group-order

enforce a stable list order when attaching/detaching instance groups

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
This commit is contained in:
softwarefactory-project-zuul[bot]
2019-05-09 21:04:29 +00:00
committed by GitHub
13 changed files with 537 additions and 39 deletions
@@ -1,3 +1,5 @@
import random
import pytest
from awx.api.versioning import reverse
@@ -6,6 +8,7 @@ from awx.main.models import (
InstanceGroup,
ProjectUpdate,
)
from awx.main.utils import camelcase_to_underscore
@pytest.fixture
@@ -78,6 +81,11 @@ def instance_group_jobs_successful(instance_group, create_job_factory, create_pr
return jobs_successful + project_updates_successful
@pytest.fixture(scope='function')
def source_model(request):
return request.getfixturevalue(request.param)
@pytest.mark.django_db
def test_instance_group_is_controller(instance_group, isolated_instance_group, non_iso_instance):
assert not isolated_instance_group.is_controller
@@ -196,3 +204,39 @@ def test_prevent_non_isolated_instance_added_to_isolated_instance_group_via_poli
resp = patch(url, {'policy_instance_list': [non_iso_instance.hostname]}, user=admin, expect=400)
assert [u"Isolated instance group membership may not be managed via the API."] == resp.data['policy_instance_list']
assert isolated_instance_group.policy_instance_list == []
@pytest.mark.django_db
@pytest.mark.parametrize(
'source_model', ['job_template', 'inventory', 'organization'], indirect=True
)
def test_instance_group_order_persistence(get, post, admin, source_model):
# create several instance groups in random order
total = 5
pks = list(range(total))
random.shuffle(pks)
instances = [InstanceGroup.objects.create(name='iso-%d' % i) for i in pks]
view_name = camelcase_to_underscore(source_model.__class__.__name__)
url = reverse(
'api:{}_instance_groups_list'.format(view_name),
kwargs={'pk': source_model.pk}
)
# associate them all
for instance in instances:
post(url, {'associate': True, 'id': instance.id}, admin, expect=204)
for _ in range(10):
# remove them all
for instance in instances:
post(url, {'disassociate': True, 'id': instance.id}, admin, expect=204)
resp = get(url, admin)
assert resp.data['count'] == 0
# add them all in random order
before = sorted(instances, key=lambda x: random.random())
for instance in before:
post(url, {'associate': True, 'id': instance.id}, admin, expect=204)
resp = get(url, admin)
assert resp.data['count'] == total
assert [ig['name'] for ig in resp.data['results']] == [ig.name for ig in before]
@@ -0,0 +1,102 @@
import pytest
from awx.main.models import InstanceGroup
@pytest.fixture(scope='function')
def source_model(request):
return request.getfixturevalue(request.param)
@pytest.mark.django_db
@pytest.mark.parametrize(
'source_model', ['job_template', 'inventory', 'organization'], indirect=True
)
def test_instance_group_ordering(source_model):
groups = [
InstanceGroup.objects.create(name='host-%d' % i)
for i in range(5)
]
groups.reverse()
for group in groups:
source_model.instance_groups.add(group)
assert [g.name for g in source_model.instance_groups.all()] == [
'host-4', 'host-3', 'host-2', 'host-1', 'host-0'
]
assert [
(row.position, row.instancegroup.name)
for row in source_model.instance_groups.through.objects.all()
] == [
(0, 'host-4'),
(1, 'host-3'),
(2, 'host-2'),
(3, 'host-1'),
(4, 'host-0'),
]
source_model.instance_groups.remove(groups[0])
assert [g.name for g in source_model.instance_groups.all()] == [
'host-3', 'host-2', 'host-1', 'host-0'
]
assert [
(row.position, row.instancegroup.name)
for row in source_model.instance_groups.through.objects.all()
] == [
(0, 'host-3'),
(1, 'host-2'),
(2, 'host-1'),
(3, 'host-0'),
]
source_model.instance_groups.clear()
assert source_model.instance_groups.through.objects.count() == 0
@pytest.mark.django_db
@pytest.mark.parametrize(
'source_model', ['job_template', 'inventory', 'organization'], indirect=True
)
def test_instance_group_middle_deletion(source_model):
groups = [
InstanceGroup.objects.create(name='host-%d' % i)
for i in range(5)
]
groups.reverse()
for group in groups:
source_model.instance_groups.add(group)
source_model.instance_groups.remove(groups[2])
assert [g.name for g in source_model.instance_groups.all()] == [
'host-4', 'host-3', 'host-1', 'host-0'
]
assert [
(row.position, row.instancegroup.name)
for row in source_model.instance_groups.through.objects.all()
] == [
(0, 'host-4'),
(1, 'host-3'),
(2, 'host-1'),
(3, 'host-0'),
]
@pytest.mark.django_db
@pytest.mark.parametrize(
'source_model', ['job_template', 'inventory', 'organization'], indirect=True
)
def test_explicit_ordering(source_model):
groups = [
InstanceGroup.objects.create(name='host-%d' % i)
for i in range(5)
]
groups.reverse()
for group in groups:
source_model.instance_groups.add(group)
assert [g.name for g in source_model.instance_groups.all()] == [
'host-4', 'host-3', 'host-2', 'host-1', 'host-0'
]
assert [g.name for g in source_model.instance_groups.order_by('name').all()] == [
'host-0', 'host-1', 'host-2', 'host-3', 'host-4'
]