def test_inventory_copy(inventory, group_factory, post, get, alice, organization): group_1_1 = group_factory('g_1_1') group_2_1 = group_factory('g_2_1') group_2_2 = group_factory('g_2_2') group_2_1.parents.add(group_1_1) group_2_2.parents.add(group_1_1) group_2_2.parents.add(group_2_1) host = group_1_1.hosts.create(name='host', inventory=inventory) group_2_1.hosts.add(host) inventory.admin_role.members.add(alice) assert get(reverse('api:inventory_copy', kwargs={'pk': inventory.pk}), alice, expect=200).data['can_copy'] is False inventory.organization.admin_role.members.add(alice) assert get(reverse('api:inventory_copy', kwargs={'pk': inventory.pk}), alice, expect=200).data['can_copy'] is True with mock.patch( 'awx.api.generics.trigger_delayed_deep_copy') as deep_copy_mock: inv_copy_pk = post(reverse('api:inventory_copy', kwargs={'pk': inventory.pk}), { 'name': 'new inv name' }, alice, expect=201).data['id'] inventory_copy = type(inventory).objects.get(pk=inv_copy_pk) args, kwargs = deep_copy_mock.call_args deep_copy_model_obj(*args, **kwargs) group_1_1_copy = inventory_copy.groups.get(name='g_1_1') group_2_1_copy = inventory_copy.groups.get(name='g_2_1') group_2_2_copy = inventory_copy.groups.get(name='g_2_2') host_copy = inventory_copy.hosts.get(name='host') assert inventory_copy.organization == organization assert inventory_copy.created_by == alice assert inventory_copy.name == 'new inv name' assert set(group_1_1_copy.parents.all()) == set() assert set(group_2_1_copy.parents.all()) == set([group_1_1_copy]) assert set(group_2_2_copy.parents.all()) == set( [group_1_1_copy, group_2_1_copy]) assert set(group_1_1_copy.hosts.all()) == set([host_copy]) assert set(group_2_1_copy.hosts.all()) == set([host_copy]) assert set(group_2_2_copy.hosts.all()) == set()
def test_workflow_job_template_copy(workflow_job_template, post, get, admin, organization): workflow_job_template.organization = organization workflow_job_template.save() jts = [ JobTemplate.objects.create(name='test-jt-{}'.format(i)) for i in range(0, 5) ] nodes = [ WorkflowJobTemplateNode.objects.create( workflow_job_template=workflow_job_template, unified_job_template=jts[i]) for i in range(0, 5) ] nodes[0].success_nodes.add(nodes[1]) nodes[1].success_nodes.add(nodes[2]) nodes[0].failure_nodes.add(nodes[3]) nodes[3].failure_nodes.add(nodes[4]) with mock.patch( 'awx.api.generics.trigger_delayed_deep_copy') as deep_copy_mock: wfjt_copy_id = post(reverse('api:workflow_job_template_copy', kwargs={'pk': workflow_job_template.pk}), { 'name': 'new wfjt name' }, admin, expect=201).data['id'] wfjt_copy = type(workflow_job_template).objects.get(pk=wfjt_copy_id) args, kwargs = deep_copy_mock.call_args deep_copy_model_obj(*args, **kwargs) assert wfjt_copy.organization == organization assert wfjt_copy.created_by == admin assert wfjt_copy.name == 'new wfjt name' copied_node_list = [x for x in wfjt_copy.workflow_job_template_nodes.all()] copied_node_list.sort(key=lambda x: int(x.unified_job_template.name[-1])) for node, success_count, failure_count, always_count in zip( copied_node_list, [1, 1, 0, 0, 0], [1, 0, 0, 1, 0], [0, 0, 0, 0, 0]): assert node.success_nodes.count() == success_count assert node.failure_nodes.count() == failure_count assert node.always_nodes.count() == always_count assert copied_node_list[1] in copied_node_list[0].success_nodes.all() assert copied_node_list[2] in copied_node_list[1].success_nodes.all() assert copied_node_list[3] in copied_node_list[0].failure_nodes.all() assert copied_node_list[4] in copied_node_list[3].failure_nodes.all()
def test_workflow_approval_node_copy(workflow_job_template, post, get, admin, organization): workflow_job_template.organization = organization workflow_job_template.save() ajts = [ WorkflowApprovalTemplate.objects.create( name='test-approval-{}'.format(i), description='description-{}'.format(i), timeout=30) for i in range(0, 5) ] nodes = [ WorkflowJobTemplateNode.objects.create( workflow_job_template=workflow_job_template, unified_job_template=ajts[i]) for i in range(0, 5) ] nodes[0].success_nodes.add(nodes[1]) nodes[1].success_nodes.add(nodes[2]) nodes[0].failure_nodes.add(nodes[3]) nodes[3].failure_nodes.add(nodes[4]) assert WorkflowJobTemplate.objects.count() == 1 assert WorkflowJobTemplateNode.objects.count() == 5 assert WorkflowApprovalTemplate.objects.count() == 5 with mock.patch( 'awx.api.generics.trigger_delayed_deep_copy') as deep_copy_mock: wfjt_copy_id = post(reverse('api:workflow_job_template_copy', kwargs={'pk': workflow_job_template.pk}), { 'name': 'new wfjt name' }, admin, expect=201).data['id'] wfjt_copy = type(workflow_job_template).objects.get(pk=wfjt_copy_id) args, kwargs = deep_copy_mock.call_args deep_copy_model_obj(*args, **kwargs) assert wfjt_copy.organization == organization assert wfjt_copy.created_by == admin assert wfjt_copy.name == 'new wfjt name' assert WorkflowJobTemplate.objects.count() == 2 assert WorkflowJobTemplateNode.objects.count() == 10 assert WorkflowApprovalTemplate.objects.count() == 10 original_templates = [ x.unified_job_template for x in workflow_job_template.workflow_job_template_nodes.all() ] copied_templates = [ x.unified_job_template for x in wfjt_copy.workflow_job_template_nodes.all() ] # make sure shallow fields like `timeout` are copied properly for i, t in enumerate(original_templates): assert t.timeout == 30 assert t.description == 'description-{}'.format(i) for i, t in enumerate(copied_templates): assert t.timeout == 30 assert t.description == 'description-{}'.format(i) # the Approval Template IDs on the *original* WFJT should not match *any* # of the Approval Template IDs on the *copied* WFJT assert not set([x.id for x in original_templates]).intersection( set([x.id for x in copied_templates])) # if you remove the " copy" suffix from the copied template names, they # should match the original templates assert set([x.name for x in original_templates]) == set( [x.name.replace(' copy', '') for x in copied_templates])