bigqueryconfiguration_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. package gcp
  2. import (
  3. "fmt"
  4. "testing"
  5. "github.com/opencost/opencost/core/pkg/log"
  6. "github.com/opencost/opencost/core/pkg/util/json"
  7. "github.com/opencost/opencost/pkg/cloud"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/require"
  10. )
  11. func TestBigQueryConfiguration_Validate(t *testing.T) {
  12. testCases := map[string]struct {
  13. config BigQueryConfiguration
  14. expected error
  15. }{
  16. "valid config GCP Key": {
  17. config: BigQueryConfiguration{
  18. ProjectID: "projectID",
  19. Dataset: "dataset",
  20. Table: "table",
  21. Authorizer: &ServiceAccountKey{
  22. Key: map[string]string{
  23. "Key": "Key",
  24. "key1": "key2",
  25. },
  26. },
  27. },
  28. expected: nil,
  29. },
  30. "valid config WorkloadIdentity": {
  31. config: BigQueryConfiguration{
  32. ProjectID: "projectID",
  33. Dataset: "dataset",
  34. Table: "table",
  35. Authorizer: &WorkloadIdentity{},
  36. },
  37. expected: nil,
  38. },
  39. "access Key invalid": {
  40. config: BigQueryConfiguration{
  41. ProjectID: "projectID",
  42. Dataset: "dataset",
  43. Table: "table",
  44. Authorizer: &ServiceAccountKey{
  45. Key: nil,
  46. },
  47. },
  48. expected: fmt.Errorf("BigQueryConfig: issue with GCP Authorizer: ServiceAccountKey: missing Key"),
  49. },
  50. "missing configurer": {
  51. config: BigQueryConfiguration{
  52. ProjectID: "projectID",
  53. Dataset: "dataset",
  54. Table: "table",
  55. Authorizer: nil,
  56. },
  57. expected: fmt.Errorf("BigQueryConfig: missing configurer"),
  58. },
  59. "missing projectID": {
  60. config: BigQueryConfiguration{
  61. ProjectID: "",
  62. Dataset: "dataset",
  63. Table: "table",
  64. Authorizer: &ServiceAccountKey{
  65. Key: map[string]string{
  66. "Key": "Key",
  67. "key1": "key2",
  68. },
  69. },
  70. },
  71. expected: fmt.Errorf("BigQueryConfig: missing ProjectID"),
  72. },
  73. "missing dataset": {
  74. config: BigQueryConfiguration{
  75. ProjectID: "projectID",
  76. Dataset: "",
  77. Table: "table",
  78. Authorizer: &ServiceAccountKey{
  79. Key: map[string]string{
  80. "Key": "Key",
  81. "key1": "key2",
  82. },
  83. },
  84. },
  85. expected: fmt.Errorf("BigQueryConfig: missing Dataset"),
  86. },
  87. "missing table": {
  88. config: BigQueryConfiguration{
  89. ProjectID: "projectID",
  90. Dataset: "dataset",
  91. Table: "",
  92. Authorizer: &ServiceAccountKey{
  93. Key: map[string]string{
  94. "Key": "Key",
  95. "key1": "key2",
  96. },
  97. },
  98. },
  99. expected: fmt.Errorf("BigQueryConfig: missing Table"),
  100. },
  101. }
  102. for name, testCase := range testCases {
  103. t.Run(name, func(t *testing.T) {
  104. actual := testCase.config.Validate()
  105. actualString := "nil"
  106. if actual != nil {
  107. actualString = actual.Error()
  108. }
  109. expectedString := "nil"
  110. if testCase.expected != nil {
  111. expectedString = testCase.expected.Error()
  112. }
  113. if actualString != expectedString {
  114. t.Errorf("errors do not match: Actual: '%s', Expected: '%s", actualString, expectedString)
  115. }
  116. })
  117. }
  118. }
  119. func TestBigQueryConfiguration_Equals(t *testing.T) {
  120. testCases := map[string]struct {
  121. left BigQueryConfiguration
  122. right cloud.Config
  123. expected bool
  124. }{
  125. "matching config": {
  126. left: BigQueryConfiguration{
  127. ProjectID: "projectID",
  128. Dataset: "dataset",
  129. Table: "table",
  130. Authorizer: &ServiceAccountKey{
  131. Key: map[string]string{
  132. "Key": "Key",
  133. "key1": "key2",
  134. },
  135. },
  136. Location: "EU",
  137. QueryProjectID: "queryProjectID",
  138. },
  139. right: &BigQueryConfiguration{
  140. ProjectID: "projectID",
  141. Dataset: "dataset",
  142. Table: "table",
  143. Authorizer: &ServiceAccountKey{
  144. Key: map[string]string{
  145. "Key": "Key",
  146. "key1": "key2",
  147. },
  148. },
  149. Location: "EU",
  150. QueryProjectID: "queryProjectID",
  151. },
  152. expected: true,
  153. },
  154. "different configurer": {
  155. left: BigQueryConfiguration{
  156. ProjectID: "projectID",
  157. Dataset: "dataset",
  158. Table: "table",
  159. Authorizer: &ServiceAccountKey{
  160. Key: map[string]string{
  161. "Key": "Key",
  162. "key1": "key2",
  163. },
  164. },
  165. },
  166. right: &BigQueryConfiguration{
  167. ProjectID: "projectID",
  168. Dataset: "dataset",
  169. Table: "table",
  170. Authorizer: &WorkloadIdentity{},
  171. },
  172. expected: false,
  173. },
  174. "missing both configurer": {
  175. left: BigQueryConfiguration{
  176. ProjectID: "projectID",
  177. Dataset: "dataset",
  178. Table: "table",
  179. Authorizer: nil,
  180. },
  181. right: &BigQueryConfiguration{
  182. ProjectID: "projectID",
  183. Dataset: "dataset",
  184. Table: "table",
  185. Authorizer: nil,
  186. },
  187. expected: true,
  188. },
  189. "missing left configurer": {
  190. left: BigQueryConfiguration{
  191. ProjectID: "projectID",
  192. Dataset: "dataset",
  193. Table: "table",
  194. Authorizer: nil,
  195. },
  196. right: &BigQueryConfiguration{
  197. ProjectID: "projectID",
  198. Dataset: "dataset",
  199. Table: "table",
  200. Authorizer: &WorkloadIdentity{},
  201. },
  202. expected: false,
  203. },
  204. "missing right configurer": {
  205. left: BigQueryConfiguration{
  206. ProjectID: "projectID",
  207. Dataset: "dataset",
  208. Table: "table",
  209. Authorizer: &ServiceAccountKey{
  210. Key: map[string]string{
  211. "Key": "Key",
  212. "key1": "key2",
  213. },
  214. },
  215. },
  216. right: &BigQueryConfiguration{
  217. ProjectID: "projectID",
  218. Dataset: "dataset",
  219. Table: "table",
  220. Authorizer: nil,
  221. },
  222. expected: false,
  223. },
  224. "different projectID": {
  225. left: BigQueryConfiguration{
  226. ProjectID: "projectID",
  227. Dataset: "dataset",
  228. Table: "table",
  229. Authorizer: &ServiceAccountKey{
  230. Key: map[string]string{
  231. "Key": "Key",
  232. "key1": "key2",
  233. },
  234. },
  235. },
  236. right: &BigQueryConfiguration{
  237. ProjectID: "projectID2",
  238. Dataset: "dataset",
  239. Table: "table",
  240. Authorizer: &ServiceAccountKey{
  241. Key: map[string]string{
  242. "Key": "Key",
  243. "key1": "key2",
  244. },
  245. },
  246. },
  247. expected: false,
  248. },
  249. "different dataset": {
  250. left: BigQueryConfiguration{
  251. ProjectID: "projectID",
  252. Dataset: "dataset",
  253. Table: "table",
  254. Authorizer: &ServiceAccountKey{
  255. Key: map[string]string{
  256. "Key": "Key",
  257. "key1": "key2",
  258. },
  259. },
  260. },
  261. right: &BigQueryConfiguration{
  262. ProjectID: "projectID",
  263. Dataset: "dataset2",
  264. Table: "table",
  265. Authorizer: &ServiceAccountKey{
  266. Key: map[string]string{
  267. "Key": "Key",
  268. "key1": "key2",
  269. },
  270. },
  271. },
  272. expected: false,
  273. },
  274. "different table": {
  275. left: BigQueryConfiguration{
  276. ProjectID: "projectID",
  277. Dataset: "dataset",
  278. Table: "table",
  279. Authorizer: &ServiceAccountKey{
  280. Key: map[string]string{
  281. "Key": "Key",
  282. "key1": "key2",
  283. },
  284. },
  285. },
  286. right: &BigQueryConfiguration{
  287. ProjectID: "projectID",
  288. Dataset: "dataset",
  289. Table: "table2",
  290. Authorizer: &ServiceAccountKey{
  291. Key: map[string]string{
  292. "Key": "Key",
  293. "key1": "key2",
  294. },
  295. },
  296. },
  297. expected: false,
  298. },
  299. "different config": {
  300. left: BigQueryConfiguration{
  301. ProjectID: "projectID",
  302. Dataset: "dataset",
  303. Table: "table",
  304. Authorizer: &ServiceAccountKey{
  305. Key: map[string]string{
  306. "Key": "Key",
  307. "key1": "key2",
  308. },
  309. },
  310. },
  311. right: &ServiceAccountKey{
  312. Key: map[string]string{
  313. "Key": "Key",
  314. "key1": "key2",
  315. },
  316. },
  317. expected: false,
  318. },
  319. "different excludePartitionTime": {
  320. left: BigQueryConfiguration{
  321. ProjectID: "projectID",
  322. Dataset: "dataset",
  323. Table: "table",
  324. ExcludePartitionTime: true,
  325. Authorizer: &ServiceAccountKey{
  326. Key: map[string]string{
  327. "Key": "Key",
  328. "key1": "key2",
  329. },
  330. },
  331. },
  332. right: &BigQueryConfiguration{
  333. ProjectID: "projectID",
  334. Dataset: "dataset",
  335. Table: "table",
  336. ExcludePartitionTime: false,
  337. Authorizer: &ServiceAccountKey{
  338. Key: map[string]string{
  339. "Key": "Key",
  340. "key1": "key2",
  341. },
  342. },
  343. },
  344. expected: false,
  345. },
  346. "matching excludePartitionTime": {
  347. left: BigQueryConfiguration{
  348. ProjectID: "projectID",
  349. Dataset: "dataset",
  350. Table: "table",
  351. ExcludePartitionTime: true,
  352. Authorizer: &ServiceAccountKey{
  353. Key: map[string]string{
  354. "Key": "Key",
  355. "key1": "key2",
  356. },
  357. },
  358. },
  359. right: &BigQueryConfiguration{
  360. ProjectID: "projectID",
  361. Dataset: "dataset",
  362. Table: "table",
  363. ExcludePartitionTime: true,
  364. Authorizer: &ServiceAccountKey{
  365. Key: map[string]string{
  366. "Key": "Key",
  367. "key1": "key2",
  368. },
  369. },
  370. },
  371. expected: true,
  372. },
  373. "different location": {
  374. left: BigQueryConfiguration{
  375. ProjectID: "projectID",
  376. Dataset: "dataset",
  377. Table: "table",
  378. Location: "EU",
  379. Authorizer: &ServiceAccountKey{
  380. Key: map[string]string{
  381. "Key": "Key",
  382. "key1": "key2",
  383. },
  384. },
  385. },
  386. right: &BigQueryConfiguration{
  387. ProjectID: "projectID",
  388. Dataset: "dataset2",
  389. Table: "table",
  390. Location: "US",
  391. Authorizer: &ServiceAccountKey{
  392. Key: map[string]string{
  393. "Key": "Key",
  394. "key1": "key2",
  395. },
  396. },
  397. },
  398. expected: false,
  399. },
  400. "different queryProjectID": {
  401. left: BigQueryConfiguration{
  402. ProjectID: "projectID",
  403. Dataset: "dataset",
  404. Table: "table",
  405. QueryProjectID: "queryProjectID",
  406. Authorizer: &ServiceAccountKey{
  407. Key: map[string]string{
  408. "Key": "Key",
  409. "key1": "key2",
  410. },
  411. },
  412. },
  413. right: &BigQueryConfiguration{
  414. ProjectID: "projectID",
  415. Dataset: "dataset",
  416. Table: "table",
  417. QueryProjectID: "queryProjectID2",
  418. Authorizer: &ServiceAccountKey{
  419. Key: map[string]string{
  420. "Key": "Key",
  421. "key1": "key2",
  422. },
  423. },
  424. },
  425. expected: false,
  426. },
  427. "empty queryProjectID equals projectID": {
  428. left: BigQueryConfiguration{
  429. ProjectID: "projectID",
  430. Dataset: "dataset",
  431. Table: "table",
  432. QueryProjectID: "",
  433. Authorizer: &ServiceAccountKey{
  434. Key: map[string]string{
  435. "Key": "Key",
  436. "key1": "key2",
  437. },
  438. },
  439. },
  440. right: &BigQueryConfiguration{
  441. ProjectID: "projectID",
  442. Dataset: "dataset",
  443. Table: "table",
  444. QueryProjectID: "projectID",
  445. Authorizer: &ServiceAccountKey{
  446. Key: map[string]string{
  447. "Key": "Key",
  448. "key1": "key2",
  449. },
  450. },
  451. },
  452. expected: true,
  453. },
  454. }
  455. for name, testCase := range testCases {
  456. t.Run(name, func(t *testing.T) {
  457. actual := testCase.left.Equals(testCase.right)
  458. if actual != testCase.expected {
  459. t.Errorf("incorrect result: Actual: '%t', Expected: '%t", actual, testCase.expected)
  460. }
  461. })
  462. }
  463. }
  464. func TestBigQueryConfiguration_JSON(t *testing.T) {
  465. testCases := map[string]struct {
  466. config BigQueryConfiguration
  467. }{
  468. "Empty Config": {
  469. config: BigQueryConfiguration{},
  470. },
  471. "Nil Authorizer": {
  472. config: BigQueryConfiguration{
  473. ProjectID: "projectID",
  474. Dataset: "dataset",
  475. Table: "table",
  476. Authorizer: nil,
  477. },
  478. },
  479. "ServiceAccountKeyConfigurer": {
  480. config: BigQueryConfiguration{
  481. ProjectID: "projectID",
  482. Dataset: "dataset",
  483. Table: "table",
  484. Authorizer: &ServiceAccountKey{
  485. Key: map[string]string{
  486. "Key": "Key",
  487. "key1": "key2",
  488. },
  489. },
  490. },
  491. },
  492. "WorkLoadIdentityConfigurer": {
  493. config: BigQueryConfiguration{
  494. ProjectID: "projectID",
  495. Dataset: "dataset",
  496. Table: "table",
  497. Authorizer: &WorkloadIdentity{},
  498. },
  499. },
  500. "ExcludePartitionTime": {
  501. config: BigQueryConfiguration{
  502. ProjectID: "projectID",
  503. Dataset: "dataset",
  504. Table: "table",
  505. ExcludePartitionTime: true,
  506. Authorizer: &WorkloadIdentity{},
  507. },
  508. },
  509. }
  510. for name, testCase := range testCases {
  511. t.Run(name, func(t *testing.T) {
  512. // test JSON Marshalling
  513. configJSON, err := json.Marshal(testCase.config)
  514. if err != nil {
  515. t.Errorf("failed to marshal configuration: %s", err.Error())
  516. }
  517. log.Info(string(configJSON))
  518. unmarshalledConfig := &BigQueryConfiguration{}
  519. err = json.Unmarshal(configJSON, unmarshalledConfig)
  520. if err != nil {
  521. t.Errorf("failed to unmarshal configuration: %s", err.Error())
  522. }
  523. if !testCase.config.Equals(unmarshalledConfig) {
  524. t.Error("config does not equal unmarshalled config")
  525. }
  526. })
  527. }
  528. }
  529. func TestBigQueryConfiguration_Key(t *testing.T) {
  530. bqc := &BigQueryConfiguration{
  531. ProjectID: "test-project",
  532. Dataset: "test-dataset",
  533. Table: "test-table",
  534. }
  535. key := bqc.Key()
  536. expected := "test-project/test-dataset.test-table"
  537. assert.Equal(t, expected, key)
  538. }
  539. func TestBigQueryConfiguration_Provider(t *testing.T) {
  540. bqc := &BigQueryConfiguration{}
  541. provider := bqc.Provider()
  542. assert.Equal(t, "GCP", provider)
  543. }
  544. func TestBigQueryConfiguration_GetBillingDataDataset(t *testing.T) {
  545. bqc := &BigQueryConfiguration{
  546. Dataset: "test-dataset",
  547. Table: "test-table",
  548. }
  549. dataset := bqc.GetBillingDataDataset()
  550. expected := "test-dataset.test-table"
  551. assert.Equal(t, expected, dataset)
  552. }
  553. func TestBigQueryConfiguration_Sanitize(t *testing.T) {
  554. bqc := &BigQueryConfiguration{
  555. ProjectID: "test-project",
  556. Dataset: "test-dataset",
  557. Table: "test-table",
  558. Location: "EU",
  559. ExcludePartitionTime: true,
  560. QueryProjectID: "query-project",
  561. Authorizer: &ServiceAccountKey{
  562. Key: map[string]string{
  563. "type": "service_account",
  564. "private_key": "secret-key",
  565. },
  566. },
  567. }
  568. sanitized := bqc.Sanitize()
  569. require.NotNil(t, sanitized)
  570. sanitizedBQC, ok := sanitized.(*BigQueryConfiguration)
  571. require.True(t, ok)
  572. assert.Equal(t, "test-project", sanitizedBQC.ProjectID)
  573. assert.Equal(t, "test-dataset", sanitizedBQC.Dataset)
  574. assert.Equal(t, "test-table", sanitizedBQC.Table)
  575. assert.Equal(t, "EU", sanitizedBQC.Location)
  576. assert.True(t, sanitizedBQC.ExcludePartitionTime)
  577. assert.Equal(t, "query-project", sanitizedBQC.QueryProjectID)
  578. assert.NotNil(t, sanitizedBQC.Authorizer)
  579. // Check that the authorizer is also sanitized
  580. saKey, ok := sanitizedBQC.Authorizer.(*ServiceAccountKey)
  581. require.True(t, ok)
  582. for _, value := range saKey.Key {
  583. assert.Equal(t, cloud.Redacted, value)
  584. }
  585. }
  586. func TestConvertBigQueryConfigToConfig(t *testing.T) {
  587. tests := []struct {
  588. name string
  589. bqc BigQueryConfig
  590. expected cloud.KeyedConfig
  591. }{
  592. {
  593. name: "Empty config",
  594. bqc: BigQueryConfig{},
  595. expected: nil,
  596. },
  597. {
  598. name: "Config with service account key",
  599. bqc: BigQueryConfig{
  600. ProjectID: "test-project",
  601. BillingDataDataset: "test-dataset.test-table",
  602. Key: map[string]string{
  603. "type": "service_account",
  604. },
  605. },
  606. expected: &BigQueryConfiguration{
  607. ProjectID: "test-project",
  608. Dataset: "test-dataset",
  609. Table: "test-table",
  610. Authorizer: &ServiceAccountKey{
  611. Key: map[string]string{
  612. "type": "service_account",
  613. },
  614. },
  615. },
  616. },
  617. {
  618. name: "Config without service account key",
  619. bqc: BigQueryConfig{
  620. ProjectID: "test-project",
  621. BillingDataDataset: "test-dataset.test-table",
  622. Key: map[string]string{},
  623. },
  624. expected: &BigQueryConfiguration{
  625. ProjectID: "test-project",
  626. Dataset: "test-dataset",
  627. Table: "test-table",
  628. Authorizer: &WorkloadIdentity{},
  629. },
  630. },
  631. {
  632. name: "Config with single part dataset",
  633. bqc: BigQueryConfig{
  634. ProjectID: "test-project",
  635. BillingDataDataset: "test-dataset",
  636. Key: map[string]string{},
  637. },
  638. expected: &BigQueryConfiguration{
  639. ProjectID: "test-project",
  640. Dataset: "test-dataset",
  641. Table: "",
  642. Authorizer: &WorkloadIdentity{},
  643. },
  644. },
  645. }
  646. for _, tt := range tests {
  647. t.Run(tt.name, func(t *testing.T) {
  648. result := ConvertBigQueryConfigToConfig(tt.bqc)
  649. if tt.expected == nil {
  650. assert.Nil(t, result)
  651. } else {
  652. assert.NotNil(t, result)
  653. expectedBQC := tt.expected.(*BigQueryConfiguration)
  654. resultBQC := result.(*BigQueryConfiguration)
  655. assert.Equal(t, expectedBQC.ProjectID, resultBQC.ProjectID)
  656. assert.Equal(t, expectedBQC.Dataset, resultBQC.Dataset)
  657. assert.Equal(t, expectedBQC.Table, resultBQC.Table)
  658. assert.NotNil(t, resultBQC.Authorizer)
  659. }
  660. })
  661. }
  662. }
  663. func TestBigQueryConfiguration_UnmarshalJSON_Valid(t *testing.T) {
  664. jsonData := `{
  665. "projectID": "test-project",
  666. "dataset": "test-dataset",
  667. "table": "test-table",
  668. "authorizer": {
  669. "authorizerType": "GCPServiceAccountKey",
  670. "key": {
  671. "type": "service_account"
  672. }
  673. }
  674. }`
  675. var bqc BigQueryConfiguration
  676. err := json.Unmarshal([]byte(jsonData), &bqc)
  677. assert.NoError(t, err)
  678. assert.Equal(t, "test-project", bqc.ProjectID)
  679. assert.Equal(t, "test-dataset", bqc.Dataset)
  680. assert.Equal(t, "test-table", bqc.Table)
  681. assert.NotNil(t, bqc.Authorizer)
  682. saKey, ok := bqc.Authorizer.(*ServiceAccountKey)
  683. assert.True(t, ok)
  684. assert.Equal(t, "service_account", saKey.Key["type"])
  685. }
  686. func TestBigQueryConfiguration_UnmarshalJSON_InvalidProjectID(t *testing.T) {
  687. jsonData := `{
  688. "dataset": "test-dataset",
  689. "table": "test-table",
  690. "authorizer": {
  691. "authorizerType": "GCPServiceAccountKey",
  692. "key": {
  693. "type": "service_account"
  694. }
  695. }
  696. }`
  697. var bqc BigQueryConfiguration
  698. err := json.Unmarshal([]byte(jsonData), &bqc)
  699. assert.Error(t, err)
  700. assert.Contains(t, err.Error(), "projectID")
  701. }
  702. func TestBigQueryConfiguration_UnmarshalJSON_InvalidDataset(t *testing.T) {
  703. jsonData := `{
  704. "projectID": "test-project",
  705. "table": "test-table",
  706. "authorizer": {
  707. "authorizerType": "GCPServiceAccountKey",
  708. "key": {
  709. "type": "service_account"
  710. }
  711. }
  712. }`
  713. var bqc BigQueryConfiguration
  714. err := json.Unmarshal([]byte(jsonData), &bqc)
  715. assert.Error(t, err)
  716. assert.Contains(t, err.Error(), "dataset")
  717. }
  718. func TestBigQueryConfiguration_UnmarshalJSON_InvalidTable(t *testing.T) {
  719. jsonData := `{
  720. "projectID": "test-project",
  721. "dataset": "test-dataset",
  722. "authorizer": {
  723. "authorizerType": "GCPServiceAccountKey",
  724. "key": {
  725. "type": "service_account"
  726. }
  727. }
  728. }`
  729. var bqc BigQueryConfiguration
  730. err := json.Unmarshal([]byte(jsonData), &bqc)
  731. assert.Error(t, err)
  732. assert.Contains(t, err.Error(), "table")
  733. }
  734. func TestBigQueryConfiguration_UnmarshalJSON_MissingAuthorizer(t *testing.T) {
  735. jsonData := `{
  736. "projectID": "test-project",
  737. "dataset": "test-dataset",
  738. "table": "test-table"
  739. }`
  740. var bqc BigQueryConfiguration
  741. err := json.Unmarshal([]byte(jsonData), &bqc)
  742. assert.Error(t, err)
  743. assert.Contains(t, err.Error(), "missing authorizer")
  744. }
  745. func TestBigQueryConfiguration_UnmarshalJSON_InvalidAuthorizer(t *testing.T) {
  746. jsonData := `{
  747. "projectID": "test-project",
  748. "dataset": "test-dataset",
  749. "table": "test-table",
  750. "authorizer": {
  751. "authorizerType": "InvalidType"
  752. }
  753. }`
  754. var bqc BigQueryConfiguration
  755. err := json.Unmarshal([]byte(jsonData), &bqc)
  756. assert.Error(t, err)
  757. assert.Contains(t, err.Error(), "InvalidType")
  758. }
  759. func TestBigQueryConfiguration_UnmarshalJSON_ExcludePartitionTime(t *testing.T) {
  760. testCases := map[string]struct {
  761. value string
  762. expected bool
  763. }{
  764. "true": {value: `"excludePartitionTime": true,`, expected: true},
  765. "false": {value: `"excludePartitionTime": false,`, expected: false},
  766. "omitted": {value: "", expected: false},
  767. }
  768. for name, testCase := range testCases {
  769. t.Run(name, func(t *testing.T) {
  770. jsonData := fmt.Sprintf(`{
  771. "projectID": "test-project",
  772. "dataset": "test-dataset",
  773. "table": "test-table",
  774. %s
  775. "authorizer": {
  776. "authorizerType": "GCPServiceAccountKey",
  777. "key": {
  778. "type": "service_account"
  779. }
  780. }
  781. }`, testCase.value)
  782. var bqc BigQueryConfiguration
  783. err := json.Unmarshal([]byte(jsonData), &bqc)
  784. assert.NoError(t, err)
  785. assert.Equal(t, testCase.expected, bqc.ExcludePartitionTime)
  786. })
  787. }
  788. }
  789. func TestBigQueryConfiguration_UnmarshalJSON_InvalidExcludePartitionTime(t *testing.T) {
  790. jsonData := `{
  791. "projectID": "test-project",
  792. "dataset": "test-dataset",
  793. "table": "test-table",
  794. "excludePartitionTime": "not-a-bool",
  795. "authorizer": {
  796. "authorizerType": "GCPServiceAccountKey",
  797. "key": {
  798. "type": "service_account"
  799. }
  800. }
  801. }`
  802. var bqc BigQueryConfiguration
  803. err := json.Unmarshal([]byte(jsonData), &bqc)
  804. assert.Error(t, err)
  805. assert.Contains(t, err.Error(), "excludePartitionTime")
  806. }