mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Rewrote test for DeviceType import
This commit is contained in:
@ -1212,7 +1212,6 @@ class ComponentTemplateImportForm(BootstrapMixin, forms.ModelForm):
|
|||||||
data.update({
|
data.update({
|
||||||
'device_type': device_type.pk,
|
'device_type': device_type.pk,
|
||||||
})
|
})
|
||||||
print(data)
|
|
||||||
|
|
||||||
super().__init__(data, *args, **kwargs)
|
super().__init__(data, *args, **kwargs)
|
||||||
|
|
||||||
@ -1279,7 +1278,7 @@ class InterfaceTemplateImportForm(ComponentTemplateImportForm):
|
|||||||
|
|
||||||
|
|
||||||
class FrontPortTemplateImportForm(ComponentTemplateImportForm):
|
class FrontPortTemplateImportForm(ComponentTemplateImportForm):
|
||||||
power_port = forms.ModelChoiceField(
|
rear_port = forms.ModelChoiceField(
|
||||||
queryset=RearPortTemplate.objects.all(),
|
queryset=RearPortTemplate.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
required=False
|
required=False
|
||||||
|
@ -8,110 +8,6 @@ def get_id(model, slug):
|
|||||||
return model.objects.get(slug=slug).id
|
return model.objects.get(slug=slug).id
|
||||||
|
|
||||||
|
|
||||||
DEVICETYPE_DATA = {
|
|
||||||
'manufacturer': 'Generic',
|
|
||||||
'model': 'TEST-1000',
|
|
||||||
'slug': 'test-1000',
|
|
||||||
'u_height': 2,
|
|
||||||
'console-ports': [
|
|
||||||
{'name': 'Console Port 1'},
|
|
||||||
{'name': 'Console Port 2'},
|
|
||||||
{'name': 'Console Port 3'},
|
|
||||||
],
|
|
||||||
'console-server-ports': [
|
|
||||||
{'name': 'Console Server Port 1'},
|
|
||||||
{'name': 'Console Server Port 2'},
|
|
||||||
{'name': 'Console Server Port 3'},
|
|
||||||
],
|
|
||||||
'power-ports': [
|
|
||||||
{'name': 'Power Port 1'},
|
|
||||||
{'name': 'Power Port 2'},
|
|
||||||
{'name': 'Power Port 3'},
|
|
||||||
],
|
|
||||||
'power-outlets': [
|
|
||||||
{'name': 'Power Outlet 1', 'power_port': 'Power Port 1', 'feed_leg': POWERFEED_LEG_A},
|
|
||||||
{'name': 'Power Outlet 2', 'power_port': 'Power Port 1', 'feed_leg': POWERFEED_LEG_A},
|
|
||||||
{'name': 'Power Outlet 3', 'power_port': 'Power Port 1', 'feed_leg': POWERFEED_LEG_A},
|
|
||||||
],
|
|
||||||
'interfaces': [
|
|
||||||
{'name': 'Interface 1', 'type': IFACE_TYPE_1GE_FIXED, 'mgmt_only': True},
|
|
||||||
{'name': 'Interface 2', 'type': IFACE_TYPE_1GE_FIXED},
|
|
||||||
{'name': 'Interface 3', 'type': IFACE_TYPE_1GE_FIXED},
|
|
||||||
],
|
|
||||||
'rear-ports': [
|
|
||||||
{'name': 'Rear Port 1', 'type': PORT_TYPE_8P8C},
|
|
||||||
{'name': 'Rear Port 2', 'type': PORT_TYPE_8P8C},
|
|
||||||
{'name': 'Rear Port 3', 'type': PORT_TYPE_8P8C},
|
|
||||||
],
|
|
||||||
'front-ports': [
|
|
||||||
{'name': 'Front Port 1', 'type': PORT_TYPE_8P8C, 'rear_port': 'Rear Port 1'},
|
|
||||||
{'name': 'Front Port 2', 'type': PORT_TYPE_8P8C, 'rear_port': 'Rear Port 2'},
|
|
||||||
{'name': 'Front Port 3', 'type': PORT_TYPE_8P8C, 'rear_port': 'Rear Port 3'},
|
|
||||||
],
|
|
||||||
'device-bays': [
|
|
||||||
{'name': 'Device Bay 1'},
|
|
||||||
{'name': 'Device Bay 2'},
|
|
||||||
{'name': 'Device Bay 3'},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceTypeImportTestCase(TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
|
|
||||||
Manufacturer(name='Generic', slug='generic').save()
|
|
||||||
|
|
||||||
def test_import_devicetype_yaml(self):
|
|
||||||
|
|
||||||
form = DeviceTypeImportForm(DEVICETYPE_DATA)
|
|
||||||
|
|
||||||
self.assertTrue(form.is_valid(), "Form validation failed: {}".format(form.errors))
|
|
||||||
|
|
||||||
form.save()
|
|
||||||
dt = DeviceType.objects.get(model='TEST-1000')
|
|
||||||
|
|
||||||
# Verify all of the components were created
|
|
||||||
# TODO: The creation of components now occurs in the view rather than the form
|
|
||||||
self.assertEqual(dt.consoleport_templates.count(), 3)
|
|
||||||
cp1 = ConsolePortTemplate.objects.first()
|
|
||||||
self.assertEqual(cp1.name, 'Console Port 1')
|
|
||||||
|
|
||||||
self.assertEqual(dt.consoleserverport_templates.count(), 3)
|
|
||||||
csp1 = ConsoleServerPortTemplate.objects.first()
|
|
||||||
self.assertEqual(csp1.name, 'Console Server Port 1')
|
|
||||||
|
|
||||||
self.assertEqual(dt.powerport_templates.count(), 3)
|
|
||||||
pp1 = PowerPortTemplate.objects.first()
|
|
||||||
self.assertEqual(pp1.name, 'Power Port 1')
|
|
||||||
|
|
||||||
self.assertEqual(dt.poweroutlet_templates.count(), 3)
|
|
||||||
po1 = PowerOutletTemplate.objects.first()
|
|
||||||
self.assertEqual(po1.name, 'Power Outlet 1')
|
|
||||||
self.assertEqual(po1.power_port, pp1)
|
|
||||||
self.assertEqual(po1.feed_leg, POWERFEED_LEG_A)
|
|
||||||
|
|
||||||
self.assertEqual(dt.interface_templates.count(), 4)
|
|
||||||
iface1 = Interface.objects.first()
|
|
||||||
self.assertEqual(iface1.name, 'Interface 1')
|
|
||||||
self.assertEqual(iface1.type, IFACE_TYPE_1GE_FIXED)
|
|
||||||
self.assertTrue(iface1.mgmt_only)
|
|
||||||
|
|
||||||
self.assertEqual(dt.rearport_templates.count(), 3)
|
|
||||||
rp1 = RearPortTemplate.objects.first()
|
|
||||||
self.assertEqual(rp1.name, 'Rear Port 1')
|
|
||||||
|
|
||||||
self.assertEqual(dt.frontport_templates.count(), 3)
|
|
||||||
fp1 = FrontPortTemplate.objects.first()
|
|
||||||
self.assertEqual(fp1.name, 'Front Port 1')
|
|
||||||
self.assertEqual(fp1.rear_port, rp1)
|
|
||||||
self.assertEqual(fp1.rear_port_position, 1)
|
|
||||||
|
|
||||||
self.assertEqual(dt.devicebay_templates.count(), 3)
|
|
||||||
db1 = DeviceBayTemplate.objects.first()
|
|
||||||
self.assertEqual(db1.name, 'Device Bay 1')
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceTestCase(TestCase):
|
class DeviceTestCase(TestCase):
|
||||||
|
|
||||||
fixtures = ['dcim', 'ipam']
|
fixtures = ['dcim', 'ipam']
|
||||||
|
@ -3,10 +3,11 @@ import urllib.parse
|
|||||||
from django.test import Client, TestCase
|
from django.test import Client, TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from dcim.constants import CABLE_TYPE_CAT6, IFACE_TYPE_1GE_FIXED
|
from dcim.constants import *
|
||||||
from dcim.models import (
|
from dcim.models import (
|
||||||
Cable, Device, DeviceRole, DeviceType, Interface, InventoryItem, Manufacturer, Platform, Rack, RackGroup,
|
Cable, ConsolePortTemplate, ConsoleServerPortTemplate, Device, DeviceBayTemplate, DeviceRole, DeviceType,
|
||||||
RackReservation, RackRole, Site, Region, VirtualChassis,
|
FrontPortTemplate, Interface, InterfaceTemplate, InventoryItem, Manufacturer, Platform, PowerPortTemplate,
|
||||||
|
PowerOutletTemplate, Rack, RackGroup, RackReservation, RackRole, RearPortTemplate, Site, Region, VirtualChassis,
|
||||||
)
|
)
|
||||||
from utilities.testing import create_test_user
|
from utilities.testing import create_test_user
|
||||||
|
|
||||||
@ -221,6 +222,132 @@ class DeviceTypeTestCase(TestCase):
|
|||||||
response = self.client.get(devicetype.get_absolute_url())
|
response = self.client.get(devicetype.get_absolute_url())
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
def test_devicetype_import(self):
|
||||||
|
|
||||||
|
IMPORT_DATA = """
|
||||||
|
manufacturer: Generic
|
||||||
|
model: TEST-1000
|
||||||
|
slug: test-1000
|
||||||
|
u_height: 2
|
||||||
|
console-ports:
|
||||||
|
- name: Console Port 1
|
||||||
|
- name: Console Port 2
|
||||||
|
- name: Console Port 3
|
||||||
|
console-server-ports:
|
||||||
|
- name: Console Server Port 1
|
||||||
|
- name: Console Server Port 2
|
||||||
|
- name: Console Server Port 3
|
||||||
|
power-ports:
|
||||||
|
- name: Power Port 1
|
||||||
|
- name: Power Port 2
|
||||||
|
- name: Power Port 3
|
||||||
|
power-outlets:
|
||||||
|
- name: Power Outlet 1
|
||||||
|
power_port: Power Port 1
|
||||||
|
feed_leg: 1
|
||||||
|
- name: Power Outlet 2
|
||||||
|
power_port: Power Port 1
|
||||||
|
feed_leg: 1
|
||||||
|
- name: Power Outlet 3
|
||||||
|
power_port: Power Port 1
|
||||||
|
feed_leg: 1
|
||||||
|
interfaces:
|
||||||
|
- name: Interface 1
|
||||||
|
type: 1000
|
||||||
|
mgmt_only: true
|
||||||
|
- name: Interface 2
|
||||||
|
type: 1000
|
||||||
|
- name: Interface 3
|
||||||
|
type: 1000
|
||||||
|
rear-ports:
|
||||||
|
- name: Rear Port 1
|
||||||
|
type: 1000
|
||||||
|
- name: Rear Port 2
|
||||||
|
type: 1000
|
||||||
|
- name: Rear Port 3
|
||||||
|
type: 1000
|
||||||
|
front-ports:
|
||||||
|
- name: Front Port 1
|
||||||
|
type: 1000
|
||||||
|
rear_port: Rear Port 1
|
||||||
|
- name: Front Port 2
|
||||||
|
type: 1000
|
||||||
|
rear_port: Rear Port 2
|
||||||
|
- name: Front Port 3
|
||||||
|
type: 1000
|
||||||
|
rear_port: Rear Port 3
|
||||||
|
device-bays:
|
||||||
|
- name: Device Bay 1
|
||||||
|
- name: Device Bay 2
|
||||||
|
- name: Device Bay 3
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Create the manufacturer
|
||||||
|
Manufacturer(name='Generic', slug='generic').save()
|
||||||
|
|
||||||
|
# Authenticate as user with necessary permissions
|
||||||
|
user = create_test_user(username='testuser2', permissions=[
|
||||||
|
'dcim.view_devicetype',
|
||||||
|
'dcim.add_devicetype',
|
||||||
|
'dcim.add_consoleporttemplate',
|
||||||
|
'dcim.add_consoleserverporttemplate',
|
||||||
|
'dcim.add_powerporttemplate',
|
||||||
|
'dcim.add_poweroutlettemplate',
|
||||||
|
'dcim.add_interfacetemplate',
|
||||||
|
'dcim.add_frontporttemplate',
|
||||||
|
'dcim.add_rearporttemplate',
|
||||||
|
'dcim.add_devicebaytemplate',
|
||||||
|
])
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
|
form_data = {
|
||||||
|
'data': IMPORT_DATA,
|
||||||
|
'format': 'yaml'
|
||||||
|
}
|
||||||
|
response = self.client.post(reverse('dcim:devicetype_import'), data=form_data, follow=True)
|
||||||
|
|
||||||
|
dt = DeviceType.objects.get(model='TEST-1000')
|
||||||
|
|
||||||
|
# Verify all of the components were created
|
||||||
|
self.assertEqual(dt.consoleport_templates.count(), 3)
|
||||||
|
cp1 = ConsolePortTemplate.objects.first()
|
||||||
|
self.assertEqual(cp1.name, 'Console Port 1')
|
||||||
|
|
||||||
|
self.assertEqual(dt.consoleserverport_templates.count(), 3)
|
||||||
|
csp1 = ConsoleServerPortTemplate.objects.first()
|
||||||
|
self.assertEqual(csp1.name, 'Console Server Port 1')
|
||||||
|
|
||||||
|
self.assertEqual(dt.powerport_templates.count(), 3)
|
||||||
|
pp1 = PowerPortTemplate.objects.first()
|
||||||
|
self.assertEqual(pp1.name, 'Power Port 1')
|
||||||
|
|
||||||
|
self.assertEqual(dt.poweroutlet_templates.count(), 3)
|
||||||
|
po1 = PowerOutletTemplate.objects.first()
|
||||||
|
self.assertEqual(po1.name, 'Power Outlet 1')
|
||||||
|
self.assertEqual(po1.power_port, pp1)
|
||||||
|
self.assertEqual(po1.feed_leg, POWERFEED_LEG_A)
|
||||||
|
|
||||||
|
self.assertEqual(dt.interface_templates.count(), 3)
|
||||||
|
iface1 = InterfaceTemplate.objects.first()
|
||||||
|
self.assertEqual(iface1.name, 'Interface 1')
|
||||||
|
self.assertEqual(iface1.type, IFACE_TYPE_1GE_FIXED)
|
||||||
|
self.assertTrue(iface1.mgmt_only)
|
||||||
|
|
||||||
|
self.assertEqual(dt.rearport_templates.count(), 3)
|
||||||
|
rp1 = RearPortTemplate.objects.first()
|
||||||
|
self.assertEqual(rp1.name, 'Rear Port 1')
|
||||||
|
|
||||||
|
self.assertEqual(dt.frontport_templates.count(), 3)
|
||||||
|
fp1 = FrontPortTemplate.objects.first()
|
||||||
|
self.assertEqual(fp1.name, 'Front Port 1')
|
||||||
|
self.assertEqual(fp1.rear_port, rp1)
|
||||||
|
self.assertEqual(fp1.rear_port_position, 1)
|
||||||
|
|
||||||
|
self.assertEqual(dt.device_bay_templates.count(), 3)
|
||||||
|
db1 = DeviceBayTemplate.objects.first()
|
||||||
|
self.assertEqual(db1.name, 'Device Bay 1')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceRoleTestCase(TestCase):
|
class DeviceRoleTestCase(TestCase):
|
||||||
|
|
||||||
|
@ -445,18 +445,23 @@ class ObjectImportView(GetReturnURLMixin, View):
|
|||||||
obj = model_form.save()
|
obj = model_form.save()
|
||||||
|
|
||||||
# Iterate through the related object forms (if any), validating and saving each instance.
|
# Iterate through the related object forms (if any), validating and saving each instance.
|
||||||
for field, related_object_form in self.related_object_forms.items():
|
for field_name, related_object_form in self.related_object_forms.items():
|
||||||
|
|
||||||
for i, rel_obj_data in enumerate(data.get(field, list())):
|
for i, rel_obj_data in enumerate(data.get(field_name, list())):
|
||||||
|
|
||||||
f = related_object_form(obj, rel_obj_data)
|
f = related_object_form(obj, rel_obj_data)
|
||||||
|
|
||||||
|
for subfield_name, field in f.fields.items():
|
||||||
|
if subfield_name not in rel_obj_data and hasattr(field, 'initial'):
|
||||||
|
f.data[subfield_name] = field.initial
|
||||||
|
|
||||||
if f.is_valid():
|
if f.is_valid():
|
||||||
f.save()
|
f.save()
|
||||||
else:
|
else:
|
||||||
# Replicate errors on the related object form to the primary form for display
|
# Replicate errors on the related object form to the primary form for display
|
||||||
for field_name, errors in f.errors.items():
|
for subfield_name, errors in f.errors.items():
|
||||||
for err in errors:
|
for err in errors:
|
||||||
err_msg = "{}[{}] {}: {}".format(field, i, field_name, err)
|
err_msg = "{}[{}] {}: {}".format(field_name, i, subfield_name, err)
|
||||||
model_form.add_error(None, err_msg)
|
model_form.add_error(None, err_msg)
|
||||||
raise AbortTransaction()
|
raise AbortTransaction()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user