|
@@ -19,7 +19,13 @@ from dcim.constants import *
|
|
|
from dcim.models import *
|
|
from dcim.models import *
|
|
|
from extras.models import ConfigTemplate
|
|
from extras.models import ConfigTemplate
|
|
|
from ipam.models import ASN, RIR, VLAN, VRF
|
|
from ipam.models import ASN, RIR, VLAN, VRF
|
|
|
-from netbox.choices import CSVDelimiterChoices, ImportFormatChoices, WeightUnitChoices
|
|
|
|
|
|
|
+from netbox.choices import (
|
|
|
|
|
+ CSVDelimiterChoices,
|
|
|
|
|
+ DiameterUnitChoices,
|
|
|
|
|
+ FlowRateUnitChoices,
|
|
|
|
|
+ ImportFormatChoices,
|
|
|
|
|
+ WeightUnitChoices,
|
|
|
|
|
+)
|
|
|
from tenancy.models import Tenant
|
|
from tenancy.models import Tenant
|
|
|
from users.models import ObjectPermission, User
|
|
from users.models import ObjectPermission, User
|
|
|
from utilities.testing import ViewTestCases, create_tags, create_test_device, post_data
|
|
from utilities.testing import ViewTestCases, create_tags, create_test_device, post_data
|
|
@@ -930,6 +936,36 @@ power-outlets:
|
|
|
type: iec-60320-c13
|
|
type: iec-60320-c13
|
|
|
power_port: Power Port 1
|
|
power_port: Power Port 1
|
|
|
feed_leg: A
|
|
feed_leg: A
|
|
|
|
|
+cooling-intakes:
|
|
|
|
|
+ - name: Cooling Intake 1
|
|
|
|
|
+ type: uqd
|
|
|
|
|
+ diameter: 1
|
|
|
|
|
+ diameter_unit: in
|
|
|
|
|
+ max_flow: 100
|
|
|
|
|
+ max_flow_unit: lpm
|
|
|
|
|
+ - name: Cooling Intake 2
|
|
|
|
|
+ type: uqd
|
|
|
|
|
+ diameter: 1
|
|
|
|
|
+ diameter_unit: in
|
|
|
|
|
+ - name: Cooling Intake 3
|
|
|
|
|
+ type: uqd
|
|
|
|
|
+ diameter: 1
|
|
|
|
|
+ diameter_unit: in
|
|
|
|
|
+cooling-outflows:
|
|
|
|
|
+ - name: Cooling Outflow 1
|
|
|
|
|
+ type: uqdb
|
|
|
|
|
+ diameter: 25
|
|
|
|
|
+ diameter_unit: mm
|
|
|
|
|
+ cooling_intake: Cooling Intake 1
|
|
|
|
|
+ - name: Cooling Outflow 2
|
|
|
|
|
+ type: uqdb
|
|
|
|
|
+ diameter: 25
|
|
|
|
|
+ diameter_unit: mm
|
|
|
|
|
+ cooling_intake: Cooling Intake 1
|
|
|
|
|
+ - name: Cooling Outflow 3
|
|
|
|
|
+ type: uqdb
|
|
|
|
|
+ diameter: 25
|
|
|
|
|
+ diameter_unit: mm
|
|
|
interfaces:
|
|
interfaces:
|
|
|
- name: Interface 1
|
|
- name: Interface 1
|
|
|
type: 1000base-t
|
|
type: 1000base-t
|
|
@@ -991,6 +1027,8 @@ inventory-items:
|
|
|
'dcim.add_consoleserverporttemplate',
|
|
'dcim.add_consoleserverporttemplate',
|
|
|
'dcim.add_powerporttemplate',
|
|
'dcim.add_powerporttemplate',
|
|
|
'dcim.add_poweroutlettemplate',
|
|
'dcim.add_poweroutlettemplate',
|
|
|
|
|
+ 'dcim.add_coolingintaketemplate',
|
|
|
|
|
+ 'dcim.add_coolingoutflowtemplate',
|
|
|
'dcim.add_interfacetemplate',
|
|
'dcim.add_interfacetemplate',
|
|
|
'dcim.add_frontporttemplate',
|
|
'dcim.add_frontporttemplate',
|
|
|
'dcim.add_rearporttemplate',
|
|
'dcim.add_rearporttemplate',
|
|
@@ -1041,6 +1079,26 @@ inventory-items:
|
|
|
self.assertEqual(po1.power_port, pp1)
|
|
self.assertEqual(po1.power_port, pp1)
|
|
|
self.assertEqual(po1.feed_leg, PowerOutletFeedLegChoices.FEED_LEG_A)
|
|
self.assertEqual(po1.feed_leg, PowerOutletFeedLegChoices.FEED_LEG_A)
|
|
|
|
|
|
|
|
|
|
+ self.assertEqual(device_type.coolingintaketemplates.count(), 3)
|
|
|
|
|
+ ci1 = CoolingIntakeTemplate.objects.first()
|
|
|
|
|
+ self.assertEqual(ci1.name, 'Cooling Intake 1')
|
|
|
|
|
+ self.assertEqual(ci1.type, CoolingConnectorTypeChoices.TYPE_UQD)
|
|
|
|
|
+ self.assertEqual(ci1.diameter, 1)
|
|
|
|
|
+ self.assertEqual(ci1.diameter_unit, DiameterUnitChoices.UNIT_INCH)
|
|
|
|
|
+ self.assertEqual(ci1.max_flow, 100)
|
|
|
|
|
+ self.assertEqual(ci1.max_flow_unit, FlowRateUnitChoices.UNIT_LITERS_PER_MINUTE)
|
|
|
|
|
+ # The normalized columns are populated on import
|
|
|
|
|
+ self.assertEqual(ci1._abs_diameter, Decimal('25.4'))
|
|
|
|
|
+ self.assertEqual(ci1._abs_max_flow, Decimal('100'))
|
|
|
|
|
+
|
|
|
|
|
+ self.assertEqual(device_type.coolingoutflowtemplates.count(), 3)
|
|
|
|
|
+ co1 = CoolingOutflowTemplate.objects.first()
|
|
|
|
|
+ self.assertEqual(co1.name, 'Cooling Outflow 1')
|
|
|
|
|
+ self.assertEqual(co1.type, CoolingConnectorTypeChoices.TYPE_UQDB)
|
|
|
|
|
+ self.assertEqual(co1.diameter, 25)
|
|
|
|
|
+ self.assertEqual(co1.diameter_unit, DiameterUnitChoices.UNIT_MILLIMETER)
|
|
|
|
|
+ self.assertEqual(co1.cooling_intake, ci1)
|
|
|
|
|
+
|
|
|
self.assertEqual(device_type.interfacetemplates.count(), 3)
|
|
self.assertEqual(device_type.interfacetemplates.count(), 3)
|
|
|
iface1 = InterfaceTemplate.objects.first()
|
|
iface1 = InterfaceTemplate.objects.first()
|
|
|
self.assertEqual(iface1.name, 'Interface 1')
|
|
self.assertEqual(iface1.name, 'Interface 1')
|
|
@@ -1087,6 +1145,8 @@ inventory-items:
|
|
|
'dcim.add_consoleserverporttemplate',
|
|
'dcim.add_consoleserverporttemplate',
|
|
|
'dcim.add_powerporttemplate',
|
|
'dcim.add_powerporttemplate',
|
|
|
'dcim.add_poweroutlettemplate',
|
|
'dcim.add_poweroutlettemplate',
|
|
|
|
|
+ 'dcim.add_coolingintaketemplate',
|
|
|
|
|
+ 'dcim.add_coolingoutflowtemplate',
|
|
|
'dcim.add_interfacetemplate',
|
|
'dcim.add_interfacetemplate',
|
|
|
'dcim.add_frontporttemplate',
|
|
'dcim.add_frontporttemplate',
|
|
|
'dcim.add_rearporttemplate',
|
|
'dcim.add_rearporttemplate',
|
|
@@ -1139,6 +1199,8 @@ module-bays:
|
|
|
'dcim.add_consoleserverporttemplate',
|
|
'dcim.add_consoleserverporttemplate',
|
|
|
'dcim.add_powerporttemplate',
|
|
'dcim.add_powerporttemplate',
|
|
|
'dcim.add_poweroutlettemplate',
|
|
'dcim.add_poweroutlettemplate',
|
|
|
|
|
+ 'dcim.add_coolingintaketemplate',
|
|
|
|
|
+ 'dcim.add_coolingoutflowtemplate',
|
|
|
'dcim.add_interfacetemplate',
|
|
'dcim.add_interfacetemplate',
|
|
|
'dcim.add_frontporttemplate',
|
|
'dcim.add_frontporttemplate',
|
|
|
'dcim.add_rearporttemplate',
|
|
'dcim.add_rearporttemplate',
|
|
@@ -1175,6 +1237,8 @@ console-ports: {value}
|
|
|
'dcim.add_consoleserverporttemplate',
|
|
'dcim.add_consoleserverporttemplate',
|
|
|
'dcim.add_powerporttemplate',
|
|
'dcim.add_powerporttemplate',
|
|
|
'dcim.add_poweroutlettemplate',
|
|
'dcim.add_poweroutlettemplate',
|
|
|
|
|
+ 'dcim.add_coolingintaketemplate',
|
|
|
|
|
+ 'dcim.add_coolingoutflowtemplate',
|
|
|
'dcim.add_interfacetemplate',
|
|
'dcim.add_interfacetemplate',
|
|
|
'dcim.add_frontporttemplate',
|
|
'dcim.add_frontporttemplate',
|
|
|
'dcim.add_rearporttemplate',
|
|
'dcim.add_rearporttemplate',
|
|
@@ -1299,6 +1363,8 @@ class ModuleTypeTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
'dcim.add_consoleserverporttemplate',
|
|
'dcim.add_consoleserverporttemplate',
|
|
|
'dcim.add_powerporttemplate',
|
|
'dcim.add_powerporttemplate',
|
|
|
'dcim.add_poweroutlettemplate',
|
|
'dcim.add_poweroutlettemplate',
|
|
|
|
|
+ 'dcim.add_coolingintaketemplate',
|
|
|
|
|
+ 'dcim.add_coolingoutflowtemplate',
|
|
|
'dcim.add_interfacetemplate',
|
|
'dcim.add_interfacetemplate',
|
|
|
'dcim.add_frontporttemplate',
|
|
'dcim.add_frontporttemplate',
|
|
|
'dcim.add_rearporttemplate',
|
|
'dcim.add_rearporttemplate',
|
|
@@ -1315,6 +1381,8 @@ class ModuleTypeTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
'dcim.add_consoleserverporttemplate',
|
|
'dcim.add_consoleserverporttemplate',
|
|
|
'dcim.add_powerporttemplate',
|
|
'dcim.add_powerporttemplate',
|
|
|
'dcim.add_poweroutlettemplate',
|
|
'dcim.add_poweroutlettemplate',
|
|
|
|
|
+ 'dcim.add_coolingintaketemplate',
|
|
|
|
|
+ 'dcim.add_coolingoutflowtemplate',
|
|
|
'dcim.add_interfacetemplate',
|
|
'dcim.add_interfacetemplate',
|
|
|
'dcim.add_frontporttemplate',
|
|
'dcim.add_frontporttemplate',
|
|
|
'dcim.add_rearporttemplate',
|
|
'dcim.add_rearporttemplate',
|
|
@@ -1331,6 +1399,8 @@ class ModuleTypeTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
'dcim.add_consoleserverporttemplate',
|
|
'dcim.add_consoleserverporttemplate',
|
|
|
'dcim.add_powerporttemplate',
|
|
'dcim.add_powerporttemplate',
|
|
|
'dcim.add_poweroutlettemplate',
|
|
'dcim.add_poweroutlettemplate',
|
|
|
|
|
+ 'dcim.add_coolingintaketemplate',
|
|
|
|
|
+ 'dcim.add_coolingoutflowtemplate',
|
|
|
'dcim.add_interfacetemplate',
|
|
'dcim.add_interfacetemplate',
|
|
|
'dcim.add_frontporttemplate',
|
|
'dcim.add_frontporttemplate',
|
|
|
'dcim.add_rearporttemplate',
|
|
'dcim.add_rearporttemplate',
|
|
@@ -1352,6 +1422,8 @@ class ModuleTypeTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
'dcim.add_consoleserverporttemplate',
|
|
'dcim.add_consoleserverporttemplate',
|
|
|
'dcim.add_powerporttemplate',
|
|
'dcim.add_powerporttemplate',
|
|
|
'dcim.add_poweroutlettemplate',
|
|
'dcim.add_poweroutlettemplate',
|
|
|
|
|
+ 'dcim.add_coolingintaketemplate',
|
|
|
|
|
+ 'dcim.add_coolingoutflowtemplate',
|
|
|
'dcim.add_interfacetemplate',
|
|
'dcim.add_interfacetemplate',
|
|
|
'dcim.add_frontporttemplate',
|
|
'dcim.add_frontporttemplate',
|
|
|
'dcim.add_rearporttemplate',
|
|
'dcim.add_rearporttemplate',
|
|
@@ -1524,6 +1596,26 @@ power-outlets:
|
|
|
type: iec-60320-c13
|
|
type: iec-60320-c13
|
|
|
power_port: Power Port 1
|
|
power_port: Power Port 1
|
|
|
feed_leg: A
|
|
feed_leg: A
|
|
|
|
|
+cooling-intakes:
|
|
|
|
|
+ - name: Cooling Intake 1
|
|
|
|
|
+ type: uqd
|
|
|
|
|
+ diameter: 1
|
|
|
|
|
+ diameter_unit: in
|
|
|
|
|
+ max_flow: 6
|
|
|
|
|
+ max_flow_unit: m3ph
|
|
|
|
|
+ - name: Cooling Intake 2
|
|
|
|
|
+ type: uqd
|
|
|
|
|
+ - name: Cooling Intake 3
|
|
|
|
|
+ type: uqd
|
|
|
|
|
+cooling-outflows:
|
|
|
|
|
+ - name: Cooling Outflow 1
|
|
|
|
|
+ type: uqdb
|
|
|
|
|
+ cooling_intake: Cooling Intake 1
|
|
|
|
|
+ - name: Cooling Outflow 2
|
|
|
|
|
+ type: uqdb
|
|
|
|
|
+ cooling_intake: Cooling Intake 1
|
|
|
|
|
+ - name: Cooling Outflow 3
|
|
|
|
|
+ type: uqdb
|
|
|
interfaces:
|
|
interfaces:
|
|
|
- name: Interface 1
|
|
- name: Interface 1
|
|
|
type: 1000base-t
|
|
type: 1000base-t
|
|
@@ -1574,6 +1666,8 @@ module-bays:
|
|
|
'dcim.add_consoleserverporttemplate',
|
|
'dcim.add_consoleserverporttemplate',
|
|
|
'dcim.add_powerporttemplate',
|
|
'dcim.add_powerporttemplate',
|
|
|
'dcim.add_poweroutlettemplate',
|
|
'dcim.add_poweroutlettemplate',
|
|
|
|
|
+ 'dcim.add_coolingintaketemplate',
|
|
|
|
|
+ 'dcim.add_coolingoutflowtemplate',
|
|
|
'dcim.add_interfacetemplate',
|
|
'dcim.add_interfacetemplate',
|
|
|
'dcim.add_frontporttemplate',
|
|
'dcim.add_frontporttemplate',
|
|
|
'dcim.add_rearporttemplate',
|
|
'dcim.add_rearporttemplate',
|
|
@@ -1616,6 +1710,24 @@ module-bays:
|
|
|
self.assertEqual(po1.power_port, pp1)
|
|
self.assertEqual(po1.power_port, pp1)
|
|
|
self.assertEqual(po1.feed_leg, PowerOutletFeedLegChoices.FEED_LEG_A)
|
|
self.assertEqual(po1.feed_leg, PowerOutletFeedLegChoices.FEED_LEG_A)
|
|
|
|
|
|
|
|
|
|
+ self.assertEqual(module_type.coolingintaketemplates.count(), 3)
|
|
|
|
|
+ ci1 = CoolingIntakeTemplate.objects.first()
|
|
|
|
|
+ self.assertEqual(ci1.name, 'Cooling Intake 1')
|
|
|
|
|
+ self.assertEqual(ci1.type, CoolingConnectorTypeChoices.TYPE_UQD)
|
|
|
|
|
+ self.assertEqual(ci1.diameter, 1)
|
|
|
|
|
+ self.assertEqual(ci1.diameter_unit, DiameterUnitChoices.UNIT_INCH)
|
|
|
|
|
+ self.assertEqual(ci1.max_flow, 6)
|
|
|
|
|
+ self.assertEqual(ci1.max_flow_unit, FlowRateUnitChoices.UNIT_CUBIC_METERS_PER_HOUR)
|
|
|
|
|
+ # The normalized columns are populated on import
|
|
|
|
|
+ self.assertEqual(ci1._abs_diameter, Decimal('25.4'))
|
|
|
|
|
+ self.assertEqual(ci1._abs_max_flow, Decimal('100'))
|
|
|
|
|
+
|
|
|
|
|
+ self.assertEqual(module_type.coolingoutflowtemplates.count(), 3)
|
|
|
|
|
+ co1 = CoolingOutflowTemplate.objects.first()
|
|
|
|
|
+ self.assertEqual(co1.name, 'Cooling Outflow 1')
|
|
|
|
|
+ self.assertEqual(co1.type, CoolingConnectorTypeChoices.TYPE_UQDB)
|
|
|
|
|
+ self.assertEqual(co1.cooling_intake, ci1)
|
|
|
|
|
+
|
|
|
self.assertEqual(module_type.interfacetemplates.count(), 3)
|
|
self.assertEqual(module_type.interfacetemplates.count(), 3)
|
|
|
iface1 = InterfaceTemplate.objects.first()
|
|
iface1 = InterfaceTemplate.objects.first()
|
|
|
self.assertEqual(iface1.name, 'Interface 1')
|
|
self.assertEqual(iface1.name, 'Interface 1')
|
|
@@ -4660,6 +4772,358 @@ class PowerFeedTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
self.assertHttpStatus(response, 200)
|
|
self.assertHttpStatus(response, 200)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+class CoolingIntakeTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTestCase):
|
|
|
|
|
+ model = CoolingIntakeTemplate
|
|
|
|
|
+ validation_excluded_fields = ('name', 'label')
|
|
|
|
|
+
|
|
|
|
|
+ @classmethod
|
|
|
|
|
+ def setUpTestData(cls):
|
|
|
|
|
+ manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1')
|
|
|
|
|
+ devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1', slug='device-type-1')
|
|
|
|
|
+
|
|
|
|
|
+ CoolingIntakeTemplate.objects.bulk_create((
|
|
|
|
|
+ CoolingIntakeTemplate(device_type=devicetype, name='Cooling Port Template 1'),
|
|
|
|
|
+ CoolingIntakeTemplate(device_type=devicetype, name='Cooling Port Template 2'),
|
|
|
|
|
+ CoolingIntakeTemplate(device_type=devicetype, name='Cooling Port Template 3'),
|
|
|
|
|
+ ))
|
|
|
|
|
+
|
|
|
|
|
+ cls.form_data = {
|
|
|
|
|
+ 'device_type': devicetype.pk,
|
|
|
|
|
+ 'name': 'Cooling Port Template X',
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ 'max_flow': 100,
|
|
|
|
|
+ 'max_flow_unit': FlowRateUnitChoices.UNIT_LITERS_PER_MINUTE,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.bulk_create_data = {
|
|
|
|
|
+ 'device_type': devicetype.pk,
|
|
|
|
|
+ 'name': 'Cooling Port Template [4-6]',
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ 'max_flow': 100,
|
|
|
|
|
+ 'max_flow_unit': FlowRateUnitChoices.UNIT_LITERS_PER_MINUTE,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.bulk_edit_data = {
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ 'max_flow': 100,
|
|
|
|
|
+ 'max_flow_unit': FlowRateUnitChoices.UNIT_LITERS_PER_MINUTE,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class CoolingOutflowTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTestCase):
|
|
|
|
|
+ model = CoolingOutflowTemplate
|
|
|
|
|
+ validation_excluded_fields = ('name', 'label')
|
|
|
|
|
+
|
|
|
|
|
+ @classmethod
|
|
|
|
|
+ def setUpTestData(cls):
|
|
|
|
|
+ manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1')
|
|
|
|
|
+ devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1', slug='device-type-1')
|
|
|
|
|
+
|
|
|
|
|
+ CoolingOutflowTemplate.objects.bulk_create((
|
|
|
|
|
+ CoolingOutflowTemplate(device_type=devicetype, name='Cooling Outlet Template 1'),
|
|
|
|
|
+ CoolingOutflowTemplate(device_type=devicetype, name='Cooling Outlet Template 2'),
|
|
|
|
|
+ CoolingOutflowTemplate(device_type=devicetype, name='Cooling Outlet Template 3'),
|
|
|
|
|
+ ))
|
|
|
|
|
+
|
|
|
|
|
+ coolingintakes = (
|
|
|
|
|
+ CoolingIntakeTemplate(device_type=devicetype, name='Cooling Port Template 1'),
|
|
|
|
|
+ )
|
|
|
|
|
+ CoolingIntakeTemplate.objects.bulk_create(coolingintakes)
|
|
|
|
|
+
|
|
|
|
|
+ cls.form_data = {
|
|
|
|
|
+ 'device_type': devicetype.pk,
|
|
|
|
|
+ 'name': 'Cooling Outlet Template X',
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ 'cooling_intake': coolingintakes[0].pk,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.bulk_create_data = {
|
|
|
|
|
+ 'device_type': devicetype.pk,
|
|
|
|
|
+ 'name': 'Cooling Outlet Template [4-6]',
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ 'cooling_intake': coolingintakes[0].pk,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.bulk_edit_data = {
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class CoolingIntakeTestCase(ViewTestCases.DeviceComponentViewTestCase):
|
|
|
|
|
+ model = CoolingIntake
|
|
|
|
|
+ validation_excluded_fields = ('name', 'label')
|
|
|
|
|
+
|
|
|
|
|
+ @classmethod
|
|
|
|
|
+ def setUpTestData(cls):
|
|
|
|
|
+ device = create_test_device('Device 1')
|
|
|
|
|
+
|
|
|
|
|
+ cooling_intakes = (
|
|
|
|
|
+ CoolingIntake(device=device, name='Cooling Port 1'),
|
|
|
|
|
+ CoolingIntake(device=device, name='Cooling Port 2'),
|
|
|
|
|
+ CoolingIntake(device=device, name='Cooling Port 3'),
|
|
|
|
|
+ )
|
|
|
|
|
+ CoolingIntake.objects.bulk_create(cooling_intakes)
|
|
|
|
|
+
|
|
|
|
|
+ tags = create_tags('Alpha', 'Bravo', 'Charlie')
|
|
|
|
|
+
|
|
|
|
|
+ cls.form_data = {
|
|
|
|
|
+ 'device': device.pk,
|
|
|
|
|
+ 'name': 'Cooling Port X',
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ 'max_flow': 100,
|
|
|
|
|
+ 'max_flow_unit': FlowRateUnitChoices.UNIT_LITERS_PER_MINUTE,
|
|
|
|
|
+ 'description': 'A cooling port',
|
|
|
|
|
+ 'tags': [t.pk for t in tags],
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.bulk_create_data = {
|
|
|
|
|
+ 'device': device.pk,
|
|
|
|
|
+ 'name': 'Cooling Port [4-6]]',
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ 'max_flow': 100,
|
|
|
|
|
+ 'max_flow_unit': FlowRateUnitChoices.UNIT_LITERS_PER_MINUTE,
|
|
|
|
|
+ 'description': 'A cooling port',
|
|
|
|
|
+ 'tags': [t.pk for t in tags],
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.bulk_edit_data = {
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ 'max_flow': 100,
|
|
|
|
|
+ 'max_flow_unit': FlowRateUnitChoices.UNIT_LITERS_PER_MINUTE,
|
|
|
|
|
+ 'description': 'New description',
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.csv_data = (
|
|
|
|
|
+ "device,name",
|
|
|
|
|
+ "Device 1,Cooling Port 4",
|
|
|
|
|
+ "Device 1,Cooling Port 5",
|
|
|
|
|
+ "Device 1,Cooling Port 6",
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ cls.csv_update_data = (
|
|
|
|
|
+ "id,name,description",
|
|
|
|
|
+ f"{cooling_intakes[0].pk},Cooling Port 7,New description7",
|
|
|
|
|
+ f"{cooling_intakes[1].pk},Cooling Port 8,New description8",
|
|
|
|
|
+ f"{cooling_intakes[2].pk},Cooling Port 9,New description9",
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class CoolingOutflowTestCase(ViewTestCases.DeviceComponentViewTestCase):
|
|
|
|
|
+ model = CoolingOutflow
|
|
|
|
|
+ validation_excluded_fields = ('name', 'label')
|
|
|
|
|
+
|
|
|
|
|
+ @classmethod
|
|
|
|
|
+ def setUpTestData(cls):
|
|
|
|
|
+ device = create_test_device('Device 1')
|
|
|
|
|
+
|
|
|
|
|
+ coolingintakes = (
|
|
|
|
|
+ CoolingIntake(device=device, name='Cooling Port 1'),
|
|
|
|
|
+ CoolingIntake(device=device, name='Cooling Port 2'),
|
|
|
|
|
+ )
|
|
|
|
|
+ CoolingIntake.objects.bulk_create(coolingintakes)
|
|
|
|
|
+
|
|
|
|
|
+ cooling_outflows = (
|
|
|
|
|
+ CoolingOutflow(device=device, name='Cooling Outlet 1', cooling_intake=coolingintakes[0]),
|
|
|
|
|
+ CoolingOutflow(device=device, name='Cooling Outlet 2', cooling_intake=coolingintakes[0]),
|
|
|
|
|
+ CoolingOutflow(device=device, name='Cooling Outlet 3', cooling_intake=coolingintakes[0]),
|
|
|
|
|
+ )
|
|
|
|
|
+ CoolingOutflow.objects.bulk_create(cooling_outflows)
|
|
|
|
|
+
|
|
|
|
|
+ tags = create_tags('Alpha', 'Bravo', 'Charlie')
|
|
|
|
|
+
|
|
|
|
|
+ cls.form_data = {
|
|
|
|
|
+ 'device': device.pk,
|
|
|
|
|
+ 'name': 'Cooling Outlet X',
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ 'cooling_intake': coolingintakes[1].pk,
|
|
|
|
|
+ 'description': 'A cooling outlet',
|
|
|
|
|
+ 'tags': [t.pk for t in tags],
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.bulk_create_data = {
|
|
|
|
|
+ 'device': device.pk,
|
|
|
|
|
+ 'name': 'Cooling Outlet [4-6]',
|
|
|
|
|
+ 'type': CoolingConnectorTypeChoices.TYPE_UQD,
|
|
|
|
|
+ 'diameter': Decimal('25'),
|
|
|
|
|
+ 'diameter_unit': DiameterUnitChoices.UNIT_MILLIMETER,
|
|
|
|
|
+ 'cooling_intake': coolingintakes[1].pk,
|
|
|
|
|
+ 'description': 'A cooling outlet',
|
|
|
|
|
+ 'tags': [t.pk for t in tags],
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.bulk_edit_data = {
|
|
|
|
|
+ 'cooling_intake': coolingintakes[1].pk,
|
|
|
|
|
+ 'description': 'New description',
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.csv_data = (
|
|
|
|
|
+ "device,name",
|
|
|
|
|
+ "Device 1,Cooling Outlet 4",
|
|
|
|
|
+ "Device 1,Cooling Outlet 5",
|
|
|
|
|
+ "Device 1,Cooling Outlet 6",
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ cls.csv_update_data = (
|
|
|
|
|
+ "id,name,description",
|
|
|
|
|
+ f"{cooling_outflows[0].pk},Cooling Outlet 7,New description7",
|
|
|
|
|
+ f"{cooling_outflows[1].pk},Cooling Outlet 8,New description8",
|
|
|
|
|
+ f"{cooling_outflows[2].pk},Cooling Outlet 9,New description9",
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class CoolingSourceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
|
|
+ model = CoolingSource
|
|
|
|
|
+
|
|
|
|
|
+ @classmethod
|
|
|
|
|
+ def setUpTestData(cls):
|
|
|
|
|
+
|
|
|
|
|
+ sites = (
|
|
|
|
|
+ Site(name='Site 1', slug='site-1'),
|
|
|
|
|
+ Site(name='Site 2', slug='site-2'),
|
|
|
|
|
+ )
|
|
|
|
|
+ Site.objects.bulk_create(sites)
|
|
|
|
|
+
|
|
|
|
|
+ locations = (
|
|
|
|
|
+ Location(name='Location 1', slug='location-1', site=sites[0]),
|
|
|
|
|
+ Location(name='Location 2', slug='location-2', site=sites[1]),
|
|
|
|
|
+ )
|
|
|
|
|
+ for location in locations:
|
|
|
|
|
+ location.save()
|
|
|
|
|
+
|
|
|
|
|
+ cooling_sources = (
|
|
|
|
|
+ CoolingSource(
|
|
|
|
|
+ site=sites[0], location=locations[0], name='Cooling Source 1',
|
|
|
|
|
+ type=CoolingSourceTypeChoices.TYPE_CHILLER
|
|
|
|
|
+ ),
|
|
|
|
|
+ CoolingSource(
|
|
|
|
|
+ site=sites[0], location=locations[0], name='Cooling Source 2',
|
|
|
|
|
+ type=CoolingSourceTypeChoices.TYPE_CHILLER
|
|
|
|
|
+ ),
|
|
|
|
|
+ CoolingSource(
|
|
|
|
|
+ site=sites[0], location=locations[0], name='Cooling Source 3',
|
|
|
|
|
+ type=CoolingSourceTypeChoices.TYPE_CHILLER
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+ CoolingSource.objects.bulk_create(cooling_sources)
|
|
|
|
|
+
|
|
|
|
|
+ tags = create_tags('Alpha', 'Bravo', 'Charlie')
|
|
|
|
|
+
|
|
|
|
|
+ cls.form_data = {
|
|
|
|
|
+ 'site': sites[1].pk,
|
|
|
|
|
+ 'location': locations[1].pk,
|
|
|
|
|
+ 'name': 'Cooling Source X',
|
|
|
|
|
+ 'type': CoolingSourceTypeChoices.TYPE_COOLING_TOWER,
|
|
|
|
|
+ 'status': CoolingSourceStatusChoices.STATUS_ACTIVE,
|
|
|
|
|
+ 'fluid_type': FluidTypeChoices.FLUID_WATER,
|
|
|
|
|
+ 'tags': [t.pk for t in tags],
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.csv_data = (
|
|
|
|
|
+ "site,location,name,type,status",
|
|
|
|
|
+ "Site 1,Location 1,Cooling Source 4,chiller,active",
|
|
|
|
|
+ "Site 1,Location 1,Cooling Source 5,chiller,active",
|
|
|
|
|
+ "Site 1,Location 1,Cooling Source 6,chiller,active",
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ cls.csv_update_data = (
|
|
|
|
|
+ "id,name",
|
|
|
|
|
+ f"{cooling_sources[0].pk},Cooling Source 7",
|
|
|
|
|
+ f"{cooling_sources[1].pk},Cooling Source 8",
|
|
|
|
|
+ f"{cooling_sources[2].pk},Cooling Source 9",
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ cls.bulk_edit_data = {
|
|
|
|
|
+ 'site': sites[1].pk,
|
|
|
|
|
+ 'location': locations[1].pk,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class CoolingFeedTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
|
|
+ model = CoolingFeed
|
|
|
|
|
+
|
|
|
|
|
+ @classmethod
|
|
|
|
|
+ def setUpTestData(cls):
|
|
|
|
|
+
|
|
|
|
|
+ site = Site.objects.create(name='Site 1', slug='site-1')
|
|
|
|
|
+
|
|
|
|
|
+ cooling_sources = (
|
|
|
|
|
+ CoolingSource(site=site, name='Cooling Source 1', type=CoolingSourceTypeChoices.TYPE_CHILLER),
|
|
|
|
|
+ CoolingSource(site=site, name='Cooling Source 2', type=CoolingSourceTypeChoices.TYPE_CHILLER),
|
|
|
|
|
+ )
|
|
|
|
|
+ CoolingSource.objects.bulk_create(cooling_sources)
|
|
|
|
|
+
|
|
|
|
|
+ racks = (
|
|
|
|
|
+ Rack(site=site, name='Rack 1'),
|
|
|
|
|
+ Rack(site=site, name='Rack 2'),
|
|
|
|
|
+ )
|
|
|
|
|
+ Rack.objects.bulk_create(racks)
|
|
|
|
|
+
|
|
|
|
|
+ cooling_feeds = (
|
|
|
|
|
+ CoolingFeed(name='Cooling Feed 1', cooling_source=cooling_sources[0], rack=racks[0]),
|
|
|
|
|
+ CoolingFeed(name='Cooling Feed 2', cooling_source=cooling_sources[0], rack=racks[0]),
|
|
|
|
|
+ CoolingFeed(name='Cooling Feed 3', cooling_source=cooling_sources[0], rack=racks[0]),
|
|
|
|
|
+ )
|
|
|
|
|
+ CoolingFeed.objects.bulk_create(cooling_feeds)
|
|
|
|
|
+
|
|
|
|
|
+ tags = create_tags('Alpha', 'Bravo', 'Charlie')
|
|
|
|
|
+
|
|
|
|
|
+ cls.form_data = {
|
|
|
|
|
+ 'name': 'Cooling Feed X',
|
|
|
|
|
+ 'cooling_source': cooling_sources[1].pk,
|
|
|
|
|
+ 'rack': racks[1].pk,
|
|
|
|
|
+ 'status': CoolingFeedStatusChoices.STATUS_PLANNED,
|
|
|
|
|
+ 'cooling_capacity': 100,
|
|
|
|
|
+ 'max_flow': 50,
|
|
|
|
|
+ 'max_flow_unit': FlowRateUnitChoices.UNIT_LITERS_PER_MINUTE,
|
|
|
|
|
+ 'comments': 'New comments',
|
|
|
|
|
+ 'tags': [t.pk for t in tags],
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cls.csv_data = (
|
|
|
|
|
+ "site,cooling_source,name,status",
|
|
|
|
|
+ "Site 1,Cooling Source 1,Cooling Feed 4,active",
|
|
|
|
|
+ "Site 1,Cooling Source 1,Cooling Feed 5,active",
|
|
|
|
|
+ "Site 1,Cooling Source 1,Cooling Feed 6,active",
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ cls.csv_update_data = (
|
|
|
|
|
+ "id,name,status",
|
|
|
|
|
+ f"{cooling_feeds[0].pk},Cooling Feed 7,{CoolingFeedStatusChoices.STATUS_PLANNED}",
|
|
|
|
|
+ f"{cooling_feeds[1].pk},Cooling Feed 8,{CoolingFeedStatusChoices.STATUS_PLANNED}",
|
|
|
|
|
+ f"{cooling_feeds[2].pk},Cooling Feed 9,{CoolingFeedStatusChoices.STATUS_PLANNED}",
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ cls.bulk_edit_data = {
|
|
|
|
|
+ 'cooling_source': cooling_sources[1].pk,
|
|
|
|
|
+ 'rack': racks[1].pk,
|
|
|
|
|
+ 'status': CoolingFeedStatusChoices.STATUS_PLANNED,
|
|
|
|
|
+ 'cooling_capacity': 100,
|
|
|
|
|
+ 'max_flow': 50,
|
|
|
|
|
+ 'max_flow_unit': FlowRateUnitChoices.UNIT_LITERS_PER_MINUTE,
|
|
|
|
|
+ 'comments': 'New comments',
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
class VirtualDeviceContextTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
class VirtualDeviceContextTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
model = VirtualDeviceContext
|
|
model = VirtualDeviceContext
|
|
|
|
|
|