Exemple #1
0
    def test_populate_monthly_cost_cluster_supplementary_cost(self):
        """Test that the monthly infrastructure cost row for clusters in the summary table is populated."""
        self.cluster_id = self.ocp_provider.authentication.provider_resource_name

        cluster_rate = random.randrange(1, 100)

        dh = DateHelper()
        start_date = dh.this_month_start
        end_date = dh.this_month_end

        first_month, _ = month_date_range_tuple(start_date)

        cluster_alias = "test_cluster_alias"
        self.accessor.populate_monthly_cost(
            "Cluster", "Supplementary", cluster_rate, start_date, end_date, self.cluster_id, cluster_alias
        )

        monthly_cost_rows = (
            self.accessor._get_db_obj_query(OCPUsageLineItemDailySummary)
            .filter(usage_start=first_month, supplementary_monthly_cost__isnull=False)
            .all()
        )
        with schema_context(self.schema):
            self.assertEquals(monthly_cost_rows.count(), 1)
            for monthly_cost_row in monthly_cost_rows:
                self.assertEquals(monthly_cost_row.supplementary_monthly_cost, cluster_rate)
Exemple #2
0
    def test_remove_monthly_cost(self):
        """Test that the monthly cost row in the summary table is removed."""
        self.cluster_id = self.ocp_provider.authentication.provider_resource_name

        node_rate = random.randrange(1, 100)

        dh = DateHelper()
        start_date = dh.this_month_start
        end_date = dh.this_month_end

        first_month, first_next_month = month_date_range_tuple(start_date)

        cluster_alias = "test_cluster_alias"
        cost_type = "Node"
        rate_type = metric_constants.SUPPLEMENTARY_COST_TYPE
        self.accessor.populate_monthly_cost(
            cost_type, rate_type, node_rate, start_date, end_date, self.cluster_id, cluster_alias
        )

        monthly_cost_rows = (
            self.accessor._get_db_obj_query(OCPUsageLineItemDailySummary)
            .filter(usage_start=first_month, supplementary_monthly_cost__isnull=False)
            .all()
        )
        with schema_context(self.schema):
            self.assertTrue(monthly_cost_rows.exists())
        self.accessor.remove_monthly_cost(start_date, first_next_month, self.cluster_id, cost_type)
        with schema_context(self.schema):
            self.assertFalse(monthly_cost_rows.exists())
    def remove_monthly_cost(self):
        """Delete all the monthly costs of a customer."""
        # start_date should be the first month this ocp was used
        start_date = OCPUsageLineItemDailySummary.objects.aggregate(
            Min("usage_start"))["usage_start__min"]
        # If end_date is not provided, recalculate till the latest month
        end_date = OCPUsageLineItemDailySummary.objects.aggregate(
            Max("usage_end"))["usage_end__max"]

        LOG.info("Removing monthly costs from %s to %s.", start_date, end_date)

        first_month = start_date.replace(day=1,
                                         hour=0,
                                         minute=0,
                                         second=0,
                                         microsecond=0)

        with schema_context(self.schema):
            # Calculate monthly cost for every month
            for curr_month in rrule(freq=MONTHLY,
                                    until=end_date,
                                    dtstart=first_month):
                first_curr_month, _ = month_date_range_tuple(curr_month)

                # Remove existing monthly costs
                OCPUsageLineItemDailySummary.objects.filter(
                    usage_start=first_curr_month,
                    monthly_cost__isnull=False).delete()
Exemple #4
0
    def test_populate_monthly_cost_node_supplementary_cost(self):
        """Test that the monthly supplementary cost row for nodes in the summary table is populated."""
        self.cluster_id = self.ocp_provider.authentication.provider_resource_name

        node_rate = random.randrange(1, 100)

        dh = DateHelper()
        start_date = dh.this_month_start
        end_date = dh.this_month_end

        first_month, _ = month_date_range_tuple(start_date)

        cluster_alias = "test_cluster_alias"
        self.accessor.populate_monthly_cost(
            "Node", "Supplementary", node_rate, start_date, end_date, self.cluster_id, cluster_alias
        )

        monthly_cost_rows = (
            self.accessor._get_db_obj_query(OCPUsageLineItemDailySummary)
            .filter(usage_start=first_month, supplementary_monthly_cost__isnull=False)
            .all()
        )
        with schema_context(self.schema):
            expected_count = (
                OCPUsageLineItemDailySummary.objects.filter(
                    report_period__provider_id=self.ocp_provider.uuid, usage_start__gte=start_date
                )
                .values("node")
                .distinct()
                .count()
            )
            self.assertEquals(monthly_cost_rows.count(), expected_count)
            for monthly_cost_row in monthly_cost_rows:
                self.assertEquals(monthly_cost_row.supplementary_monthly_cost, node_rate)
    def test_remove_monthly_cost(self):
        """Test that the monthly cost row in the summary table is removed."""
        report_table_name = OCP_REPORT_TABLE_MAP["report"]

        report_table = getattr(self.accessor.report_schema, report_table_name)

        node_cost = random.randrange(1, 100)
        for _ in range(5):
            self.creator.create_ocp_usage_line_item(self.reporting_period,
                                                    self.report)

        with schema_context(self.schema):
            report_entry = report_table.objects.all().aggregate(
                Min("interval_start"), Max("interval_start"))
            start_date = report_entry["interval_start__min"]
            end_date = report_entry["interval_start__max"]

        self.accessor.populate_line_item_daily_table(start_date, end_date,
                                                     self.cluster_id)
        self.accessor.populate_line_item_daily_summary_table(
            start_date, end_date, self.cluster_id)
        cluster_alias = "test_cluster_alias"
        self.accessor.populate_monthly_cost(node_cost, start_date, end_date,
                                            self.cluster_id, cluster_alias)

        first_month, _ = month_date_range_tuple(start_date)
        monthly_cost = self.accessor._get_db_obj_query(
            OCPUsageLineItemDailySummary).filter(usage_start=first_month,
                                                 monthly_cost__isnull=False)
        self.assertTrue(monthly_cost.exists())
        self.accessor.remove_monthly_cost()
        self.assertFalse(monthly_cost.exists())
Exemple #6
0
    def test_populate_monthly_cost(self):
        """Test that the monthly cost row in the summary table is populated."""
        report_table_name = OCP_REPORT_TABLE_MAP['report']
        report_table = getattr(self.accessor.report_schema, report_table_name)

        node_cost = random.randrange(1, 100)
        for _ in range(5):
            self.creator.create_ocp_usage_line_item(self.reporting_period, self.report)

        with schema_context(self.schema):
            report_entry = report_table.objects.all().aggregate(
                Min('interval_start'), Max('interval_start')
            )
            start_date = report_entry['interval_start__min']
            end_date = report_entry['interval_start__max']

        start_date = start_date.replace(hour=0, minute=0, second=0, microsecond=0)
        end_date = end_date.replace(hour=0, minute=0, second=0, microsecond=0)
        first_month, _ = month_date_range_tuple(start_date)

        self.accessor.populate_line_item_daily_table(start_date, end_date, self.cluster_id)
        self.accessor.populate_line_item_daily_summary_table(
            start_date, end_date, self.cluster_id
        )
        self.accessor.populate_monthly_cost(node_cost, start_date, end_date)

        monthly_cost_row = self.accessor._get_db_obj_query(OCPUsageLineItemDailySummary).filter(
            usage_start=first_month,
            monthly_cost__isnull=False
        ).first()
        self.assertEquals(monthly_cost_row.monthly_cost, 6 * node_cost)
    def populate_monthly_cost(self, node_cost, start_date=None, end_date=None):
        """
        Populate the monthly cost of a customer.

        Right now this is just the node/month cost. Calculated from
        node_cost * number_unique_nodes.

        args:
            node_cost (Decimal): The node cost per month
            start_date (datetime, str): The start_date to calculate monthly_cost.
            end_date (datetime, str): The end_date to calculate monthly_cost.

        """
        if isinstance(start_date, str):
            start_date = parse(start_date)
        if isinstance(end_date, str):
            end_date = parse(end_date)
        if not start_date:
            # If start_date is not provided, recalculate from the first month
            start_date = OCPUsageLineItemDailySummary.objects.aggregate(
                Min('usage_start')
            )['usage_start__min']
        if not end_date:
            # If end_date is not provided, recalculate till the latest month
            end_date = OCPUsageLineItemDailySummary.objects.aggregate(
                Max('usage_end')
            )['usage_end__max']

        LOG.info('Populating Monthly cost from %s to %s.', start_date, end_date)

        first_month = start_date.replace(day=1, hour=0, minute=0, second=0, microsecond=0)

        with schema_context(self.schema):
            # Calculate monthly cost for every month
            for curr_month in rrule(freq=MONTHLY, until=end_date, dtstart=first_month):
                first_curr_month, first_next_month = month_date_range_tuple(curr_month)

                unique_nodes = OCPUsageLineItemDailySummary.objects.\
                    filter(usage_start__gte=first_curr_month,
                           usage_start__lt=first_next_month,
                           node__isnull=False
                           ).values_list('node').distinct().count()
                total_cost = node_cost * unique_nodes
                LOG.info('Total Cost is %s for %s nodes.', total_cost, unique_nodes)

                # Remove existing monthly costs
                OCPUsageLineItemDailySummary.objects.filter(
                    usage_start=first_curr_month,
                    monthly_cost__isnull=False
                ).delete()

                # Create new monthly cost
                OCPUsageLineItemDailySummary.objects.create(
                    usage_start=first_curr_month,
                    usage_end=first_curr_month,
                    monthly_cost=total_cost
                )
Exemple #8
0
    def test_month_date_range_tuple(self):
        """Test month_date_range_tuple returns first of the month and first of next month."""
        test_date = datetime(year=2018, month=12, day=15)
        expected_start_month = datetime(year=2018, month=12, day=1)
        expected_start_next_month = datetime(year=2019, month=1, day=1)

        start_month, first_next_month = common_utils.month_date_range_tuple(test_date)

        self.assertEquals(start_month, expected_start_month)
        self.assertEquals(first_next_month, expected_start_next_month)
    def populate_monthly_cost(self, cost_type, rate_type, rate, start_date,
                              end_date, cluster_id, cluster_alias):
        """
        Populate the monthly cost of a customer.

        Right now this is just the node/month cost. Calculated from
        node_cost * number_unique_nodes.

        args:
            node_cost (Decimal): The node cost per month
            start_date (datetime, str): The start_date to calculate monthly_cost.
            end_date (datetime, str): The end_date to calculate monthly_cost.

        """
        if isinstance(start_date, str):
            start_date = parse(start_date).date()
        if isinstance(end_date, str):
            end_date = parse(end_date).date()

        # usage_start, usage_end are date types
        first_month = datetime.datetime(*start_date.replace(
            day=1).timetuple()[:3]).replace(tzinfo=pytz.UTC)
        end_date = datetime.datetime(*end_date.timetuple()[:3]).replace(
            hour=23, minute=59, second=59, tzinfo=pytz.UTC)

        # Calculate monthly cost for each month from start date to end date
        for curr_month in rrule(freq=MONTHLY,
                                until=end_date,
                                dtstart=first_month):
            first_curr_month, first_next_month = month_date_range_tuple(
                curr_month)
            LOG.info("Populating monthly cost from %s to %s.",
                     first_curr_month, first_next_month)
            if cost_type == "Node":
                if rate is None:
                    self.remove_monthly_cost(first_curr_month,
                                             first_next_month, cluster_id,
                                             cost_type)
                else:
                    self.upsert_monthly_node_cost_line_item(
                        first_curr_month, first_next_month, cluster_id,
                        cluster_alias, rate_type, rate)
            elif cost_type == "Cluster":
                if rate is None:
                    self.remove_monthly_cost(first_curr_month,
                                             first_next_month, cluster_id,
                                             cost_type)
                else:
                    self.upsert_monthly_cluster_cost_line_item(
                        first_curr_month, first_next_month, cluster_id,
                        cluster_alias, rate_type, rate)
    def populate_monthly_cost(self, node_cost, start_date, end_date,
                              cluster_id, cluster_alias):
        """
        Populate the monthly cost of a customer.

        Right now this is just the node/month cost. Calculated from
        node_cost * number_unique_nodes.

        args:
            node_cost (Decimal): The node cost per month
            start_date (datetime, str): The start_date to calculate monthly_cost.
            end_date (datetime, str): The end_date to calculate monthly_cost.

        """
        if isinstance(start_date, str):
            start_date = parse(start_date)
        if isinstance(end_date, str):
            end_date = parse(end_date)
        if not start_date:
            # If start_date is not provided, recalculate from the first month
            start_date = OCPUsageLineItemDailySummary.objects.aggregate(
                Min("usage_start"))["usage_start__min"]
        if not end_date:
            # If end_date is not provided, recalculate till the latest month
            end_date = OCPUsageLineItemDailySummary.objects.aggregate(
                Max("usage_end"))["usage_end__max"]

        first_month = start_date.replace(day=1,
                                         hour=0,
                                         minute=0,
                                         second=0,
                                         microsecond=0)

        with schema_context(self.schema):
            # Calculate monthly cost for every month
            for curr_month in rrule(freq=MONTHLY,
                                    until=end_date,
                                    dtstart=first_month):
                first_curr_month, first_next_month = month_date_range_tuple(
                    curr_month)
                LOG.info("Populating Monthly node cost from %s to %s.",
                         first_curr_month, first_next_month)

                unique_nodes = (OCPUsageLineItemDailySummary.objects.filter(
                    usage_start__gte=first_curr_month,
                    usage_start__lt=first_next_month,
                    cluster_id=cluster_id,
                    node__isnull=False,
                ).values_list("node").distinct())

                report_period = self.get_usage_period_by_dates_and_cluster(
                    first_curr_month, first_next_month, cluster_id)

                for node in unique_nodes:
                    LOG.info("Node (%s) has a monthly cost of %s.", node[0],
                             node_cost)
                    # delete node cost per month
                    OCPUsageLineItemDailySummary.objects.filter(
                        usage_start=first_curr_month,
                        usage_end=first_curr_month,
                        monthly_cost=node_cost,
                        report_period=report_period,
                        cluster_id=cluster_id,
                        cluster_alias=cluster_alias,
                        monthly_cost__isnull=False,
                        node=node[0],
                    ).delete()
                    # add node cost per month
                    OCPUsageLineItemDailySummary.objects.create(
                        usage_start=first_curr_month,
                        usage_end=first_curr_month,
                        monthly_cost=node_cost,
                        report_period=report_period,
                        cluster_id=cluster_id,
                        cluster_alias=cluster_alias,
                        node=node[0],
                    )