Add recipe-based PoC for CircuitTestCase (#22087)

Add baker_recipes.py files for circuits, dcim, tenancy, and ipam apps
with Recipe objects that document model relationships and provide named
status variants (active_circuit, planned_circuit, offline_circuit).

Convert CircuitTestCase in test_filtersets.py to use recipes instead of
bare baker.make() calls. All 127 filterset tests pass.

This commit sits alongside the existing baker.make() conversion so
reviewers can compare both approaches.
This commit is contained in:
Jason Novinger 2026-05-21 13:31:46 -05:00
parent 2ce649aa70
commit e91c8b97e1
5 changed files with 169 additions and 78 deletions

View File

@ -0,0 +1,68 @@
from model_bakery.recipe import Recipe, foreign_key, seq
from circuits.choices import CircuitStatusChoices
#
# Provider
#
provider = Recipe(
'circuits.Provider',
name=seq('Provider '),
slug=seq('provider-'),
)
#
# CircuitType
#
circuit_type = Recipe(
'circuits.CircuitType',
name=seq('Circuit Type '),
slug=seq('circuit-type-'),
)
#
# ProviderAccount
#
provider_account = Recipe(
'circuits.ProviderAccount',
name=seq('Provider Account '),
provider=foreign_key(provider),
account=seq('ACCT-'),
)
#
# ProviderNetwork
#
provider_network = Recipe(
'circuits.ProviderNetwork',
name=seq('Provider Network '),
provider=foreign_key(provider),
)
#
# Circuit
#
circuit = Recipe(
'circuits.Circuit',
cid=seq('CID-'),
provider=foreign_key(provider),
type=foreign_key(circuit_type),
status=CircuitStatusChoices.STATUS_ACTIVE,
)
active_circuit = circuit.extend(
status=CircuitStatusChoices.STATUS_ACTIVE,
)
planned_circuit = circuit.extend(
status=CircuitStatusChoices.STATUS_PLANNED,
)
offline_circuit = circuit.extend(
status=CircuitStatusChoices.STATUS_OFFLINE,
)

View File

@ -157,117 +157,97 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
@classmethod
def setUpTestData(cls):
# MPTT models: use .save() directly
regions = (
Region(name='Test Region 1', slug='test-region-1'),
Region(name='Test Region 2', slug='test-region-2'),
Region(name='Test Region 3', slug='test-region-3'),
from circuits.baker_recipes import (
active_circuit,
offline_circuit,
planned_circuit,
provider,
provider_account,
provider_network,
)
# MPTT models: use .save() directly (baker triggers mptt guard)
regions = [Region(name=f'Test Region {i}', slug=f'test-region-{i}') for i in range(1, 4)]
for r in regions:
r.save()
site_groups = (
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'),
)
for site_group in site_groups:
site_group.save()
site_groups = [SiteGroup(name=f'Site Group {i}', slug=f'site-group-{i}') for i in range(1, 4)]
for sg in site_groups:
sg.save()
sites = (
baker.make('dcim.Site', name='Test Site 1', slug='test-site-1', region=regions[0], group=site_groups[0]),
baker.make('dcim.Site', name='Test Site 2', slug='test-site-2', region=regions[1], group=site_groups[1]),
baker.make('dcim.Site', name='Test Site 3', slug='test-site-3', region=regions[2], group=site_groups[2]),
)
# MPTT models: use .save() directly
tenant_groups = (
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'),
)
for tenantgroup in tenant_groups:
tenantgroup.save()
tenants = (
baker.make('tenancy.Tenant', name='Tenant 1', slug='tenant-1', group=tenant_groups[0]),
baker.make('tenancy.Tenant', name='Tenant 2', slug='tenant-2', group=tenant_groups[1]),
baker.make('tenancy.Tenant', name='Tenant 3', slug='tenant-3', group=tenant_groups[2]),
)
circuit_types = baker.make('circuits.CircuitType', _quantity=2)
providers = baker.make('circuits.Provider', _quantity=3)
tenant_groups = [TenantGroup(name=f'Tenant group {i}', slug=f'tenant-group-{i}') for i in range(1, 4)]
for tg in tenant_groups:
tg.save()
# Non-MPTT models: use recipes
sites = [
baker.make_recipe('dcim.site', region=regions[i], group=site_groups[i])
for i in range(3)
]
tenants = [
baker.make_recipe('tenancy.tenant', group=tenant_groups[i])
for i in range(3)
]
circuit_types = baker.make_recipe('circuits.circuit_type', _quantity=2)
providers = provider.make(_quantity=3)
provider_accounts = [
baker.make('circuits.ProviderAccount', provider=providers[0]),
baker.make('circuits.ProviderAccount', provider=providers[1]),
baker.make('circuits.ProviderAccount', provider=providers[2]),
provider_account.make(provider=providers[i])
for i in range(3)
]
provider_networks = provider_network.make(provider=providers[1], _quantity=3)
# Location is MPTT: use .objects.create()
locations = [
Location.objects.create(
site=sites[i], name=f'Test Location {i + 1}', slug=f'test-location-{i + 1}',
status=LocationStatusChoices.STATUS_ACTIVE,
)
for i in range(2)
]
provider_networks = baker.make('circuits.ProviderNetwork', provider=providers[1], _quantity=3)
locations = (
Location.objects.create(
site=sites[0], name='Test Location 1', slug='test-location-1',
status=LocationStatusChoices.STATUS_ACTIVE,
),
Location.objects.create(
site=sites[1], name='Test Location 2', slug='test-location-2',
status=LocationStatusChoices.STATUS_ACTIVE,
),
)
circuits = (
baker.make(
'circuits.Circuit',
# Circuits: recipes encode status; test-specific fields passed as overrides
circuits = [
active_circuit.make(
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,
commit_rate=1000, description='foobar1',
distance=10, distance_unit=DistanceUnitChoices.UNIT_FOOT,
),
baker.make(
'circuits.Circuit',
active_circuit.make(
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,
commit_rate=2000, description='foobar2',
distance=20, distance_unit=DistanceUnitChoices.UNIT_METER,
),
baker.make(
'circuits.Circuit',
planned_circuit.make(
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,
commit_rate=3000, distance=30, distance_unit=DistanceUnitChoices.UNIT_METER,
),
baker.make(
'circuits.Circuit',
planned_circuit.make(
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,
commit_rate=4000,
),
baker.make(
'circuits.Circuit',
offline_circuit.make(
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,
commit_rate=5000,
),
baker.make(
'circuits.Circuit',
offline_circuit.make(
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,
commit_rate=6000,
),
)
]
circuit_terminations = ((
circuit_terminations = (
CircuitTermination(circuit=circuits[0], termination=sites[0], term_side='A'),
CircuitTermination(circuit=circuits[0], termination=locations[0], term_side='Z'),
CircuitTermination(circuit=circuits[1], termination=sites[1], term_side='A'),
@ -276,7 +256,7 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
CircuitTermination(circuit=circuits[3], termination=provider_networks[0], term_side='A'),
CircuitTermination(circuit=circuits[4], termination=provider_networks[1], term_side='A'),
CircuitTermination(circuit=circuits[5], termination=provider_networks[2], term_side='A'),
))
)
for ct in circuit_terminations:
ct.save()

View File

@ -0,0 +1,11 @@
from model_bakery.recipe import Recipe, seq
#
# Site
#
site = Recipe(
'dcim.Site',
name=seq('Site '),
slug=seq('site-'),
)

View File

@ -0,0 +1,21 @@
from model_bakery.recipe import Recipe, foreign_key, seq
#
# RIR
#
rir = Recipe(
'ipam.RIR',
name=seq('RIR '),
slug=seq('rir-'),
)
#
# ASN
#
asn = Recipe(
'ipam.ASN',
asn=seq(64512),
rir=foreign_key(rir),
)

View File

@ -0,0 +1,11 @@
from model_bakery.recipe import Recipe, seq
#
# Tenant
#
tenant = Recipe(
'tenancy.Tenant',
name=seq('Tenant '),
slug=seq('tenant-'),
)