Merge pull request #4080 from netbox-community/4077-view-tests

Closes #4077: Add tests for bulk edit/delete views
This commit is contained in:
Jeremy Stretch 2020-02-03 14:32:56 -05:00 committed by GitHub
commit 91929aae1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 643 additions and 149 deletions

View File

@ -36,6 +36,15 @@ class ProviderTestCase(StandardTestCases.Views):
"Provider 6,provider-6",
)
cls.bulk_edit_data = {
'asn': 65009,
'account': '5678',
'portal_url': 'http://example.com/portal2',
'noc_contact': 'noc2@example.com',
'admin_contact': 'admin2@example.com',
'comments': 'New comments',
}
class CircuitTypeTestCase(StandardTestCases.Views):
model = CircuitType
@ -43,6 +52,7 @@ class CircuitTypeTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -73,23 +83,29 @@ class CircuitTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
provider = Provider(name='Provider 1', slug='provider-1', asn=65001)
provider.save()
providers = (
Provider(name='Provider 1', slug='provider-1', asn=65001),
Provider(name='Provider 2', slug='provider-2', asn=65002),
)
Provider.objects.bulk_create(providers)
circuittype = CircuitType(name='Circuit Type 1', slug='circuit-type-1')
circuittype.save()
circuittypes = (
CircuitType(name='Circuit Type 1', slug='circuit-type-1'),
CircuitType(name='Circuit Type 2', slug='circuit-type-2'),
)
CircuitType.objects.bulk_create(circuittypes)
Circuit.objects.bulk_create([
Circuit(cid='Circuit 1', provider=provider, type=circuittype),
Circuit(cid='Circuit 2', provider=provider, type=circuittype),
Circuit(cid='Circuit 3', provider=provider, type=circuittype),
Circuit(cid='Circuit 1', provider=providers[0], type=circuittypes[0]),
Circuit(cid='Circuit 2', provider=providers[0], type=circuittypes[0]),
Circuit(cid='Circuit 3', provider=providers[0], type=circuittypes[0]),
])
cls.form_data = {
'cid': 'Circuit X',
'provider': provider.pk,
'type': circuittype.pk,
'status': CircuitStatusChoices.STATUS_ACTIVE,
'provider': providers[1].pk,
'type': circuittypes[1].pk,
'status': CircuitStatusChoices.STATUS_DECOMMISSIONED,
'tenant': None,
'install_date': datetime.date(2020, 1, 1),
'commit_rate': 1000,
@ -104,3 +120,14 @@ class CircuitTestCase(StandardTestCases.Views):
"Circuit 5,Provider 1,Circuit Type 1",
"Circuit 6,Provider 1,Circuit Type 1",
)
cls.bulk_edit_data = {
'provider': providers[1].pk,
'type': circuittypes[1].pk,
'status': CircuitStatusChoices.STATUS_DECOMMISSIONED,
'tenant': None,
'commit_rate': 2000,
'description': 'New description',
'comments': 'New comments',
}

View File

@ -19,6 +19,7 @@ class RegionTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -52,20 +53,24 @@ class SiteTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
region = Region(name='Region 1', slug='region-1')
region.save()
regions = (
Region(name='Region 1', slug='region-1'),
Region(name='Region 2', slug='region-2'),
)
for region in regions:
region.save()
Site.objects.bulk_create([
Site(name='Site 1', slug='site-1', region=region),
Site(name='Site 2', slug='site-2', region=region),
Site(name='Site 3', slug='site-3', region=region),
Site(name='Site 1', slug='site-1', region=regions[0]),
Site(name='Site 2', slug='site-2', region=regions[0]),
Site(name='Site 3', slug='site-3', region=regions[0]),
])
cls.form_data = {
'name': 'Site X',
'slug': 'site-x',
'status': SiteStatusChoices.STATUS_PLANNED,
'region': region.pk,
'region': regions[1].pk,
'tenant': None,
'facility': 'Facility X',
'asn': 65001,
@ -89,6 +94,15 @@ class SiteTestCase(StandardTestCases.Views):
"Site 6,site-6",
)
cls.bulk_edit_data = {
'status': SiteStatusChoices.STATUS_PLANNED,
'region': regions[1].pk,
'tenant': None,
'asn': 65009,
'time_zone': pytz.timezone('US/Eastern'),
'description': 'New description',
}
class RackGroupTestCase(StandardTestCases.Views):
model = RackGroup
@ -96,6 +110,7 @@ class RackGroupTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -129,6 +144,7 @@ class RackRoleTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -159,32 +175,40 @@ class RackReservationTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_create_object = None # TODO: Fix URL name for view
test_create_object = None
# TODO: Fix URL name for view
test_import_objects = None
@classmethod
def setUpTestData(cls):
user = User.objects.create_user(username='testuser2')
user2 = User.objects.create_user(username='testuser2')
user3 = User.objects.create_user(username='testuser3')
site = Site(name='Site 1', slug='site-1')
site.save()
site = Site.objects.create(name='Site 1', slug='site-1')
rack = Rack(name='Rack 1', site=site)
rack.save()
RackReservation.objects.bulk_create([
RackReservation(rack=rack, user=user, units=[1, 2, 3], description='Reservation 1'),
RackReservation(rack=rack, user=user, units=[4, 5, 6], description='Reservation 2'),
RackReservation(rack=rack, user=user, units=[7, 8, 9], description='Reservation 3'),
RackReservation(rack=rack, user=user2, units=[1, 2, 3], description='Reservation 1'),
RackReservation(rack=rack, user=user2, units=[4, 5, 6], description='Reservation 2'),
RackReservation(rack=rack, user=user2, units=[7, 8, 9], description='Reservation 3'),
])
cls.form_data = {
'rack': rack.pk,
'units': [10, 11, 12],
'user': user.pk,
'user': user3.pk,
'tenant': None,
'description': 'New reservation',
'description': 'Rack reservation',
}
cls.bulk_edit_data = {
'user': user3.pk,
'tenant': None,
'description': 'New description',
}
@ -194,24 +218,38 @@ class RackTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
site = Site.objects.create(name='Site 1', slug='site-1')
rackgroup = RackGroup.objects.create(name='Rack Group 1', slug='rack-group-1', site=site)
rackrole = RackRole.objects.create(name='Rack Role 1', slug='rack-role-1')
sites = (
Site(name='Site 1', slug='site-1'),
Site(name='Site 2', slug='site-2'),
)
Site.objects.bulk_create(sites)
Rack.objects.bulk_create([
Rack(name='Rack 1', site=site),
Rack(name='Rack 2', site=site),
Rack(name='Rack 3', site=site),
])
rackgroups = (
RackGroup(name='Rack Group 1', slug='rack-group-1', site=sites[0]),
RackGroup(name='Rack Group 2', slug='rack-group-2', site=sites[1])
)
RackGroup.objects.bulk_create(rackgroups)
rackroles = (
RackRole(name='Rack Role 1', slug='rack-role-1'),
RackRole(name='Rack Role 2', slug='rack-role-2'),
)
RackRole.objects.bulk_create(rackroles)
Rack.objects.bulk_create((
Rack(name='Rack 1', site=sites[0]),
Rack(name='Rack 2', site=sites[0]),
Rack(name='Rack 3', site=sites[0]),
))
cls.form_data = {
'name': 'Rack X',
'facility_id': 'Facility X',
'site': site.pk,
'group': rackgroup.pk,
'site': sites[1].pk,
'group': rackgroups[1].pk,
'tenant': None,
'status': RackStatusChoices.STATUS_PLANNED,
'role': rackrole.pk,
'role': rackroles[1].pk,
'serial': '123456',
'asset_tag': 'ABCDEF',
'type': RackTypeChoices.TYPE_CABINET,
@ -232,6 +270,23 @@ class RackTestCase(StandardTestCases.Views):
"Site 1,Rack 6,19,42",
)
cls.bulk_edit_data = {
'site': sites[1].pk,
'group': rackgroups[1].pk,
'tenant': None,
'status': RackStatusChoices.STATUS_DEPRECATED,
'role': rackroles[1].pk,
'serial': '654321',
'type': RackTypeChoices.TYPE_4POST,
'width': RackWidthChoices.WIDTH_23IN,
'u_height': 49,
'desc_units': True,
'outer_width': 30,
'outer_depth': 30,
'outer_unit': RackDimensionUnitChoices.UNIT_INCH,
'comments': 'New comments',
}
class ManufacturerTestCase(StandardTestCases.Views):
model = Manufacturer
@ -239,6 +294,7 @@ class ManufacturerTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -268,17 +324,20 @@ class DeviceTypeTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
manufacturer = Manufacturer(name='Manufacturer 1', slug='manufacturer-1')
manufacturer.save()
manufacturers = (
Manufacturer(name='Manufacturer 1', slug='manufacturer-1'),
Manufacturer(name='Manufacturer 2', slug='manufacturer-2')
)
Manufacturer.objects.bulk_create(manufacturers)
DeviceType.objects.bulk_create([
DeviceType(model='Device Type 1', slug='device-type-1', manufacturer=manufacturer),
DeviceType(model='Device Type 2', slug='device-type-2', manufacturer=manufacturer),
DeviceType(model='Device Type 3', slug='device-type-3', manufacturer=manufacturer),
DeviceType(model='Device Type 1', slug='device-type-1', manufacturer=manufacturers[0]),
DeviceType(model='Device Type 2', slug='device-type-2', manufacturer=manufacturers[0]),
DeviceType(model='Device Type 3', slug='device-type-3', manufacturer=manufacturers[0]),
])
cls.form_data = {
'manufacturer': manufacturer.pk,
'manufacturer': manufacturers[1].pk,
'model': 'Device Type X',
'slug': 'device-type-x',
'part_number': '123ABC',
@ -289,6 +348,12 @@ class DeviceTypeTestCase(StandardTestCases.Views):
'tags': 'Alpha,Bravo,Charlie',
}
cls.bulk_edit_data = {
'manufacturer': manufacturers[1].pk,
'u_height': 3,
'is_full_depth': False,
}
def test_import_objects(self):
"""
Custom import test for YAML-based imports (versus CSV)
@ -451,6 +516,7 @@ class DeviceRoleTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -483,6 +549,7 @@ class PlatformTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -517,29 +584,54 @@ class DeviceTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
site = Site.objects.create(name='Site 1', slug='site-1')
rack = Rack.objects.create(name='Rack 1', site=site)
sites = (
Site(name='Site 1', slug='site-1'),
Site(name='Site 2', slug='site-2'),
)
Site.objects.bulk_create(sites)
racks = (
Rack(name='Rack 1', site=sites[0]),
Rack(name='Rack 2', site=sites[1]),
)
Rack.objects.bulk_create(racks)
manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1')
devicetype = DeviceType.objects.create(model='Device Type 1', manufacturer=manufacturer)
devicerole = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
platform = Platform.objects.create(name='Platform 1', slug='platform-1')
devicetypes = (
DeviceType(model='Device Type 1', slug='device-type-1', manufacturer=manufacturer),
DeviceType(model='Device Type 2', slug='device-type-2', manufacturer=manufacturer),
)
DeviceType.objects.bulk_create(devicetypes)
deviceroles = (
DeviceRole(name='Device Role 1', slug='device-role-1'),
DeviceRole(name='Device Role 2', slug='device-role-2'),
)
DeviceRole.objects.bulk_create(deviceroles)
platforms = (
Platform(name='Platform 1', slug='platform-1'),
Platform(name='Platform 2', slug='platform-2'),
)
Platform.objects.bulk_create(platforms)
Device.objects.bulk_create([
Device(name='Device 1', site=site, device_type=devicetype, device_role=devicerole),
Device(name='Device 2', site=site, device_type=devicetype, device_role=devicerole),
Device(name='Device 3', site=site, device_type=devicetype, device_role=devicerole),
Device(name='Device 1', site=sites[0], rack=racks[0], device_type=devicetypes[0], device_role=deviceroles[0], platform=platforms[0]),
Device(name='Device 2', site=sites[0], rack=racks[0], device_type=devicetypes[0], device_role=deviceroles[0], platform=platforms[0]),
Device(name='Device 3', site=sites[0], rack=racks[0], device_type=devicetypes[0], device_role=deviceroles[0], platform=platforms[0]),
])
cls.form_data = {
'device_type': devicetype.pk,
'device_role': devicerole.pk,
'device_type': devicetypes[1].pk,
'device_role': deviceroles[1].pk,
'tenant': None,
'platform': platform.pk,
'platform': platforms[1].pk,
'name': 'Device X',
'serial': '123456',
'asset_tag': 'ABCDEF',
'site': site.pk,
'rack': rack.pk,
'site': sites[1].pk,
'rack': racks[1].pk,
'position': 1,
'face': DeviceFaceChoices.FACE_FRONT,
'status': DeviceStatusChoices.STATUS_PLANNED,
@ -561,6 +653,15 @@ class DeviceTestCase(StandardTestCases.Views):
"Device Role 1,Manufacturer 1,Device Type 1,Active,Site 1,Device 6",
)
cls.bulk_edit_data = {
'device_type': devicetypes[1].pk,
'device_role': deviceroles[1].pk,
'tenant': None,
'platform': platforms[1].pk,
'serial': '123456',
'status': DeviceStatusChoices.STATUS_DECOMMISSIONING,
}
# TODO: Convert to StandardTestCases.Views
class ConsolePortTestCase(TestCase):
@ -1071,28 +1172,28 @@ class CableTestCase(StandardTestCases.Views):
manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1')
devicetype = DeviceType.objects.create(model='Device Type 1', manufacturer=manufacturer)
devicerole = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
device1 = Device(name='Device 1', site=site, device_type=devicetype, device_role=devicerole)
device1.save()
device2 = Device(name='Device 2', site=site, device_type=devicetype, device_role=devicerole)
device2.save()
device3 = Device(name='Device 3', site=site, device_type=devicetype, device_role=devicerole)
device3.save()
device4 = Device(name='Device 4', site=site, device_type=devicetype, device_role=devicerole)
device4.save()
devices = (
Device(name='Device 1', site=site, device_type=devicetype, device_role=devicerole),
Device(name='Device 2', site=site, device_type=devicetype, device_role=devicerole),
Device(name='Device 3', site=site, device_type=devicetype, device_role=devicerole),
Device(name='Device 4', site=site, device_type=devicetype, device_role=devicerole),
)
Device.objects.bulk_create(devices)
interfaces = (
Interface(device=device1, name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device1, name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device1, name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device2, name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device2, name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device2, name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device3, name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device3, name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device3, name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device4, name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device4, name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=device4, name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[0], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[0], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[0], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[1], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[1], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[1], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[2], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[2], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[2], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[3], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[3], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
Interface(device=devices[3], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
)
Interface.objects.bulk_create(interfaces)
@ -1109,7 +1210,7 @@ class CableTestCase(StandardTestCases.Views):
'termination_b_id': interfaces[3].pk,
'type': CableTypeChoices.TYPE_CAT6,
'status': CableStatusChoices.STATUS_PLANNED,
'label': 'New cable',
'label': 'Label',
'color': 'c0c0c0',
'length': 100,
'length_unit': CableLengthUnitChoices.UNIT_FOOT,
@ -1122,6 +1223,15 @@ class CableTestCase(StandardTestCases.Views):
"Device 3,interface,Interface 3,Device 4,interface,Interface 3",
)
cls.bulk_edit_data = {
'type': CableTypeChoices.TYPE_CAT5E,
'status': CableStatusChoices.STATUS_CONNECTED,
'label': 'New label',
'color': '00ff00',
'length': 50,
'length_unit': CableLengthUnitChoices.UNIT_METER,
}
class VirtualChassisTestCase(StandardTestCases.Views):
model = VirtualChassis
@ -1129,6 +1239,8 @@ class VirtualChassisTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_import_objects = None
test_bulk_edit_objects = None
test_bulk_delete_objects = None
# TODO: Requires special form handling
test_create_object = None
@ -1173,3 +1285,114 @@ class VirtualChassisTestCase(StandardTestCases.Views):
Device.objects.filter(pk=device4.pk).update(virtual_chassis=vc2, vc_position=2)
vc3 = VirtualChassis.objects.create(master=device5, domain='test-domain-3')
Device.objects.filter(pk=device6.pk).update(virtual_chassis=vc3, vc_position=2)
class PowerPanelTestCase(StandardTestCases.Views):
model = PowerPanel
# Disable inapplicable tests
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
sites = (
Site(name='Site 1', slug='site-1'),
Site(name='Site 2', slug='site-2'),
)
Site.objects.bulk_create(sites)
rackgroups = (
RackGroup(name='Rack Group 1', slug='rack-group-1', site=sites[0]),
RackGroup(name='Rack Group 2', slug='rack-group-2', site=sites[1]),
)
RackGroup.objects.bulk_create(rackgroups)
PowerPanel.objects.bulk_create((
PowerPanel(site=sites[0], rack_group=rackgroups[0], name='Power Panel 1'),
PowerPanel(site=sites[0], rack_group=rackgroups[0], name='Power Panel 2'),
PowerPanel(site=sites[0], rack_group=rackgroups[0], name='Power Panel 3'),
))
cls.form_data = {
'site': sites[1].pk,
'rack_group': rackgroups[1].pk,
'name': 'Power Panel X',
}
cls.csv_data = (
"site,rack_group_name,name",
"Site 1,Rack Group 1,Power Panel 4",
"Site 1,Rack Group 1,Power Panel 5",
"Site 1,Rack Group 1,Power Panel 6",
)
class PowerFeedTestCase(StandardTestCases.Views):
model = PowerFeed
# TODO: Re-enable this test once #4079 is fixed
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
site = Site.objects.create(name='Site 1', slug='site-1')
powerpanels = (
PowerPanel(site=site, name='Power Panel 1'),
PowerPanel(site=site, name='Power Panel 2'),
)
PowerPanel.objects.bulk_create(powerpanels)
racks = (
Rack(site=site, name='Rack 1'),
Rack(site=site, name='Rack 2'),
)
Rack.objects.bulk_create(racks)
PowerFeed.objects.bulk_create((
PowerFeed(name='Power Feed 1', power_panel=powerpanels[0], rack=racks[0]),
PowerFeed(name='Power Feed 2', power_panel=powerpanels[0], rack=racks[0]),
PowerFeed(name='Power Feed 3', power_panel=powerpanels[0], rack=racks[0]),
))
cls.form_data = {
'name': 'Power Feed X',
'power_panel': powerpanels[1].pk,
'rack': racks[1].pk,
'status': PowerFeedStatusChoices.STATUS_PLANNED,
'type': PowerFeedTypeChoices.TYPE_REDUNDANT,
'supply': PowerFeedSupplyChoices.SUPPLY_DC,
'phase': PowerFeedPhaseChoices.PHASE_3PHASE,
'voltage': 100,
'amperage': 100,
'max_utilization': 50,
'comments': 'New comments',
'tags': 'Alpha,Bravo,Charlie',
# Connection
'cable': None,
'connected_endpoint': None,
'connection_status': None,
}
cls.csv_data = (
"site,panel_name,name,voltage,amperage,max_utilization",
"Site 1,Power Panel 1,Power Feed 4,120,20,80",
"Site 1,Power Panel 1,Power Feed 5,120,20,80",
"Site 1,Power Panel 1,Power Feed 6,120,20,80",
)
cls.bulk_edit_data = {
'power_panel': powerpanels[1].pk,
'rack': racks[1].pk,
'status': PowerFeedStatusChoices.STATUS_PLANNED,
'type': PowerFeedTypeChoices.TYPE_REDUNDANT,
'supply': PowerFeedSupplyChoices.SUPPLY_DC,
'phase': PowerFeedPhaseChoices.PHASE_3PHASE,
'voltage': 100,
'amperage': 100,
'max_utilization': 50,
'comments': 'New comments',
}

View File

@ -318,7 +318,7 @@ urlpatterns = [
# Power feeds
path(r'power-feeds/', views.PowerFeedListView.as_view(), name='powerfeed_list'),
path(r'power-feeds/add/', views.PowerFeedEditView.as_view(), name='powerfeed_add'),
path(r'power-feeds/add/', views.PowerFeedCreateView.as_view(), name='powerfeed_add'),
path(r'power-feeds/import/', views.PowerFeedBulkImportView.as_view(), name='powerfeed_import'),
path(r'power-feeds/edit/', views.PowerFeedBulkEditView.as_view(), name='powerfeed_bulk_edit'),
path(r'power-feeds/delete/', views.PowerFeedBulkDeleteView.as_view(), name='powerfeed_bulk_delete'),

View File

@ -33,6 +33,10 @@ class TagTestCase(StandardTestCases.Views):
'comments': 'Some comments',
}
cls.bulk_edit_data = {
'color': '00ff00',
}
class ConfigContextTestCase(StandardTestCases.Views):
model = ConfigContext
@ -53,7 +57,7 @@ class ConfigContextTestCase(StandardTestCases.Views):
for i in range(1, 4):
configcontext = ConfigContext(
name='Config Context {}'.format(i),
data='{{"foo": {}}}'.format(i)
data={'foo': i}
)
configcontext.save()
configcontext.sites.add(site)
@ -73,7 +77,14 @@ class ConfigContextTestCase(StandardTestCases.Views):
'data': '{"foo": 123}',
}
cls.bulk_edit_data = {
'weight': 300,
'is_active': False,
'description': 'New description',
}
# TODO: Convert to StandardTestCases.Views
class ObjectChangeTestCase(TestCase):
user_permissions = (
'extras.view_objectchange',

View File

@ -85,10 +85,9 @@ class TagBulkEditView(PermissionRequiredMixin, BulkEditView):
).order_by(
'name'
)
# filter = filters.ProviderFilter
table = TagTable
form = forms.TagBulkEditForm
default_return_url = 'circuits:provider_list'
default_return_url = 'extras:tag_list'
class TagBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):

View File

@ -1392,5 +1392,5 @@ class ServiceBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
class Meta:
nullable_fields = [
'site', 'tenant', 'role', 'description',
'description',
]

View File

@ -36,6 +36,12 @@ class VRFTestCase(StandardTestCases.Views):
"VRF 6",
)
cls.bulk_edit_data = {
'tenant': None,
'enforce_unique': False,
'description': 'New description',
}
class RIRTestCase(StandardTestCases.Views):
model = RIR
@ -43,6 +49,7 @@ class RIRTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -73,18 +80,22 @@ class AggregateTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
rir = RIR.objects.create(name='RIR 1', slug='rir-1')
rirs = (
RIR(name='RIR 1', slug='rir-1'),
RIR(name='RIR 2', slug='rir-2'),
)
RIR.objects.bulk_create(rirs)
Aggregate.objects.bulk_create([
Aggregate(family=4, prefix=IPNetwork('10.1.0.0/16'), rir=rir),
Aggregate(family=4, prefix=IPNetwork('10.2.0.0/16'), rir=rir),
Aggregate(family=4, prefix=IPNetwork('10.3.0.0/16'), rir=rir),
Aggregate(family=4, prefix=IPNetwork('10.1.0.0/16'), rir=rirs[0]),
Aggregate(family=4, prefix=IPNetwork('10.2.0.0/16'), rir=rirs[0]),
Aggregate(family=4, prefix=IPNetwork('10.3.0.0/16'), rir=rirs[0]),
])
cls.form_data = {
'family': 4,
'prefix': IPNetwork('10.99.0.0/16'),
'rir': rir.pk,
'rir': rirs[1].pk,
'date_added': datetime.date(2020, 1, 1),
'description': 'A new aggregate',
'tags': 'Alpha,Bravo,Charlie',
@ -97,6 +108,12 @@ class AggregateTestCase(StandardTestCases.Views):
"10.6.0.0/16,RIR 1",
)
cls.bulk_edit_data = {
'rir': rirs[1].pk,
'date_added': datetime.date(2020, 1, 1),
'description': 'New description',
}
class RoleTestCase(StandardTestCases.Views):
model = Role
@ -104,6 +121,7 @@ class RoleTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -135,25 +153,37 @@ class PrefixTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
site = Site.objects.create(name='Site 1', slug='site-1')
vrf = VRF.objects.create(name='VRF 1', rd='65000:1')
role = Role.objects.create(name='Role 1', slug='role-1')
# vlan = VLAN.objects.create(vid=123, name='VLAN 123')
sites = (
Site(name='Site 1', slug='site-1'),
Site(name='Site 2', slug='site-2'),
)
Site.objects.bulk_create(sites)
vrfs = (
VRF(name='VRF 1', rd='65000:1'),
VRF(name='VRF 2', rd='65000:2'),
)
VRF.objects.bulk_create(vrfs)
roles = (
Role(name='Role 1', slug='role-1'),
Role(name='Role 2', slug='role-2'),
)
Prefix.objects.bulk_create([
Prefix(family=4, prefix=IPNetwork('10.1.0.0/16'), site=site),
Prefix(family=4, prefix=IPNetwork('10.2.0.0/16'), site=site),
Prefix(family=4, prefix=IPNetwork('10.3.0.0/16'), site=site),
Prefix(family=4, prefix=IPNetwork('10.1.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]),
Prefix(family=4, prefix=IPNetwork('10.2.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]),
Prefix(family=4, prefix=IPNetwork('10.3.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]),
])
cls.form_data = {
'prefix': IPNetwork('192.0.2.0/24'),
'site': site.pk,
'vrf': vrf.pk,
'site': sites[1].pk,
'vrf': vrfs[1].pk,
'tenant': None,
'vlan': None,
'status': PrefixStatusChoices.STATUS_RESERVED,
'role': role.pk,
'role': roles[1].pk,
'is_pool': True,
'description': 'A new prefix',
'tags': 'Alpha,Bravo,Charlie',
@ -166,6 +196,16 @@ class PrefixTestCase(StandardTestCases.Views):
"10.6.0.0/16,Active",
)
cls.bulk_edit_data = {
'site': sites[1].pk,
'vrf': vrfs[1].pk,
'tenant': None,
'status': PrefixStatusChoices.STATUS_RESERVED,
'role': roles[1].pk,
'is_pool': False,
'description': 'New description',
}
class IPAddressTestCase(StandardTestCases.Views):
model = IPAddress
@ -173,16 +213,19 @@ class IPAddressTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
vrf = VRF.objects.create(name='VRF 1', rd='65000:1')
vrfs = (
VRF(name='VRF 1', rd='65000:1'),
VRF(name='VRF 2', rd='65000:2'),
)
IPAddress.objects.bulk_create([
IPAddress(family=4, address=IPNetwork('192.0.2.1/24'), vrf=vrf),
IPAddress(family=4, address=IPNetwork('192.0.2.2/24'), vrf=vrf),
IPAddress(family=4, address=IPNetwork('192.0.2.3/24'), vrf=vrf),
IPAddress(family=4, address=IPNetwork('192.0.2.1/24'), vrf=vrfs[0]),
IPAddress(family=4, address=IPNetwork('192.0.2.2/24'), vrf=vrfs[0]),
IPAddress(family=4, address=IPNetwork('192.0.2.3/24'), vrf=vrfs[0]),
])
cls.form_data = {
'vrf': vrf.pk,
'vrf': vrfs[1].pk,
'address': IPNetwork('192.0.2.99/24'),
'tenant': None,
'status': IPAddressStatusChoices.STATUS_RESERVED,
@ -201,6 +244,15 @@ class IPAddressTestCase(StandardTestCases.Views):
"192.0.2.6/24,Active",
)
cls.bulk_edit_data = {
'vrf': vrfs[1].pk,
'tenant': None,
'status': IPAddressStatusChoices.STATUS_RESERVED,
'role': IPAddressRoleChoices.ROLE_ANYCAST,
'dns_name': 'example',
'description': 'New description',
}
class VLANGroupTestCase(StandardTestCases.Views):
model = VLANGroup
@ -208,6 +260,7 @@ class VLANGroupTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -240,24 +293,38 @@ class VLANTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
site = Site.objects.create(name='Site 1', slug='site-1')
vlangroup = VLANGroup.objects.create(name='VLAN Group 1', slug='vlan-group-1', site=site)
role = Role.objects.create(name='Role 1', slug='role-1')
sites = (
Site(name='Site 1', slug='site-1'),
Site(name='Site 2', slug='site-2'),
)
Site.objects.bulk_create(sites)
vlangroups = (
VLANGroup(name='VLAN Group 1', slug='vlan-group-1', site=sites[0]),
VLANGroup(name='VLAN Group 2', slug='vlan-group-2', site=sites[1]),
)
VLANGroup.objects.bulk_create(vlangroups)
roles = (
Role(name='Role 1', slug='role-1'),
Role(name='Role 2', slug='role-2'),
)
Role.objects.bulk_create(roles)
VLAN.objects.bulk_create([
VLAN(group=vlangroup, vid=101, name='VLAN101'),
VLAN(group=vlangroup, vid=102, name='VLAN102'),
VLAN(group=vlangroup, vid=103, name='VLAN103'),
VLAN(group=vlangroups[0], vid=101, name='VLAN101', site=sites[0], role=roles[0]),
VLAN(group=vlangroups[0], vid=102, name='VLAN102', site=sites[0], role=roles[0]),
VLAN(group=vlangroups[0], vid=103, name='VLAN103', site=sites[0], role=roles[0]),
])
cls.form_data = {
'site': site.pk,
'group': vlangroup.pk,
'site': sites[1].pk,
'group': vlangroups[1].pk,
'vid': 999,
'name': 'VLAN999',
'tenant': None,
'status': VLANStatusChoices.STATUS_RESERVED,
'role': role.pk,
'role': roles[1].pk,
'description': 'A new VLAN',
'tags': 'Alpha,Bravo,Charlie',
}
@ -269,6 +336,15 @@ class VLANTestCase(StandardTestCases.Views):
"106,VLAN106,Active",
)
cls.bulk_edit_data = {
'site': sites[1].pk,
'group': vlangroups[1].pk,
'tenant': None,
'status': VLANStatusChoices.STATUS_RESERVED,
'role': roles[1].pk,
'description': 'New description',
}
class ServiceTestCase(StandardTestCases.Views):
model = Service
@ -304,3 +380,9 @@ class ServiceTestCase(StandardTestCases.Views):
'description': 'A new service',
'tags': 'Alpha,Bravo,Charlie',
}
cls.bulk_edit_data = {
'protocol': ServiceProtocolChoices.PROTOCOL_UDP,
'port': 888,
'description': 'New description',
}

View File

@ -14,6 +14,7 @@ class SecretRoleTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -56,21 +57,38 @@ class SecretTestCase(StandardTestCases.Views):
manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1')
devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1')
devicerole = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
device = Device.objects.create(name='Device 1', site=site, device_type=devicetype, device_role=devicerole)
secretrole = SecretRole.objects.create(name='Secret Role 1', slug='secret-role-1')
Secret.objects.bulk_create([
Secret(device=device, role=secretrole, name='Secret 1', ciphertext=b'1234567890'),
Secret(device=device, role=secretrole, name='Secret 2', ciphertext=b'1234567890'),
Secret(device=device, role=secretrole, name='Secret 3', ciphertext=b'1234567890'),
])
devices = (
Device(name='Device 1', site=site, device_type=devicetype, device_role=devicerole),
Device(name='Device 2', site=site, device_type=devicetype, device_role=devicerole),
Device(name='Device 3', site=site, device_type=devicetype, device_role=devicerole),
)
Device.objects.bulk_create(devices)
secretroles = (
SecretRole(name='Secret Role 1', slug='secret-role-1'),
SecretRole(name='Secret Role 2', slug='secret-role-2'),
)
SecretRole.objects.bulk_create(secretroles)
# Create one secret per device to allow bulk-editing of names (which must be unique per device/role)
Secret.objects.bulk_create((
Secret(device=devices[0], role=secretroles[0], name='Secret 1', ciphertext=b'1234567890'),
Secret(device=devices[1], role=secretroles[0], name='Secret 2', ciphertext=b'1234567890'),
Secret(device=devices[2], role=secretroles[0], name='Secret 3', ciphertext=b'1234567890'),
))
cls.form_data = {
'device': device.pk,
'role': secretrole.pk,
'device': devices[1].pk,
'role': secretroles[1].pk,
'name': 'Secret X',
}
cls.bulk_edit_data = {
'role': secretroles[1].pk,
'name': 'New name',
}
def setUp(self):
super().setUp()

View File

@ -8,6 +8,7 @@ class TenantGroupTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -37,18 +38,22 @@ class TenantTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
tenantgroup = TenantGroup.objects.create(name='Tenant Group 1', slug='tenant-group-1')
tenantgroups = (
TenantGroup(name='Tenant Group 1', slug='tenant-group-1'),
TenantGroup(name='Tenant Group 2', slug='tenant-group-2'),
)
TenantGroup.objects.bulk_create(tenantgroups)
Tenant.objects.bulk_create([
Tenant(name='Tenant 1', slug='tenant-1', group=tenantgroup),
Tenant(name='Tenant 2', slug='tenant-2', group=tenantgroup),
Tenant(name='Tenant 3', slug='tenant-3', group=tenantgroup),
Tenant(name='Tenant 1', slug='tenant-1', group=tenantgroups[0]),
Tenant(name='Tenant 2', slug='tenant-2', group=tenantgroups[0]),
Tenant(name='Tenant 3', slug='tenant-3', group=tenantgroups[0]),
])
cls.form_data = {
'name': 'Tenant X',
'slug': 'tenant-x',
'group': tenantgroup.pk,
'group': tenantgroups[1].pk,
'description': 'A new tenant',
'comments': 'Some comments',
'tags': 'Alpha,Bravo,Charlie',
@ -60,3 +65,7 @@ class TenantTestCase(StandardTestCases.Views):
"Tenant 5,tenant-5",
"Tenant 6,tenant-6",
)
cls.bulk_edit_data = {
'group': tenantgroups[1].pk,
}

View File

@ -85,8 +85,15 @@ class StandardTestCases:
- Import multiple new objects
"""
model = None
# Data to be sent when creating/editing individual objects
form_data = {}
csv_data = {}
# CSV lines used for bulk import of new objects
csv_data = ()
# Form data to be used when editing multiple objects at once
bulk_edit_data = {}
maxDiff = None
@ -107,7 +114,7 @@ class StandardTestCases:
self.model._meta.model_name
)
if action in ('list', 'add', 'import'):
if action in ('list', 'add', 'import', 'bulk_edit', 'bulk_delete'):
return reverse(url_format.format(action))
elif action in ('get', 'edit', 'delete'):
@ -253,3 +260,66 @@ class StandardTestCases:
self.assertHttpStatus(response, 200)
self.assertEqual(self.model.objects.count(), initial_count + len(self.csv_data) - 1)
@override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_bulk_edit_objects(self):
pk_list = self.model.objects.values_list('pk', flat=True)
request = {
'path': self._get_url('bulk_edit'),
'data': {
'pk': pk_list,
'_apply': True, # Form button
},
'follow': False, # Do not follow 302 redirects
}
# Append the form data to the request
request['data'].update(post_data(self.bulk_edit_data))
# Attempt to make the request without required permissions
with disable_warnings('django.request'):
self.assertHttpStatus(self.client.post(**request), 403)
# Assign the required permission and submit again
self.add_permissions(
'{}.change_{}'.format(self.model._meta.app_label, self.model._meta.model_name)
)
response = self.client.post(**request)
self.assertHttpStatus(response, 302)
bulk_edit_fields = self.bulk_edit_data.keys()
for i, instance in enumerate(self.model.objects.filter(pk__in=pk_list)):
self.assertDictEqual(
model_to_dict(instance, fields=bulk_edit_fields),
self.bulk_edit_data,
msg="Instance {} failed to validate after bulk edit: {}".format(i, instance)
)
@override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_bulk_delete_objects(self):
pk_list = self.model.objects.values_list('pk', flat=True)
request = {
'path': self._get_url('bulk_delete'),
'data': {
'pk': pk_list,
'confirm': True,
'_confirm': True, # Form button
},
'follow': False, # Do not follow 302 redirects
}
# Attempt to make the request without required permissions
with disable_warnings('django.request'):
self.assertHttpStatus(self.client.post(**request), 403)
# Assign the required permission and submit again
self.add_permissions(
'{}.delete_{}'.format(self.model._meta.app_label, self.model._meta.model_name)
)
response = self.client.post(**request)
self.assertHttpStatus(response, 302)
# Check that all objects were deleted
self.assertEqual(self.model.objects.count(), 0)

View File

@ -4,11 +4,10 @@ from copy import deepcopy
from django.conf import settings
from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.core.exceptions import FieldDoesNotExist, ValidationError
from django.db import transaction, IntegrityError
from django.db.models import Count, ManyToManyField, ProtectedError
from django.db.models.query import QuerySet
from django.forms import CharField, Form, ModelMultipleChoiceField, MultipleHiddenInput, Textarea
from django.forms import Form, ModelMultipleChoiceField, MultipleHiddenInput, Textarea
from django.http import HttpResponse, HttpResponseServerError
from django.shortcuts import get_object_or_404, redirect, render
from django.template import loader
@ -651,7 +650,7 @@ class BulkEditView(GetReturnURLMixin, View):
custom_fields = form.custom_fields if hasattr(form, 'custom_fields') else []
standard_fields = [
field for field in form.fields if field not in custom_fields + ['pk', 'add_tags', 'remove_tags']
field for field in form.fields if field not in custom_fields + ['pk']
]
nullified_fields = request.POST.getlist('_nullify')
@ -665,7 +664,12 @@ class BulkEditView(GetReturnURLMixin, View):
# Update standard fields. If a field is listed in _nullify, delete its value.
for name in standard_fields:
model_field = model._meta.get_field(name)
try:
model_field = model._meta.get_field(name)
except FieldDoesNotExist:
# The form field is used to modify a field rather than set its value directly,
# so we skip it.
continue
# Handle nullification
if name in form.nullable_fields and name in nullified_fields:

View File

@ -10,6 +10,7 @@ class ClusterGroupTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -39,6 +40,7 @@ class ClusterTypeTestCase(StandardTestCases.Views):
# Disable inapplicable tests
test_get_object = None
test_delete_object = None
test_bulk_edit_objects = None
@classmethod
def setUpTestData(cls):
@ -68,22 +70,36 @@ class ClusterTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
site = Site.objects.create(name='Site 1', slug='site-1')
clustergroup = ClusterGroup.objects.create(name='Cluster Group 1', slug='cluster-group-1')
clustertype = ClusterType.objects.create(name='Cluster Type 1', slug='cluster-type-1')
sites = (
Site(name='Site 1', slug='site-1'),
Site(name='Site 2', slug='site-2'),
)
Site.objects.bulk_create(sites)
clustergroups = (
ClusterGroup(name='Cluster Group 1', slug='cluster-group-1'),
ClusterGroup(name='Cluster Group 2', slug='cluster-group-2'),
)
ClusterGroup.objects.bulk_create(clustergroups)
clustertypes = (
ClusterType(name='Cluster Type 1', slug='cluster-type-1'),
ClusterType(name='Cluster Type 2', slug='cluster-type-2'),
)
ClusterType.objects.bulk_create(clustertypes)
Cluster.objects.bulk_create([
Cluster(name='Cluster 1', group=clustergroup, type=clustertype),
Cluster(name='Cluster 2', group=clustergroup, type=clustertype),
Cluster(name='Cluster 3', group=clustergroup, type=clustertype),
Cluster(name='Cluster 1', group=clustergroups[0], type=clustertypes[0], site=sites[0]),
Cluster(name='Cluster 2', group=clustergroups[0], type=clustertypes[0], site=sites[0]),
Cluster(name='Cluster 3', group=clustergroups[0], type=clustertypes[0], site=sites[0]),
])
cls.form_data = {
'name': 'Cluster X',
'group': clustergroup.pk,
'type': clustertype.pk,
'group': clustergroups[1].pk,
'type': clustertypes[1].pk,
'tenant': None,
'site': site.pk,
'site': sites[1].pk,
'comments': 'Some comments',
'tags': 'Alpha,Bravo,Charlie',
}
@ -95,6 +111,14 @@ class ClusterTestCase(StandardTestCases.Views):
"Cluster 6,Cluster Type 1",
)
cls.bulk_edit_data = {
'group': clustergroups[1].pk,
'type': clustertypes[1].pk,
'tenant': None,
'site': sites[1].pk,
'comments': 'New comments',
}
class VirtualMachineTestCase(StandardTestCases.Views):
model = VirtualMachine
@ -102,24 +126,39 @@ class VirtualMachineTestCase(StandardTestCases.Views):
@classmethod
def setUpTestData(cls):
devicerole = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
platform = Platform.objects.create(name='Platform 1', slug='platform-1')
deviceroles = (
DeviceRole(name='Device Role 1', slug='device-role-1'),
DeviceRole(name='Device Role 2', slug='device-role-2'),
)
DeviceRole.objects.bulk_create(deviceroles)
platforms = (
Platform(name='Platform 1', slug='platform-1'),
Platform(name='Platform 2', slug='platform-2'),
)
Platform.objects.bulk_create(platforms)
clustertype = ClusterType.objects.create(name='Cluster Type 1', slug='cluster-type-1')
cluster = Cluster.objects.create(name='Cluster 1', type=clustertype)
clusters = (
Cluster(name='Cluster 1', type=clustertype),
Cluster(name='Cluster 2', type=clustertype),
)
Cluster.objects.bulk_create(clusters)
VirtualMachine.objects.bulk_create([
VirtualMachine(name='Virtual Machine 1', cluster=cluster),
VirtualMachine(name='Virtual Machine 2', cluster=cluster),
VirtualMachine(name='Virtual Machine 3', cluster=cluster),
VirtualMachine(name='Virtual Machine 1', cluster=clusters[0], role=deviceroles[0], platform=platforms[0]),
VirtualMachine(name='Virtual Machine 2', cluster=clusters[0], role=deviceroles[0], platform=platforms[0]),
VirtualMachine(name='Virtual Machine 3', cluster=clusters[0], role=deviceroles[0], platform=platforms[0]),
])
cls.form_data = {
'cluster': cluster.pk,
'cluster': clusters[1].pk,
'tenant': None,
'platform': None,
'platform': platforms[1].pk,
'name': 'Virtual Machine X',
'status': VirtualMachineStatusChoices.STATUS_STAGED,
'role': devicerole.pk,
'role': deviceroles[1].pk,
'primary_ip4': None,
'primary_ip6': None,
'vcpus': 4,
@ -136,3 +175,15 @@ class VirtualMachineTestCase(StandardTestCases.Views):
"Virtual Machine 5,Cluster 1",
"Virtual Machine 6,Cluster 1",
)
cls.bulk_edit_data = {
'cluster': clusters[1].pk,
'tenant': None,
'platform': platforms[1].pk,
'status': VirtualMachineStatusChoices.STATUS_STAGED,
'role': deviceroles[1].pk,
'vcpus': 8,
'memory': 65535,
'disk': 8000,
'comments': 'New comments',
}