Add billing annotations and tests

This commit is contained in:
Tobias Kunze 2025-12-04 16:43:59 +01:00 committed by Tobias Brunner
parent 3e6623278c
commit 84c0220af0
Signed by: tobru
SSH key fingerprint: SHA256:kOXg1R6c11XW3/Pt9dbLdQvOJGFAy+B2K6v6PtRWBGQ
2 changed files with 258 additions and 7 deletions

View file

@ -5,6 +5,7 @@ import pytest
from servala.core.models import (
ComputePlan,
ComputePlanAssignment,
InvoiceGroupingChoice,
ServiceInstance,
)
@ -125,7 +126,8 @@ def test_build_billing_annotations_complete():
control_plane.storage_plan_odoo_unit_id = "storage-unit-id"
annotations = ServiceInstance._build_billing_annotations(
compute_plan_assignment, control_plane
compute_plan_assignment=compute_plan_assignment,
control_plane=control_plane,
)
assert annotations["servala.com/erp_product_id_resource"] == "test-product-123"
@ -140,7 +142,10 @@ def test_build_billing_annotations_no_compute_plan():
control_plane.storage_plan_odoo_product_id = "storage-product-id"
control_plane.storage_plan_odoo_unit_id = "storage-unit-id"
annotations = ServiceInstance._build_billing_annotations(None, control_plane)
annotations = ServiceInstance._build_billing_annotations(
compute_plan_assignment=None,
control_plane=control_plane,
)
assert "servala.com/erp_product_id_resource" not in annotations
assert "servala.com/erp_unit_id_resource" not in annotations
@ -158,7 +163,8 @@ def test_build_billing_annotations_no_storage_plan():
control_plane.storage_plan_odoo_unit_id = None
annotations = ServiceInstance._build_billing_annotations(
compute_plan_assignment, control_plane
compute_plan_assignment=compute_plan_assignment,
control_plane=control_plane,
)
assert annotations["servala.com/erp_product_id_resource"] == "product-id"
@ -172,7 +178,10 @@ def test_build_billing_annotations_empty():
control_plane.storage_plan_odoo_product_id = None
control_plane.storage_plan_odoo_unit_id = None
annotations = ServiceInstance._build_billing_annotations(None, control_plane)
annotations = ServiceInstance._build_billing_annotations(
compute_plan_assignment=None,
control_plane=control_plane,
)
assert annotations == {}
@ -197,3 +206,205 @@ def test_all_billing_units():
assert str(choices["day"]) == "Day"
assert "Month" in str(choices["month"])
assert str(choices["year"]) == "Year"
def test_build_billing_annotations_by_service_grouping():
control_plane = Mock()
control_plane.storage_plan_odoo_product_id = None
control_plane.storage_plan_odoo_unit_id = None
control_plane.cloud_provider = Mock()
control_plane.cloud_provider.name = "Exoscale"
control_plane.name = "Geneva (CH-GVA-2)"
organization = Mock()
organization.name = "ACME Corp"
organization.osb_guid = "01998651-dc86-7d43-9e49-cdb790fcc4f0"
organization.origin = Mock()
organization.origin.invoice_grouping = InvoiceGroupingChoice.BY_SERVICE
service = Mock()
service.name = "Redis"
annotations = ServiceInstance._build_billing_annotations(
compute_plan_assignment=None,
control_plane=control_plane,
instance_name="MyProdRedis",
organization=organization,
service=service,
)
assert (
annotations["servala.com/erp_item_group_description"]
== "Servala Service: Redis"
)
assert (
annotations["servala.com/erp_item_description"]
== "MyProdRedis on Exoscale Geneva (CH-GVA-2)"
)
def test_build_billing_annotations_by_organization_grouping_with_osb_guid():
control_plane = Mock()
control_plane.storage_plan_odoo_product_id = None
control_plane.storage_plan_odoo_unit_id = None
control_plane.cloud_provider = Mock()
control_plane.cloud_provider.name = "Exoscale"
control_plane.name = "Geneva (CH-GVA-2)"
organization = Mock()
organization.name = "ACME"
organization.osb_guid = "01998651-dc86-7d43-9e49-cdb790fcc4f0"
organization.origin = Mock()
organization.origin.invoice_grouping = InvoiceGroupingChoice.BY_ORGANIZATION
service = Mock()
service.name = "Redis"
annotations = ServiceInstance._build_billing_annotations(
compute_plan_assignment=None,
control_plane=control_plane,
instance_name="MyProdRedis",
organization=organization,
service=service,
)
assert (
annotations["servala.com/erp_item_group_description"]
== "Organization: ACME (01998651-dc86-7d43-9e49-cdb790fcc4f0)"
)
assert (
annotations["servala.com/erp_item_description"]
== "MyProdRedis on Geneva (CH-GVA-2) [Org: 01998651-dc86-7d43-9e49-cdb790fcc4f0]"
)
def test_build_billing_annotations_by_organization_grouping_without_osb_guid():
control_plane = Mock()
control_plane.storage_plan_odoo_product_id = None
control_plane.storage_plan_odoo_unit_id = None
control_plane.cloud_provider = Mock()
control_plane.cloud_provider.name = "Exoscale"
control_plane.name = "Geneva (CH-GVA-2)"
organization = Mock()
organization.name = "ACME Corp"
organization.osb_guid = None # No OSB GUID
organization.origin = Mock()
organization.origin.invoice_grouping = InvoiceGroupingChoice.BY_ORGANIZATION
service = Mock()
service.name = "Redis"
annotations = ServiceInstance._build_billing_annotations(
compute_plan_assignment=None,
control_plane=control_plane,
instance_name="MyProdRedis",
organization=organization,
service=service,
)
assert (
annotations["servala.com/erp_item_group_description"]
== "Organization: ACME Corp"
)
assert (
annotations["servala.com/erp_item_description"]
== "MyProdRedis on Geneva (CH-GVA-2)"
)
def test_build_billing_annotations_by_organization_grouping_with_empty_osb_guid():
control_plane = Mock()
control_plane.storage_plan_odoo_product_id = None
control_plane.storage_plan_odoo_unit_id = None
control_plane.cloud_provider = Mock()
control_plane.cloud_provider.name = "Exoscale"
control_plane.name = "Geneva (CH-GVA-2)"
organization = Mock()
organization.name = "ACME Corp"
organization.osb_guid = "" # Empty string OSB GUID
organization.origin = Mock()
organization.origin.invoice_grouping = InvoiceGroupingChoice.BY_ORGANIZATION
service = Mock()
service.name = "Redis"
annotations = ServiceInstance._build_billing_annotations(
compute_plan_assignment=None,
control_plane=control_plane,
instance_name="MyProdRedis",
organization=organization,
service=service,
)
assert (
annotations["servala.com/erp_item_group_description"]
== "Organization: ACME Corp"
)
assert (
annotations["servala.com/erp_item_description"]
== "MyProdRedis on Geneva (CH-GVA-2)"
)
def test_build_billing_annotations_no_item_description_without_organization():
control_plane = Mock()
control_plane.storage_plan_odoo_product_id = "storage-product"
control_plane.storage_plan_odoo_unit_id = "storage-unit"
annotations = ServiceInstance._build_billing_annotations(
compute_plan_assignment=None,
control_plane=control_plane,
instance_name="MyProdRedis",
organization=None, # No organization
service=None,
)
assert "servala.com/erp_item_group_description" not in annotations
assert "servala.com/erp_item_description" not in annotations
# Storage annotations should still be there
assert annotations["servala.com/erp_product_id_storage"] == "storage-product"
def test_build_billing_annotations_combined():
compute_plan_assignment = Mock()
compute_plan_assignment.odoo_product_id = "compute-product"
compute_plan_assignment.odoo_unit_id = "compute-unit"
control_plane = Mock()
control_plane.storage_plan_odoo_product_id = "storage-product"
control_plane.storage_plan_odoo_unit_id = "storage-unit"
control_plane.cloud_provider = Mock()
control_plane.cloud_provider.name = "Exoscale"
control_plane.name = "Geneva (CH-GVA-2)"
organization = Mock()
organization.name = "ACME"
organization.osb_guid = "test-guid"
organization.origin = Mock()
organization.origin.invoice_grouping = InvoiceGroupingChoice.BY_SERVICE
service = Mock()
service.name = "PostgreSQL"
annotations = ServiceInstance._build_billing_annotations(
compute_plan_assignment=compute_plan_assignment,
control_plane=control_plane,
instance_name="ProdDB",
organization=organization,
service=service,
)
assert annotations["servala.com/erp_product_id_resource"] == "compute-product"
assert annotations["servala.com/erp_unit_id_resource"] == "compute-unit"
assert annotations["servala.com/erp_product_id_storage"] == "storage-product"
assert annotations["servala.com/erp_unit_id_storage"] == "storage-unit"
assert (
annotations["servala.com/erp_item_group_description"]
== "Servala Service: PostgreSQL"
)
assert (
annotations["servala.com/erp_item_description"]
== "ProdDB on Exoscale Geneva (CH-GVA-2)"
)