account_pool_retry_status_codes_test.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. //go:build unit
  2. package service
  3. import (
  4. "encoding/json"
  5. "testing"
  6. "github.com/stretchr/testify/require"
  7. )
  8. func TestGetPoolModeRetryStatusCodes(t *testing.T) {
  9. tests := []struct {
  10. name string
  11. account *Account
  12. expected []int
  13. }{
  14. {
  15. name: "nil_account_returns_nil",
  16. account: nil,
  17. expected: nil,
  18. },
  19. {
  20. name: "nil_credentials_returns_nil",
  21. account: &Account{
  22. Type: AccountTypeAPIKey,
  23. Platform: PlatformOpenAI,
  24. },
  25. expected: nil,
  26. },
  27. {
  28. name: "missing_key_returns_nil",
  29. account: &Account{
  30. Type: AccountTypeAPIKey,
  31. Platform: PlatformOpenAI,
  32. Credentials: map[string]any{"pool_mode": true},
  33. },
  34. expected: nil,
  35. },
  36. {
  37. name: "empty_slice_is_preserved",
  38. account: &Account{
  39. Credentials: map[string]any{
  40. "pool_mode_retry_status_codes": []any{},
  41. },
  42. },
  43. expected: []int{},
  44. },
  45. {
  46. name: "float64_values_from_json_are_normalized",
  47. account: &Account{
  48. Credentials: map[string]any{
  49. "pool_mode_retry_status_codes": []any{float64(429), float64(401), float64(403)},
  50. },
  51. },
  52. expected: []int{401, 403, 429},
  53. },
  54. {
  55. name: "json_number_values_supported",
  56. account: &Account{
  57. Credentials: map[string]any{
  58. "pool_mode_retry_status_codes": []any{json.Number("502"), json.Number("503")},
  59. },
  60. },
  61. expected: []int{502, 503},
  62. },
  63. {
  64. name: "string_values_supported",
  65. account: &Account{
  66. Credentials: map[string]any{
  67. "pool_mode_retry_status_codes": []any{"520", "529"},
  68. },
  69. },
  70. expected: []int{520, 529},
  71. },
  72. {
  73. name: "duplicates_are_deduped",
  74. account: &Account{
  75. Credentials: map[string]any{
  76. "pool_mode_retry_status_codes": []any{float64(429), float64(429), float64(401)},
  77. },
  78. },
  79. expected: []int{401, 429},
  80. },
  81. {
  82. name: "out_of_range_values_dropped",
  83. account: &Account{
  84. Credentials: map[string]any{
  85. "pool_mode_retry_status_codes": []any{float64(99), float64(600), float64(429)},
  86. },
  87. },
  88. expected: []int{429},
  89. },
  90. {
  91. name: "invalid_string_dropped",
  92. account: &Account{
  93. Credentials: map[string]any{
  94. "pool_mode_retry_status_codes": []any{"oops", float64(429)},
  95. },
  96. },
  97. expected: []int{429},
  98. },
  99. {
  100. name: "non_array_value_returns_nil",
  101. account: &Account{
  102. Credentials: map[string]any{
  103. "pool_mode_retry_status_codes": "not-an-array",
  104. },
  105. },
  106. expected: nil,
  107. },
  108. }
  109. for _, tt := range tests {
  110. t.Run(tt.name, func(t *testing.T) {
  111. require.Equal(t, tt.expected, tt.account.GetPoolModeRetryStatusCodes())
  112. })
  113. }
  114. }
  115. func TestIsPoolModeRetryableStatus_Account(t *testing.T) {
  116. tests := []struct {
  117. name string
  118. account *Account
  119. statusCode int
  120. expected bool
  121. }{
  122. {
  123. name: "nil_account_falls_back_to_default_401",
  124. account: nil,
  125. statusCode: 401,
  126. expected: true,
  127. },
  128. {
  129. name: "nil_account_falls_back_to_default_500",
  130. account: nil,
  131. statusCode: 500,
  132. expected: false,
  133. },
  134. {
  135. name: "unconfigured_uses_default_403",
  136. account: &Account{
  137. Credentials: map[string]any{"pool_mode": true},
  138. },
  139. statusCode: 403,
  140. expected: true,
  141. },
  142. {
  143. name: "unconfigured_uses_default_502_false",
  144. account: &Account{
  145. Credentials: map[string]any{"pool_mode": true},
  146. },
  147. statusCode: 502,
  148. expected: false,
  149. },
  150. {
  151. name: "configured_list_overrides_default_401_dropped",
  152. account: &Account{
  153. Credentials: map[string]any{
  154. "pool_mode_retry_status_codes": []any{float64(502), float64(503)},
  155. },
  156. },
  157. statusCode: 401,
  158. expected: false,
  159. },
  160. {
  161. name: "configured_list_overrides_default_502_added",
  162. account: &Account{
  163. Credentials: map[string]any{
  164. "pool_mode_retry_status_codes": []any{float64(502), float64(503)},
  165. },
  166. },
  167. statusCode: 502,
  168. expected: true,
  169. },
  170. {
  171. name: "empty_list_disables_all_default_codes",
  172. account: &Account{
  173. Credentials: map[string]any{
  174. "pool_mode_retry_status_codes": []any{},
  175. },
  176. },
  177. statusCode: 429,
  178. expected: false,
  179. },
  180. }
  181. for _, tt := range tests {
  182. t.Run(tt.name, func(t *testing.T) {
  183. require.Equal(t, tt.expected, tt.account.IsPoolModeRetryableStatus(tt.statusCode))
  184. })
  185. }
  186. }