Exemple #1
0
class TestDataCenterAssetForm(RalphTestCase):
    def setUp(self):
        self.dca = DataCenterAssetFactory(rack=RackFactory(), position=1)
        self.dca1 = DataCenterAssetFactory(rack=RackFactory(), position=2)

        self.user = get_user_model().objects.create_superuser(
            username='******',
            password='******',
            email='*****@*****.**'
        )
        result = self.client.login(username='******', password='******')
        self.assertEqual(result, True)
        self.factory = RequestFactory()

    def _get_initial_data(self, dca=None):
        dca = dca or self.dca
        data = {
            'barcode': dca.barcode,
            'depreciation_rate': 25,
            'rack': dca.rack.pk,
            'hostname': dca.hostname,
            'model': dca.model.pk,
            'orientation': 1,
            'position': dca.position,
            'service_env': dca.service_env.pk,
            'sn': dca.sn,
            'status': 1,
            'custom_fields-customfieldvalue-content_type-object_id-INITIAL_FORMS': '0',
            'custom_fields-customfieldvalue-content_type-object_id-MAX_NUM_FORMS': '1000',
            'custom_fields-customfieldvalue-content_type-object_id-MIN_NUM_FORMS': '0',
            'custom_fields-customfieldvalue-content_type-object_id-TOTAL_FORMS': '3',
        }
        return data

    def test_enter_valid_mgmt_should_pass(self):
        data = self._get_initial_data()
        data.update({
            'management_ip': '10.20.30.40',
            'management_hostname': 'qwerty.mydc.net',
        })
        response = self.client.post(self.dca.get_absolute_url(), data)
        self.assertEqual(response.status_code, 302)
        self.dca.refresh_from_db()
        self.assertEqual(self.dca.management_ip, '10.20.30.40')
        self.assertEqual(self.dca.management_hostname, 'qwerty.mydc.net')

    def test_enter_duplicated_mgmt_ip_should_not_pass(self):
        IPAddressFactory(
            is_management=True, address='10.20.30.41',
            ethernet__base_object=self.dca1,
        )
        data = self._get_initial_data()
        data.update({
            'management_ip': '10.20.30.41',
            'management_hostname': 'qwerty.mydc.net',
        })
        response = self.client.post(self.dca.get_absolute_url(), data)
        self.assertEqual(response.status_code, 200)
        self.dca.refresh_from_db()
        self.assertIn(
            'Management IP is already assigned to',
            response.context['errors'][0]
        )

    def test_enter_duplicated_mgmt_hostname_should_not_pass(self):
        IPAddressFactory(
            is_management=True, address='10.20.30.41',
            hostname='qwerty.mydc.net',
            ethernet__base_object=self.dca1,
        )
        data = self._get_initial_data()
        data.update({
            'management_ip': '10.20.30.42',
            'management_hostname': 'qwerty.mydc.net',
        })
        response = self.client.post(self.dca.get_absolute_url(), data)
        self.assertEqual(response.status_code, 200)
        self.assertIn(
            'Management hostname is already assigned to',
            response.context['errors'][0]
        )

    def test_reenter_mgmt_ip_should_pass(self):
        IPAddressFactory(
            is_management=True, address='10.20.30.41',
            ethernet__base_object=self.dca,  # mgmt ip assigned to the same obj
        )
        data = self._get_initial_data()
        data.update({
            'management_ip': '10.20.30.41',
            'management_hostname': 'qwerty.mydc.net',
        })
        response = self.client.post(self.dca.get_absolute_url(), data)
        self.assertEqual(response.status_code, 302)
        self.dca.refresh_from_db()
        self.assertEqual(self.dca.management_ip, '10.20.30.41')
        self.assertEqual(self.dca.management_hostname, 'qwerty.mydc.net')

    def test_change_mgmt_ip_should_pass(self):
        IPAddressFactory(
            is_management=True, address='10.20.30.41',
            ethernet__base_object=self.dca,
        )
        ip_count = IPAddress.objects.count()
        data = self._get_initial_data()
        data.update({
            'management_ip': '10.20.30.42',
            'management_hostname': 'qwerty22.mydc.net',
        })
        response = self.client.post(self.dca.get_absolute_url(), data)
        self.assertEqual(response.status_code, 302)
        self.dca.refresh_from_db()
        self.assertEqual(self.dca.management_ip, '10.20.30.42')
        self.assertEqual(self.dca.management_hostname, 'qwerty22.mydc.net')
        self.assertEqual(ip_count, IPAddress.objects.count())

    def test_clean_mgmt_hostname_should_pass(self):
        IPAddressFactory(
            is_management=True, address='10.20.30.41',
            ethernet__base_object=self.dca,
        )
        data = self._get_initial_data()
        data.update({
            'management_ip': '10.20.30.42',
            'management_hostname': '',
        })
        response = self.client.post(self.dca.get_absolute_url(), data)
        self.assertEqual(response.status_code, 302)
        self.dca.refresh_from_db()
        self.assertEqual(self.dca.management_ip, '10.20.30.42')
        self.assertEqual(self.dca.management_hostname, '')

    def test_clean_mgmt_ip_when_mgmt_hostname_is_not_empty_should_not_pass(self):  # noqa
        IPAddressFactory(
            is_management=True, address='10.20.30.41',
            ethernet__base_object=self.dca,
        )
        data = self._get_initial_data()
        data.update({
            'management_ip': '',
            'management_hostname': 'qwerty.mydc.net',
        })
        response = self.client.post(self.dca.get_absolute_url(), data)
        self.assertEqual(response.status_code, 200)
        self.assertIn(
            'Management IP could not be empty when management hostname is passed',  # noqa
            response.context['errors'][0]
        )

    def test_delete_mgmt(self):
        ip = IPAddressFactory(
            is_management=True, address='10.20.30.41',
            hostname='qwerty.mydc.net',
            ethernet__base_object=self.dca,
        )
        eth = ip.ethernet
        ip_count = IPAddress.objects.count()
        data = self._get_initial_data()
        data.update({
            'management_ip': '',
            'management_hostname': '',
        })
        response = self.client.post(self.dca.get_absolute_url(), data)
        self.assertEqual(response.status_code, 302)
        self.dca.refresh_from_db()
        self.assertEqual(self.dca.management_ip, '')
        self.assertEqual(self.dca.management_hostname, '')
        self.assertEqual(IPAddress.objects.count(), ip_count - 1)
        self.assertEqual(len(IPAddress.objects.filter(pk=ip.pk)), 0)
        self.assertEqual(len(Ethernet.objects.filter(pk=eth.pk)), 0)

    def test_create_new_data_center_asset_with_management(self):
        data = self._get_initial_data()
        data.update({
            'barcode': '1234',
            'sn': '321',
            'management_ip': '10.20.30.44',
            'management_hostname': 'qwerty.mydc.net',
        })
        response = self.client.post(
            reverse('admin:data_center_datacenterasset_add'), data
        )
        self.assertEqual(response.status_code, 302)
        dca = DataCenterAsset.objects.get(barcode='1234')
        self.assertEqual(dca.management_ip, '10.20.30.44')
        self.assertEqual(dca.management_hostname, 'qwerty.mydc.net')

    def test_create_new_data_center_asset_without_management(self):
        data = self._get_initial_data()
        data.update({
            'barcode': '1234',
            'sn': '321',
            'management_ip': '',
            'management_hostname': '',
        })
        ip_count = IPAddress.objects.count()
        response = self.client.post(
            reverse('admin:data_center_datacenterasset_add'), data
        )
        self.assertEqual(response.status_code, 302)
        dca = DataCenterAsset.objects.get(barcode='1234')
        self.assertEqual(dca.management_ip, '')
        self.assertEqual(dca.management_hostname, '')
        self.assertEqual(IPAddress.objects.count(), ip_count)

    def test_get_add_form(self):
        response = self.client.get(
            reverse('admin:data_center_datacenterasset_add'),
        )
        self.assertEqual(response.status_code, 200)

    def test_get_add_details_form(self):
        response = self.client.get(self.dca.get_absolute_url())
        self.assertEqual(response.status_code, 200)

    def test_get_add_details_form_with_management_ip(self):
        self.dca.management_ip = '10.20.30.40'
        self.dca.management_hostname = 'qwerty.mydc.net'
        response = self.client.get(self.dca.get_absolute_url())
        self.assertEqual(response.status_code, 200)

    def test_model_asset_type_data_center_shall_pass(self):
        data_center_model = DataCenterAssetModelFactory(
            type=ObjectModelType.from_name('data_center')
        )
        data = self._get_initial_data()
        data.update({
            'model': data_center_model.pk
        })
        response = self.client.post(
            self.dca.get_absolute_url(), data
        )
        self.dca.refresh_from_db()
        self.assertEqual(response.status_code, 302)
        self.assertEqual(self.dca.model, data_center_model)

    def test_model_asset_type_back_office_asset_shall_not_pass(self):
        back_office_model = DataCenterAssetModelFactory(
            type=ObjectModelType.from_name('back_office')
        )
        data = self._get_initial_data()
        data.update({
            'model': back_office_model.pk
        })
        response = self.client.post(
            self.dca.get_absolute_url(), data
        )
        self.dca.refresh_from_db()
        self.assertIn(
            'Model must be of',
            response.content.decode('utf-8')
        )
        self.assertNotEqual(self.dca.model, back_office_model)
        self.assertEqual(response.status_code, 200)
Exemple #2
0
 def setUp(self):
     self.dc_asset = DataCenterAssetFactory(
         status=DataCenterAssetStatus.liquidated.id)
     self.dc_asset_2 = DataCenterAssetFactory(parent=self.dc_asset, )
     self.dc_asset_3 = DataCenterAssetFactory()
Exemple #3
0
    def setUpClass(cls):
        from ralph.data_center.tests.factories import (
            ClusterFactory,
            DataCenterAssetFactory,
            RackFactory,
        )
        super().setUpClass()
        cls.dc_asset = DataCenterAssetFactory(
            hostname='ralph0.allegro.pl',
            service_env__service__name='service',
            service_env__environment__name='test',
            model__name='DL360',
            model__manufacturer__name='Asus',
            model__category__name='ATS',
            rack=RackFactory(
                name='Rack #100',
                server_room__name='Server Room A',
                server_room__data_center__name='DC1',
            ),
            position=1,
            slot_no='1',
            configuration_path__class_name='www',
            configuration_path__module__name='ralph',
        )
        cls.dc_ip = IPAddressFactory(
            base_object=cls.dc_asset,
            ethernet=EthernetFactory(base_object=cls.dc_asset),
        )
        IPAddressFactory(
            base_object=cls.dc_asset,
            ethernet=EthernetFactory(base_object=cls.dc_asset),
            is_management=True,
        )
        cls.virtual_server = VirtualServerFactory(
            hostname='s000.local',
            configuration_path=ConfigurationClassFactory(
                class_name='worker',
                module__name='auth'
            ),
            service_env__service__name='service',
            service_env__environment__name='prod',
            type__name='Xen',
            parent=DataCenterAssetFactory(
                hostname='parent',
                model__name='DL380p',
                model__manufacturer__name='Brother',
                model__category__name='Database Machine',
                rack=RackFactory(
                    name='Rack #101',
                    server_room__name='Server Room B',
                    server_room__data_center__name='DC2',
                ),
                position=1,
                slot_no='1',
            ),
        )
        # refresh virtual server to get parent as BaseObject, not
        # DataCenterAsset
        cls.vs_ip = IPAddressFactory(
            base_object=cls.virtual_server,
            ethernet=EthernetFactory(base_object=cls.virtual_server),
        )
        cls.virtual_server = VirtualServer.objects.get(
            pk=cls.virtual_server.id
        )

        cluster = ClusterFactory(
            hostname='',
            type__name='Application',
            configuration_path__class_name='www',
            configuration_path__module__name='ralph',
            service_env__service__name='service',
            service_env__environment__name='preprod',
        )
        cls.boc_1 = BaseObjectCluster.objects.create(
            cluster=cluster,
            base_object=DataCenterAssetFactory(
                rack=RackFactory(), position=1,
            )
        )
        cls.boc_2 = BaseObjectCluster.objects.create(
            cluster=cluster,
            base_object=DataCenterAssetFactory(
                rack=RackFactory(
                    server_room__data_center__name='DC2',
                    server_room__name='Server Room B',
                    name='Rack #101',
                ),
                position=1,
            ),
            is_master=True
        )

        cls.cluster = ClusterFactory._meta.model.objects.get(pk=cluster)
        cls.cluster_ip = IPAddressFactory(
            base_object=cls.cluster,
            ethernet=EthernetFactory(base_object=cls.cluster),
        )
Exemple #4
0
 def test_should_pass_when_slot_no_filled_on_blade(self):
     dc_asset = DataCenterAssetFactory(model__has_parent=True)
     dc_asset.slot_no = '1A'
     dc_asset._validate_slot_no()
Exemple #5
0
class DataCenterAssetTest(RalphTestCase):
    def setUp(self):
        self.dc_asset = DataCenterAssetFactory(
            status=DataCenterAssetStatus.liquidated.id)
        self.dc_asset_2 = DataCenterAssetFactory(parent=self.dc_asset, )
        self.dc_asset_3 = DataCenterAssetFactory()

    def test_convert_to_backoffice_asset(self):
        dc_asset = DataCenterAssetFactory()
        transition = Transition.objects.create(
            name='transition',
            model=TransitionModel.get_for_field(dc_asset, 'status'),
            source=0,
            target=0,
        )
        dc_asset_pk = dc_asset.pk
        hostname = dc_asset.hostname
        DataCenterAsset.convert_to_backoffice_asset(
            instances=[dc_asset],
            region=RegionFactory().id,
            warehouse=WarehouseFactory().id,
            request=None,
            transition_id=transition.pk)
        bo_asset = BackOfficeAsset.objects.get(pk=dc_asset_pk)
        self.assertFalse(
            DataCenterAsset.objects.filter(pk=dc_asset_pk).exists())
        self.assertEqual(bo_asset.hostname, hostname)

    def test_convert_to_backoffice_asset_preserves_status_name(self):
        dc_asset = DataCenterAssetFactory(
            status=DataCenterAssetStatus.from_name('damaged'))
        transition = Transition.objects.create(
            name='transition',
            model=TransitionModel.get_for_field(dc_asset, 'status'),
            source=0,
            target=0,
        )
        dc_asset_pk = dc_asset.pk
        dc_asset_status_name = DataCenterAssetStatus.from_id(
            dc_asset.status).name
        DataCenterAsset.convert_to_backoffice_asset(
            instances=[dc_asset],
            region=RegionFactory().id,
            warehouse=WarehouseFactory().id,
            request=None,
            transition_id=transition.pk)
        bo_asset = BackOfficeAsset.objects.get(pk=dc_asset_pk)
        bo_asset_status_name = BackOfficeAssetStatus.from_id(
            bo_asset.status).name
        self.assertEqual(dc_asset_status_name, bo_asset_status_name)

    def test_convert_to_backoffice_asset_uses_default_from_transition(self):
        target_status_id = BackOfficeAssetStatus.from_name(
            "new"  # status name common for dc_asset and bo_asset
        ).id
        dc_asset = DataCenterAssetFactory(
            status=DataCenterAssetStatus.from_name('damaged'))
        transition = Transition.objects.create(
            name='transition',
            model=TransitionModel.get_for_field(dc_asset, 'status'),
            source=0,
            target=target_status_id,
        )
        dc_asset_pk = dc_asset.pk
        target_status_name = DataCenterAssetStatus.from_id(
            target_status_id).name
        DataCenterAsset.convert_to_backoffice_asset(
            instances=[dc_asset],
            region=RegionFactory().id,
            warehouse=WarehouseFactory().id,
            request=None,
            transition_id=transition.pk)
        bo_asset = BackOfficeAsset.objects.get(pk=dc_asset_pk)
        bo_asset_status_name = BackOfficeAssetStatus.from_id(
            bo_asset.status).name
        self.assertEqual(target_status_name, bo_asset_status_name)

    def test_convert_to_backoffice_asset_uses_default_from_settings(self):
        target_status_id = BackOfficeAssetStatus.from_id(
            settings.CONVERT_TO_BACKOFFICE_ASSET_DEFAULT_STATUS_ID).id
        dc_asset = DataCenterAssetFactory(
            status=DataCenterAssetStatus.from_name('pre_liquidated'))
        transition = Transition.objects.create(
            name='transition',
            model=TransitionModel.get_for_field(dc_asset, 'status'),
            source=0,
            target=0,
        )
        dc_asset_pk = dc_asset.pk
        target_status_name = DataCenterAssetStatus.from_id(
            target_status_id).name
        DataCenterAsset.convert_to_backoffice_asset(
            instances=[dc_asset],
            region=RegionFactory().id,
            warehouse=WarehouseFactory().id,
            request=None,
            transition_id=transition.pk)
        bo_asset = BackOfficeAsset.objects.get(pk=dc_asset_pk)
        bo_asset_status_name = BackOfficeAssetStatus.from_id(
            bo_asset.status).name
        self.assertEqual(target_status_name, bo_asset_status_name)

    # =========================================================================
    # slot_no
    #  =========================================================================
    @unpack
    @data(
        ('1A', ),
        ('1B', ),
        ('9A', ),
        ('9B', ),
        ('10A', ),
        ('10B', ),
        ('16A', ),
        ('16B', ),
        ('1', ),
        ('9', ),
        ('10', ),
        ('16', ),
    )
    def test_should_pass_when_slot_no_is_correct(self, slot_no):
        slot_no_field = self.dc_asset._meta.get_field_by_name('slot_no')[0]
        slot_no_field.clean(slot_no, self.dc_asset)

    @unpack
    @data(
        ('1C', ),
        ('0A', ),
        ('0', ),
        ('B', ),
        ('17A', ),
        ('17B', ),
        ('20A', ),
        ('1a', ),
        ('1b', ),
        ('111', ),
    )
    def test_should_raise_validation_error_when_slot_no_is_incorrect(
            self, slot_no):
        slot_no_field = self.dc_asset._meta.get_field_by_name('slot_no')[0]
        with self.assertRaises(ValidationError):
            slot_no_field.clean(slot_no, self.dc_asset)

    def test_should_raise_validation_error_when_slot_no_is_busy(self):
        model = DataCenterAssetModelFactory(has_parent=True)
        DataCenterAssetFactory(parent=self.dc_asset, slot_no=1, model=model)
        dc_asset = DataCenterAssetFactory(parent=self.dc_asset, model=model)
        dc_asset.slot_no = 1
        with self.assertRaises(ValidationError):
            dc_asset.clean()

    def test_should_pass_when_slot_no_is_busy_but_different_orientation(self):
        model = DataCenterAssetModelFactory(has_parent=True)
        DataCenterAssetFactory(
            parent=self.dc_asset,
            slot_no=1,
            model=model,
            orientation=Orientation.back,
        )
        dc_asset = DataCenterAssetFactory(parent=self.dc_asset, model=model)
        dc_asset.slot_no = 1
        dc_asset._validate_slot_no()

    def test_should_raise_validation_error_when_empty_slot_no_on_blade(self):
        dc_asset = DataCenterAssetFactory(model__has_parent=True)
        dc_asset.slot_no = ''
        with self.assertRaises(ValidationError):
            dc_asset._validate_slot_no()

    def test_should_raise_validation_error_when_slot_not_filled_when_not_blade(
            self):  # noqa
        dc_asset = DataCenterAssetFactory(model__has_parent=False)
        dc_asset.slot_no = '1A'
        with self.assertRaises(ValidationError):
            dc_asset._validate_slot_no()

    def test_should_pass_when_slot_no_filled_on_blade(self):
        dc_asset = DataCenterAssetFactory(model__has_parent=True)
        dc_asset.slot_no = '1A'
        dc_asset._validate_slot_no()

    def test_should_pass_when_slot_not_filled_without_model(self):
        dc_asset = DataCenterAsset()
        dc_asset.slot_no = '1A'
        dc_asset._validate_slot_no()

    # =========================================================================
    # orientation
    # =========================================================================
    @unpack
    @data(
        (None, Orientation.front),
        (None, Orientation.left),
        (0, Orientation.left),
        (0, Orientation.right),
        (1, Orientation.front),
        (10, Orientation.back),
        (100, Orientation.middle),
    )
    def test_should_pass_when_orientation_is_correct(self, position,
                                                     orientation):
        self.dc_asset.position = position
        self.dc_asset.orientation = orientation
        self.dc_asset._validate_orientation()

    @unpack
    @data(
        (0, Orientation.front),
        (0, Orientation.back),
        (0, Orientation.middle),
        (1, Orientation.left),
        (10, Orientation.right),
    )
    def test_should_raise_validation_error_when_orientation_is_correct(
            self, position, orientation):
        self.dc_asset.position = position
        self.dc_asset.orientation = orientation
        with self.assertRaises(ValidationError):
            self.dc_asset._validate_orientation()

    # =========================================================================
    # position in rack
    # =========================================================================
    @unpack
    @data(
        (None, 100),
        (10, 10),
        (10, 100),
    )
    def test_should_pass_when_position_in_rack_is_correct(
            self, position, rack_max_height):
        self.dc_asset.position = position
        self.dc_asset.rack = RackFactory(max_u_height=rack_max_height)
        self.dc_asset._validate_position_in_rack()

    def test_should_pass_when_rack_is_null(self):
        self.dc_asset.position = 10
        self.dc_asset.rack = None
        self.dc_asset._validate_position_in_rack()

    @unpack
    @data((10, 9), (1, 0), (-1, 10))
    def test_should_raise_validation_error_when_position_in_rack_is_incorrect(
            self, position, rack_max_height):
        self.dc_asset.position = position
        self.dc_asset.rack = RackFactory(max_u_height=rack_max_height)
        with self.assertRaises(ValidationError):
            self.dc_asset._validate_position_in_rack()

    # =========================================================================
    # position requirement
    # =========================================================================
    def test_should_pass_when_position_is_passed_and_rack_requires_it(self):
        self.dc_asset.position = 10
        self.dc_asset.rack = RackFactory(require_position=True)
        self.dc_asset._validate_position()

    def test_should_pass_when_position_is_passed_and_rack_doesnt_require_it(
            self):  # noqa
        self.dc_asset.position = 10
        self.dc_asset.rack = RackFactory(require_position=False)
        self.dc_asset._validate_position()

    def test_should_pass_when_position_is_not_passed_and_rack_doesnt_require_it(
            self):  # noqa
        self.dc_asset.position = None
        self.dc_asset.rack = RackFactory(require_position=False)
        self.dc_asset._validate_position()

    def test_should_raise_validation_error_when_position_is_not_passed_and_rack_requires_it(
            self):  # noqa
        self.dc_asset.position = None
        self.dc_asset.rack = RackFactory(require_position=True)
        with self.assertRaises(ValidationError):
            self.dc_asset._validate_position()

    def test_update_rack_when_parent_rack_is_change(self):
        rack_1, rack_2 = RackFactory.create_batch(2)
        parent_asset = DataCenterAssetFactory(
            rack=rack_1, model=DataCenterAssetModelFactory(has_parent=True))
        dc_asset = DataCenterAssetFactory(parent=parent_asset)
        parent_asset.rack = rack_2
        parent_asset.save()
        dc_asset.refresh_from_db()
        self.assertEqual(dc_asset.rack_id, rack_2.id)

    def test_update_position_when_parent_position_is_change(self):
        rack = RackFactory()
        parent_asset = DataCenterAssetFactory(
            rack=rack,
            position=1,
            model=DataCenterAssetModelFactory(has_parent=True))
        dc_asset = DataCenterAssetFactory(parent=parent_asset, position=2)
        parent_asset.position = 4
        parent_asset.save()
        dc_asset.refresh_from_db()
        self.assertEqual(dc_asset.position, 4)

    # =========================================================================
    # network environment
    # =========================================================================
    def _prepare_rack(self, dc_asset, address, network_address, rack=None):
        self.rack = rack or RackFactory()
        self.net_env = NetworkEnvironmentFactory(
            hostname_template_prefix='server_1',
            hostname_template_postfix='.mydc.net',
        )
        self.net_env2 = NetworkEnvironmentFactory(
            hostname_template_prefix='server_2',
            hostname_template_postfix='.mydc.net',
        )
        self.net = NetworkFactory(
            network_environment=self.net_env,
            address=network_address,
        )
        self.net2 = NetworkFactory(
            network_environment=self.net_env2,
            address='10.20.30.0/24',
        )
        self.net.racks.add(self.rack)
        self.net2.racks.add(self.rack)
        dc_asset.rack = self.rack
        dc_asset.save()
        IPAddressFactory(ethernet__base_object=self.dc_asset, address=address)

    def test_network_environment(self):
        self._prepare_rack(self.dc_asset, '192.168.1.11', '192.168.1.0/24')

        self.assertEqual(self.dc_asset.network_environment, self.net_env)

    def test_network_environment_null(self):
        self._prepare_rack(self.dc_asset, '192.168.1.11', '192.222.1.0/24')
        self.assertIsNone(self.dc_asset.network_environment)

    # =========================================================================
    # next free hostname
    # =========================================================================
    def test_get_next_free_hostname(self):
        self._prepare_rack(self.dc_asset, '192.168.1.11', '192.168.1.0/24')
        self.assertEqual(self.dc_asset.get_next_free_hostname(),
                         'server_10001.mydc.net')
        # running it again shouldn't change next hostname
        self.assertEqual(self.dc_asset.get_next_free_hostname(),
                         'server_10001.mydc.net')

    def test_get_next_free_hostname_without_network_env(self):
        self.assertEqual(self.dc_asset.get_next_free_hostname(), '')

    def test_issue_next_free_hostname(self):
        self._prepare_rack(self.dc_asset, '192.168.1.11', '192.168.1.0/24')
        self.assertEqual(self.dc_asset.issue_next_free_hostname(),
                         'server_10001.mydc.net')
        # running it again should change next hostname
        self.assertEqual(self.dc_asset.issue_next_free_hostname(),
                         'server_10002.mydc.net')

    def test_issue_next_free_hostname_without_network_env(self):
        self.assertEqual(self.dc_asset.issue_next_free_hostname(), '')

    # =========================================================================
    # available networks
    # =========================================================================
    def test_get_available_networks(self):
        self._prepare_rack(self.dc_asset, '192.168.1.1', '192.168.1.0/24')
        self.net3 = NetworkFactory(address='192.168.3.0/24')

        self.assertCountEqual(self.dc_asset._get_available_networks(),
                              [self.net, self.net2])

    def test_get_available_networks_is_broadcasted_in_dhcp(self):
        self._prepare_rack(self.dc_asset, '192.168.1.1', '192.168.1.0/24')
        self.net3 = NetworkFactory(address='192.168.3.0/24',
                                   dhcp_broadcast=True)
        self.assertCountEqual(
            self.dc_asset._get_available_networks(is_broadcasted_in_dhcp=True),
            [self.net, self.net2])

    def test_get_available_networks_no_rack(self):
        NetworkFactory(address='192.168.1.0/24')
        NetworkFactory(address='192.168.2.0/24')
        self.assertEqual(self.dc_asset._get_available_networks(), [])

    # =========================================================================
    # other
    # =========================================================================
    def test_change_rack_in_descendants(self):
        self.dc_asset.rack = RackFactory()
        self.dc_asset.save()
        asset = DataCenterAsset.objects.get(pk=self.dc_asset_2.pk)

        self.assertEquals(self.dc_asset.rack_id, asset.rack_id)

    def test_get_autocomplete_queryset(self):
        queryset = DataCenterAsset.get_autocomplete_queryset()
        self.assertEquals(2, queryset.count())

    # =========================================================================
    # management_ip
    # =========================================================================
    def test_assign_new_management_ip_should_pass(self):
        self.dc_asset.management_ip = '10.20.30.40'
        self.dc_asset.refresh_from_db()
        self.assertEqual(self.dc_asset.management_ip, '10.20.30.40')

    def test_assign_existing_ip_assigned_to_another_obj_should_not_pass(self):
        IPAddressFactory(address='10.20.30.40', is_management=True)
        with self.assertRaises(ValidationError):
            self.dc_asset.management_ip = '10.20.30.40'

    def test_assign_existing_ip_not_assigned_to_another_obj_should_pass(self):
        IPAddressFactory(address='10.20.30.40', ethernet=None)
        self.dc_asset.management_ip = '10.20.30.40'
        self.dc_asset.refresh_from_db()
        self.assertEqual(self.dc_asset.management_ip, '10.20.30.40')

    def test_change_mgmt_ip_for_new_ip_should_pass(self):
        self.dc_asset.management_ip = '10.20.30.40'
        self.dc_asset.refresh_from_db()
        self.assertEqual(self.dc_asset.management_ip, '10.20.30.40')
        self.dc_asset.management_ip = '10.20.30.41'
        self.dc_asset.refresh_from_db()
        self.assertEqual(self.dc_asset.management_ip, '10.20.30.41')
        self.assertFalse(
            IPAddress.objects.filter(address='10.20.30.40').exists())

    def test_change_mgmt_ip_for_existing_ip_without_object_should_pass(self):
        IPAddressFactory(address='10.20.30.42', ethernet=None)
        self.dc_asset.management_ip = '10.20.30.40'
        self.dc_asset.refresh_from_db()
        self.assertEqual(self.dc_asset.management_ip, '10.20.30.40')
        self.dc_asset.management_ip = '10.20.30.42'
        self.dc_asset.refresh_from_db()
        self.assertEqual(self.dc_asset.management_ip, '10.20.30.42')
        self.assertFalse(
            IPAddress.objects.filter(address='10.20.30.40').exists())

    def test_change_mgmt_ip_for_existing_ip_with_object_should_not_pass(self):
        IPAddressFactory(address='10.20.30.42')
        self.dc_asset.management_ip = '10.20.30.40'
        self.dc_asset.refresh_from_db()
        self.assertEqual(self.dc_asset.management_ip, '10.20.30.40')
        with self.assertRaises(ValidationError):
            self.dc_asset.management_ip = '10.20.30.42'

    def test_should_return_only_common_networks(self):
        rack100 = RackFactory()
        rack101 = RackFactory()
        rack_100_net = NetworkFactory(address='10.0.100.0/24')
        rack_101_net = NetworkFactory(address='10.0.101.0/24')
        common_net = NetworkFactory(address='10.0.0.0/24')
        rack_100_net.racks = [rack100]
        rack_101_net.racks = [rack101]
        common_net.racks = [rack100, rack101]
        self.dc_asset_2.rack = rack100
        self.dc_asset_3.rack = rack101

        rack_100_result = assign_additional_hostname_choices(
            None, [self.dc_asset_2])
        common_result = assign_additional_hostname_choices(
            None, [self.dc_asset_2, self.dc_asset_3])
        expected_rack100_result = [(str(rack_100_net.pk), rack_100_net),
                                   (str(common_net.pk), common_net)]
        expected_common_result = [(str(common_net.pk), common_net)]
        self.assertEqual(rack_100_result, expected_rack100_result)
        self.assertEqual(len(rack_100_result), 2)
        self.assertEqual(common_result, expected_common_result)
        self.assertEqual(len(common_result), 1)
Exemple #6
0
 def test_should_raise_validation_error_when_empty_slot_no_on_blade(self):
     dc_asset = DataCenterAssetFactory(model__has_parent=True)
     dc_asset.slot_no = ''
     with self.assertRaises(ValidationError):
         dc_asset._validate_slot_no()
Exemple #7
0
 def test_should_raise_validation_error_when_slot_not_filled_when_not_blade(
         self):  # noqa
     dc_asset = DataCenterAssetFactory(model__has_parent=False)
     dc_asset.slot_no = '1A'
     with self.assertRaises(ValidationError):
         dc_asset._validate_slot_no()
Exemple #8
0
class TestRestAssetInfoPerRack(TestCase):

    def setUp(self):
        get_user_model().objects.create_superuser(
            'test', '*****@*****.**', 'test'
        )

        self.client = APIClient()
        self.client.login(username='******', password='******')

        environment = EnvironmentFactory()
        service = ServiceFactory(name='Service1')
        service_env = ServiceEnvironment.objects.create(
            service=service,
            environment=environment
        )
        asset_model = DataCenterAssetModelFactory(
            type=ObjectModelType.data_center
        )
        self.server_room = ServerRoomFactory()

        self.accesory_1 = AccessoryFactory()

        self.rack_1 = RackFactory(
            server_room=self.server_room,
            max_u_height=3
        )

        self.asset_1 = DataCenterAssetFactory(
            service_env=service_env,
            position=1,
            slot_no='',
            force_depreciation=False,
            model=asset_model,
            rack=self.rack_1,
        )
        self.asset_1.management_ip = '10.15.25.45'

        self.pdu_1 = DataCenterAssetFactory(
            service_env=service_env,
            rack=self.rack_1,
            orientation=Orientation.left,
            force_depreciation=False,
            model=asset_model,
            position=0,
        )
        self.rack1_accessory = RackAccessoryFactory(
            rack=self.rack_1,
            orientation=Orientation.front,
            accessory=self.accesory_1,
            position=1
        )

    def tearDown(self):
        self.client.logout()

    def test_get(self):
        returned_json = json.loads(
            self.client.get(
                '/api/rack/{0}/'.format(self.rack_1.id)
            ).content.decode()
        )
        self.maxDiff = None
        expected_json = {
            'info': {
                'id': self.rack_1.id,
                'name': self.rack_1.name,
                'server_room': self.rack_1.server_room.id,
                'max_u_height': self.rack_1.max_u_height,
                'visualization_col': self.rack_1.visualization_col,
                'visualization_row': self.rack_1.visualization_row,
                'free_u': self.rack_1.get_free_u(),
                'description': '{}'.format(self.rack_1.description),
                'orientation': '{}'.format(self.rack_1.get_orientation_desc()),
                'rack_admin_url': self.rack_1.get_absolute_url(),
                'reverse_ordering': self.rack_1.reverse_ordering
            },
            'devices':
            [
                {
                    '_type': TYPE_ASSET,
                    'id': self.asset_1.id,
                    'hostname': self.asset_1.hostname,
                    'category': self.asset_1.model.category.name,
                    'barcode': self.asset_1.barcode,
                    'sn': self.asset_1.sn,
                    'height': float(self.asset_1.model.height_of_device),
                    'position': self.asset_1.position,
                    'model': self.asset_1.model.name,
                    'children': [],
                    'front_layout': '',
                    'back_layout': '',
                    'management_ip': self.asset_1.management_ip,
                    'orientation': 'front',
                    'remarks': '',
                    'service': 'Service1',
                    'url': self.asset_1.get_absolute_url()
                },
                {
                    '_type': TYPE_ACCESSORY,
                    'orientation': 'front',
                    'position': self.rack1_accessory.position,
                    'remarks': self.rack1_accessory.remarks,
                    'type': self.rack1_accessory.accessory.name,
                    'url': self.rack1_accessory.get_absolute_url(),
                },
            ],
            'pdus': [
                {
                    'model': self.pdu_1.model.name,
                    'orientation': 'left',
                    'sn': self.pdu_1.sn,
                    'url': self.pdu_1.get_absolute_url()
                },
            ]
        }
        self.assertEqual(returned_json, expected_json)
Exemple #9
0
class DataCenterAssetAdminTest(TransactionTestCase):
    def setUp(self):
        self.user = get_user_model().objects.create_superuser(
            username='******', password='******', email='*****@*****.**')
        result = self.client.login(username='******', password='******')
        self.assertEqual(result, True)
        self.factory = RequestFactory()
        self.dca = DataCenterAssetFactory(hostname='ralph1.allegro.pl',
                                          rack=RackFactory(),
                                          position=1)
        self.custom_fields_inline_prefix = 'custom_fields-customfieldvalue-content_type-object_id-'  # noqa
        self.custom_field_str = CustomField.objects.create(
            name='test_str', type=CustomFieldTypes.STRING, default_value='xyz')
        self.custom_field_choices = CustomField.objects.create(
            name='test_choice',
            type=CustomFieldTypes.CHOICE,
            choices='qwerty|asdfgh|zxcvbn',
            default_value='zxcvbn',
            use_as_configuration_variable=True,
        )

    def _update_dca(self, dca_data=None, inline_data=None):
        data = {
            'id': self.dca.id,
            'sn': self.dca.sn,
            'barcode': self.dca.barcode,
            'hostname': self.dca.hostname,
            'model': self.dca.model_id,
            'orientation': self.dca.orientation,
            'rack': self.dca.rack.pk,
            'position': self.dca.position,
            'service_env': self.dca.service_env_id,
            'status': self.dca.status,
            'depreciation_rate': self.dca.depreciation_rate,
        }
        data.update(dca_data or {})
        if inline_data:
            data.update(self._prepare_inline_data(inline_data))
        response = self.client.post(self.dca.get_absolute_url(), data)
        self.assertEqual(
            response.status_code, 302,
            (repr(response.context['form'].errors)
             if response.context and 'form' in response.context else ''))

    def _prepare_inline_data(self, d):
        return {
            '{}{}'.format(self.custom_fields_inline_prefix, k): v
            for (k, v) in d.items()
        }

    def test_if_mail_notification_is_send_when_dca_is_updated_through_gui(
            self):
        old_service = ServiceFactory(name='test')
        new_service = ServiceFactory(name='prod')
        old_service.business_owners.add(UserFactory(email='*****@*****.**'))
        new_service.business_owners.add(UserFactory(email='*****@*****.**'))
        old_service_env = ServiceEnvironmentFactory(service=old_service)
        new_service_env = ServiceEnvironmentFactory(service=new_service)
        # update without triggering signals
        DataCenterAsset.objects.filter(pk=self.dca.pk).update(
            service_env=old_service_env)

        data_custom_fields = {
            'TOTAL_FORMS': 3,
            'INITIAL_FORMS': 0,
        }
        self._update_dca(dca_data={'service_env': new_service_env.id},
                         inline_data=data_custom_fields)

        self.dca.refresh_from_db()

        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(
            'Device has been assigned to Service: {} ({})'.format(
                new_service, self.dca), mail.outbox[0].subject)
        self.assertCountEqual(mail.outbox[0].to,
                              ['*****@*****.**', '*****@*****.**'])

    @override_settings(HERMES_HOST_UPDATE_TOPIC_NAME='ralph.host_update')
    @mock.patch('ralph.data_center.publishers.publish')
    def test_if_host_update_is_published_to_hermes_when_dca_is_updated_through_gui(  # noqa: E501
            self, publish_mock):
        self.cfv1 = CustomFieldValue.objects.create(
            object=self.dca,
            custom_field=self.custom_field_str,
            value='sample_value',
        )
        new_service = ServiceFactory(name='service1', uid='sc-44444')
        new_service_env = ServiceEnvironmentFactory(service=new_service,
                                                    environment__name='dev')

        data_custom_fields = {
            'TOTAL_FORMS': 3,
            'INITIAL_FORMS': 1,
            '0-id': self.cfv1.id,
            '0-custom_field': self.custom_field_str.id,
            '0-value': 'sample_value22',
            '1-id': '',
            '1-custom_field': self.custom_field_choices.id,
            '1-value': 'qwerty',
        }
        with transaction.atomic():
            self._update_dca(dca_data={
                'service_env': new_service_env.id,
                'hostname': 'my-host.mydc.net',
            },
                             inline_data=data_custom_fields)
            # DCA is saved twice
            self.assertGreater(len(connection.run_on_commit), 0)

        self.dca.refresh_from_db()
        publish_data = publish_mock.call_args[0][1]
        publish_data.pop('modified')
        publish_data.pop('created')
        self.assertEqual(
            publish_data, {
                '__str__': 'data center asset: ' + str(self.dca),
                'configuration_path': None,
                'configuration_variables': {
                    'test_choice': 'qwerty',
                },
                'custom_fields': {
                    'test_str': 'sample_value22',
                    'test_choice': 'qwerty'
                },
                'ethernet': [],
                'hostname': 'my-host.mydc.net',
                'id': self.dca.id,
                'model': str(self.dca.model),
                'ipaddresses': [],
                'object_type': 'datacenterasset',
                'parent': None,
                'remarks': '',
                'service_env': {
                    'id': new_service_env.id,
                    'service': 'service1',
                    'environment': 'dev',
                    'service_uid': 'sc-44444',
                    'ui_url': ''
                },
                'tags': [],
                'securityscan': None,
                '_previous_state': {
                    'hostname': 'ralph1.allegro.pl'
                },
            })
        # Despite `save` is called twice, publish update data is called only
        # once
        self.assertEqual(publish_mock.call_count, 1)
        # check if on_commit callbacks are removed from current db connections
        self.assertEqual(connection.run_on_commit, [])
Exemple #10
0
 def setUp(self):
     DataCenterAssetFactory.create_batch(10)
Exemple #11
0
    def generate_data_center(self):
        self.stdout.write('Generating Data Center assets')
        data_center_status = DataCenterAssetStatus()
        parent_category = DataCenterCategoryFactory(
            name='DATA CENTER',
            imei_required=False
        )
        for i in range(2):
            server_room = ServerRoomFactory()
            visualization_col = 1
            visualization_row = 1
            for j in range(10):
                rack = RackFactory(
                    server_room=server_room,
                    visualization_row=visualization_row,
                    visualization_col=visualization_col
                )
                visualization_row += 1
                if (
                    visualization_row >
                    server_room.visualization_rows_num
                ):
                    visualization_row = 1
                    visualization_col += 1

                accessory = AccessoryFactory()
                RackAccessoryFactory(rack=rack, accessory=accessory)
                position = 1
                for status_id, name in data_center_status:
                    for i in range(2):
                        asset_model = DataCenterAssetModelFactory(
                            category=DataCenterCategoryFactory(
                                parent=parent_category
                            )
                        )
                        DataCenterAssetFactory(
                            rack=rack,
                            status=status_id,
                            position=position,
                            slot_no='',
                            service_env=ServiceEnvironmentFactory(),
                            model=asset_model
                        )
                        position += asset_model.height_of_device
                        if position > rack.max_u_height:
                            position = 1

            chassis = DataCenterAssetFactory(
                rack=rack,
                status=DataCenterAssetStatus.used.id,
                position=38,
                slot_no=None,
                service_env=ServiceEnvironmentFactory(),
                model=DataCenterAssetModelFactory(
                    name='Chassis',
                    category=DataCenterCategoryFactory(parent=parent_category),
                    height_of_device=5
                )
            )
            for i in range(5):
                DataCenterAssetFactory(
                    rack=rack,
                    status=DataCenterAssetStatus.used.id,
                    position=None,
                    service_env=ServiceEnvironmentFactory(),
                    slot_no=i,
                    parent=chassis,
                    model=DataCenterAssetModelFactory(
                        name='Blade',
                        has_parent=True,
                        category=DataCenterCategoryFactory(
                            parent=parent_category
                        )
                    )
                )
Exemple #12
0
 def setUp(self):
     self.view = RelationsView()
     self.view.object = DataCenterAssetFactory()
Exemple #13
0
class DataCenterAssetTest(RalphTestCase):
    def setUp(self):
        self.dc_asset = DataCenterAssetFactory(
            status=DataCenterAssetStatus.liquidated.id
        )
        self.dc_asset_2 = DataCenterAssetFactory(
            parent=self.dc_asset,
        )

    def test_convert_to_backoffice_asset(self):
        dc_asset = DataCenterAssetFactory()
        dc_asset_pk = dc_asset.pk
        hostname = dc_asset.hostname
        DataCenterAsset.convert_to_backoffice_asset(
            instances=[dc_asset],
            region=RegionFactory().id,
            warehouse=WarehouseFactory().id,
            request=None
        )
        bo_asset = BackOfficeAsset.objects.get(pk=dc_asset_pk)
        self.assertFalse(
            DataCenterAsset.objects.filter(pk=dc_asset_pk).exists()
        )
        self.assertEqual(bo_asset.hostname, hostname)

    # =========================================================================
    # slot_no
    #  =========================================================================
    @unpack
    @data(
        ('1A',),
        ('1B',),
        ('9A',),
        ('9B',),
        ('10A',),
        ('10B',),
        ('16A',),
        ('16B',),
        ('1',),
        ('9',),
        ('10',),
        ('16',),
    )
    def test_should_pass_when_slot_no_is_correct(self, slot_no):
        slot_no_field = self.dc_asset._meta.get_field_by_name('slot_no')[0]
        slot_no_field.clean(slot_no, self.dc_asset)

    @unpack
    @data(
        ('1C',),
        ('0A',),
        ('0',),
        ('B',),
        ('17A',),
        ('17B',),
        ('20A',),
        ('1a',),
        ('1b',),
        ('111',),
    )
    def test_should_raise_validation_error_when_slot_no_is_incorrect(
        self, slot_no
    ):
        slot_no_field = self.dc_asset._meta.get_field_by_name('slot_no')[0]
        with self.assertRaises(ValidationError):
            slot_no_field.clean(slot_no, self.dc_asset)

    def test_should_raise_validation_error_when_empty_slot_no_on_blade(self):
        dc_asset = DataCenterAssetFactory(model__has_parent=True)
        dc_asset.slot_no = ''
        with self.assertRaises(ValidationError):
            dc_asset._validate_slot_no()

    def test_should_raise_validation_error_when_slot_not_filled_when_not_blade(self):  # noqa
        dc_asset = DataCenterAssetFactory(model__has_parent=False)
        dc_asset.slot_no = '1A'
        with self.assertRaises(ValidationError):
            dc_asset._validate_slot_no()

    def test_should_pass_when_slot_no_filled_on_blade(self):
        dc_asset = DataCenterAssetFactory(model__has_parent=True)
        dc_asset.slot_no = '1A'
        dc_asset._validate_slot_no()

    def test_should_pass_when_slot_not_filled_without_model(self):
        dc_asset = DataCenterAsset()
        dc_asset.slot_no = '1A'
        dc_asset._validate_slot_no()

    # =========================================================================
    # orientation
    # =========================================================================
    @unpack
    @data(
        (None, Orientation.front),
        (None, Orientation.left),
        (0, Orientation.left),
        (0, Orientation.right),
        (1, Orientation.front),
        (10, Orientation.back),
        (100, Orientation.middle),
    )
    def test_should_pass_when_orientation_is_correct(
        self, position, orientation
    ):
        self.dc_asset.position = position
        self.dc_asset.orientation = orientation
        self.dc_asset._validate_orientation()

    @unpack
    @data(
        (0, Orientation.front),
        (0, Orientation.back),
        (0, Orientation.middle),
        (1, Orientation.left),
        (10, Orientation.right),
    )
    def test_should_raise_validation_error_when_orientation_is_correct(
        self, position, orientation
    ):
        self.dc_asset.position = position
        self.dc_asset.orientation = orientation
        with self.assertRaises(ValidationError):
            self.dc_asset._validate_orientation()

    # =========================================================================
    # position in rack
    # =========================================================================
    @unpack
    @data(
        (None, 100),
        (10, 10),
        (10, 100),
    )
    def test_should_pass_when_position_in_rack_is_correct(
        self, position, rack_max_height
    ):
        self.dc_asset.position = position
        self.dc_asset.rack = RackFactory(max_u_height=rack_max_height)
        self.dc_asset._validate_position_in_rack()

    def test_should_pass_when_rack_is_null(self):
        self.dc_asset.position = 10
        self.dc_asset.rack = None
        self.dc_asset._validate_position_in_rack()

    @unpack
    @data(
        (10, 9),
        (1, 0),
        (-1, 10)
    )
    def test_should_raise_validation_error_when_position_in_rack_is_incorrect(
        self, position, rack_max_height
    ):
        self.dc_asset.position = position
        self.dc_asset.rack = RackFactory(max_u_height=rack_max_height)
        with self.assertRaises(ValidationError):
            self.dc_asset._validate_position_in_rack()

    # =========================================================================
    # position requirement
    # =========================================================================
    def test_should_pass_when_position_is_passed_and_rack_requires_it(self):
        self.dc_asset.position = 10
        self.dc_asset.rack = RackFactory(require_position=True)
        self.dc_asset._validate_position()

    def test_should_pass_when_position_is_passed_and_rack_doesnt_require_it(self):  # noqa
        self.dc_asset.position = 10
        self.dc_asset.rack = RackFactory(require_position=False)
        self.dc_asset._validate_position()

    def test_should_pass_when_position_is_not_passed_and_rack_doesnt_require_it(self):  # noqa
        self.dc_asset.position = None
        self.dc_asset.rack = RackFactory(require_position=False)
        self.dc_asset._validate_position()

    def test_should_raise_validation_error_when_position_is_not_passed_and_rack_requires_it(self):  # noqa
        self.dc_asset.position = None
        self.dc_asset.rack = RackFactory(require_position=True)
        with self.assertRaises(ValidationError):
            self.dc_asset._validate_position()

    # =========================================================================
    # other
    # =========================================================================
    def test_change_rack_in_descendants(self):
        self.dc_asset.rack = RackFactory()
        self.dc_asset.save()
        asset = DataCenterAsset.objects.get(pk=self.dc_asset_2.pk)

        self.assertEquals(self.dc_asset.rack_id, asset.rack_id)

    def test_get_autocomplete_queryset(self):
        queryset = DataCenterAsset.get_autocomplete_queryset()
        self.assertEquals(1, queryset.count())
Exemple #14
0
 def test_autocomplete_service_env_should_return_pk(self):
     asset = DataCenterAssetFactory(service_env=ServiceEnvironmentFactory())
     self.assertEqual(
         asset.service_env.pk, autocomplete_service_env([], [asset])
     )
Exemple #15
0
 def setUp(self):
     self.instance = DataCenterAssetFactory()
Exemple #16
0
class BaseObjectAPITests(RalphAPITestCase):
    def setUp(self):
        super().setUp()
        self.bo_asset = BackOfficeAssetFactory(
            barcode='12345', hostname='host1'
        )
        self.bo_asset.tags.add('tag1')
        self.conf_module_1 = ConfigurationModuleFactory()
        self.conf_module_2 = ConfigurationModuleFactory(
            parent=self.conf_module_1, name='mod1'
        )
        self.conf_class_1 = ConfigurationClassFactory(
            id=999999,
            module=self.conf_module_2, class_name='cls1'
        )
        self.dc_asset = DataCenterAssetFactory(
            barcode='12543', price='9.00',
            service_env__service__name='test-service',
            service_env__service__uid='sc-123',
            service_env__environment__name='prod',
            configuration_path=self.conf_class_1,
        )
        self.dc_asset.tags.add('tag2')
        self.ip = IPAddressFactory(
            ethernet=EthernetFactory(base_object=self.dc_asset)
        )
        self.service = ServiceEnvironmentFactory(service__name='myservice')

    def test_get_base_objects_list(self):
        url = reverse('baseobject-list')
        response = self.client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], BaseObject.objects.count())
        barcodes = [
            item['barcode']
            for item in response.data['results']
            if 'barcode' in item
        ]
        self.assertCountEqual(barcodes, set(['12345', '12543']))

    def test_get_base_objects_list_different_type_with_custom_fields(self):
        CustomField.objects.create(name='test_field')
        self.dc_asset.update_custom_field('test_field', 'abc')
        self.bo_asset.update_custom_field('test_field', 'def')
        url = reverse('baseobject-list')
        response = self.client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        count = 0
        for item in response.data['results']:
            if item['id'] == self.dc_asset.id:
                self.assertEqual(item['custom_fields'], {'test_field': 'abc'})
                count += 1
            if item['id'] == self.bo_asset.id:
                self.assertEqual(item['custom_fields'], {'test_field': 'def'})
                count += 1
        self.assertEqual(count, 2)

    def test_get_asset_model_details(self):
        url = reverse('baseobject-detail', args=(self.bo_asset.id,))
        response = self.client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['barcode'], '12345')

    def test_get_asset_service_simple_details(self):
        url = reverse('baseobject-detail', args=(self.dc_asset.id,))
        response = self.client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        service_env = response.data['service_env']
        self.assertEqual(service_env['service_uid'], 'sc-123')
        self.assertEqual(service_env['service'], 'test-service')
        self.assertEqual(service_env['environment'], 'prod')

    def test_icontains_polymorphic(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'hostname__icontains': 'host'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_icontains_polymorphic_with_extended_filters(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'name__startswith': 'host'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_startswith_polymorphic_different_types(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'barcode__startswith': '12'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 2)

    def test_lte_polymorphic(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'price__lte': '9'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_is_lookup_used(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'hostname__icontains': 'no_exists_host'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 0)

    def test_filter_by_ip(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'ip': self.ip.address}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_filter_by_scm_status_check_result(self):
        status_checks = {
            SCMCheckResult.scm_error: 2,
            SCMCheckResult.scm_ok: 1,
            SCMCheckResult.check_failed: 3
        }
        objects = []
        for obj_type in (CloudHostFactory,
                         DataCenterAssetFactory,
                         VirtualServerFactory):
            for _ in range(2):
                objects.append(obj_type())

        for check_result in status_checks:
            for i in range(status_checks[check_result]):
                SCMStatusCheckFactory(
                    base_object=objects.pop().baseobject_ptr,
                    check_result=check_result
                )

            url = '{}?{}'.format(
                reverse('baseobject-list'), urlencode(
                    {'scmstatuscheck__check_result': check_result.numerator}
                )
            )
            response = self.client.get(url, format='json')
            self.assertEqual(
                len(response.data['results']),
                status_checks[check_result]
            )

            for obj in response.data['results']:
                self.assertIn('scmstatuscheck', obj)
                self.assertEqual(
                    obj['scmstatuscheck']['check_result'],
                    check_result.raw
                )

    def test_filter_by_service_uid(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'service': self.dc_asset.service_env.service.uid}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_filter_by_uid(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'uid': self.dc_asset.service_env.service.uid}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)
        self.assertEqual(
            response.data['results'][0]['id'],
            self.dc_asset.service_env.id
        )

    def test_filter_by_service_name(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'service': self.dc_asset.service_env.service.name}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_filter_by_configuration_path(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'configuration_path': 'mod1/cls1'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)
        self.assertEqual(response.data['results'][0]['id'], self.dc_asset.id)

    def test_filter_by_configuration_path_module_name(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'configuration_path__module__name': 'mod1'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)
        self.assertEqual(response.data['results'][0]['id'], self.dc_asset.id)

    def test_filter_by_id_startswith(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'id__startswith': '99999'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)
        self.assertEqual(
            response.data['results'][0]['id'], self.conf_class_1.id
        )

    def test_filter_by_id_exact(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'id__exact': '999999'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)
        self.assertEqual(
            response.data['results'][0]['id'], self.conf_class_1.id
        )

    def test_tags(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                [
                    ('tag', 'tag1'), ('tag', 'tag2')
                ]
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 0)

        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode([('tag', 'tag1')])
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_str_and_type_field(self):
        count = 0
        for descendant in BaseObject._polymorphic_descendants:
            if descendant._meta.proxy or descendant in [
                PolymorphicTestModel
            ]:
                continue
            if not descendant._polymorphic_descendants:
                count += 1
                obj = BASE_OBJECTS_FACTORIES[descendant]()
                url = reverse('baseobject-detail', args=(obj.id,))
                response = self.client.get(url, format='json')
                self.assertEqual(response.status_code, status.HTTP_200_OK)
                self.assertEqual(
                    response.data.get('__str__'),
                    '{}: {}'.format(obj._meta.verbose_name, str(obj)),
                    msg='__str__ not found (or different) for {}'.format(
                        descendant
                    )
                )
                self.assertEqual(
                    response.data.get('object_type'), obj.content_type.model
                )
        self.assertEqual(count, len(BASE_OBJECTS_FACTORIES))

    def test_filter_by_configurationclass_path(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'name__startswith': 'mod1/cls'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_filter_by_service_env_service_name(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'name__startswith': 'myserv'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_filter_by_cloudproject_name(self):
        CloudProjectFactory(name='my-cloud-project')
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'name__startswith': 'my-cloud'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_filter_by_cluster_name(self):
        ClusterFactory(name='my-cluster')
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'name__startswith': 'my-clus'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)

    def test_filter_by_service_env_env_name(self):
        url = '{}?{}'.format(
            reverse('baseobject-list'), urlencode(
                {'env': 'prod'}
            )
        )
        response = self.client.get(url, format='json')
        self.assertEqual(len(response.data['results']), 1)