controller_test.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. package config
  2. import (
  3. "os"
  4. "path/filepath"
  5. "testing"
  6. cloudconfig "github.com/opencost/opencost/pkg/cloud"
  7. "github.com/opencost/opencost/pkg/cloud/aws"
  8. "github.com/opencost/opencost/pkg/cloud/gcp"
  9. "github.com/opencost/opencost/pkg/env"
  10. )
  11. // Baseline valid config
  12. var validAthenaConf = &aws.AthenaConfiguration{
  13. Bucket: "bucket",
  14. Region: "region",
  15. Database: "database",
  16. Table: "table",
  17. Workgroup: "workgroup",
  18. Account: "account",
  19. Authorizer: &aws.ServiceAccount{},
  20. }
  21. // Config with the same key as the baseline but is not equal to it because of the change in the non-keyed property Workgroup
  22. var validAthenaConfModifiedProperty = &aws.AthenaConfiguration{
  23. Bucket: "bucket",
  24. Region: "region",
  25. Database: "database",
  26. Table: "table",
  27. Workgroup: "workgroup1",
  28. Account: "account",
  29. Authorizer: &aws.ServiceAccount{},
  30. }
  31. // Config with the same key as baseline but is invalid due to missing Authorizer
  32. var invalidAthenaConf = &aws.AthenaConfiguration{
  33. Bucket: "bucket",
  34. Region: "region",
  35. Database: "database",
  36. Table: "table",
  37. Workgroup: "workgroup",
  38. Account: "account",
  39. Authorizer: nil,
  40. }
  41. // A valid config with a different key from the baseline
  42. var validBigQueryConf = &gcp.BigQueryConfiguration{
  43. ProjectID: "projectID",
  44. Dataset: "dataset",
  45. Table: "table",
  46. Authorizer: &gcp.WorkloadIdentity{},
  47. }
  48. func TestIntegrationController_pullWatchers(t *testing.T) {
  49. testCases := map[string]struct {
  50. initialStatuses []*Status
  51. configWatchers map[ConfigSource]cloudconfig.KeyedConfigWatcher
  52. expectedStatuses []*Status
  53. }{
  54. // Helm Source
  55. "Helm Source init": {
  56. initialStatuses: []*Status{},
  57. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  58. HelmSource: &MockKeyedConfigWatcher{
  59. Integrations: []cloudconfig.KeyedConfig{
  60. validAthenaConf,
  61. },
  62. },
  63. },
  64. expectedStatuses: []*Status{
  65. {
  66. Source: HelmSource,
  67. Key: validAthenaConf.Key(),
  68. Active: true,
  69. Valid: true,
  70. ConfigType: AthenaConfigType,
  71. Config: validAthenaConf,
  72. },
  73. },
  74. },
  75. "Helm Source No Change": {
  76. initialStatuses: []*Status{
  77. {
  78. Source: HelmSource,
  79. Key: validAthenaConf.Key(),
  80. Active: true,
  81. Valid: true,
  82. ConfigType: AthenaConfigType,
  83. Config: validAthenaConf,
  84. },
  85. },
  86. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  87. HelmSource: &MockKeyedConfigWatcher{
  88. Integrations: []cloudconfig.KeyedConfig{
  89. validAthenaConf,
  90. },
  91. },
  92. },
  93. expectedStatuses: []*Status{
  94. {
  95. Source: HelmSource,
  96. Key: validAthenaConf.Key(),
  97. Active: true,
  98. Valid: true,
  99. ConfigType: AthenaConfigType,
  100. Config: validAthenaConf,
  101. },
  102. },
  103. },
  104. "Helm Source Update Config": {
  105. initialStatuses: []*Status{
  106. {
  107. Source: HelmSource,
  108. Key: validAthenaConfModifiedProperty.Key(),
  109. Active: true,
  110. Valid: true,
  111. ConfigType: AthenaConfigType,
  112. Config: validAthenaConfModifiedProperty,
  113. },
  114. },
  115. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  116. HelmSource: &MockKeyedConfigWatcher{
  117. Integrations: []cloudconfig.KeyedConfig{
  118. validAthenaConf,
  119. },
  120. },
  121. },
  122. expectedStatuses: []*Status{
  123. {
  124. Source: HelmSource,
  125. Key: validAthenaConf.Key(),
  126. Active: true,
  127. Valid: true,
  128. ConfigType: AthenaConfigType,
  129. Config: validAthenaConf,
  130. },
  131. },
  132. },
  133. "Helm Source Update Config Invalid": {
  134. initialStatuses: []*Status{
  135. {
  136. Source: HelmSource,
  137. Key: validAthenaConf.Key(),
  138. Active: true,
  139. Valid: true,
  140. ConfigType: AthenaConfigType,
  141. Config: validAthenaConf,
  142. },
  143. },
  144. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  145. HelmSource: &MockKeyedConfigWatcher{
  146. Integrations: []cloudconfig.KeyedConfig{
  147. invalidAthenaConf,
  148. },
  149. },
  150. },
  151. expectedStatuses: []*Status{
  152. {
  153. Source: HelmSource,
  154. Key: invalidAthenaConf.Key(),
  155. Active: false,
  156. Valid: false,
  157. ConfigType: AthenaConfigType,
  158. Config: invalidAthenaConf,
  159. },
  160. },
  161. },
  162. "Helm Source New Config": {
  163. initialStatuses: []*Status{
  164. {
  165. Source: HelmSource,
  166. Key: validAthenaConf.Key(),
  167. Active: true,
  168. Valid: true,
  169. ConfigType: AthenaConfigType,
  170. Config: validAthenaConf,
  171. },
  172. },
  173. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  174. HelmSource: &MockKeyedConfigWatcher{
  175. Integrations: []cloudconfig.KeyedConfig{
  176. validBigQueryConf,
  177. },
  178. },
  179. },
  180. expectedStatuses: []*Status{
  181. {
  182. Source: HelmSource,
  183. Key: validAthenaConf.Key(),
  184. Active: false, // this value changed
  185. Valid: true,
  186. ConfigType: AthenaConfigType,
  187. Config: validAthenaConf,
  188. },
  189. {
  190. Source: HelmSource,
  191. Key: validBigQueryConf.Key(),
  192. Active: true,
  193. Valid: true,
  194. ConfigType: AthenaConfigType,
  195. Config: validBigQueryConf,
  196. },
  197. },
  198. },
  199. // Config File
  200. "Config File Source init": {
  201. initialStatuses: []*Status{},
  202. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  203. ConfigFileSource: &MockKeyedConfigWatcher{
  204. Integrations: []cloudconfig.KeyedConfig{
  205. validAthenaConf,
  206. },
  207. },
  208. },
  209. expectedStatuses: []*Status{
  210. {
  211. Source: ConfigFileSource,
  212. Key: validAthenaConf.Key(),
  213. Active: true,
  214. Valid: true,
  215. ConfigType: AthenaConfigType,
  216. Config: validAthenaConf,
  217. },
  218. },
  219. },
  220. "Config File No Change": {
  221. initialStatuses: []*Status{
  222. {
  223. Source: ConfigFileSource,
  224. Key: validAthenaConf.Key(),
  225. Active: true,
  226. Valid: true,
  227. ConfigType: AthenaConfigType,
  228. Config: validAthenaConf,
  229. },
  230. },
  231. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  232. ConfigFileSource: &MockKeyedConfigWatcher{
  233. Integrations: []cloudconfig.KeyedConfig{
  234. validAthenaConf,
  235. },
  236. },
  237. },
  238. expectedStatuses: []*Status{
  239. {
  240. Source: ConfigFileSource,
  241. Key: validAthenaConf.Key(),
  242. Active: true,
  243. Valid: true,
  244. ConfigType: AthenaConfigType,
  245. Config: validAthenaConf,
  246. },
  247. },
  248. },
  249. "Config File Update Config": {
  250. initialStatuses: []*Status{
  251. {
  252. Source: ConfigFileSource,
  253. Key: validAthenaConf.Key(),
  254. Active: true,
  255. Valid: true,
  256. ConfigType: AthenaConfigType,
  257. Config: validAthenaConf,
  258. },
  259. },
  260. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  261. ConfigFileSource: &MockKeyedConfigWatcher{
  262. Integrations: []cloudconfig.KeyedConfig{
  263. validAthenaConf,
  264. },
  265. },
  266. },
  267. expectedStatuses: []*Status{
  268. {
  269. Source: ConfigFileSource,
  270. Key: validAthenaConf.Key(),
  271. Active: true,
  272. Valid: true,
  273. ConfigType: AthenaConfigType,
  274. Config: validAthenaConf,
  275. },
  276. },
  277. },
  278. "Config File Update Config Invalid": {
  279. initialStatuses: []*Status{
  280. {
  281. Source: ConfigFileSource,
  282. Key: validAthenaConf.Key(),
  283. Active: true,
  284. Valid: true,
  285. ConfigType: AthenaConfigType,
  286. Config: validAthenaConf,
  287. },
  288. },
  289. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  290. ConfigFileSource: &MockKeyedConfigWatcher{
  291. Integrations: []cloudconfig.KeyedConfig{
  292. invalidAthenaConf,
  293. },
  294. },
  295. },
  296. expectedStatuses: []*Status{
  297. {
  298. Source: ConfigFileSource,
  299. Key: invalidAthenaConf.Key(),
  300. Active: false,
  301. Valid: false,
  302. ConfigType: AthenaConfigType,
  303. Config: invalidAthenaConf,
  304. },
  305. },
  306. },
  307. "Config File New Config": {
  308. initialStatuses: []*Status{
  309. {
  310. Source: ConfigFileSource,
  311. Key: validAthenaConf.Key(),
  312. Active: true,
  313. Valid: true,
  314. ConfigType: AthenaConfigType,
  315. Config: validAthenaConf,
  316. },
  317. },
  318. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  319. ConfigFileSource: &MockKeyedConfigWatcher{
  320. Integrations: []cloudconfig.KeyedConfig{
  321. validBigQueryConf,
  322. },
  323. },
  324. },
  325. expectedStatuses: []*Status{
  326. {
  327. Source: ConfigFileSource,
  328. Key: validAthenaConf.Key(),
  329. Active: false, // this value changed
  330. Valid: true,
  331. ConfigType: AthenaConfigType,
  332. Config: validAthenaConf,
  333. },
  334. {
  335. Source: ConfigFileSource,
  336. Key: validBigQueryConf.Key(),
  337. Active: true,
  338. Valid: true,
  339. ConfigType: BigQueryConfigType,
  340. Config: validBigQueryConf,
  341. },
  342. },
  343. },
  344. // Multi Cloud
  345. "Multi Cloud Source init": {
  346. initialStatuses: []*Status{},
  347. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  348. MultiCloudSource: &MockKeyedConfigWatcher{
  349. Integrations: []cloudconfig.KeyedConfig{
  350. validAthenaConf,
  351. },
  352. },
  353. },
  354. expectedStatuses: []*Status{
  355. {
  356. Source: MultiCloudSource,
  357. Key: validAthenaConf.Key(),
  358. Active: true,
  359. Valid: true,
  360. ConfigType: AthenaConfigType,
  361. Config: validAthenaConf,
  362. },
  363. },
  364. },
  365. "Multi Cloud No Change": {
  366. initialStatuses: []*Status{
  367. {
  368. Source: MultiCloudSource,
  369. Key: validAthenaConf.Key(),
  370. Active: true,
  371. Valid: true,
  372. ConfigType: AthenaConfigType,
  373. Config: validAthenaConf,
  374. },
  375. },
  376. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  377. MultiCloudSource: &MockKeyedConfigWatcher{
  378. Integrations: []cloudconfig.KeyedConfig{
  379. validAthenaConf,
  380. },
  381. },
  382. },
  383. expectedStatuses: []*Status{
  384. {
  385. Source: MultiCloudSource,
  386. Key: validAthenaConf.Key(),
  387. Active: true,
  388. Valid: true,
  389. ConfigType: AthenaConfigType,
  390. Config: validAthenaConf,
  391. },
  392. },
  393. },
  394. "Multi Cloud Update Config": {
  395. initialStatuses: []*Status{
  396. {
  397. Source: MultiCloudSource,
  398. Key: validAthenaConf.Key(),
  399. Active: true,
  400. Valid: true,
  401. ConfigType: AthenaConfigType,
  402. Config: validAthenaConf,
  403. },
  404. },
  405. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  406. MultiCloudSource: &MockKeyedConfigWatcher{
  407. Integrations: []cloudconfig.KeyedConfig{
  408. validAthenaConfModifiedProperty,
  409. },
  410. },
  411. },
  412. expectedStatuses: []*Status{
  413. {
  414. Source: MultiCloudSource,
  415. Key: validAthenaConfModifiedProperty.Key(),
  416. Active: true,
  417. Valid: true,
  418. ConfigType: AthenaConfigType,
  419. Config: validAthenaConfModifiedProperty,
  420. },
  421. },
  422. },
  423. "Multi Cloud Update Config Invalid": {
  424. initialStatuses: []*Status{
  425. {
  426. Source: MultiCloudSource,
  427. Key: validAthenaConf.Key(),
  428. Active: true,
  429. Valid: true,
  430. ConfigType: AthenaConfigType,
  431. Config: validAthenaConf,
  432. },
  433. },
  434. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  435. MultiCloudSource: &MockKeyedConfigWatcher{
  436. Integrations: []cloudconfig.KeyedConfig{
  437. invalidAthenaConf,
  438. },
  439. },
  440. },
  441. expectedStatuses: []*Status{
  442. {
  443. Source: MultiCloudSource,
  444. Key: invalidAthenaConf.Key(),
  445. Active: false,
  446. Valid: false,
  447. ConfigType: AthenaConfigType,
  448. Config: invalidAthenaConf,
  449. },
  450. },
  451. },
  452. "Multi Cloud New Config": {
  453. initialStatuses: []*Status{
  454. {
  455. Source: MultiCloudSource,
  456. Key: validAthenaConf.Key(),
  457. Active: true,
  458. Valid: true,
  459. ConfigType: AthenaConfigType,
  460. Config: validAthenaConf,
  461. },
  462. },
  463. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  464. MultiCloudSource: &MockKeyedConfigWatcher{
  465. Integrations: []cloudconfig.KeyedConfig{
  466. validBigQueryConf,
  467. },
  468. },
  469. },
  470. expectedStatuses: []*Status{
  471. {
  472. Source: MultiCloudSource,
  473. Key: validAthenaConf.Key(),
  474. Active: true,
  475. Valid: true,
  476. ConfigType: AthenaConfigType,
  477. Config: validAthenaConf,
  478. },
  479. {
  480. Source: MultiCloudSource,
  481. Key: validBigQueryConf.Key(),
  482. Active: true,
  483. Valid: true,
  484. ConfigType: BigQueryConfigType,
  485. Config: validBigQueryConf,
  486. },
  487. },
  488. },
  489. // Watch Interaction
  490. "New Helm, Existing Config File": {
  491. initialStatuses: []*Status{
  492. {
  493. Source: ConfigFileSource,
  494. Key: validAthenaConf.Key(),
  495. Active: true,
  496. Valid: true,
  497. ConfigType: AthenaConfigType,
  498. Config: validAthenaConf,
  499. },
  500. },
  501. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  502. ConfigFileSource: &MockKeyedConfigWatcher{
  503. Integrations: []cloudconfig.KeyedConfig{
  504. validAthenaConf,
  505. },
  506. },
  507. HelmSource: &MockKeyedConfigWatcher{
  508. Integrations: []cloudconfig.KeyedConfig{
  509. validBigQueryConf,
  510. },
  511. },
  512. },
  513. expectedStatuses: []*Status{
  514. {
  515. Source: ConfigFileSource,
  516. Key: validAthenaConf.Key(),
  517. Active: false,
  518. Valid: true,
  519. ConfigType: AthenaConfigType,
  520. Config: validAthenaConf,
  521. },
  522. {
  523. Source: HelmSource,
  524. Key: validBigQueryConf.Key(),
  525. Active: true,
  526. Valid: true,
  527. ConfigType: BigQueryConfigType,
  528. Config: validBigQueryConf,
  529. },
  530. },
  531. },
  532. "Update Helm, Existing Config File": {
  533. initialStatuses: []*Status{
  534. {
  535. Source: HelmSource,
  536. Key: validAthenaConf.Key(),
  537. Active: false,
  538. Valid: true,
  539. ConfigType: AthenaConfigType,
  540. Config: validAthenaConf,
  541. },
  542. {
  543. Source: ConfigFileSource,
  544. Key: validBigQueryConf.Key(),
  545. Active: true,
  546. Valid: true,
  547. ConfigType: BigQueryConfigType,
  548. Config: validBigQueryConf,
  549. },
  550. },
  551. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  552. ConfigFileSource: &MockKeyedConfigWatcher{
  553. Integrations: []cloudconfig.KeyedConfig{
  554. validBigQueryConf,
  555. },
  556. },
  557. HelmSource: &MockKeyedConfigWatcher{
  558. Integrations: []cloudconfig.KeyedConfig{
  559. validAthenaConfModifiedProperty,
  560. },
  561. },
  562. },
  563. expectedStatuses: []*Status{
  564. {
  565. Source: HelmSource,
  566. Key: validAthenaConfModifiedProperty.Key(),
  567. Active: true,
  568. Valid: true,
  569. ConfigType: AthenaConfigType,
  570. Config: validAthenaConfModifiedProperty,
  571. },
  572. {
  573. Source: ConfigFileSource,
  574. Key: validBigQueryConf.Key(),
  575. Active: false,
  576. Valid: true,
  577. ConfigType: BigQueryConfigType,
  578. Config: validBigQueryConf,
  579. },
  580. },
  581. },
  582. "New Helm Invalid, Existing Config File": {
  583. initialStatuses: []*Status{
  584. {
  585. Source: ConfigFileSource,
  586. Key: validBigQueryConf.Key(),
  587. Active: true,
  588. Valid: true,
  589. ConfigType: BigQueryConfigType,
  590. Config: validBigQueryConf,
  591. },
  592. },
  593. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  594. ConfigFileSource: &MockKeyedConfigWatcher{
  595. Integrations: []cloudconfig.KeyedConfig{
  596. validBigQueryConf,
  597. },
  598. },
  599. HelmSource: &MockKeyedConfigWatcher{
  600. Integrations: []cloudconfig.KeyedConfig{
  601. invalidAthenaConf,
  602. },
  603. },
  604. },
  605. expectedStatuses: []*Status{
  606. {
  607. Source: ConfigFileSource,
  608. Key: validBigQueryConf.Key(),
  609. Active: true,
  610. Valid: true,
  611. ConfigType: BigQueryConfigType,
  612. Config: validBigQueryConf,
  613. },
  614. {
  615. Source: HelmSource,
  616. Key: invalidAthenaConf.Key(),
  617. Active: false,
  618. Valid: false,
  619. ConfigType: AthenaConfigType,
  620. Config: invalidAthenaConf,
  621. },
  622. },
  623. },
  624. "Update Helm Invalid, Existing Config File": {
  625. initialStatuses: []*Status{
  626. {
  627. Source: ConfigFileSource,
  628. Key: validBigQueryConf.Key(),
  629. Active: true,
  630. Valid: true,
  631. ConfigType: BigQueryConfigType,
  632. Config: validBigQueryConf,
  633. },
  634. {
  635. Source: HelmSource,
  636. Key: validAthenaConf.Key(),
  637. Active: false,
  638. Valid: true,
  639. ConfigType: AthenaConfigType,
  640. Config: validAthenaConf,
  641. },
  642. },
  643. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  644. ConfigFileSource: &MockKeyedConfigWatcher{
  645. Integrations: []cloudconfig.KeyedConfig{
  646. validBigQueryConf,
  647. },
  648. },
  649. HelmSource: &MockKeyedConfigWatcher{
  650. Integrations: []cloudconfig.KeyedConfig{
  651. invalidAthenaConf,
  652. },
  653. },
  654. },
  655. expectedStatuses: []*Status{
  656. {
  657. Source: ConfigFileSource,
  658. Key: validBigQueryConf.Key(),
  659. Active: true,
  660. Valid: true,
  661. ConfigType: BigQueryConfigType,
  662. Config: validBigQueryConf,
  663. },
  664. {
  665. Source: HelmSource,
  666. Key: invalidAthenaConf.Key(),
  667. Active: false,
  668. Valid: false,
  669. ConfigType: AthenaConfigType,
  670. Config: invalidAthenaConf,
  671. },
  672. },
  673. },
  674. "New Config File, Existing Helm": {
  675. initialStatuses: []*Status{
  676. {
  677. Source: HelmSource,
  678. Key: validAthenaConf.Key(),
  679. Active: true,
  680. Valid: true,
  681. ConfigType: AthenaConfigType,
  682. Config: validAthenaConf,
  683. },
  684. },
  685. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  686. HelmSource: &MockKeyedConfigWatcher{
  687. Integrations: []cloudconfig.KeyedConfig{
  688. validAthenaConf,
  689. },
  690. },
  691. ConfigFileSource: &MockKeyedConfigWatcher{
  692. Integrations: []cloudconfig.KeyedConfig{
  693. validBigQueryConf,
  694. },
  695. },
  696. },
  697. expectedStatuses: []*Status{
  698. {
  699. Source: HelmSource,
  700. Key: validAthenaConf.Key(),
  701. Active: false,
  702. Valid: true,
  703. ConfigType: AthenaConfigType,
  704. Config: validAthenaConf,
  705. },
  706. {
  707. Source: ConfigFileSource,
  708. Key: validBigQueryConf.Key(),
  709. Active: true,
  710. Valid: true,
  711. ConfigType: BigQueryConfigType,
  712. Config: validBigQueryConf,
  713. },
  714. },
  715. },
  716. "Update Config File, Existing Helm": {
  717. initialStatuses: []*Status{
  718. {
  719. Source: ConfigFileSource,
  720. Key: validAthenaConf.Key(),
  721. Active: false,
  722. Valid: true,
  723. ConfigType: AthenaConfigType,
  724. Config: validAthenaConf,
  725. },
  726. {
  727. Source: HelmSource,
  728. Key: validBigQueryConf.Key(),
  729. Active: true,
  730. Valid: true,
  731. ConfigType: BigQueryConfigType,
  732. Config: validBigQueryConf,
  733. },
  734. },
  735. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  736. HelmSource: &MockKeyedConfigWatcher{
  737. Integrations: []cloudconfig.KeyedConfig{},
  738. },
  739. ConfigFileSource: &MockKeyedConfigWatcher{
  740. Integrations: []cloudconfig.KeyedConfig{
  741. validAthenaConfModifiedProperty,
  742. },
  743. },
  744. },
  745. expectedStatuses: []*Status{
  746. {
  747. Source: ConfigFileSource,
  748. Key: validAthenaConfModifiedProperty.Key(),
  749. Active: true,
  750. Valid: true,
  751. ConfigType: AthenaConfigType,
  752. Config: validAthenaConfModifiedProperty,
  753. },
  754. {
  755. Source: HelmSource,
  756. Key: validBigQueryConf.Key(),
  757. Active: false,
  758. Valid: true,
  759. ConfigType: BigQueryConfigType,
  760. Config: validBigQueryConf,
  761. },
  762. },
  763. },
  764. "New Config File Invalid, Existing Helm": {
  765. initialStatuses: []*Status{
  766. {
  767. Source: HelmSource,
  768. Key: validBigQueryConf.Key(),
  769. Active: true,
  770. Valid: true,
  771. ConfigType: BigQueryConfigType,
  772. Config: validBigQueryConf,
  773. },
  774. },
  775. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  776. HelmSource: &MockKeyedConfigWatcher{
  777. Integrations: []cloudconfig.KeyedConfig{
  778. validBigQueryConf,
  779. },
  780. },
  781. ConfigFileSource: &MockKeyedConfigWatcher{
  782. Integrations: []cloudconfig.KeyedConfig{
  783. invalidAthenaConf,
  784. },
  785. },
  786. },
  787. expectedStatuses: []*Status{
  788. {
  789. Source: HelmSource,
  790. Key: validBigQueryConf.Key(),
  791. Active: true,
  792. Valid: true,
  793. ConfigType: BigQueryConfigType,
  794. Config: validBigQueryConf,
  795. },
  796. {
  797. Source: ConfigFileSource,
  798. Key: invalidAthenaConf.Key(),
  799. Active: false,
  800. Valid: false,
  801. ConfigType: AthenaConfigType,
  802. Config: invalidAthenaConf,
  803. },
  804. },
  805. },
  806. "Update Config File Invalid, Existing Helm": {
  807. initialStatuses: []*Status{
  808. {
  809. Source: HelmSource,
  810. Key: validBigQueryConf.Key(),
  811. Active: true,
  812. Valid: true,
  813. ConfigType: BigQueryConfigType,
  814. Config: validBigQueryConf,
  815. },
  816. {
  817. Source: ConfigFileSource,
  818. Key: validAthenaConf.Key(),
  819. Active: false,
  820. Valid: true,
  821. ConfigType: AthenaConfigType,
  822. Config: validAthenaConf,
  823. },
  824. },
  825. configWatchers: map[ConfigSource]cloudconfig.KeyedConfigWatcher{
  826. HelmSource: &MockKeyedConfigWatcher{
  827. Integrations: []cloudconfig.KeyedConfig{
  828. validBigQueryConf,
  829. },
  830. },
  831. ConfigFileSource: &MockKeyedConfigWatcher{
  832. Integrations: []cloudconfig.KeyedConfig{
  833. invalidAthenaConf,
  834. },
  835. },
  836. },
  837. expectedStatuses: []*Status{
  838. {
  839. Source: HelmSource,
  840. Key: validBigQueryConf.Key(),
  841. Active: true,
  842. Valid: true,
  843. ConfigType: BigQueryConfigType,
  844. Config: validBigQueryConf,
  845. },
  846. {
  847. Source: ConfigFileSource,
  848. Key: invalidAthenaConf.Key(),
  849. Active: false,
  850. Valid: false,
  851. ConfigType: AthenaConfigType,
  852. Config: invalidAthenaConf,
  853. },
  854. },
  855. },
  856. }
  857. for name, tc := range testCases {
  858. t.Run(name, func(t *testing.T) {
  859. // Test set up and validation
  860. initialStatuses := Statuses{}
  861. for _, status := range tc.initialStatuses {
  862. if _, ok := initialStatuses.Get(status.Key, status.Source); ok {
  863. t.Errorf("invalid test, duplicate initial status with key: %s source: %s", status.Key, status.Source.String())
  864. }
  865. initialStatuses.Insert(status)
  866. }
  867. expectedStatuses := Statuses{}
  868. for _, status := range tc.expectedStatuses {
  869. if _, ok := expectedStatuses.Get(status.Key, status.Source); ok {
  870. t.Errorf("invalid test, duplicate expected status with key: %s source: %s", status.Key, status.Source.String())
  871. }
  872. expectedStatuses.Insert(status)
  873. }
  874. tempDir := os.TempDir()
  875. os.Setenv(env.ConfigPathEnvVar, tempDir)
  876. defer os.Remove(filepath.Join(tempDir, configFile))
  877. // Initialize controller
  878. icd := &Controller{
  879. watchers: tc.configWatchers,
  880. }
  881. icd.save(initialStatuses)
  882. icd.pullWatchers()
  883. status, err := icd.load()
  884. if err != nil {
  885. t.Errorf("failed to load status file: %s", err.Error())
  886. }
  887. if len(status.List()) != len(expectedStatuses.List()) {
  888. t.Errorf("integration statueses did not have the correct length actaul: %d, expected: %d", len(status), len(tc.expectedStatuses))
  889. }
  890. for _, actualStatus := range status.List() {
  891. expectedStatus, ok := expectedStatuses.Get(actualStatus.Key, actualStatus.Source)
  892. if !ok {
  893. t.Errorf("expected integration statuses is missing with integration key: %s, source: %s", actualStatus.Key, actualStatus.Source.String())
  894. }
  895. // failure here indicates an issue with the configID
  896. if actualStatus.Key != expectedStatus.Key {
  897. t.Errorf("integration status does not have the correct Key values actual: %s, expected: %s", actualStatus.Key, expectedStatus.Key)
  898. }
  899. // failure here indicates an issue with the configID
  900. if actualStatus.Key != expectedStatus.Key {
  901. t.Errorf("integration status does not have the correct Source values actual: %s, expected: %s", actualStatus.Source, expectedStatus.Source)
  902. }
  903. if actualStatus.Active != expectedStatus.Active {
  904. t.Errorf("integration status does not have the correct Active values actual: %v, expected: %v", actualStatus.Active, expectedStatus.Active)
  905. }
  906. if actualStatus.Valid != expectedStatus.Valid {
  907. t.Errorf("integration status does not have the correct Valid values actual: %v, expected: %v", actualStatus.Valid, expectedStatus.Valid)
  908. }
  909. if !actualStatus.Config.Equals(expectedStatus.Config) {
  910. t.Errorf("integration status does not have the correct config values actual: %v, expected: %v", actualStatus.Config, expectedStatus.Config)
  911. }
  912. }
  913. })
  914. }
  915. }