test descriptions
This commit is contained in:
@@ -33,6 +33,8 @@ HIVE_SECRET = "test-hive-secret"
|
||||
|
||||
|
||||
def test_charge_single_node_gets_90_percent():
|
||||
"Charge single node gets 90 percent\n\nTags: billing, http, payments"
|
||||
|
||||
ledger = BillingLedger(starting_credit=1.0, default_price_per_1k=0.02)
|
||||
ledger.ensure_client("key-a")
|
||||
event = ledger.charge_request("key-a", MODEL, total_tokens=1000, node_work=[("wallet-1", 12)])
|
||||
@@ -43,6 +45,8 @@ def test_charge_single_node_gets_90_percent():
|
||||
|
||||
|
||||
def test_default_starting_credit_is_zero_and_fresh_key_is_unfunded():
|
||||
"Default starting credit is zero and fresh key is unfunded\n\nTags: billing, http, payments"
|
||||
|
||||
ledger = BillingLedger(default_price_per_1k=0.02)
|
||||
|
||||
assert DEFAULT_STARTING_CREDIT == 0.0
|
||||
@@ -53,6 +57,8 @@ def test_default_starting_credit_is_zero_and_fresh_key_is_unfunded():
|
||||
|
||||
|
||||
def test_charge_three_node_split_by_work_units():
|
||||
"Charge three node split by work units\n\nTags: billing, http, payments"
|
||||
|
||||
ledger = BillingLedger(starting_credit=1.0, default_price_per_1k=0.02)
|
||||
ledger.ensure_client("key-a")
|
||||
ledger.charge_request(
|
||||
@@ -67,6 +73,8 @@ def test_charge_three_node_split_by_work_units():
|
||||
|
||||
|
||||
def test_walletless_node_share_accrues_to_protocol_cut():
|
||||
"Walletless node share accrues to protocol cut\n\nTags: billing, http, payments, security, wallet"
|
||||
|
||||
ledger = BillingLedger(starting_credit=1.0, default_price_per_1k=0.02)
|
||||
ledger.ensure_client("key-a")
|
||||
ledger.charge_request(
|
||||
@@ -80,6 +88,8 @@ def test_walletless_node_share_accrues_to_protocol_cut():
|
||||
|
||||
|
||||
def test_per_model_price_override():
|
||||
"Per model price override\n\nTags: billing, http, payments"
|
||||
|
||||
ledger = BillingLedger(
|
||||
starting_credit=1.0,
|
||||
default_price_per_1k=0.02,
|
||||
@@ -93,6 +103,8 @@ def test_per_model_price_override():
|
||||
|
||||
|
||||
def test_non_stream_billable_tokens_cap_usage_by_request_bound():
|
||||
"Non stream billable tokens cap usage by request bound\n\nTags: billing, http, payments, streaming"
|
||||
|
||||
payload = {"usage": {"total_tokens": 1_000_000}}
|
||||
request = {"messages": [{"role": "user", "content": "hello tracker"}], "max_tokens": 3}
|
||||
|
||||
@@ -101,6 +113,8 @@ def test_non_stream_billable_tokens_cap_usage_by_request_bound():
|
||||
|
||||
|
||||
def test_non_stream_billable_tokens_fallback_when_usage_missing():
|
||||
"Non stream billable tokens fallback when usage missing\n\nTags: billing, http, payments, streaming"
|
||||
|
||||
payload = {"choices": [{"message": {"role": "assistant", "content": "ok now"}}]}
|
||||
request = {"messages": [{"role": "user", "content": "hello tracker"}], "max_tokens": 10}
|
||||
|
||||
@@ -109,6 +123,8 @@ def test_non_stream_billable_tokens_fallback_when_usage_missing():
|
||||
|
||||
|
||||
def test_stream_billable_tokens_allow_usage_to_lower_observed_count_only():
|
||||
"Stream billable tokens allow usage to lower observed count only\n\nTags: billing, http, payments, streaming"
|
||||
|
||||
observed_payload = {
|
||||
"choices": [{
|
||||
"index": 0,
|
||||
@@ -123,6 +139,8 @@ def test_stream_billable_tokens_allow_usage_to_lower_observed_count_only():
|
||||
|
||||
|
||||
def test_payout_and_forfeit_hooks():
|
||||
"Payout and forfeit hooks\n\nTags: billing, http, payments"
|
||||
|
||||
ledger = BillingLedger(starting_credit=1.0, default_price_per_1k=0.02)
|
||||
ledger.charge_request("key-a", MODEL, 1000, [("wallet-1", 1)])
|
||||
pending = ledger.get_node_pending("wallet-1")
|
||||
@@ -138,6 +156,8 @@ def test_payout_and_forfeit_hooks():
|
||||
|
||||
|
||||
def test_restart_persistence(tmp_path):
|
||||
"Restart persistence\n\nTags: billing, http, payments, persistence"
|
||||
|
||||
db = str(tmp_path / "billing.db")
|
||||
ledger = BillingLedger(db_path=db, starting_credit=1.0, default_price_per_1k=0.02)
|
||||
ledger.credit_client("key-a", 5.0)
|
||||
@@ -153,6 +173,8 @@ def test_restart_persistence(tmp_path):
|
||||
|
||||
|
||||
def test_tracker_enables_billing_with_default_db_when_requested(tmp_path, monkeypatch):
|
||||
"Tracker enables billing with default db when requested\n\nTags: billing, http, payments"
|
||||
|
||||
from meshnet_tracker.billing import DEFAULT_BILLING_DB_PATH
|
||||
|
||||
monkeypatch.chdir(tmp_path)
|
||||
@@ -171,6 +193,8 @@ def test_tracker_enables_billing_with_default_db_when_requested(tmp_path, monkey
|
||||
|
||||
|
||||
def test_event_replication_converges_and_dedupes():
|
||||
"Event replication converges and dedupes\n\nTags: billing, http, payments"
|
||||
|
||||
leader = BillingLedger(starting_credit=1.0, default_price_per_1k=0.02)
|
||||
follower = BillingLedger(starting_credit=1.0, default_price_per_1k=0.02)
|
||||
|
||||
@@ -360,6 +384,8 @@ def _chat(tracker_url: str, api_key: str | None, **body_overrides):
|
||||
|
||||
|
||||
def test_proxy_chat_requires_api_key_when_billing_enabled(billed_tracker):
|
||||
"Proxy chat requires api key when billing enabled\n\nTags: billing, http, payments"
|
||||
|
||||
tracker_url, _, _ = billed_tracker
|
||||
with pytest.raises(urllib.error.HTTPError) as exc_info:
|
||||
_chat(tracker_url, api_key=None)
|
||||
@@ -367,6 +393,8 @@ def test_proxy_chat_requires_api_key_when_billing_enabled(billed_tracker):
|
||||
|
||||
|
||||
def test_proxy_chat_402_for_fresh_key_before_routing(billed_tracker):
|
||||
"Proxy chat 402 for fresh key before routing\n\nTags: billing, http, payments"
|
||||
|
||||
tracker_url, ledger, stub = billed_tracker
|
||||
with pytest.raises(urllib.error.HTTPError) as exc_info:
|
||||
_chat(tracker_url, api_key="fresh-client")
|
||||
@@ -376,6 +404,8 @@ def test_proxy_chat_402_for_fresh_key_before_routing(billed_tracker):
|
||||
|
||||
|
||||
def test_proxy_chat_bills_credited_client_and_credits_node(billed_tracker):
|
||||
"Proxy chat bills credited client and credits node\n\nTags: billing, http, payments"
|
||||
|
||||
tracker_url, ledger, _ = billed_tracker
|
||||
ledger.credit_client("client-1", 0.03, note="admin-credit")
|
||||
_chat(tracker_url, api_key="client-1")
|
||||
@@ -396,6 +426,8 @@ def test_proxy_chat_bills_credited_client_and_credits_node(billed_tracker):
|
||||
|
||||
|
||||
def test_proxy_chat_caps_inflated_non_streaming_usage_by_request_bounds(billed_tracker):
|
||||
"Proxy chat caps inflated non streaming usage by request bounds\n\nTags: billing, http, payments, streaming"
|
||||
|
||||
tracker_url, ledger, stub = billed_tracker
|
||||
stub.total_tokens = 1_000_000
|
||||
ledger.credit_client("bounded-client", 100.0, note="admin-credit")
|
||||
@@ -412,6 +444,8 @@ def test_proxy_chat_caps_inflated_non_streaming_usage_by_request_bounds(billed_t
|
||||
|
||||
|
||||
def test_proxy_chat_caps_inflated_streaming_usage_by_observed_chunks():
|
||||
"Proxy chat caps inflated streaming usage by observed chunks\n\nTags: billing, http, payments, streaming"
|
||||
|
||||
ledger = BillingLedger(starting_credit=0.0, default_price_per_1k=0.02)
|
||||
ledger.credit_client("stream-client", 1.0, note="admin-credit")
|
||||
tracker = TrackerServer(
|
||||
@@ -460,6 +494,8 @@ def test_proxy_chat_caps_inflated_streaming_usage_by_observed_chunks():
|
||||
|
||||
|
||||
def test_proxy_chat_splits_payout_by_tracker_assigned_route_span():
|
||||
"Proxy chat splits payout by tracker assigned route span\n\nTags: billing, http, payments, routing"
|
||||
|
||||
ledger = BillingLedger(starting_credit=0.0, default_price_per_1k=0.02)
|
||||
ledger.credit_client("route-client", 1.0, note="admin-credit")
|
||||
tracker = TrackerServer(
|
||||
@@ -515,6 +551,8 @@ def test_proxy_chat_splits_payout_by_tracker_assigned_route_span():
|
||||
|
||||
|
||||
def test_proxy_chat_402_when_balance_exhausted(billed_tracker):
|
||||
"Proxy chat 402 when balance exhausted\n\nTags: billing, http, payments"
|
||||
|
||||
tracker_url, ledger, _ = billed_tracker
|
||||
ledger.credit_client("client-2", 0.03, note="admin-credit")
|
||||
_chat(tracker_url, api_key="client-2") # 0.03 -> 0.01
|
||||
@@ -528,6 +566,8 @@ def test_proxy_chat_402_when_balance_exhausted(billed_tracker):
|
||||
|
||||
|
||||
def test_proxy_chat_rejects_request_above_spend_cap_before_routing():
|
||||
"Proxy chat rejects request above spend cap before routing\n\nTags: billing, http, payments"
|
||||
|
||||
ledger = BillingLedger(starting_credit=0.0, default_price_per_1k=0.02)
|
||||
ledger.credit_client("capped-client", 10.0, note="admin-credit")
|
||||
tracker = TrackerServer(
|
||||
@@ -584,6 +624,8 @@ def test_proxy_chat_rejects_request_above_spend_cap_before_routing():
|
||||
|
||||
|
||||
def test_proxy_chat_records_validation_event_with_plain_route_metadata():
|
||||
"Proxy chat records validation event with plain route metadata\n\nTags: billing, http, payments, routing"
|
||||
|
||||
class FakeRegistry:
|
||||
def get_wallet(self, wallet_address):
|
||||
return type("Wallet", (), {"banned": False})()
|
||||
@@ -657,6 +699,8 @@ def test_proxy_chat_records_validation_event_with_plain_route_metadata():
|
||||
|
||||
|
||||
def test_billing_gossip_endpoint_applies_events(billed_tracker):
|
||||
"Billing gossip endpoint applies events\n\nTags: billing, gossip, http, network, payments"
|
||||
|
||||
tracker_url, ledger, _ = billed_tracker
|
||||
peer = BillingLedger(starting_credit=0.03, default_price_per_1k=0.02)
|
||||
peer.credit_client("remote-client", 7.0)
|
||||
|
||||
Reference in New Issue
Block a user