force_cache_billing_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. //go:build unit
  2. package service
  3. import (
  4. "context"
  5. "testing"
  6. )
  7. func TestIsForceCacheBilling(t *testing.T) {
  8. tests := []struct {
  9. name string
  10. ctx context.Context
  11. expected bool
  12. }{
  13. {
  14. name: "context without force cache billing",
  15. ctx: context.Background(),
  16. expected: false,
  17. },
  18. {
  19. name: "context with force cache billing set to true",
  20. ctx: context.WithValue(context.Background(), ForceCacheBillingContextKey, true),
  21. expected: true,
  22. },
  23. {
  24. name: "context with force cache billing set to false",
  25. ctx: context.WithValue(context.Background(), ForceCacheBillingContextKey, false),
  26. expected: false,
  27. },
  28. {
  29. name: "context with wrong type value",
  30. ctx: context.WithValue(context.Background(), ForceCacheBillingContextKey, "true"),
  31. expected: false,
  32. },
  33. }
  34. for _, tt := range tests {
  35. t.Run(tt.name, func(t *testing.T) {
  36. result := IsForceCacheBilling(tt.ctx)
  37. if result != tt.expected {
  38. t.Errorf("IsForceCacheBilling() = %v, want %v", result, tt.expected)
  39. }
  40. })
  41. }
  42. }
  43. func TestWithForceCacheBilling(t *testing.T) {
  44. ctx := context.Background()
  45. // 原始上下文没有标记
  46. if IsForceCacheBilling(ctx) {
  47. t.Error("original context should not have force cache billing")
  48. }
  49. // 使用 WithForceCacheBilling 后应该有标记
  50. newCtx := WithForceCacheBilling(ctx)
  51. if !IsForceCacheBilling(newCtx) {
  52. t.Error("new context should have force cache billing")
  53. }
  54. // 原始上下文应该不受影响
  55. if IsForceCacheBilling(ctx) {
  56. t.Error("original context should still not have force cache billing")
  57. }
  58. }
  59. func TestForceCacheBilling_TokenConversion(t *testing.T) {
  60. tests := []struct {
  61. name string
  62. forceCacheBilling bool
  63. inputTokens int
  64. cacheReadInputTokens int
  65. expectedInputTokens int
  66. expectedCacheReadTokens int
  67. }{
  68. {
  69. name: "force cache billing converts input to cache_read",
  70. forceCacheBilling: true,
  71. inputTokens: 1000,
  72. cacheReadInputTokens: 500,
  73. expectedInputTokens: 0,
  74. expectedCacheReadTokens: 1500, // 500 + 1000
  75. },
  76. {
  77. name: "no force cache billing keeps tokens unchanged",
  78. forceCacheBilling: false,
  79. inputTokens: 1000,
  80. cacheReadInputTokens: 500,
  81. expectedInputTokens: 1000,
  82. expectedCacheReadTokens: 500,
  83. },
  84. {
  85. name: "force cache billing with zero input tokens does nothing",
  86. forceCacheBilling: true,
  87. inputTokens: 0,
  88. cacheReadInputTokens: 500,
  89. expectedInputTokens: 0,
  90. expectedCacheReadTokens: 500,
  91. },
  92. {
  93. name: "force cache billing with zero cache_read tokens",
  94. forceCacheBilling: true,
  95. inputTokens: 1000,
  96. cacheReadInputTokens: 0,
  97. expectedInputTokens: 0,
  98. expectedCacheReadTokens: 1000,
  99. },
  100. }
  101. for _, tt := range tests {
  102. t.Run(tt.name, func(t *testing.T) {
  103. // 模拟 RecordUsage 中的 ForceCacheBilling 逻辑
  104. usage := ClaudeUsage{
  105. InputTokens: tt.inputTokens,
  106. CacheReadInputTokens: tt.cacheReadInputTokens,
  107. }
  108. // 这是 RecordUsage 中的实际逻辑
  109. if tt.forceCacheBilling && usage.InputTokens > 0 {
  110. usage.CacheReadInputTokens += usage.InputTokens
  111. usage.InputTokens = 0
  112. }
  113. if usage.InputTokens != tt.expectedInputTokens {
  114. t.Errorf("InputTokens = %d, want %d", usage.InputTokens, tt.expectedInputTokens)
  115. }
  116. if usage.CacheReadInputTokens != tt.expectedCacheReadTokens {
  117. t.Errorf("CacheReadInputTokens = %d, want %d", usage.CacheReadInputTokens, tt.expectedCacheReadTokens)
  118. }
  119. })
  120. }
  121. }