bigqueryquerier_test.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. package gcp
  2. import (
  3. "context"
  4. "testing"
  5. "github.com/opencost/opencost/pkg/cloud"
  6. "github.com/stretchr/testify/assert"
  7. )
  8. func TestBigQueryQuerier_GetStatus(t *testing.T) {
  9. tests := []struct {
  10. name string
  11. initialStatus cloud.ConnectionStatus
  12. expectedStatus cloud.ConnectionStatus
  13. }{
  14. {
  15. name: "Initial status",
  16. initialStatus: "",
  17. expectedStatus: cloud.InitialStatus,
  18. },
  19. {
  20. name: "Successful connection",
  21. initialStatus: cloud.SuccessfulConnection,
  22. expectedStatus: cloud.SuccessfulConnection,
  23. },
  24. {
  25. name: "Failed connection",
  26. initialStatus: cloud.FailedConnection,
  27. expectedStatus: cloud.FailedConnection,
  28. },
  29. {
  30. name: "Invalid configuration",
  31. initialStatus: cloud.InvalidConfiguration,
  32. expectedStatus: cloud.InvalidConfiguration,
  33. },
  34. }
  35. for _, tt := range tests {
  36. t.Run(tt.name, func(t *testing.T) {
  37. bqq := &BigQueryQuerier{
  38. ConnectionStatus: tt.initialStatus,
  39. }
  40. status := bqq.GetStatus()
  41. assert.Equal(t, tt.expectedStatus, status)
  42. })
  43. }
  44. }
  45. func TestBigQueryQuerier_Equals(t *testing.T) {
  46. config1 := &BigQueryQuerier{
  47. BigQueryConfiguration: BigQueryConfiguration{
  48. ProjectID: "project1",
  49. Dataset: "dataset1",
  50. Table: "table1",
  51. Authorizer: &ServiceAccountKey{
  52. Key: map[string]string{"type": "service_account"},
  53. },
  54. },
  55. }
  56. config2 := &BigQueryQuerier{
  57. BigQueryConfiguration: BigQueryConfiguration{
  58. ProjectID: "project1",
  59. Dataset: "dataset1",
  60. Table: "table1",
  61. Authorizer: &ServiceAccountKey{
  62. Key: map[string]string{"type": "service_account"},
  63. },
  64. },
  65. }
  66. config3 := &BigQueryQuerier{
  67. BigQueryConfiguration: BigQueryConfiguration{
  68. ProjectID: "project2",
  69. Dataset: "dataset1",
  70. Table: "table1",
  71. Authorizer: &ServiceAccountKey{
  72. Key: map[string]string{"type": "service_account"},
  73. },
  74. },
  75. }
  76. tests := []struct {
  77. name string
  78. config1 cloud.Config
  79. config2 cloud.Config
  80. expected bool
  81. }{
  82. {
  83. name: "Same configuration",
  84. config1: config1,
  85. config2: config2,
  86. expected: true,
  87. },
  88. {
  89. name: "Different configuration",
  90. config1: config1,
  91. config2: config3,
  92. expected: false,
  93. },
  94. {
  95. name: "Nil config",
  96. config1: config1,
  97. config2: nil,
  98. expected: false,
  99. },
  100. {
  101. name: "Different type",
  102. config1: config1,
  103. config2: &ServiceAccountKey{Key: map[string]string{}},
  104. expected: false,
  105. },
  106. }
  107. for _, tt := range tests {
  108. t.Run(tt.name, func(t *testing.T) {
  109. result := tt.config1.Equals(tt.config2)
  110. assert.Equal(t, tt.expected, result)
  111. })
  112. }
  113. }
  114. func TestBigQueryQuerier_Query_ValidationError(t *testing.T) {
  115. bqq := &BigQueryQuerier{
  116. BigQueryConfiguration: BigQueryConfiguration{
  117. // Missing required fields to trigger validation error
  118. ProjectID: "",
  119. Dataset: "",
  120. Table: "",
  121. Authorizer: nil,
  122. },
  123. }
  124. ctx := context.Background()
  125. _, err := bqq.Query(ctx, "SELECT * FROM table")
  126. assert.Error(t, err)
  127. // Print the actual status for debugging
  128. t.Logf("Expected: %v, Actual: %v", cloud.InvalidConfiguration, bqq.ConnectionStatus)
  129. assert.Equal(t, cloud.ConnectionStatus("Invalid Configuration"), bqq.ConnectionStatus)
  130. }
  131. func TestBigQueryQuerier_Query_ClientCreationError(t *testing.T) {
  132. bqq := &BigQueryQuerier{
  133. BigQueryConfiguration: BigQueryConfiguration{
  134. ProjectID: "project1",
  135. Dataset: "dataset1",
  136. Table: "table1",
  137. Authorizer: &ServiceAccountKey{
  138. Key: map[string]string{
  139. "type": "service_account",
  140. // Invalid key to trigger client creation error
  141. "private_key": "invalid-key",
  142. },
  143. },
  144. },
  145. }
  146. ctx := context.Background()
  147. _, err := bqq.Query(ctx, "SELECT * FROM table")
  148. assert.Error(t, err)
  149. // Print the actual status for debugging
  150. t.Logf("Expected: %v, Actual: %v", cloud.FailedConnection, bqq.ConnectionStatus)
  151. assert.Equal(t, cloud.ConnectionStatus("Failed Connection"), bqq.ConnectionStatus)
  152. }
  153. func TestBigQueryQuerier_Query_Success(t *testing.T) {
  154. // This test would require mocking the BigQuery client
  155. // For now, we'll test the validation path
  156. bqq := &BigQueryQuerier{
  157. BigQueryConfiguration: BigQueryConfiguration{
  158. ProjectID: "project1",
  159. Dataset: "dataset1",
  160. Table: "table1",
  161. Authorizer: &WorkloadIdentity{}, // Use WorkloadIdentity to avoid key validation issues
  162. },
  163. }
  164. ctx := context.Background()
  165. // This will likely fail due to missing credentials, but we can test the validation
  166. _, err := bqq.Query(ctx, "SELECT * FROM table")
  167. // The actual result depends on the environment, but we can verify the status is set
  168. if err == nil {
  169. assert.Equal(t, cloud.SuccessfulConnection, bqq.ConnectionStatus)
  170. } else {
  171. // If there's an error, it should be due to connection issues
  172. assert.Contains(t, err.Error(), "credentials")
  173. }
  174. }
  175. func TestBigQueryQuerier_Query_EmptyResult(t *testing.T) {
  176. bqq := &BigQueryQuerier{
  177. BigQueryConfiguration: BigQueryConfiguration{
  178. ProjectID: "project1",
  179. Dataset: "dataset1",
  180. Table: "table1",
  181. Authorizer: &WorkloadIdentity{},
  182. },
  183. ConnectionStatus: cloud.InitialStatus,
  184. }
  185. ctx := context.Background()
  186. // Test with a query that would return empty results
  187. _, err := bqq.Query(ctx, "SELECT * FROM non_existent_table")
  188. // The status should be set to MissingData if the result is empty
  189. if err == nil {
  190. assert.Equal(t, cloud.MissingData, bqq.ConnectionStatus)
  191. }
  192. }