From 2fe3c7035a93624914bca12f23212fe26c7a25b6 Mon Sep 17 00:00:00 2001 From: Aaron Iles ayiles Date: Wed, 7 Feb 2024 13:05:11 -0500 Subject: [PATCH 1/9] 4283: adds maintenance mode to device status, adds unit tests --- netbox/dcim/choices.py | 2 + netbox/dcim/tests/test_filtersets.py | 42 +++++++++++- netbox/dcim/tests/test_forms.py | 18 ++++++ netbox/utilities/tests/test_filters.py | 88 ++++++++++++++++++++++++-- 4 files changed, 145 insertions(+), 5 deletions(-) diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 2ba24e0aa..4d7fe3a83 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -167,6 +167,7 @@ class DeviceStatusChoices(ChoiceSet): STATUS_FAILED = 'failed' STATUS_INVENTORY = 'inventory' STATUS_DECOMMISSIONING = 'decommissioning' + STATUS_MAINTENANCE = 'maintenance' CHOICES = [ (STATUS_OFFLINE, _('Offline'), 'gray'), @@ -176,6 +177,7 @@ class DeviceStatusChoices(ChoiceSet): (STATUS_FAILED, _('Failed'), 'red'), (STATUS_INVENTORY, _('Inventory'), 'purple'), (STATUS_DECOMMISSIONING, _('Decommissioning'), 'yellow'), + (STATUS_MAINTENANCE, _('Maintenance'), 'orange'), ] diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 89d15a0ef..c37af0b8f 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -1825,6 +1825,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): Manufacturer(name='Manufacturer 1', slug='manufacturer-1'), Manufacturer(name='Manufacturer 2', slug='manufacturer-2'), Manufacturer(name='Manufacturer 3', slug='manufacturer-3'), + Manufacturer(name='Manufacturer 4', slug='manufacturer-4'), ) Manufacturer.objects.bulk_create(manufacturers) @@ -1832,6 +1833,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): DeviceType(manufacturer=manufacturers[0], model='Model 1', slug='model-1', is_full_depth=True), DeviceType(manufacturer=manufacturers[1], model='Model 2', slug='model-2', is_full_depth=True), DeviceType(manufacturer=manufacturers[2], model='Model 3', slug='model-3', is_full_depth=False), + DeviceType(manufacturer=manufacturers[3], model='Model 4', slug='model-4', is_full_depth=False), ) DeviceType.objects.bulk_create(device_types) @@ -1839,6 +1841,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): DeviceRole(name='Device Role 1', slug='device-role-1'), DeviceRole(name='Device Role 2', slug='device-role-2'), DeviceRole(name='Device Role 3', slug='device-role-3'), + DeviceRole(name='Device Role 4', slug='device-role-4'), ) DeviceRole.objects.bulk_create(roles) @@ -1846,6 +1849,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): Platform(name='Platform 1', slug='platform-1'), Platform(name='Platform 2', slug='platform-2'), Platform(name='Platform 3', slug='platform-3'), + Platform(name='Platform 4', slug='platform-4'), ) Platform.objects.bulk_create(platforms) @@ -1853,6 +1857,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): Region(name='Region 1', slug='region-1'), Region(name='Region 2', slug='region-2'), Region(name='Region 3', slug='region-3'), + Region(name='Region 4', slug='region-4'), ) for region in regions: region.save() @@ -1861,6 +1866,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): SiteGroup(name='Site Group 1', slug='site-group-1'), SiteGroup(name='Site Group 2', slug='site-group-2'), SiteGroup(name='Site Group 3', slug='site-group-3'), + SiteGroup(name='Site Group 4', slug='site-group-4'), ) for group in groups: group.save() @@ -1869,6 +1875,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): Site(name='Site 1', slug='site-1', region=regions[0], group=groups[0]), Site(name='Site 2', slug='site-2', region=regions[1], group=groups[1]), Site(name='Site 3', slug='site-3', region=regions[2], group=groups[2]), + Site(name='Site 4', slug='site-4', region=regions[3], group=groups[3]), ) Site.objects.bulk_create(sites) @@ -1876,6 +1883,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): Location(name='Location 1', slug='location-1', site=sites[0]), Location(name='Location 2', slug='location-2', site=sites[1]), Location(name='Location 3', slug='location-3', site=sites[2]), + Location(name='Location 4', slug='location-4', site=sites[3]), ) for location in locations: location.save() @@ -1884,6 +1892,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): Rack(name='Rack 1', site=sites[0], location=locations[0]), Rack(name='Rack 2', site=sites[1], location=locations[1]), Rack(name='Rack 3', site=sites[2], location=locations[2]), + Rack(name='Rack 4', site=sites[3], location=locations[3]), ) Rack.objects.bulk_create(racks) @@ -1892,6 +1901,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): Cluster(name='Cluster 1', type=cluster_type), Cluster(name='Cluster 2', type=cluster_type), Cluster(name='Cluster 3', type=cluster_type), + Cluster(name='Cluster 4', type=cluster_type), ) Cluster.objects.bulk_create(clusters) @@ -1899,6 +1909,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): TenantGroup(name='Tenant group 1', slug='tenant-group-1'), TenantGroup(name='Tenant group 2', slug='tenant-group-2'), TenantGroup(name='Tenant group 3', slug='tenant-group-3'), + TenantGroup(name='Tenant group 4', slug='tenant-group-4'), ) for tenantgroup in tenant_groups: tenantgroup.save() @@ -1907,6 +1918,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): Tenant(name='Tenant 1', slug='tenant-1', group=tenant_groups[0]), Tenant(name='Tenant 2', slug='tenant-2', group=tenant_groups[1]), Tenant(name='Tenant 3', slug='tenant-3', group=tenant_groups[2]), + Tenant(name='Tenant 4', slug='tenant-4', group=tenant_groups[4]), ) Tenant.objects.bulk_create(tenants) @@ -1971,6 +1983,26 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): cluster=clusters[2], description='foobar3' ), + Device( + name='Device 4', + device_type=device_types[3], + role=roles[3], + platform=platforms[3], + tenant=tenants[3], + serial='JKL', + asset_tag='1004', + site=sites[3], + location=locations[3], + rack=racks[3], + position=4, + face=DeviceFaceChoices.FACE_FRONT, + latitude=40, + longitude=40, + status=DeviceStatusChoices.STATUS_MAINTENANCE, + airflow=DeviceAirflowChoices.AIRFLOW_REAR_TO_FRONT, + cluster=clusters[3], + description='foobar4' + ), ) Device.objects.bulk_create(devices) @@ -2036,6 +2068,10 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'q': 'foobar1'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + def test_q_maintenance(self): + params = {'q': 'foobar4'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + def test_name(self): params = {'name': ['Device 1', 'Device 2']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) @@ -2143,10 +2179,14 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'model': ['model-1', 'model-2']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_status(self): + def test_status_active_and_staged(self): params = {'status': [DeviceStatusChoices.STATUS_ACTIVE, DeviceStatusChoices.STATUS_STAGED]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + def test_status_maintenance(self): + params = {'status': [DeviceStatusChoices.STATUS_MAINTENANCE]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + def test_is_full_depth(self): params = {'is_full_depth': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) diff --git a/netbox/dcim/tests/test_forms.py b/netbox/dcim/tests/test_forms.py index 7a57bf3f0..a6280c38a 100644 --- a/netbox/dcim/tests/test_forms.py +++ b/netbox/dcim/tests/test_forms.py @@ -50,6 +50,24 @@ class DeviceTestCase(TestCase): self.assertTrue(form.is_valid()) self.assertTrue(form.save()) + def test_racked_device_maintenance_status(self): + form = DeviceForm(data={ + 'name': 'Maintenance Device', + 'role': DeviceRole.objects.first().pk, + 'tenant': None, + 'manufacturer': Manufacturer.objects.first().pk, + 'device_type': DeviceType.objects.first().pk, + 'site': Site.objects.first().pk, + 'rack': Rack.objects.first().pk, + 'face': DeviceFaceChoices.FACE_FRONT, + 'position': 3, + 'platform': Platform.objects.first().pk, + 'status': DeviceStatusChoices.STATUS_MAINTENANCE, + }) + self.assertTrue(form.is_valid()) + self.assertTrue(form.save()) + + def test_racked_device_occupied(self): form = DeviceForm(data={ 'name': 'test', diff --git a/netbox/utilities/tests/test_filters.py b/netbox/utilities/tests/test_filters.py index 6caeb9d14..5d8f5798a 100644 --- a/netbox/utilities/tests/test_filters.py +++ b/netbox/utilities/tests/test_filters.py @@ -368,6 +368,7 @@ class DynamicFilterLookupExpressionTest(TestCase): ASN(asn=65001, rir=rir), ASN(asn=65101, rir=rir), ASN(asn=65201, rir=rir), + ASN(asn=65301, rir=rir), ) ASN.objects.bulk_create(asns) @@ -375,6 +376,7 @@ class DynamicFilterLookupExpressionTest(TestCase): Manufacturer(name='Manufacturer 1', slug='manufacturer-1'), Manufacturer(name='Manufacturer 2', slug='manufacturer-2'), Manufacturer(name='Manufacturer 3', slug='manufacturer-3'), + Manufacturer(name='Manufacturer 4', slug='manufacturer-4'), ) Manufacturer.objects.bulk_create(manufacturers) @@ -382,6 +384,7 @@ class DynamicFilterLookupExpressionTest(TestCase): DeviceType(manufacturer=manufacturers[0], model='Model 1', slug='model-1', is_full_depth=True), DeviceType(manufacturer=manufacturers[1], model='Model 2', slug='model-2', is_full_depth=True), DeviceType(manufacturer=manufacturers[2], model='Model 3', slug='model-3', is_full_depth=False), + DeviceType(manufacturer=manufacturers[3], model='Model 4', slug='model-4', is_full_depth=False), ) DeviceType.objects.bulk_create(device_types) @@ -389,6 +392,7 @@ class DynamicFilterLookupExpressionTest(TestCase): DeviceRole(name='Device Role 1', slug='device-role-1'), DeviceRole(name='Device Role 2', slug='device-role-2'), DeviceRole(name='Device Role 3', slug='device-role-3'), + DeviceRole(name='Device Role 4', slug='device-role-4'), ) DeviceRole.objects.bulk_create(roles) @@ -396,6 +400,7 @@ class DynamicFilterLookupExpressionTest(TestCase): Platform(name='Platform 1', slug='platform-1'), Platform(name='Platform 2', slug='platform-2'), Platform(name='Platform 3', slug='platform-3'), + Platform(name='Platform 4', slug='platform-4'), ) Platform.objects.bulk_create(platforms) @@ -403,6 +408,7 @@ class DynamicFilterLookupExpressionTest(TestCase): Region(name='Region 1', slug='region-1'), Region(name='Region 2', slug='region-2'), Region(name='Region 3', slug='region-3'), + Region(name='Region 4', slug='region-4'), ) for region in regions: region.save() @@ -411,25 +417,80 @@ class DynamicFilterLookupExpressionTest(TestCase): Site(name='Site 1', slug='abc-site-1', region=regions[0]), Site(name='Site 2', slug='def-site-2', region=regions[1]), Site(name='Site 3', slug='ghi-site-3', region=regions[2]), + Site(name='Site 4', slug='jkl-site-4', region=regions[3]), ) Site.objects.bulk_create(sites) asns[0].sites.add(sites[0]) asns[1].sites.add(sites[1]) asns[2].sites.add(sites[2]) + asns[3].sites.add(sites[3]) racks = ( Rack(name='Rack 1', site=sites[0]), Rack(name='Rack 2', site=sites[1]), Rack(name='Rack 3', site=sites[2]), + Rack(name='Rack 4', site=sites[3]), ) Rack.objects.bulk_create(racks) + # Assemble the tuple of devices to be created in bulk. devices = ( - Device(name='Device 1', device_type=device_types[0], role=roles[0], platform=platforms[0], serial='ABC', asset_tag='1001', site=sites[0], rack=racks[0], position=1, face=DeviceFaceChoices.FACE_FRONT, status=DeviceStatusChoices.STATUS_ACTIVE, local_context_data={"foo": 123}), - Device(name='Device 2', device_type=device_types[1], role=roles[1], platform=platforms[1], serial='DEF', asset_tag='1002', site=sites[1], rack=racks[1], position=2, face=DeviceFaceChoices.FACE_FRONT, status=DeviceStatusChoices.STATUS_STAGED), - Device(name='Device 3', device_type=device_types[2], role=roles[2], platform=platforms[2], serial='GHI', asset_tag='1003', site=sites[2], rack=racks[2], position=3, face=DeviceFaceChoices.FACE_REAR, status=DeviceStatusChoices.STATUS_FAILED), + Device( + name='Device 1', + device_type=device_types[0], + role=roles[0], + platform=platforms[0], + serial='ABC', + asset_tag='1001', + site=sites[0], + rack=racks[0], + position=1, + face=DeviceFaceChoices.FACE_FRONT, + status=DeviceStatusChoices.STATUS_ACTIVE, + local_context_data={"foo": 123}, + ), + Device( + name='Device 2', + device_type=device_types[1], + role=roles[1], + platform=platforms[1], + serial='DEF', + asset_tag='1002', + site=sites[1], + rack=racks[1], + position=2, + face=DeviceFaceChoices.FACE_FRONT, + status=DeviceStatusChoices.STATUS_STAGED, + ), + Device( + name='Device 3', + device_type=device_types[2], + role=roles[2], + platform=platforms[2], + serial='GHI', + asset_tag='1003', + site=sites[2], + rack=racks[2], + position=3, + face=DeviceFaceChoices.FACE_REAR, + status=DeviceStatusChoices.STATUS_FAILED, + ), + Device( + name='Device 4', + device_type=device_types[3], + role=roles[3], + platform=platforms[3], + serial='JKL', + asset_tag='1004', + site=sites[3], + rack=racks[3], + position=4, + face=DeviceFaceChoices.FACE_REAR, + status=DeviceStatusChoices.STATUS_MAINTENANCE, + ), ) + Device.objects.bulk_create(devices) interfaces = ( @@ -439,6 +500,9 @@ class DynamicFilterLookupExpressionTest(TestCase): Interface(device=devices[1], name='Interface 4', mac_address='bb-00-00-00-00-02'), Interface(device=devices[2], name='Interface 5', mac_address='00-00-00-00-00-03'), Interface(device=devices[2], name='Interface 6', mac_address='cc-00-00-00-00-03'), + Interface(device=devices[3], name='Interface 7', mac_address='00-00-00-00-00-04'), + Interface(device=devices[3], name='Interface 8', mac_address='cc-00-00-00-00-04'), + ) Interface.objects.bulk_create(interfaces) @@ -504,7 +568,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_device_name_startswith(self): params = {'name__isw': ['Device']} - self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 4) def test_device_name_startswith_negation(self): params = {'name__nisw': ['Device 1']} @@ -553,3 +617,19 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_device_mac_address_icontains_negation(self): params = {'mac_address__nic': ['aa:', 'bb']} self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1) + + def test_device_status_negation_active(self): + params = {'status__n': 'active'} + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) + + def test_device_status_negation_maintenance(self): + params = {'status__n': 'maintenance'} + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) + + def test_device_status_active(self): + params = {'status': 'active'} + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1) + + def test_device_status_maintenance(self): + params = {'status': 'maintenance'} + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1) From df86d02dd692a83c533b2dc06c158165f1ca83cb Mon Sep 17 00:00:00 2001 From: Aaron Iles ayiles Date: Wed, 7 Feb 2024 13:30:58 -0500 Subject: [PATCH 2/9] 4283: fixing indentation --- netbox/utilities/tests/test_filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/utilities/tests/test_filters.py b/netbox/utilities/tests/test_filters.py index 5d8f5798a..c362255e0 100644 --- a/netbox/utilities/tests/test_filters.py +++ b/netbox/utilities/tests/test_filters.py @@ -500,7 +500,7 @@ class DynamicFilterLookupExpressionTest(TestCase): Interface(device=devices[1], name='Interface 4', mac_address='bb-00-00-00-00-02'), Interface(device=devices[2], name='Interface 5', mac_address='00-00-00-00-00-03'), Interface(device=devices[2], name='Interface 6', mac_address='cc-00-00-00-00-03'), - Interface(device=devices[3], name='Interface 7', mac_address='00-00-00-00-00-04'), + Interface(device=devices[3], name='Interface 7', mac_address='00-00-00-00-00-04'), Interface(device=devices[3], name='Interface 8', mac_address='cc-00-00-00-00-04'), ) From ef201733c9848ac0a8713b76781d9f3254c83156 Mon Sep 17 00:00:00 2001 From: Aaron Iles ayiles Date: Wed, 7 Feb 2024 13:37:39 -0500 Subject: [PATCH 3/9] 4283: fixing indentation --- netbox/utilities/tests/test_filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/utilities/tests/test_filters.py b/netbox/utilities/tests/test_filters.py index c362255e0..3e0439ca6 100644 --- a/netbox/utilities/tests/test_filters.py +++ b/netbox/utilities/tests/test_filters.py @@ -434,7 +434,7 @@ class DynamicFilterLookupExpressionTest(TestCase): ) Rack.objects.bulk_create(racks) - # Assemble the tuple of devices to be created in bulk. + # Assemble the tuple of devices to be created in bulk. devices = ( Device( name='Device 1', From 1cf19f4b8f4b6305001e8a01fe0db54ea785089d Mon Sep 17 00:00:00 2001 From: Aaron Iles ayiles Date: Wed, 7 Feb 2024 13:42:30 -0500 Subject: [PATCH 4/9] 4283: fixing spacing --- netbox/dcim/tests/test_forms.py | 1 - 1 file changed, 1 deletion(-) diff --git a/netbox/dcim/tests/test_forms.py b/netbox/dcim/tests/test_forms.py index a6280c38a..01ee948f8 100644 --- a/netbox/dcim/tests/test_forms.py +++ b/netbox/dcim/tests/test_forms.py @@ -67,7 +67,6 @@ class DeviceTestCase(TestCase): self.assertTrue(form.is_valid()) self.assertTrue(form.save()) - def test_racked_device_occupied(self): form = DeviceForm(data={ 'name': 'test', From e5f98e720812e27e100cb5cfb380e05f99465b60 Mon Sep 17 00:00:00 2001 From: Aaron Iles ayiles Date: Wed, 7 Feb 2024 13:57:31 -0500 Subject: [PATCH 5/9] 4283: fixing wrong query type in test --- netbox/utilities/tests/test_filters.py | 38 +++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/netbox/utilities/tests/test_filters.py b/netbox/utilities/tests/test_filters.py index 3e0439ca6..97d63c884 100644 --- a/netbox/utilities/tests/test_filters.py +++ b/netbox/utilities/tests/test_filters.py @@ -508,7 +508,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_site_name_negation(self): params = {'name__n': ['Site 1']} - self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2) + self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 3) def test_site_slug_icontains(self): params = {'slug__ic': ['-1']} @@ -516,7 +516,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_site_slug_icontains_negation(self): params = {'slug__nic': ['-1']} - self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2) + self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 3) def test_site_slug_startswith(self): params = {'slug__isw': ['abc']} @@ -524,7 +524,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_site_slug_startswith_negation(self): params = {'slug__nisw': ['abc']} - self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2) + self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 3) def test_site_slug_endswith(self): params = {'slug__iew': ['-1']} @@ -532,7 +532,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_site_slug_endswith_negation(self): params = {'slug__niew': ['-1']} - self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2) + self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 3) def test_provider_asn_lt(self): params = {'asn__lt': [65101]} @@ -540,7 +540,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_provider_asn_lte(self): params = {'asn__lte': [65101]} - self.assertEqual(ASNFilterSet(params, ASN.objects.all()).qs.count(), 2) + self.assertEqual(ASNFilterSet(params, ASN.objects.all()).qs.count(), 3) def test_provider_asn_gt(self): params = {'asn__lt': [65101]} @@ -548,15 +548,15 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_provider_asn_gte(self): params = {'asn__gte': [65101]} - self.assertEqual(ASNFilterSet(params, ASN.objects.all()).qs.count(), 2) + self.assertEqual(ASNFilterSet(params, ASN.objects.all()).qs.count(), 3) def test_site_region_negation(self): params = {'region__n': ['region-1']} - self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2) + self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 3) def test_site_region_id_negation(self): params = {'region_id__n': [Region.objects.first().pk]} - self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2) + self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 3) def test_device_name_eq(self): params = {'name': ['Device 1']} @@ -564,7 +564,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_device_name_negation(self): params = {'name__n': ['Device 1']} - self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2) + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) def test_device_name_startswith(self): params = {'name__isw': ['Device']} @@ -572,7 +572,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_device_name_startswith_negation(self): params = {'name__nisw': ['Device 1']} - self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2) + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) def test_device_name_endswith(self): params = {'name__iew': [' 1']} @@ -580,7 +580,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_device_name_endswith_negation(self): params = {'name__niew': [' 1']} - self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2) + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) def test_device_name_icontains(self): params = {'name__ic': [' 2']} @@ -592,7 +592,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_device_mac_address_negation(self): params = {'mac_address__n': ['00-00-00-00-00-01', 'aa-00-00-00-00-01']} - self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2) + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) def test_device_mac_address_startswith(self): params = {'mac_address__isw': ['aa:']} @@ -600,7 +600,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_device_mac_address_startswith_negation(self): params = {'mac_address__nisw': ['aa:']} - self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2) + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) def test_device_mac_address_endswith(self): params = {'mac_address__iew': [':02']} @@ -608,28 +608,28 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_device_mac_address_endswith_negation(self): params = {'mac_address__niew': [':02']} - self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2) + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) def test_device_mac_address_icontains(self): params = {'mac_address__ic': ['aa:', 'bb']} - self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2) + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) def test_device_mac_address_icontains_negation(self): params = {'mac_address__nic': ['aa:', 'bb']} self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1) def test_device_status_negation_active(self): - params = {'status__n': 'active'} + params = {'status__n': ['active']} self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) def test_device_status_negation_maintenance(self): - params = {'status__n': 'maintenance'} + params = {'status__n': ['maintenance']} self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) def test_device_status_active(self): - params = {'status': 'active'} + params = {'status': ['active']} self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1) def test_device_status_maintenance(self): - params = {'status': 'maintenance'} + params = {'status': ['maintenance']} self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1) From 414d355fb2df135d083815ea79330699a90feb56 Mon Sep 17 00:00:00 2001 From: Aaron Iles ayiles Date: Wed, 7 Feb 2024 14:13:42 -0500 Subject: [PATCH 6/9] 4283: fixing wrong query type in test --- netbox/dcim/tests/test_filtersets.py | 2 +- netbox/utilities/tests/test_filters.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index c37af0b8f..1e03246ed 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -1918,7 +1918,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): Tenant(name='Tenant 1', slug='tenant-1', group=tenant_groups[0]), Tenant(name='Tenant 2', slug='tenant-2', group=tenant_groups[1]), Tenant(name='Tenant 3', slug='tenant-3', group=tenant_groups[2]), - Tenant(name='Tenant 4', slug='tenant-4', group=tenant_groups[4]), + Tenant(name='Tenant 4', slug='tenant-4', group=tenant_groups[3]), ) Tenant.objects.bulk_create(tenants) diff --git a/netbox/utilities/tests/test_filters.py b/netbox/utilities/tests/test_filters.py index 97d63c884..e3599499d 100644 --- a/netbox/utilities/tests/test_filters.py +++ b/netbox/utilities/tests/test_filters.py @@ -540,7 +540,7 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_provider_asn_lte(self): params = {'asn__lte': [65101]} - self.assertEqual(ASNFilterSet(params, ASN.objects.all()).qs.count(), 3) + self.assertEqual(ASNFilterSet(params, ASN.objects.all()).qs.count(), 2) def test_provider_asn_gt(self): params = {'asn__lt': [65101]} @@ -612,11 +612,11 @@ class DynamicFilterLookupExpressionTest(TestCase): def test_device_mac_address_icontains(self): params = {'mac_address__ic': ['aa:', 'bb']} - self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3) + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2) def test_device_mac_address_icontains_negation(self): params = {'mac_address__nic': ['aa:', 'bb']} - self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1) + self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2) def test_device_status_negation_active(self): params = {'status__n': ['active']} From 5908ecbc293b80c4a17568627108322c42314a10 Mon Sep 17 00:00:00 2001 From: Aaron Iles ayiles Date: Wed, 7 Feb 2024 14:29:27 -0500 Subject: [PATCH 7/9] 4283: fixing indentation --- netbox/dcim/tests/test_filtersets.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 1e03246ed..ceac8a325 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -971,7 +971,7 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'is_full_depth': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'is_full_depth': False} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_subdevice_role(self): params = {'subdevice_role': SubdeviceRoleChoices.ROLE_PARENT} @@ -1011,19 +1011,19 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'console_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'console_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_console_server_ports(self): params = {'console_server_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'console_server_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_power_ports(self): params = {'power_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'power_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_power_outlets(self): params = {'power_outlets': 'true'} @@ -1047,13 +1047,13 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'device_bays': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'device_bays': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_module_bays(self): params = {'module_bays': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'module_bays': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_inventory_items(self): params = {'inventory_items': 'true'} @@ -1200,7 +1200,7 @@ class ModuleTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'pass_through_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'pass_through_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_weight(self): params = {'weight': [10, 20]} @@ -2089,7 +2089,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): def test_face(self): params = {'face': DeviceFaceChoices.FACE_FRONT} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) def test_position(self): params = {'position': [1, 2]} @@ -2211,7 +2211,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'has_primary_ip': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'has_primary_ip': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_primary_ip4(self): addresses = IPAddress.objects.filter(address__family=4) @@ -2235,7 +2235,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'virtual_chassis_member': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'virtual_chassis_member': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_console_ports(self): params = {'console_ports': 'true'} @@ -2259,13 +2259,13 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'power_outlets': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'power_outlets': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_interfaces(self): params = {'interfaces': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'interfaces': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_pass_through_ports(self): params = {'pass_through_ports': 'true'} @@ -2289,7 +2289,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'local_context_data': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) params = {'local_context_data': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) def test_tenant(self): tenants = Tenant.objects.all()[:2] From 22a0546c583aa359e9b11b77e01f7d81244986e2 Mon Sep 17 00:00:00 2001 From: Aaron Iles ayiles Date: Wed, 7 Feb 2024 14:44:24 -0500 Subject: [PATCH 8/9] 4283: fixing unit tests --- netbox/dcim/tests/test_filtersets.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index ceac8a325..f47717966 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -971,7 +971,7 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'is_full_depth': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'is_full_depth': False} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_subdevice_role(self): params = {'subdevice_role': SubdeviceRoleChoices.ROLE_PARENT} @@ -1023,7 +1023,7 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'power_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'power_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_power_outlets(self): params = {'power_outlets': 'true'} @@ -1053,7 +1053,7 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'module_bays': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'module_bays': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_inventory_items(self): params = {'inventory_items': 'true'} @@ -1200,7 +1200,7 @@ class ModuleTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'pass_through_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'pass_through_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_weight(self): params = {'weight': [10, 20]} @@ -2191,7 +2191,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'is_full_depth': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'is_full_depth': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_airflow(self): params = {'airflow': DeviceAirflowChoices.AIRFLOW_FRONT_TO_REAR} @@ -2253,7 +2253,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'power_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'power_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_power_outlets(self): params = {'power_outlets': 'true'} @@ -2271,13 +2271,13 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'pass_through_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'pass_through_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_module_bays(self): params = {'module_bays': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'module_bays': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_device_bays(self): params = {'device_bays': 'true'} From 1760cb553dd911410f72b7982b4c151a3b9ccd53 Mon Sep 17 00:00:00 2001 From: Aaron Iles ayiles Date: Wed, 7 Feb 2024 14:55:39 -0500 Subject: [PATCH 9/9] 4283: fixing unit tests --- netbox/dcim/tests/test_filtersets.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index f47717966..76644c60e 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -1011,13 +1011,13 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'console_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'console_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_console_server_ports(self): params = {'console_server_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'console_server_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_power_ports(self): params = {'power_ports': 'true'} @@ -1047,7 +1047,7 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'device_bays': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'device_bays': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_module_bays(self): params = {'module_bays': 'true'} @@ -2241,13 +2241,13 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'console_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'console_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_console_server_ports(self): params = {'console_server_ports': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'console_server_ports': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_power_ports(self): params = {'power_ports': 'true'} @@ -2283,7 +2283,7 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'device_bays': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) params = {'device_bays': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_local_context_data(self): params = {'local_context_data': 'true'}