Просмотр исходного кода

Address review feedback on model_bakery conversion (#22087)

- Add model-bakery to base_requirements.txt and requirements.txt
- Add comment explaining MPTT_ALLOW_TESTING_GENERATORS setting
- Convert remaining bulk_create calls to baker.make in filtersets
- Replace fragile .objects.first() refs with stored class attributes
  in JSON import tests
Jason Novinger 3 дней назад
Родитель
Сommit
2f891538d0

+ 4 - 0
base_requirements.txt

@@ -101,6 +101,10 @@ jsonschema
 # https://python-markdown.github.io/changelog/
 Markdown
 
+# Test object generation via field introspection
+# https://github.com/model-bakers/model_bakery
+model-bakery
+
 # Retain MkDocs 1.x for mkdocstrings
 # https://github.com/mkdocs/mkdocs
 mkdocs<2.0

+ 76 - 169
netbox/circuits/tests/test_filtersets.py

@@ -220,82 +220,52 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
         )
 
         circuits = (
-            Circuit(
-                provider=providers[0],
-                provider_account=provider_accounts[0],
-                tenant=tenants[0],
-                type=circuit_types[0],
-                cid='Test Circuit 1',
-                install_date='2020-01-01',
-                termination_date='2021-01-01',
-                commit_rate=1000,
-                status=CircuitStatusChoices.STATUS_ACTIVE,
-                description='foobar1',
-                distance=10,
-                distance_unit=DistanceUnitChoices.UNIT_FOOT,
+            baker.make(
+                'circuits.Circuit',
+                provider=providers[0], provider_account=provider_accounts[0],
+                tenant=tenants[0], type=circuit_types[0],
+                cid='Test Circuit 1', install_date='2020-01-01', termination_date='2021-01-01',
+                commit_rate=1000, status=CircuitStatusChoices.STATUS_ACTIVE,
+                description='foobar1', distance=10, distance_unit=DistanceUnitChoices.UNIT_FOOT,
             ),
-            Circuit(
-                provider=providers[0],
-                provider_account=provider_accounts[0],
-                tenant=tenants[0],
-                type=circuit_types[0],
-                cid='Test Circuit 2',
-                install_date='2020-01-02',
-                termination_date='2021-01-02',
-                commit_rate=2000,
-                status=CircuitStatusChoices.STATUS_ACTIVE,
-                description='foobar2',
-                distance=20,
-                distance_unit=DistanceUnitChoices.UNIT_METER,
+            baker.make(
+                'circuits.Circuit',
+                provider=providers[0], provider_account=provider_accounts[0],
+                tenant=tenants[0], type=circuit_types[0],
+                cid='Test Circuit 2', install_date='2020-01-02', termination_date='2021-01-02',
+                commit_rate=2000, status=CircuitStatusChoices.STATUS_ACTIVE,
+                description='foobar2', distance=20, distance_unit=DistanceUnitChoices.UNIT_METER,
             ),
-            Circuit(
-                provider=providers[0],
-                provider_account=provider_accounts[1],
-                tenant=tenants[1],
-                type=circuit_types[0],
-                cid='Test Circuit 3',
-                install_date='2020-01-03',
-                termination_date='2021-01-03',
-                commit_rate=3000,
-                status=CircuitStatusChoices.STATUS_PLANNED,
-                distance=30,
-                distance_unit=DistanceUnitChoices.UNIT_METER,
+            baker.make(
+                'circuits.Circuit',
+                provider=providers[0], provider_account=provider_accounts[1],
+                tenant=tenants[1], type=circuit_types[0],
+                cid='Test Circuit 3', install_date='2020-01-03', termination_date='2021-01-03',
+                commit_rate=3000, status=CircuitStatusChoices.STATUS_PLANNED,
+                distance=30, distance_unit=DistanceUnitChoices.UNIT_METER,
             ),
-            Circuit(
-                provider=providers[1],
-                provider_account=provider_accounts[1],
-                tenant=tenants[1],
-                type=circuit_types[1],
-                cid='Test Circuit 4',
-                install_date='2020-01-04',
-                termination_date='2021-01-04',
-                commit_rate=4000,
-                status=CircuitStatusChoices.STATUS_PLANNED,
+            baker.make(
+                'circuits.Circuit',
+                provider=providers[1], provider_account=provider_accounts[1],
+                tenant=tenants[1], type=circuit_types[1],
+                cid='Test Circuit 4', install_date='2020-01-04', termination_date='2021-01-04',
+                commit_rate=4000, status=CircuitStatusChoices.STATUS_PLANNED,
             ),
-            Circuit(
-                provider=providers[1],
-                provider_account=provider_accounts[2],
-                tenant=tenants[2],
-                type=circuit_types[1],
-                cid='Test Circuit 5',
-                install_date='2020-01-05',
-                termination_date='2021-01-05',
-                commit_rate=5000,
-                status=CircuitStatusChoices.STATUS_OFFLINE,
+            baker.make(
+                'circuits.Circuit',
+                provider=providers[1], provider_account=provider_accounts[2],
+                tenant=tenants[2], type=circuit_types[1],
+                cid='Test Circuit 5', install_date='2020-01-05', termination_date='2021-01-05',
+                commit_rate=5000, status=CircuitStatusChoices.STATUS_OFFLINE,
             ),
-            Circuit(
-                provider=providers[1],
-                provider_account=provider_accounts[2],
-                tenant=tenants[2],
-                type=circuit_types[1],
-                cid='Test Circuit 6',
-                install_date='2020-01-06',
-                termination_date='2021-01-06',
-                commit_rate=6000,
-                status=CircuitStatusChoices.STATUS_OFFLINE,
+            baker.make(
+                'circuits.Circuit',
+                provider=providers[1], provider_account=provider_accounts[2],
+                tenant=tenants[2], type=circuit_types[1],
+                cid='Test Circuit 6', install_date='2020-01-06', termination_date='2021-01-06',
+                commit_rate=6000, status=CircuitStatusChoices.STATUS_OFFLINE,
             ),
         )
-        Circuit.objects.bulk_create(circuits)
 
         circuit_terminations = ((
             CircuitTermination(circuit=circuits[0], termination=sites[0], term_side='A'),
@@ -667,39 +637,19 @@ class CircuitGroupAssignmentTestCase(TestCase, ChangeLoggedFilterSetTests):
             for i in range(3)
         ]
 
-        assignments = (
-            CircuitGroupAssignment(
-                group=circuit_groups[0],
-                member=circuits[0],
-                priority=CircuitPriorityChoices.PRIORITY_PRIMARY
-            ),
-            CircuitGroupAssignment(
-                group=circuit_groups[1],
-                member=circuits[1],
-                priority=CircuitPriorityChoices.PRIORITY_SECONDARY
-            ),
-            CircuitGroupAssignment(
-                group=circuit_groups[2],
-                member=circuits[2],
-                priority=CircuitPriorityChoices.PRIORITY_TERTIARY
-            ),
-            CircuitGroupAssignment(
-                group=circuit_groups[0],
-                member=virtual_circuits[0],
-                priority=CircuitPriorityChoices.PRIORITY_PRIMARY
-            ),
-            CircuitGroupAssignment(
-                group=circuit_groups[1],
-                member=virtual_circuits[1],
-                priority=CircuitPriorityChoices.PRIORITY_SECONDARY
-            ),
-            CircuitGroupAssignment(
-                group=circuit_groups[2],
-                member=virtual_circuits[2],
-                priority=CircuitPriorityChoices.PRIORITY_TERTIARY
-            ),
-        )
-        CircuitGroupAssignment.objects.bulk_create(assignments)
+        for i, priority in enumerate([
+            CircuitPriorityChoices.PRIORITY_PRIMARY,
+            CircuitPriorityChoices.PRIORITY_SECONDARY,
+            CircuitPriorityChoices.PRIORITY_TERTIARY,
+        ]):
+            baker.make(
+                'circuits.CircuitGroupAssignment',
+                group=circuit_groups[i], member=circuits[i], priority=priority,
+            )
+            baker.make(
+                'circuits.CircuitGroupAssignment',
+                group=circuit_groups[i], member=virtual_circuits[i], priority=priority,
+            )
 
     def test_group(self):
         groups = CircuitGroup.objects.all()[:2]
@@ -882,35 +832,17 @@ class VirtualCircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
 
         virtual_circuit_types = baker.make('circuits.VirtualCircuitType', _quantity=3)
 
-        VirtualCircuit.objects.bulk_create((
-            VirtualCircuit(
-                provider_network=provider_networks[0],
-                provider_account=provider_accounts[0],
-                tenant=tenants[0],
-                cid='Virtual Circuit 1',
-                type=virtual_circuit_types[0],
-                status=CircuitStatusChoices.STATUS_PLANNED,
-                description='virtualcircuit1',
-            ),
-            VirtualCircuit(
-                provider_network=provider_networks[1],
-                provider_account=provider_accounts[1],
-                tenant=tenants[1],
-                cid='Virtual Circuit 2',
-                type=virtual_circuit_types[1],
-                status=CircuitStatusChoices.STATUS_ACTIVE,
-                description='virtualcircuit2',
-            ),
-            VirtualCircuit(
-                provider_network=provider_networks[2],
-                provider_account=provider_accounts[2],
-                tenant=tenants[2],
-                cid='Virtual Circuit 3',
-                type=virtual_circuit_types[2],
-                status=CircuitStatusChoices.STATUS_DEPROVISIONING,
-                description='virtualcircuit3',
-            ),
-        ))
+        for i, (status, desc) in enumerate([
+            (CircuitStatusChoices.STATUS_PLANNED, 'virtualcircuit1'),
+            (CircuitStatusChoices.STATUS_ACTIVE, 'virtualcircuit2'),
+            (CircuitStatusChoices.STATUS_DEPROVISIONING, 'virtualcircuit3'),
+        ]):
+            baker.make(
+                'circuits.VirtualCircuit',
+                provider_network=provider_networks[i], provider_account=provider_accounts[i],
+                tenant=tenants[i], cid=f'Virtual Circuit {i + 1}',
+                type=virtual_circuit_types[i], status=status, description=desc,
+            )
 
     def test_q(self):
         params = {'q': 'virtualcircuit1'}
@@ -1014,45 +946,20 @@ class VirtualCircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests):
             for i in range(3)
         ]
 
-        virtual_circuit_terminations = (
-            VirtualCircuitTermination(
-                virtual_circuit=virtual_circuits[0],
-                role=VirtualCircuitTerminationRoleChoices.ROLE_HUB,
-                interface=virtual_interfaces[0],
-                description='termination1'
-            ),
-            VirtualCircuitTermination(
-                virtual_circuit=virtual_circuits[0],
-                role=VirtualCircuitTerminationRoleChoices.ROLE_SPOKE,
-                interface=virtual_interfaces[3],
-                description='termination2'
-            ),
-            VirtualCircuitTermination(
-                virtual_circuit=virtual_circuits[1],
-                role=VirtualCircuitTerminationRoleChoices.ROLE_PEER,
-                interface=virtual_interfaces[1],
-                description='termination3'
-            ),
-            VirtualCircuitTermination(
-                virtual_circuit=virtual_circuits[1],
-                role=VirtualCircuitTerminationRoleChoices.ROLE_PEER,
-                interface=virtual_interfaces[4],
-                description='termination4'
-            ),
-            VirtualCircuitTermination(
-                virtual_circuit=virtual_circuits[2],
-                role=VirtualCircuitTerminationRoleChoices.ROLE_PEER,
-                interface=virtual_interfaces[2],
-                description='termination5'
-            ),
-            VirtualCircuitTermination(
-                virtual_circuit=virtual_circuits[2],
-                role=VirtualCircuitTerminationRoleChoices.ROLE_PEER,
-                interface=virtual_interfaces[5],
-                description='termination6'
-            ),
+        termination_data = (
+            (virtual_circuits[0], VirtualCircuitTerminationRoleChoices.ROLE_HUB, virtual_interfaces[0]),
+            (virtual_circuits[0], VirtualCircuitTerminationRoleChoices.ROLE_SPOKE, virtual_interfaces[3]),
+            (virtual_circuits[1], VirtualCircuitTerminationRoleChoices.ROLE_PEER, virtual_interfaces[1]),
+            (virtual_circuits[1], VirtualCircuitTerminationRoleChoices.ROLE_PEER, virtual_interfaces[4]),
+            (virtual_circuits[2], VirtualCircuitTerminationRoleChoices.ROLE_PEER, virtual_interfaces[2]),
+            (virtual_circuits[2], VirtualCircuitTerminationRoleChoices.ROLE_PEER, virtual_interfaces[5]),
         )
-        VirtualCircuitTermination.objects.bulk_create(virtual_circuit_terminations)
+        for i, (vc, role, iface) in enumerate(termination_data, start=1):
+            baker.make(
+                'circuits.VirtualCircuitTermination',
+                virtual_circuit=vc, role=role, interface=iface,
+                description=f'termination{i}',
+            )
 
     def test_q(self):
         params = {'q': 'termination1'}

+ 15 - 12
netbox/circuits/tests/test_views.py

@@ -106,16 +106,16 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
 
     @classmethod
     def setUpTestData(cls):
-        baker.make('dcim.Site', name='Site 1', slug='site-1')
+        cls.site = baker.make('dcim.Site', name='Site 1', slug='site-1')
 
-        providers = baker.make('circuits.Provider', _quantity=2)
+        cls.providers = providers = baker.make('circuits.Provider', _quantity=2)
 
         provider_accounts = [
             baker.make('circuits.ProviderAccount', provider=providers[0]),
             baker.make('circuits.ProviderAccount', provider=providers[1]),
         ]
 
-        circuittypes = baker.make('circuits.CircuitType', _quantity=2)
+        cls.circuittypes = circuittypes = baker.make('circuits.CircuitType', _quantity=2)
 
         circuits = baker.make(
             'circuits.Circuit',
@@ -182,25 +182,24 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
 
     @override_settings(EXEMPT_VIEW_PERMISSIONS=['*'], EXEMPT_EXCLUDE_MODELS=[])
     def test_bulk_import_objects_with_terminations(self):
-        site = Site.objects.first()
         json_data = f"""
             [
               {{
                 "cid": "Circuit 7",
-                "provider": "{Provider.objects.first().name}",
-                "type": "{CircuitType.objects.first().name}",
+                "provider": "{self.providers[0].name}",
+                "type": "{self.circuittypes[0].name}",
                 "status": "active",
                 "description": "Testing Import",
                 "terminations": [
                   {{
                     "term_side": "A",
                     "termination_type": "dcim.site",
-                    "termination_id": "{site.pk}"
+                    "termination_id": "{self.site.pk}"
                   }},
                   {{
                     "term_side": "Z",
                     "termination_type": "dcim.site",
-                    "termination_id": "{site.pk}"
+                    "termination_id": "{self.site.pk}"
                   }}
                 ]
               }}
@@ -530,9 +529,13 @@ class VirtualCircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
     @classmethod
     def setUpTestData(cls):
         provider = baker.make('circuits.Provider')
-        provider_networks = baker.make('circuits.ProviderNetwork', provider=provider, _quantity=2)
+        cls.provider_networks = provider_networks = baker.make(
+            'circuits.ProviderNetwork', provider=provider, _quantity=2
+        )
         provider_accounts = baker.make('circuits.ProviderAccount', provider=provider, _quantity=2)
-        virtual_circuit_types = baker.make('circuits.VirtualCircuitType', _quantity=2)
+        cls.virtual_circuit_types = virtual_circuit_types = baker.make(
+            'circuits.VirtualCircuitType', _quantity=2
+        )
 
         virtual_circuits = baker.make(
             'circuits.VirtualCircuit',
@@ -612,8 +615,8 @@ class VirtualCircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
             [
               {{
                 "cid": "Virtual Circuit 7",
-                "provider_network": "{ProviderNetwork.objects.first().name}",
-                "type": "{VirtualCircuitType.objects.first().name}",
+                "provider_network": "{self.provider_networks[0].name}",
+                "type": "{self.virtual_circuit_types[0].name}",
                 "status": "active",
                 "terminations": [
                   {{

+ 1 - 0
netbox/netbox/settings.py

@@ -144,6 +144,7 @@ JINJA2_FILTERS = getattr(configuration, 'JINJA2_FILTERS', {})
 LANGUAGE_CODE = getattr(configuration, 'DEFAULT_LANGUAGE', 'en-us')
 LANGUAGE_COOKIE_PATH = CSRF_COOKIE_PATH
 LOGGING = getattr(configuration, 'LOGGING', {})
+# Allow model_bakery to generate MPTT model instances in tests (django-mptt blocks this by default)
 MPTT_ALLOW_TESTING_GENERATORS = getattr(configuration, 'MPTT_ALLOW_TESTING_GENERATORS', False)
 LOGIN_PERSISTENCE = getattr(configuration, 'LOGIN_PERSISTENCE', False)
 LOGIN_REQUIRED = getattr(configuration, 'LOGIN_REQUIRED', True)

+ 1 - 0
requirements.txt

@@ -23,6 +23,7 @@ gunicorn==25.3.0
 Jinja2==3.1.6
 jsonschema==4.26.0
 Markdown==3.10.2
+model-bakery==1.23.4
 mkdocs==1.6.1
 mkdocs-material==9.7.6
 mkdocstrings==1.0.4