Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion data/seed/aws_pricelist_seed.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
{"vendor": "aws", "service": "AmazonALB", "region": "us-east-1", "usage_metric": "ALB-LCU-NewConnections", "unit": "LCU-Hours", "price_usd": 0.008, "source": "seed", "description": "ALB LCU new connections pricing ($0.008 per LCU-hour, 1 LCU = 25 new connections/sec)"},
{"vendor": "aws", "service": "AmazonALB", "region": "us-east-1", "usage_metric": "ALB-LCU-ActiveConnections", "unit": "LCU-Hours", "price_usd": 0.008, "source": "seed", "description": "ALB LCU active connections pricing ($0.008 per LCU-hour, 1 LCU = 3000 active)"},
{"vendor": "aws", "service": "AmazonALB", "region": "us-east-1", "usage_metric": "ALB-LCU-RuleEvaluations", "unit": "LCU-Hours", "price_usd": 0.008, "source": "seed", "description": "ALB LCU rule evaluations pricing ($0.008 per LCU-hour, 1 LCU = 1000 rules/sec)"},
{"vendor": "aws", "service": "AmazonCloudWatch", "region": "us-east-1", "usage_metric": "CloudWatch-Log-Storage", "unit": "GB-Mo", "price_usd": 0.03, "source": "seed", "description": "CloudWatch Logs storage pricing ($0.03 per GB-month stored)"},
{"vendor": "aws", "service": "AmazonVPC", "region": "us-east-1", "usage_metric": "NAT-Gateway-Hour", "unit": "Hours", "price_usd": 0.045, "source": "seed", "description": "NAT Gateway hourly pricing ($0.045 per NAT-hour)"},
{"vendor": "aws", "service": "AmazonVPC", "region": "us-east-1", "usage_metric": "NAT-Gateway-DataProcessed", "unit": "GB", "price_usd": 0.045, "source": "seed", "description": "NAT Gateway data processing pricing ($0.045 per GB processed)"},
{"vendor": "aws", "service": "AmazonVPC", "region": "us-east-1", "usage_metric": "VPC-Endpoint-Hour", "unit": "Hours", "price_usd": 0.01, "source": "seed", "description": "VPC Interface Endpoint hourly pricing ($0.01 per ENI-hour)"},
Expand Down
2 changes: 1 addition & 1 deletion infra_cost_model/pricing/sources/infracost.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def _to_float(value) -> Optional[float]:
"eu-west-1": "EU", "eu-west-2": "EUW2", "eu-west-3": "EUW3",
"eu-central-1": "EUC1", "eu-central-2": "EUC2", "eu-north-1": "EUN1",
"eu-south-1": "EUS1", "eu-south-2": "EUS2",
"ap-southeast-1": "APS1", "ap-southeast-2": "APS2", "ap-southeast-3": "APS3",
"ap-southeast-1": "APS1", "ap-southeast-2": "APS2", "ap-southeast-3": "APS4",
"ap-south-1": "APS3", "ap-south-2": "APS5",
"ap-northeast-1": "APN1", "ap-northeast-2": "APN2", "ap-northeast-3": "APN3",
"ap-east-1": "APE1",
Expand Down
3 changes: 1 addition & 2 deletions infra_cost_model/resources/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ def _infer_provider(cls, resource_type: Type[ResourceType]) -> Optional[str]:
"alb": "aws",
"networking": "aws",
"cloudwatch": "aws",
"rds": "aws",
"rds": "aws", "misc_services": "aws",
"misc_services": "aws",
"kms": "aws",
"data_transfer": "aws",
"gcp": "gcp", "azure": "azure",
Expand Down
20 changes: 20 additions & 0 deletions tests/test_infracost_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,3 +416,23 @@ def test_regionless_usagetype_unknown_region_upserts_nothing(monkeypatch):
cache, "DataTransfer-Internet-Out-GB", "moon-base-1")
assert n == 0
cache.upsert.assert_not_called()


# --- Region usagetype prefix map integrity -------------------------------------

def test_region_usagetype_prefixes_are_unique():
"""Each region must map to a DISTINCT usagetype prefix — a collision makes two
regions' prices indistinguishable in the usagetype filters (e.g. the data-
transfer region-pair / regionless sync)."""
from collections import Counter
from infra_cost_model.pricing.sources.infracost import _REGION_PREFIX
dupes = {v: n for v, n in Counter(_REGION_PREFIX.values()).items() if n > 1}
assert not dupes, f"duplicate region usagetype prefixes: {dupes}"


def test_ap_region_prefixes_match_aws_codes():
"""AWS assigns usage-type region codes by launch order, not name."""
from infra_cost_model.pricing.sources.infracost import _REGION_PREFIX
assert _REGION_PREFIX["ap-south-1"] == "APS3" # Mumbai
assert _REGION_PREFIX["ap-southeast-3"] == "APS4" # Jakarta
assert _REGION_PREFIX["ap-south-2"] == "APS5" # Hyderabad
15 changes: 15 additions & 0 deletions tests/test_pricing.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,18 @@ def test_seed_prices_is_idempotent():

assert count_once > 0
assert count_twice == count_once


def test_seed_pricelist_has_no_duplicate_rows():
"""The bundled seed list must not carry duplicate price rows: SQLite treats
seed rows (purchase_option=NULL) as distinct under the UNIQUE constraint, so a
dup would load twice and a single logical price could return as a spurious
multi-tier TieredPrice."""
import json
from collections import Counter
from infra_cost_model.pricing.cache import SEED_PRICES_PATH
rows = json.loads(SEED_PRICES_PATH.read_text())
keys = [(r["vendor"], r["service"], r["region"], r["usage_metric"],
r.get("start_usage_amount")) for r in rows]
dupes = {k: n for k, n in Counter(keys).items() if n > 1}
assert not dupes, f"duplicate seed rows: {dupes}"
Loading