content: import django_filters
  from django.conf import settings
  from django.db import models
  from django.test import TestCase
  from mptt.fields import TreeForeignKey
  from taggit.managers import TaggableManager
  
  from dcim.choices import *
  from dcim.fields import MACAddressField
  from dcim.filtersets import DeviceFilterSet, SiteFilterSet, InterfaceFilterSet
  from dcim.models import (
      Device, DeviceRole, DeviceType, Interface, MACAddress, Manufacturer, Platform, Rack, Region, Site
  )
  from extras.filters import TagFilter
  from extras.models import TaggedItem
  from ipam.filtersets import ASNFilterSet
  from ipam.models import RIR, ASN
  from netbox.filtersets import BaseFilterSet
  from wireless.choices import WirelessRoleChoices
  from utilities.filters import (
      MultiValueCharFilter, MultiValueDateFilter, MultiValueDateTimeFilter, MultiValueMACAddressFilter,
      MultiValueNumberFilter, MultiValueTimeFilter, TreeNodeMultipleChoiceFilter,
  )
  
  
  class TreeNodeMultipleChoiceFilterTest(TestCase):
  
      class SiteFilterSet(django_filters.FilterSet):
          region = TreeNodeMultipleChoiceFilter(
              queryset=Region.objects.all(),
              field_name='region',
              lookup_expr='in',
              to_field_name='slug',
          )
  
      def setUp(self):
  
          super().setUp()
  
          self.region1 = Region.objects.create(name='Test Region 1', slug='test-region-1')
          self.region2 = Region.objects.create(name='Test Region 2', slug='test-region-2')
          self.site1 = Site.objects.create(region=self.region1, name='Test Site 1', slug='test-site1')
          self.site2 = Site.objects.create(region=self.region2, name='Test Site 2', slug='test-site2')
          self.site3 = Site.objects.create(region=None, name='Test Site 3', slug='test-site3')
  
          self.queryset = Site.objects.all()
  
      def test_filter_single(self):
  
          kwargs = {'region': ['test-region-1']}
          qs = self.SiteFilterSet(kwargs, self.queryset).qs
  
          self.assertEqual(qs.count(), 1)
          self.assertEqual(qs[0], self.site1)
  
      def test_filter_multiple(self):
  
          kwargs = {'region': ['test-region-1', 'test-region-2']}
          qs = self.SiteFilterSet(kwargs, self.queryset).qs
  
          self.assertEqual(qs.count(), 2)
          self.assertEqual(qs[0], self.site1)
          self.assertEqual(qs[1], self.site2)
  
      def test_filter_null(self):
  
          kwargs = {'region': [settings.FILTERS_NULL_CHOICE_VALUE]}
          qs = self.SiteFilterSet(kwargs, self.queryset).qs
  
          self.assertEqual(qs.count(), 1)
          self.assertEqual(qs[0], self.site3)
  
      def test_filter_combined(self):
  
          kwargs = {'region': ['test-region-1', settings.FILTERS_NULL_CHOICE_VALUE]}
          qs = self.SiteFilterSet(kwargs, self.queryset).qs
  
          self.assertEqual(qs.count(), 2)
          self.assertEqual(qs[0], self.site1)
          self.assertEqual(qs[1], self.site3)
  
  
  class DummyModel(models.Model):
      """
      Dummy model used by BaseFilterSetTest for filter validation. Should never appear in a schema migration.
      """
      charfield = models.CharField(
          max_length=10
      )
      numberfield = models.IntegerField(
          blank=True,
          null=True
      )
      choicefield = models.IntegerField(
          choices=(('A', 1), ('B', 2), ('C', 3))
      )
      datefield = models.DateField()
      datetimefield = models.DateTimeField()
      integerfield = models.IntegerField()
      macaddressfield = MACAddressField()
      timefield = models.TimeField()
      treeforeignkeyfield = TreeForeignKey(
          to='self',
          on_delete=models.CASCADE
      )
  
      tags = TaggableManager(through=TaggedItem)
  
  
  class BaseFilterSetTest(TestCase):
      """
      Ensure that a BaseFilterSet automatically creates the expected set of filters for each filter type.
      """
      class DummyFilterSet(BaseFilterSet):
          charfield = django_filters.CharFilter()
          numberfield = django_filters.NumberFilter()
          macaddressfield = MultiValueMACAddressFilter()
          modelchoicefield = django_filters.ModelChoiceFilter(
              field_name='integerfield',  # We're pretending this is a ForeignKey field
              queryset=Site.objects.all()
          )
          modelmultiplechoicefield = django_filters.ModelMultipleChoiceFilter(
              field_name='integerfield',  # We're pretending this is a ForeignKey field
              queryset=Site.objects.all()
          )
          multiplechoicefield = django_filters.MultipleChoiceFilter(
              field_name='choicefield'
          )
          multivaluecharfield = MultiValueCharFilter(
              field_name='charfield'
          )
          tagfield = TagFilter()
          treeforeignkeyfield = TreeNodeMultipleChoiceFilter(
              queryset=DummyModel.objects.all()
          )
  
          class Meta:
              model = DummyModel
              fields = (
                  'charfield',
                  'numberfield',
                  'choicefield',
                  'datefield',
                  'datetimefield',
                  'integerfield',
                  'macaddressfield',
                  'modelchoicefield',
                  'modelmultiplechoicefield',
                  'multiplechoicefield',
                  'tagfield',
                  'timefield',
                  'treeforeignkeyfield',
              )
  
      @classmethod
      def setUpTestData(cls):
          cls.filters = cls.DummyFilterSet().filters
  
      def test_char_filter(self):
          self.assertIsInstance(self.filters['charfield'], django_filters.CharFilter)
          self.assertEqual(self.filters['charfield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['charfield'].exclude, False)
          self.assertEqual(self.filters['charfield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['charfield__n'].exclude, True)
          self.assertEqual(self.filters['charfield__ie'].lookup_expr, 'iexact')
          self.assertEqual(self.filters['charfield__ie'].exclude, False)
          self.assertEqual(self.filters['charfield__nie'].lookup_expr, 'iexact')
          self.assertEqual(self.filters['charfield__nie'].exclude, True)
          self.assertEqual(self.filters['charfield__ic'].lookup_expr, 'icontains')
          self.assertEqual(self.filters['charfield__ic'].exclude, False)
          self.assertEqual(self.filters['charfield__nic'].lookup_expr, 'icontains')
          self.assertEqual(self.filters['charfield__nic'].exclude, True)
          self.assertEqual(self.filters['charfield__isw'].lookup_expr, 'istartswith')
          self.assertEqual(self.filters['charfield__isw'].exclude, False)
          self.assertEqual(self.filters['charfield__nisw'].lookup_expr, 'istartswith')
          self.assertEqual(self.filters['charfield__nisw'].exclude, True)
          self.assertEqual(self.filters['charfield__iew'].lookup_expr, 'iendswith')
          self.assertEqual(self.filters['charfield__iew'].exclude, False)
          self.assertEqual(self.filters['charfield__niew'].lookup_expr, 'iendswith')
          self.assertEqual(self.filters['charfield__niew'].exclude, True)
          self.assertEqual(self.filters['charfield__empty'].lookup_expr, 'empty')
          self.assertEqual(self.filters['charfield__empty'].exclude, False)
          self.assertEqual(self.filters['charfield__regex'].lookup_expr, 'regex')
          self.assertEqual(self.filters['charfield__regex'].exclude, False)
          self.assertEqual(self.filters['charfield__iregex'].lookup_expr, 'iregex')
          self.assertEqual(self.filters['charfield__iregex'].exclude, False)
  
      def test_number_filter(self):
          self.assertIsInstance(self.filters['numberfield'], django_filters.NumberFilter)
          self.assertEqual(self.filters['numberfield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['numberfield'].exclude, False)
          self.assertEqual(self.filters['numberfield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['numberfield__n'].exclude, True)
          self.assertEqual(self.filters['numberfield__lt'].lookup_expr, 'lt')
          self.assertEqual(self.filters['numberfield__lt'].exclude, False)
          self.assertEqual(self.filters['numberfield__lte'].lookup_expr, 'lte')
          self.assertEqual(self.filters['numberfield__lte'].exclude, False)
          self.assertEqual(self.filters['numberfield__gt'].lookup_expr, 'gt')
          self.assertEqual(self.filters['numberfield__gt'].exclude, False)
          self.assertEqual(self.filters['numberfield__gte'].lookup_expr, 'gte')
          self.assertEqual(self.filters['numberfield__gte'].exclude, False)
          self.assertEqual(self.filters['numberfield__empty'].lookup_expr, 'isnull')
          self.assertEqual(self.filters['numberfield__empty'].exclude, False)
  
      def test_mac_address_filter(self):
          self.assertIsInstance(self.filters['macaddressfield'], MultiValueMACAddressFilter)
          self.assertEqual(self.filters['macaddressfield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['macaddressfield'].exclude, False)
          self.assertEqual(self.filters['macaddressfield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['macaddressfield__n'].exclude, True)
          self.assertEqual(self.filters['macaddressfield__ie'].lookup_expr, 'iexact')
          self.assertEqual(self.filters['macaddressfield__ie'].exclude, False)
          self.assertEqual(self.filters['macaddressfield__nie'].lookup_expr, 'iexact')
          self.assertEqual(self.filters['macaddressfield__nie'].exclude, True)
          self.assertEqual(self.filters['macaddressfield__ic'].lookup_expr, 'icontains')
          self.assertEqual(self.filters['macaddressfield__ic'].exclude, False)
          self.assertEqual(self.filters['macaddressfield__nic'].lookup_expr, 'icontains')
          self.assertEqual(self.filters['macaddressfield__nic'].exclude, True)
          self.assertEqual(self.filters['macaddressfield__isw'].lookup_expr, 'istartswith')
          self.assertEqual(self.filters['macaddressfield__isw'].exclude, False)
          self.assertEqual(self.filters['macaddressfield__nisw'].lookup_expr, 'istartswith')
          self.assertEqual(self.filters['macaddressfield__nisw'].exclude, True)
          self.assertEqual(self.filters['macaddressfield__iew'].lookup_expr, 'iendswith')
          self.assertEqual(self.filters['macaddressfield__iew'].exclude, False)
          self.assertEqual(self.filters['macaddressfield__niew'].lookup_expr, 'iendswith')
          self.assertEqual(self.filters['macaddressfield__niew'].exclude, True)
          self.assertEqual(self.filters['macaddressfield__regex'].lookup_expr, 'regex')
          self.assertEqual(self.filters['macaddressfield__regex'].exclude, False)
          self.assertEqual(self.filters['macaddressfield__iregex'].lookup_expr, 'iregex')
          self.assertEqual(self.filters['macaddressfield__iregex'].exclude, False)
  
      def test_model_choice_filter(self):
          self.assertIsInstance(self.filters['modelchoicefield'], django_filters.ModelChoiceFilter)
          self.assertEqual(self.filters['modelchoicefield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['modelchoicefield'].exclude, False)
          self.assertEqual(self.filters['modelchoicefield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['modelchoicefield__n'].exclude, True)
  
      def test_model_multiple_choice_filter(self):
          self.assertIsInstance(self.filters['modelmultiplechoicefield'], django_filters.ModelMultipleChoiceFilter)
          self.assertEqual(self.filters['modelmultiplechoicefield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['modelmultiplechoicefield'].exclude, False)
          self.assertEqual(self.filters['modelmultiplechoicefield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['modelmultiplechoicefield__n'].exclude, True)
  
      def test_multi_value_char_filter(self):
          self.assertIsInstance(self.filters['multivaluecharfield'], MultiValueCharFilter)
          self.assertEqual(self.filters['multivaluecharfield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['multivaluecharfield'].exclude, False)
          self.assertEqual(self.filters['multivaluecharfield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['multivaluecharfield__n'].exclude, True)
          self.assertEqual(self.filters['multivaluecharfield__ie'].lookup_expr, 'iexact')
          self.assertEqual(self.filters['multivaluecharfield__ie'].exclude, False)
          self.assertEqual(self.filters['multivaluecharfield__nie'].lookup_expr, 'iexact')
          self.assertEqual(self.filters['multivaluecharfield__nie'].exclude, True)
          self.assertEqual(self.filters['multivaluecharfield__ic'].lookup_expr, 'icontains')
          self.assertEqual(self.filters['multivaluecharfield__ic'].exclude, False)
          self.assertEqual(self.filters['multivaluecharfield__nic'].lookup_expr, 'icontains')
          self.assertEqual(self.filters['multivaluecharfield__nic'].exclude, True)
          self.assertEqual(self.filters['multivaluecharfield__isw'].lookup_expr, 'istartswith')
          self.assertEqual(self.filters['multivaluecharfield__isw'].exclude, False)
          self.assertEqual(self.filters['multivaluecharfield__nisw'].lookup_expr, 'istartswith')
          self.assertEqual(self.filters['multivaluecharfield__nisw'].exclude, True)
          self.assertEqual(self.filters['multivaluecharfield__iew'].lookup_expr, 'iendswith')
          self.assertEqual(self.filters['multivaluecharfield__iew'].exclude, False)
          self.assertEqual(self.filters['multivaluecharfield__niew'].lookup_expr, 'iendswith')
          self.assertEqual(self.filters['multivaluecharfield__niew'].exclude, True)
          self.assertEqual(self.filters['multivaluecharfield__regex'].lookup_expr, 'regex')
          self.assertEqual(self.filters['multivaluecharfield__regex'].exclude, False)
          self.assertEqual(self.filters['multivaluecharfield__iregex'].lookup_expr, 'iregex')
          self.assertEqual(self.filters['multivaluecharfield__iregex'].exclude, False)
  
      def test_multi_value_date_filter(self):
          self.assertIsInstance(self.filters['datefield'], MultiValueDateFilter)
          self.assertEqual(self.filters['datefield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['datefield'].exclude, False)
          self.assertEqual(self.filters['datefield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['datefield__n'].exclude, True)
          self.assertEqual(self.filters['datefield__lt'].lookup_expr, 'lt')
          self.assertEqual(self.filters['datefield__lt'].exclude, False)
          self.assertEqual(self.filters['datefield__lte'].lookup_expr, 'lte')
          self.assertEqual(self.filters['datefield__lte'].exclude, False)
          self.assertEqual(self.filters['datefield__gt'].lookup_expr, 'gt')
          self.assertEqual(self.filters['datefield__gt'].exclude, False)
          self.assertEqual(self.filters['datefield__gte'].lookup_expr, 'gte')
          self.assertEqual(self.filters['datefield__gte'].exclude, False)
  
      def test_multi_value_datetime_filter(self):
          self.assertIsInstance(self.filters['datetimefield'], MultiValueDateTimeFilter)
          self.assertEqual(self.filters['datetimefield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['datetimefield'].exclude, False)
          self.assertEqual(self.filters['datetimefield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['datetimefield__n'].exclude, True)
          self.assertEqual(self.filters['datetimefield__lt'].lookup_expr, 'lt')
          self.assertEqual(self.filters['datetimefield__lt'].exclude, False)
          self.assertEqual(self.filters['datetimefield__lte'].lookup_expr, 'lte')
          self.assertEqual(self.filters['datetimefield__lte'].exclude, False)
          self.assertEqual(self.filters['datetimefield__gt'].lookup_expr, 'gt')
          self.assertEqual(self.filters['datetimefield__gt'].exclude, False)
          self.assertEqual(self.filters['datetimefield__gte'].lookup_expr, 'gte')
          self.assertEqual(self.filters['datetimefield__gte'].exclude, False)
  
      def test_multi_value_number_filter(self):
          self.assertIsInstance(self.filters['integerfield'], MultiValueNumberFilter)
          self.assertEqual(self.filters['integerfield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['integerfield'].exclude, False)
          self.assertEqual(self.filters['integerfield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['integerfield__n'].exclude, True)
          self.assertEqual(self.filters['integerfield__lt'].lookup_expr, 'lt')
          self.assertEqual(self.filters['integerfield__lt'].exclude, False)
          self.assertEqual(self.filters['integerfield__lte'].lookup_expr, 'lte')
          self.assertEqual(self.filters['integerfield__lte'].exclude, False)
          self.assertEqual(self.filters['integerfield__gt'].lookup_expr, 'gt')
          self.assertEqual(self.filters['integerfield__gt'].exclude, False)
          self.assertEqual(self.filters['integerfield__gte'].lookup_expr, 'gte')
          self.assertEqual(self.filters['integerfield__gte'].exclude, False)
  
      def test_multi_value_time_filter(self):
          self.assertIsInstance(self.filters['timefield'], MultiValueTimeFilter)
          self.assertEqual(self.filters['timefield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['timefield'].exclude, False)
          self.assertEqual(self.filters['timefield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['timefield__n'].exclude, True)
          self.assertEqual(self.filters['timefield__lt'].lookup_expr, 'lt')
          self.assertEqual(self.filters['timefield__lt'].exclude, False)
          self.assertEqual(self.filters['timefield__lte'].lookup_expr, 'lte')
          self.assertEqual(self.filters['timefield__lte'].exclude, False)
          self.assertEqual(self.filters['timefield__gt'].lookup_expr, 'gt')
          self.assertEqual(self.filters['timefield__gt'].exclude, False)
          self.assertEqual(self.filters['timefield__gte'].lookup_expr, 'gte')
          self.assertEqual(self.filters['timefield__gte'].exclude, False)
  
      def test_multiple_choice_filter(self):
          self.assertIsInstance(self.filters['multiplechoicefield'], django_filters.MultipleChoiceFilter)
          self.assertEqual(self.filters['multiplechoicefield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['multiplechoicefield'].exclude, False)
          self.assertEqual(self.filters['multiplechoicefield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['multiplechoicefield__n'].exclude, True)
          self.assertEqual(self.filters['multiplechoicefield__ie'].lookup_expr, 'iexact')
          self.assertEqual(self.filters['multiplechoicefield__ie'].exclude, False)
          self.assertEqual(self.filters['multiplechoicefield__nie'].lookup_expr, 'iexact')
          self.assertEqual(self.filters['multiplechoicefield__nie'].exclude, True)
          self.assertEqual(self.filters['multiplechoicefield__ic'].lookup_expr, 'icontains')
          self.assertEqual(self.filters['multiplechoicefield__ic'].exclude, False)
          self.assertEqual(self.filters['multiplechoicefield__nic'].lookup_expr, 'icontains')
          self.assertEqual(self.filters['multiplechoicefield__nic'].exclude, True)
          self.assertEqual(self.filters['multiplechoicefield__isw'].lookup_expr, 'istartswith')
          self.assertEqual(self.filters['multiplechoicefield__isw'].exclude, False)
          self.assertEqual(self.filters['multiplechoicefield__nisw'].lookup_expr, 'istartswith')
          self.assertEqual(self.filters['multiplechoicefield__nisw'].exclude, True)
          self.assertEqual(self.filters['multiplechoicefield__iew'].lookup_expr, 'iendswith')
          self.assertEqual(self.filters['multiplechoicefield__iew'].exclude, False)
          self.assertEqual(self.filters['multiplechoicefield__niew'].lookup_expr, 'iendswith')
          self.assertEqual(self.filters['multiplechoicefield__niew'].exclude, True)
          self.assertEqual(self.filters['multiplechoicefield__regex'].lookup_expr, 'regex')
          self.assertEqual(self.filters['multiplechoicefield__regex'].exclude, False)
          self.assertEqual(self.filters['multiplechoicefield__iregex'].lookup_expr, 'iregex')
          self.assertEqual(self.filters['multiplechoicefield__iregex'].exclude, False)
  
      def test_tag_filter(self):
          self.assertIsInstance(self.filters['tagfield'], TagFilter)
          self.assertEqual(self.filters['tagfield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['tagfield'].exclude, False)
          self.assertEqual(self.filters['tagfield__n'].lookup_expr, 'exact')
          self.assertEqual(self.filters['tagfield__n'].exclude, True)
  
      def test_tree_node_multiple_choice_filter(self):
          self.assertIsInstance(self.filters['treeforeignkeyfield'], TreeNodeMultipleChoiceFilter)
          # TODO: lookup_expr different for negation?
          self.assertEqual(self.filters['treeforeignkeyfield'].lookup_expr, 'exact')
          self.assertEqual(self.filters['treeforeignkeyfield'].exclude, False)
          self.assertEqual(self.filters['treeforeignkeyfield__n'].lookup_expr, 'in')
          self.assertEqual(self.filters['treeforeignkeyfield__n'].exclude, True)
  
  
  class DynamicFilterLookupExpressionTest(TestCase):
      """
      Validate function of automatically generated filters using the Device model as an example.
      """
      @classmethod
      def setUpTestData(cls):
          rir = RIR.objects.create(name='RIR 1', slug='rir-1')
  
          asns = (
              ASN(asn=65001, rir=rir),
              ASN(asn=65101, rir=rir),
              ASN(asn=65201, rir=rir),
          )
          ASN.objects.bulk_create(asns)
  
          manufacturers = (
              Manufacturer(name='Manufacturer 1', slug='manufacturer-1'),
              Manufacturer(name='Manufacturer 2', slug='manufacturer-2'),
              Manufacturer(name='Manufacturer 3', slug='manufacturer-3'),
          )
          Manufacturer.objects.bulk_create(manufacturers)
  
          device_types = (
              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.objects.bulk_create(device_types)
  
          roles = (
              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'),
          )
          for role in roles:
              role.save()
  
          platforms = (
              Platform(name='Platform 1', slug='platform-1'),
              Platform(name='Platform 2', slug='platform-2'),
              Platform(name='Platform 3', slug='platform-3'),
          )
          for platform in platforms:
              platform.save()
  
          regions = (
              Region(name='Region 1', slug='region-1'),
              Region(name='Region 2', slug='region-2'),
              Region(name='Region 3', slug='region-3'),
          )
          for region in regions:
              region.save()
  
          sites = (
              Site(name='Site 1', slug='abc-site-1', region=regions[0], status=SiteStatusChoices.STATUS_ACTIVE),
              Site(name='Site 2', slug='def-site-2', region=regions[1], status=SiteStatusChoices.STATUS_ACTIVE),
              Site(name='Site 3', slug='ghi-site-3', region=regions[2], status=SiteStatusChoices.STATUS_PLANNED),
          )
          Site.objects.bulk_create(sites)
  
          asns[0].sites.add(sites[0])
          asns[1].sites.add(sites[1])
          asns[2].sites.add(sites[2])
  
          racks = (
              Rack(name='Rack 1', site=sites[0]),
              Rack(name='Rack 2', site=sites[1]),
              Rack(name='Rack 3', site=sites[2]),
          )
          Rack.objects.bulk_create(racks)
  
          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.objects.bulk_create(devices)
  
          mac_addresses = (
              MACAddress(mac_address='00-00-00-00-00-01'),
              MACAddress(mac_address='aa-00-00-00-00-01'),
              MACAddress(mac_address='00-00-00-00-00-02'),
              MACAddress(mac_address='bb-00-00-00-00-02'),
              MACAddress(mac_address='00-00-00-00-00-03'),
              MACAddress(mac_address='cc-00-00-00-00-03'),
          )
          MACAddress.objects.bulk_create(mac_addresses)
  
          interfaces = (
              Interface(device=devices[0], name='Interface 1'),
              Interface(device=devices[0], name='Interface 2'),
              Interface(device=devices[1], name='Interface 3'),
              Interface(device=devices[1], name='Interface 4'),
              Interface(device=devices[2], name='Interface 5'),
              Interface(device=devices[2], name='Interface 6', rf_role=WirelessRoleChoices.ROLE_AP),
          )
          Interface.objects.bulk_create(interfaces)
  
          interfaces[0].mac_addresses.set([mac_addresses[0]])
          interfaces[1].mac_addresses.set([mac_addresses[1]])
          interfaces[2].mac_addresses.set([mac_addresses[2]])
          interfaces[3].mac_addresses.set([mac_addresses[3]])
          interfaces[4].mac_addresses.set([mac_addresses[4]])
          interfaces[5].mac_addresses.set([mac_addresses[5]])
  
      def test_site_name_negation(self):
          params = {'name__n': ['Site 1']}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
  
      def test_site_status_icontains(self):
          params = {'status__ic': [SiteStatusChoices.STATUS_ACTIVE]}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
  
      def test_site_status_icontains_negation(self):
          params = {'status__nic': [SiteStatusChoices.STATUS_ACTIVE]}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
  
      def test_site_slug_icontains(self):
          params = {'slug__ic': ['-1']}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
  
      def test_site_slug_icontains_negation(self):
          params = {'slug__nic': ['-1']}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
  
      def test_site_slug_startswith(self):
          params = {'slug__isw': ['abc']}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
  
      def test_site_slug_startswith_negation(self):
          params = {'slug__nisw': ['abc']}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
  
      def test_site_slug_endswith(self):
          params = {'slug__iew': ['-1']}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
  
      def test_site_slug_endswith_negation(self):
          params = {'slug__niew': ['-1']}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
  
      def test_site_slug_regex(self):
          params = {'slug__regex': ['^def-[a-z]*-2$']}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
  
      def test_site_slug_iregex(self):
          params = {'slug__iregex': ['^DEF-[a-z]*-2$']}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
  
      def test_provider_asn_lt(self):
          params = {'asn__lt': [65101]}
          self.assertEqual(ASNFilterSet(params, ASN.objects.all()).qs.count(), 1)
  
      def test_provider_asn_lte(self):
          params = {'asn__lte': [65101]}
          self.assertEqual(ASNFilterSet(params, ASN.objects.all()).qs.count(), 2)
  
      def test_provider_asn_gt(self):
          params = {'asn__lt': [65101]}
          self.assertEqual(ASNFilterSet(params, ASN.objects.all()).qs.count(), 1)
  
      def test_provider_asn_gte(self):
          params = {'asn__gte': [65101]}
          self.assertEqual(ASNFilterSet(params, ASN.objects.all()).qs.count(), 2)
  
      def test_site_region_negation(self):
          params = {'region__n': ['region-1']}
          self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
  
      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)
  
      def test_device_name_eq(self):
          params = {'name': ['Device 1']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1)
  
      def test_device_name_negation(self):
          params = {'name__n': ['Device 1']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2)
  
      def test_device_name_startswith(self):
          params = {'name__isw': ['Device']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 3)
  
      def test_device_name_startswith_negation(self):
          params = {'name__nisw': ['Device 1']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2)
  
      def test_device_name_endswith(self):
          params = {'name__iew': [' 1']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1)
  
      def test_device_name_endswith_negation(self):
          params = {'name__niew': [' 1']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2)
  
      def test_device_name_icontains(self):
          params = {'name__ic': [' 2']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1)
  
      def test_device_name_icontains_negation(self):
          params = {'name__nic': [' ']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 0)
  
      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)
  
      def test_device_mac_address_startswith(self):
          params = {'mac_address__isw': ['aa:']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1)
  
      def test_device_mac_address_startswith_negation(self):
          params = {'mac_address__nisw': ['aa:']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2)
  
      def test_device_mac_address_endswith(self):
          params = {'mac_address__iew': [':02']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1)
  
      def test_device_mac_address_endswith_negation(self):
          params = {'mac_address__niew': [':02']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 2)
  
      def test_device_mac_address_icontains(self):
          params = {'mac_address__ic': ['aa:', 'bb']}
          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)
  
      def test_device_mac_address_regex(self):
          params = {'mac_address__regex': ['^cc.*:03$']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1)
  
      def test_device_mac_address_iregex(self):
          params = {'mac_address__iregex': ['^CC.*:03$']}
          self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1)
  
      def test_interface_rf_role_empty(self):
          params = {'rf_role__empty': 'true'}
          self.assertEqual(InterfaceFilterSet(params, Interface.objects.all()).qs.count(), 5)
          params = {'rf_role__empty': 'false'}
  