Пример #1
0
    def test_create_storage_no_tiers_rate(self):
        """Test creating a non tiered storage rate."""
        storage_rates = (CostModelMetricsMap.OCP_METRIC_STORAGE_GB_REQUEST_MONTH,
                         CostModelMetricsMap.OCP_METRIC_STORAGE_GB_USAGE_MONTH)
        for storage_rate in storage_rates:
            ocp_data = {
                'name': 'Test Cost Model',
                'description': 'Test',
                'source_type': 'OCP',
                'provider_uuids': [self.provider.uuid],
                'rates': [
                    {
                        'metric': {'name': storage_rate},
                        'tiered_rates': [{
                            'unit': 'USD',
                            'value': 0.22
                        }]
                    }
                ]
            }

            with tenant_context(self.tenant):
                instance = None
                serializer = CostModelSerializer(data=ocp_data)
                if serializer.is_valid(raise_exception=True):
                    instance = serializer.save()
                self.assertIsNotNone(instance)
                self.assertIsNotNone(instance.uuid)
Пример #2
0
 def test_multiple_tag_values(self):
     """Test that tag keys can be multiple cost types."""
     value_kwargs = [
         {
             "tag_value": "value_one",
             "value": 0.1,
             "default": True
         },
         {
             "tag_value": "value_two",
             "value": 0.2
         },
     ]
     self.basic_model["rates"][0]["tag_rates"] = [
         format_tag_rate(tag_values=value_kwargs)
     ]
     with tenant_context(self.tenant):
         serializer = CostModelSerializer(data=self.basic_model)
         self.assertTrue(serializer.is_valid(raise_exception=True))
         serializer.save()
         data = serializer.data
     rates = data["rates"]
     self.assertEqual(len(rates), 1)
     for rate in rates:
         tag_rates = rate.get("tag_rates")
         self.assertIsNotNone(tag_rates)
         for tag_rate in tag_rates:
             tag_values = tag_rate["tag_values"]
             self.assertEqual(len(tag_values), 2)
Пример #3
0
    def test_tiered_rate_with_overlaps(self):
        """Test creating a tiered rate with a overlaps between the tiers."""
        self.ocp_data['rates'][0]['tiered_rates'] = [
            {
                'unit': 'USD',
                'value': 0.22,
                'usage': {
                    'usage_start': None,
                    'usage_end': 10.0
                }
            }, {
                'unit': 'USD',
                'value': 0.26,
                'usage': {
                    'usage_start': 5.0,
                    'usage_end': 20.0
                }
            }, {
                'unit': 'USD',
                'value': 0.26,
                'usage': {
                    'usage_start': 20.0,
                    'usage_end': None
                }
            }
        ]

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #4
0
 def test_invalid_currency(self):
     """Test failure while handling invalid cost_type."""
     currency = "invalid"
     serializer = CostModelSerializer(data=self.ocp_data,
                                      context=self.request_context)
     with self.assertRaises(serializers.ValidationError):
         serializer.validate_currency(currency)
Пример #5
0
    def test_create_cpu_core_per_hour_tiered_rate(self):
        """Test creating a cpu_core_per_hour rate."""
        self.ocp_data['rates'][0]['tiered_rates'] = [
            {
                'unit': 'USD',
                'value': 0.22,
                'usage': {
                    'usage_start': None,
                    'usage_end': 10.0
                }
            },
            {
                'unit': 'USD',
                'value': 0.26,
                'usage': {
                    'usage_start': 10.0,
                    'usage_end': None
                }
            }
        ]

        with tenant_context(self.tenant):
            instance = None
            serializer = CostModelSerializer(data=self.ocp_data)
            if serializer.is_valid(raise_exception=True):
                instance = serializer.save()

            self.assertIsNotNone(instance)
            self.assertIsNotNone(instance.uuid)
Пример #6
0
    def test_tiered_rate_null_start_end(self):
        """Test creating a rate with out a start and end."""
        self.ocp_data['rates'][0]['tiered_rates'] = [
            {
                'unit': 'USD',
                'value': 0.22,
                'usage': {
                    'usage_start': 0.0,
                    'usage_end': 7.0
                }
            },
            {
                'unit': 'USD',
                'value': 0.26,
                'usage': {
                    'usage_start': 10.0,
                    'usage_end': 20.0
                }
            }
        ]

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #7
0
    def test_create_storage_tiered_rate(self):
        """Test creating a storage tiered rate."""
        storage_rates = (
            metric_constants.OCP_METRIC_STORAGE_GB_REQUEST_MONTH,
            metric_constants.OCP_METRIC_STORAGE_GB_USAGE_MONTH,
        )
        for storage_rate in storage_rates:
            ocp_data = {
                "name": "Test Cost Model",
                "description": "Test",
                "source_type": Provider.PROVIDER_OCP,
                "providers": [{"uuid": self.provider.uuid, "name": self.provider.name}],
                "rates": [
                    {
                        "metric": {"name": storage_rate},
                        "tiered_rates": [
                            {"unit": "USD", "value": 0.22, "usage": {"usage_start": None, "usage_end": 10.0}},
                            {"unit": "USD", "value": 0.26, "usage": {"usage_start": 10.0, "usage_end": None}},
                        ],
                    }
                ],
            }

            with tenant_context(self.tenant):
                instance = None
                serializer = CostModelSerializer(data=ocp_data)
                if serializer.is_valid(raise_exception=True):
                    instance = serializer.save()
                self.assertIsNotNone(instance)
                self.assertIsNotNone(instance.uuid)
Пример #8
0
 def currency_filter(self, qs, name, values):
     """Filter currency if a valid currency is passed in"""
     serializer = CostModelSerializer(qs)
     if serializer.validate_currency(values[0]):
         lookup = "__".join([name, "iexact"])
         queries = [Q(**{lookup: val}) for val in values]
         return qs.filter(reduce(and_, queries))
Пример #9
0
    def test_tiered_rate_null_start_end(self):
        """Test creating a rate with out a start and end."""
        self.ocp_data["rates"][0]["tiered_rates"] = [
            {
                "unit": "USD",
                "value": 0.22,
                "usage": {
                    "usage_start": 0.0,
                    "usage_end": 7.0
                }
            },
            {
                "unit": "USD",
                "value": 0.26,
                "usage": {
                    "usage_start": 10.0,
                    "usage_end": 20.0
                }
            },
        ]

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #10
0
 def test_tag_key_can_be_multiple_cost_types(self):
     """Test that tag keys can be multiple cost types."""
     value_kwargs = [{"value": 0.1, "default": True, "usage_start": 1, "usage_end": 10}]
     tag_rates_list = []
     cost_types = ["Infrastructure", "Supplementary"]
     for cost_type in cost_types:
         rate = {"metric": {"name": metric_constants.OCP_METRIC_CPU_CORE_USAGE_HOUR}, "cost_type": cost_type}
         rate["tag_rates"] = format_tag_rate(tag_values=value_kwargs)
         tag_rates_list.append(rate)
     self.basic_model["rates"] = tag_rates_list
     with tenant_context(self.tenant):
         serializer = CostModelSerializer(data=self.basic_model)
         self.assertTrue(serializer.is_valid(raise_exception=True))
         serializer.save()
         data = serializer.data
     rates = data.get("rates", [])
     self.assertEqual(len(rates), 2)
     for rate in rates:
         tag_rate = rate.get("tag_rates")
         self.assertIsNotNone(tag_rate)
         # Check cost types
         result_cost_type = rate["cost_type"]
         self.assertIn(result_cost_type, cost_types)
         cost_types.remove(result_cost_type)
         # Check that to_representation is working
         tag_value = tag_rate["tag_values"][0]
         decimals = [tag_value["value"], tag_value["usage"]["usage_start"], tag_value["usage"]["usage_end"]]
         for expected_decimal in decimals:
             self.assertIsInstance(expected_decimal, Decimal)
Пример #11
0
    def test_tiered_rate_with_overlaps(self):
        """Test creating a tiered rate with a overlaps between the tiers."""
        self.ocp_data["rates"][0]["tiered_rates"] = [
            {
                "unit": "USD",
                "value": 0.22,
                "usage": {
                    "usage_start": None,
                    "usage_end": 10.0
                }
            },
            {
                "unit": "USD",
                "value": 0.26,
                "usage": {
                    "usage_start": 5.0,
                    "usage_end": 20.0
                }
            },
            {
                "unit": "USD",
                "value": 0.26,
                "usage": {
                    "usage_start": 20.0,
                    "usage_end": None
                }
            },
        ]

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #12
0
    def test_rate_cost_type_valid(self):
        """Test that a valid cost type is accepted."""
        self.ocp_data["rates"][0]["tiered_rates"] = [
            {
                "unit": "USD",
                "value": 0.22,
                "usage": {"usage_start": None, "usage_end": None},
                "cost_type": "Infrastructure",
            }
        ]

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            if serializer.is_valid(raise_exception=True):
                serializer.save()

        self.ocp_data["rates"][0]["tiered_rates"] = [
            {
                "unit": "USD",
                "value": 0.22,
                "usage": {"usage_start": None, "usage_end": None},
                "cost_type": "Supplementary",
            }
        ]

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            if serializer.is_valid(raise_exception=True):
                serializer.save()
Пример #13
0
    def test_create_cpu_core_per_hour_tiered_rate(self):
        """Test creating a cpu_core_per_hour rate."""
        self.ocp_data["rates"][0]["tiered_rates"] = [
            {
                "unit": "USD",
                "value": 0.22,
                "usage": {
                    "usage_start": None,
                    "usage_end": 10.0
                }
            },
            {
                "unit": "USD",
                "value": 0.26,
                "usage": {
                    "usage_start": 10.0,
                    "usage_end": None
                }
            },
        ]

        with tenant_context(self.tenant):
            instance = None
            serializer = CostModelSerializer(data=self.ocp_data)
            if serializer.is_valid(raise_exception=True):
                instance = serializer.save()

            self.assertIsNotNone(instance)
            self.assertIsNotNone(instance.uuid)
Пример #14
0
 def test_validate_source_uuid_error(self):
     """Test validate source uuid error."""
     tag_value = {"tag_value": "key_one", "value": 0.2}
     self.basic_model["rates"][0]["tag_rates"] = format_tag_rate(tag_values=[tag_value])
     with tenant_context(self.tenant):
         serializer = CostModelSerializer(data=self.basic_model)
         with self.assertRaises(serializers.ValidationError):
             serializer.validate_source_uuids([uuid4()])
Пример #15
0
 def test_error_on_invalid_metric(self):
     """Test error on an invalid metric rate."""
     self.ocp_data.get("rates", [])[0]["metric"]["name"] = "invalid_metric"
     with tenant_context(self.tenant):
         serializer = CostModelSerializer(data=self.ocp_data)
         with self.assertRaises(serializers.ValidationError):
             if serializer.is_valid(raise_exception=True):
                 serializer.save()
Пример #16
0
 def test_error_on_invalid_provider(self):
     """Test error with an invalid provider id."""
     self.ocp_data.update({'provider_uuids': ['1dd7204c-72c4-4ec4-95bc-d5c447688b27']})
     with tenant_context(self.tenant):
         serializer = CostModelSerializer(data=self.ocp_data)
         with self.assertRaises(serializers.ValidationError):
             if serializer.is_valid(raise_exception=True):
                 serializer.save()
Пример #17
0
    def test_get_metric_display_data_openshift(self):
        """Test the display data helper function for OpenShift metrics."""
        serializer = CostModelSerializer(data=None)

        for metric_choice in metric_constants.METRIC_CHOICES:
            response = serializer._get_metric_display_data(Provider.PROVIDER_OCP, metric_choice[0])
            self.assertIsNotNone(response.get("label_measurement_unit"))
            self.assertIsNotNone(response.get("label_measurement"))
            self.assertIsNotNone(response.get("label_metric"))
Пример #18
0
    def test_error_on_nonOCP_source_type_with_markup_and_rates(self):
        """Test error when non OCP source is added with markup and rates."""
        self.ocp_data["source_type"] = Provider.PROVIDER_AWS

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #19
0
    def test_error_source_type_with_markup(self):
        """Test that non-existent source type is invalid."""
        self.ocp_data["source_type"] = "invalid-source"

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #20
0
    def test_error_on_negative_rate(self):
        """Test error when trying to create an negative rate input."""
        self.ocp_data['rates'][0]['tiered_rates'][0]['value'] = float(round(Decimal(random.random()), 6) * -1)

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #21
0
 def test_error_on_rate_type(self):
     """Test error when trying to create an invalid rate input."""
     self.ocp_data["rates"][0].pop("tiered_rates")
     self.ocp_data["rates"][0]["bad_rates"] = []
     with tenant_context(self.tenant):
         serializer = CostModelSerializer(data=self.ocp_data)
         with self.assertRaises(serializers.ValidationError):
             if serializer.is_valid(raise_exception=True):
                 serializer.save()
Пример #22
0
    def test_error_on_usage_bad_upper_bound(self):
        """Test error on a usage_end that does not cover lower bound."""
        self.ocp_data["rates"][0]["tiered_rates"][0]["usage"] = {"usage_start": None, "usage_end": 5}

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #23
0
 def test_error_on_source_type_without_markup(self):
     """Test error when non OCP source is added without markup."""
     self.ocp_data['source_type'] = 'AWS'
     self.ocp_data['markup'] = {}
     with tenant_context(self.tenant):
         serializer = CostModelSerializer(data=self.ocp_data)
         with self.assertRaises(serializers.ValidationError):
             if serializer.is_valid(raise_exception=True):
                 serializer.save()
Пример #24
0
    def test_error_no_rate(self):
        """Test error when trying to create an empty rate."""
        self.ocp_data["rates"][0]["tiered_rates"] = []

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #25
0
    def test_get_metric_display_data_openshift(self):
        """Test the display data helper function for OpenShift metrics."""
        serializer = CostModelSerializer(data=None)

        for metric_choice in CostModelMetricsMap.METRIC_CHOICES:
            response = serializer._get_metric_display_data('OCP', metric_choice[0])
            self.assertIsNotNone(response.label_measurement_unit)
            self.assertIsNotNone(response.label_measurement)
            self.assertIsNotNone(response.label_metric)
Пример #26
0
    def test_error_tier_usage_end_less_than(self):
        """Test error when trying to create a tiered usage_end less than usage_start."""
        self.ocp_data["rates"][0]["tiered_rates"][0]["usage"] = {"usage_start": 10.0, "usage_end": 3.0}

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #27
0
    def test_rate_cost_type_invalid(self):
        """Test that an invalid cost type is rejected."""
        self.ocp_data["rates"][0]["cost_type"] = "Infrastructurez"

        with tenant_context(self.tenant):
            serializer = CostModelSerializer(data=self.ocp_data)
            with self.assertRaises(serializers.ValidationError):
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
Пример #28
0
 def test_error_bad_distribution_choice(self):
     """Test that source successfully fails if bad distribution type."""
     bad_choice_list = ["bad1", "bad2", "bad3"]
     for bad_input in bad_choice_list:
         self.ocp_data["distribution"] = bad_input
         self.assertEqual(self.ocp_data["distribution"], bad_input)
         with tenant_context(self.tenant):
             serializer = CostModelSerializer(data=self.ocp_data)
             with self.assertRaises(serializers.ValidationError):
                 serializer.validate_distribution(bad_input)
Пример #29
0
 def test_error_on_empty_list_for_tag_values(self):
     """Test that tag_values can not be an empty list."""
     self.basic_model["rates"][0]["tag_rates"] = format_tag_rate(tag_values=[])
     with tenant_context(self.tenant):
         serializer = CostModelSerializer(data=self.basic_model)
         with self.assertRaises(serializers.ValidationError):
             self.assertFalse(serializer.is_valid(raise_exception=True))
     result_err_msg = serializer.errors["rates"][0]["tag_values"][0]
     expected_err_msg = "A tag_values can not be an empty list."
     self.assertEqual(result_err_msg, expected_err_msg)
Пример #30
0
 def test_valid_data(self):
     """Test rate and markup for valid entries."""
     with tenant_context(self.tenant):
         instance = None
         serializer = CostModelSerializer(data=self.ocp_data)
         if serializer.is_valid(raise_exception=True):
             instance = serializer.save()
         self.assertIn(instance.source_type, SOURCE_TYPE_MAP.keys())
         self.assertIsNotNone(instance.markup)
         self.assertIsNotNone(instance.rates)