2
0

athenaconfiguration_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. package aws
  2. import (
  3. "fmt"
  4. "testing"
  5. "github.com/opencost/opencost/pkg/cloud/config"
  6. "github.com/opencost/opencost/pkg/log"
  7. "github.com/opencost/opencost/pkg/util/json"
  8. )
  9. func TestAthenaConfiguration_Validate(t *testing.T) {
  10. testCases := map[string]struct {
  11. config AthenaConfiguration
  12. expected error
  13. }{
  14. "valid config access key": {
  15. config: AthenaConfiguration{
  16. Bucket: "bucket",
  17. Region: "region",
  18. Database: "database",
  19. Table: "table",
  20. Workgroup: "workgroup",
  21. Account: "account",
  22. Authorizer: &AccessKey{
  23. ID: "id",
  24. Secret: "secret",
  25. },
  26. },
  27. expected: nil,
  28. },
  29. "valid config service account": {
  30. config: AthenaConfiguration{
  31. Bucket: "bucket",
  32. Region: "region",
  33. Database: "database",
  34. Table: "table",
  35. Workgroup: "workgroup",
  36. Account: "account",
  37. Authorizer: &ServiceAccount{},
  38. },
  39. expected: nil,
  40. },
  41. "access key invalid": {
  42. config: AthenaConfiguration{
  43. Bucket: "bucket",
  44. Region: "region",
  45. Database: "database",
  46. Table: "table",
  47. Workgroup: "workgroup",
  48. Account: "account",
  49. Authorizer: &AccessKey{
  50. ID: "id",
  51. },
  52. },
  53. expected: fmt.Errorf("AthenaConfiguration: AccessKey: missing Secret"),
  54. },
  55. "missing Authorizer": {
  56. config: AthenaConfiguration{
  57. Bucket: "bucket",
  58. Region: "region",
  59. Database: "database",
  60. Table: "table",
  61. Workgroup: "workgroup",
  62. Account: "account",
  63. Authorizer: nil,
  64. },
  65. expected: fmt.Errorf("AthenaConfiguration: missing Authorizer"),
  66. },
  67. "missing bucket": {
  68. config: AthenaConfiguration{
  69. Bucket: "",
  70. Region: "region",
  71. Database: "database",
  72. Table: "table",
  73. Workgroup: "workgroup",
  74. Account: "account",
  75. Authorizer: &ServiceAccount{},
  76. },
  77. expected: fmt.Errorf("AthenaConfiguration: missing bucket"),
  78. },
  79. "missing region": {
  80. config: AthenaConfiguration{
  81. Bucket: "bucket",
  82. Region: "",
  83. Database: "database",
  84. Table: "table",
  85. Workgroup: "workgroup",
  86. Account: "account",
  87. Authorizer: &ServiceAccount{},
  88. },
  89. expected: fmt.Errorf("AthenaConfiguration: missing region"),
  90. },
  91. "missing database": {
  92. config: AthenaConfiguration{
  93. Bucket: "bucket",
  94. Region: "region",
  95. Database: "",
  96. Table: "table",
  97. Workgroup: "workgroup",
  98. Account: "account",
  99. Authorizer: &ServiceAccount{},
  100. },
  101. expected: fmt.Errorf("AthenaConfiguration: missing database"),
  102. },
  103. "missing table": {
  104. config: AthenaConfiguration{
  105. Bucket: "bucket",
  106. Region: "region",
  107. Database: "database",
  108. Table: "",
  109. Workgroup: "workgroup",
  110. Account: "account",
  111. Authorizer: &ServiceAccount{},
  112. },
  113. expected: fmt.Errorf("AthenaConfiguration: missing table"),
  114. },
  115. "missing workgroup": {
  116. config: AthenaConfiguration{
  117. Bucket: "bucket",
  118. Region: "region",
  119. Database: "database",
  120. Table: "table",
  121. Workgroup: "",
  122. Account: "account",
  123. Authorizer: &ServiceAccount{},
  124. },
  125. expected: nil,
  126. },
  127. "missing account": {
  128. config: AthenaConfiguration{
  129. Bucket: "bucket",
  130. Region: "region",
  131. Database: "database",
  132. Table: "table",
  133. Workgroup: "workgroup",
  134. Account: "",
  135. Authorizer: &ServiceAccount{},
  136. },
  137. expected: fmt.Errorf("AthenaConfiguration: missing account"),
  138. },
  139. }
  140. for name, testCase := range testCases {
  141. t.Run(name, func(t *testing.T) {
  142. actual := testCase.config.Validate()
  143. actualString := "nil"
  144. if actual != nil {
  145. actualString = actual.Error()
  146. }
  147. expectedString := "nil"
  148. if testCase.expected != nil {
  149. expectedString = testCase.expected.Error()
  150. }
  151. if actualString != expectedString {
  152. t.Errorf("errors do not match: Actual: '%s', Expected: '%s", actualString, expectedString)
  153. }
  154. })
  155. }
  156. }
  157. func TestAthenaConfiguration_Equals(t *testing.T) {
  158. testCases := map[string]struct {
  159. left AthenaConfiguration
  160. right config.Config
  161. expected bool
  162. }{
  163. "matching config": {
  164. left: AthenaConfiguration{
  165. Bucket: "bucket",
  166. Region: "region",
  167. Database: "database",
  168. Table: "table",
  169. Workgroup: "workgroup",
  170. Account: "account",
  171. Authorizer: &AccessKey{
  172. ID: "id",
  173. Secret: "secret",
  174. },
  175. },
  176. right: &AthenaConfiguration{
  177. Bucket: "bucket",
  178. Region: "region",
  179. Database: "database",
  180. Table: "table",
  181. Workgroup: "workgroup",
  182. Account: "account",
  183. Authorizer: &AccessKey{
  184. ID: "id",
  185. Secret: "secret",
  186. },
  187. },
  188. expected: true,
  189. },
  190. "different Authorizer": {
  191. left: AthenaConfiguration{
  192. Bucket: "bucket",
  193. Region: "region",
  194. Database: "database",
  195. Table: "table",
  196. Workgroup: "workgroup",
  197. Account: "account",
  198. Authorizer: &AccessKey{
  199. ID: "id",
  200. Secret: "secret",
  201. },
  202. },
  203. right: &AthenaConfiguration{
  204. Bucket: "bucket",
  205. Region: "region",
  206. Database: "database",
  207. Table: "table",
  208. Workgroup: "workgroup",
  209. Account: "account",
  210. Authorizer: &ServiceAccount{},
  211. },
  212. expected: false,
  213. },
  214. "missing both Authorizer": {
  215. left: AthenaConfiguration{
  216. Bucket: "bucket",
  217. Region: "region",
  218. Database: "database",
  219. Table: "table",
  220. Workgroup: "workgroup",
  221. Account: "account",
  222. Authorizer: nil,
  223. },
  224. right: &AthenaConfiguration{
  225. Bucket: "bucket",
  226. Region: "region",
  227. Database: "database",
  228. Table: "table",
  229. Workgroup: "workgroup",
  230. Account: "account",
  231. Authorizer: nil,
  232. },
  233. expected: true,
  234. },
  235. "missing left Authorizer": {
  236. left: AthenaConfiguration{
  237. Bucket: "bucket",
  238. Region: "region",
  239. Database: "database",
  240. Table: "table",
  241. Workgroup: "workgroup",
  242. Account: "account",
  243. Authorizer: nil,
  244. },
  245. right: &AthenaConfiguration{
  246. Bucket: "bucket",
  247. Region: "region",
  248. Database: "database",
  249. Table: "table",
  250. Workgroup: "workgroup",
  251. Account: "account",
  252. Authorizer: &ServiceAccount{},
  253. },
  254. expected: false,
  255. },
  256. "missing right Authorizer": {
  257. left: AthenaConfiguration{
  258. Bucket: "bucket",
  259. Region: "region",
  260. Database: "database",
  261. Table: "table",
  262. Workgroup: "workgroup",
  263. Account: "account",
  264. Authorizer: &AccessKey{
  265. ID: "id",
  266. Secret: "secret",
  267. },
  268. },
  269. right: &AthenaConfiguration{
  270. Bucket: "bucket",
  271. Region: "region",
  272. Database: "database",
  273. Table: "table",
  274. Workgroup: "workgroup",
  275. Account: "account",
  276. Authorizer: nil,
  277. },
  278. expected: false,
  279. },
  280. "different bucket": {
  281. left: AthenaConfiguration{
  282. Bucket: "bucket",
  283. Region: "region",
  284. Database: "database",
  285. Table: "table",
  286. Workgroup: "workgroup",
  287. Account: "account",
  288. Authorizer: &AccessKey{
  289. ID: "id",
  290. Secret: "secret",
  291. },
  292. },
  293. right: &AthenaConfiguration{
  294. Bucket: "bucket2",
  295. Region: "region",
  296. Database: "database",
  297. Table: "table",
  298. Workgroup: "workgroup",
  299. Account: "account",
  300. Authorizer: &AccessKey{
  301. ID: "id",
  302. Secret: "secret",
  303. },
  304. },
  305. expected: false,
  306. },
  307. "different region": {
  308. left: AthenaConfiguration{
  309. Bucket: "bucket",
  310. Region: "region",
  311. Database: "database",
  312. Table: "table",
  313. Workgroup: "workgroup",
  314. Account: "account",
  315. Authorizer: &AccessKey{
  316. ID: "id",
  317. Secret: "secret",
  318. },
  319. },
  320. right: &AthenaConfiguration{
  321. Bucket: "bucket",
  322. Region: "region2",
  323. Database: "database",
  324. Table: "table",
  325. Workgroup: "workgroup",
  326. Account: "account",
  327. Authorizer: &AccessKey{
  328. ID: "id",
  329. Secret: "secret",
  330. },
  331. },
  332. expected: false,
  333. },
  334. "different database": {
  335. left: AthenaConfiguration{
  336. Bucket: "bucket",
  337. Region: "region",
  338. Database: "database",
  339. Table: "table",
  340. Workgroup: "workgroup",
  341. Account: "account",
  342. Authorizer: &AccessKey{
  343. ID: "id",
  344. Secret: "secret",
  345. },
  346. },
  347. right: &AthenaConfiguration{
  348. Bucket: "bucket",
  349. Region: "region",
  350. Database: "database2",
  351. Table: "table",
  352. Workgroup: "workgroup",
  353. Account: "account",
  354. Authorizer: &AccessKey{
  355. ID: "id",
  356. Secret: "secret",
  357. },
  358. },
  359. expected: false,
  360. },
  361. "different table": {
  362. left: AthenaConfiguration{
  363. Bucket: "bucket",
  364. Region: "region",
  365. Database: "database",
  366. Table: "table",
  367. Workgroup: "workgroup",
  368. Account: "account",
  369. Authorizer: &AccessKey{
  370. ID: "id",
  371. Secret: "secret",
  372. },
  373. },
  374. right: &AthenaConfiguration{
  375. Bucket: "bucket",
  376. Region: "region",
  377. Database: "database",
  378. Table: "table2",
  379. Workgroup: "workgroup",
  380. Account: "account",
  381. Authorizer: &AccessKey{
  382. ID: "id",
  383. Secret: "secret",
  384. },
  385. },
  386. expected: false,
  387. },
  388. "different workgroup": {
  389. left: AthenaConfiguration{
  390. Bucket: "bucket",
  391. Region: "region",
  392. Database: "database",
  393. Table: "table",
  394. Workgroup: "workgroup",
  395. Account: "account",
  396. Authorizer: &AccessKey{
  397. ID: "id",
  398. Secret: "secret",
  399. },
  400. },
  401. right: &AthenaConfiguration{
  402. Bucket: "bucket",
  403. Region: "region",
  404. Database: "database",
  405. Table: "table",
  406. Workgroup: "workgroup2",
  407. Account: "account",
  408. Authorizer: &AccessKey{
  409. ID: "id",
  410. Secret: "secret",
  411. },
  412. },
  413. expected: false,
  414. },
  415. "different account": {
  416. left: AthenaConfiguration{
  417. Bucket: "bucket",
  418. Region: "region",
  419. Database: "database",
  420. Table: "table",
  421. Workgroup: "workgroup",
  422. Account: "account",
  423. Authorizer: &AccessKey{
  424. ID: "id",
  425. Secret: "secret",
  426. },
  427. },
  428. right: &AthenaConfiguration{
  429. Bucket: "bucket",
  430. Region: "region",
  431. Database: "database",
  432. Table: "table",
  433. Workgroup: "workgroup",
  434. Account: "account2",
  435. Authorizer: &AccessKey{
  436. ID: "id",
  437. Secret: "secret",
  438. },
  439. },
  440. expected: false,
  441. },
  442. "different config": {
  443. left: AthenaConfiguration{
  444. Bucket: "bucket",
  445. Region: "region",
  446. Database: "database",
  447. Table: "table",
  448. Workgroup: "workgroup",
  449. Account: "account",
  450. Authorizer: &AccessKey{
  451. ID: "id",
  452. Secret: "secret",
  453. },
  454. },
  455. right: &AccessKey{
  456. ID: "id",
  457. Secret: "secret",
  458. },
  459. expected: false,
  460. },
  461. }
  462. for name, testCase := range testCases {
  463. t.Run(name, func(t *testing.T) {
  464. actual := testCase.left.Equals(testCase.right)
  465. if actual != testCase.expected {
  466. t.Errorf("incorrect result: Actual: '%t', Expected: '%t", actual, testCase.expected)
  467. }
  468. })
  469. }
  470. }
  471. func TestAthenaConfiguration_JSON(t *testing.T) {
  472. testCases := map[string]struct {
  473. config AthenaConfiguration
  474. }{
  475. "Empty Config": {
  476. config: AthenaConfiguration{},
  477. },
  478. "AccessKey": {
  479. config: AthenaConfiguration{
  480. Bucket: "bucket",
  481. Region: "region",
  482. Database: "database",
  483. Table: "table",
  484. Workgroup: "workgroup",
  485. Account: "account",
  486. Authorizer: &AccessKey{
  487. ID: "id",
  488. Secret: "secret",
  489. },
  490. },
  491. },
  492. "ServiceAccount": {
  493. config: AthenaConfiguration{
  494. Bucket: "bucket",
  495. Region: "region",
  496. Database: "database",
  497. Table: "table",
  498. Workgroup: "workgroup",
  499. Account: "account",
  500. Authorizer: &ServiceAccount{},
  501. },
  502. },
  503. "AssumeRole with AccessKey": {
  504. config: AthenaConfiguration{
  505. Bucket: "bucket",
  506. Region: "region",
  507. Database: "database",
  508. Table: "table",
  509. Workgroup: "workgroup",
  510. Account: "account",
  511. Authorizer: &AssumeRole{
  512. Authorizer: &AccessKey{
  513. ID: "id",
  514. Secret: "secret",
  515. },
  516. RoleARN: "12345",
  517. },
  518. },
  519. },
  520. "AssumeRole with ServiceAccount": {
  521. config: AthenaConfiguration{
  522. Bucket: "bucket",
  523. Region: "region",
  524. Database: "database",
  525. Table: "table",
  526. Workgroup: "workgroup",
  527. Account: "account",
  528. Authorizer: &AssumeRole{
  529. Authorizer: &ServiceAccount{},
  530. RoleARN: "12345",
  531. },
  532. },
  533. },
  534. "RoleArnNil": {
  535. config: AthenaConfiguration{
  536. Bucket: "bucket",
  537. Region: "region",
  538. Database: "database",
  539. Table: "table",
  540. Workgroup: "workgroup",
  541. Account: "account",
  542. Authorizer: &AssumeRole{
  543. Authorizer: nil,
  544. RoleARN: "12345",
  545. },
  546. },
  547. },
  548. "AssumeRole with AssumeRole with ServiceAccount": {
  549. config: AthenaConfiguration{
  550. Bucket: "bucket",
  551. Region: "region",
  552. Database: "database",
  553. Table: "table",
  554. Workgroup: "workgroup",
  555. Account: "account",
  556. Authorizer: &AssumeRole{
  557. Authorizer: &AssumeRole{
  558. RoleARN: "12345",
  559. Authorizer: &ServiceAccount{},
  560. },
  561. RoleARN: "12345",
  562. },
  563. },
  564. },
  565. }
  566. for name, testCase := range testCases {
  567. t.Run(name, func(t *testing.T) {
  568. // test JSON Marshalling
  569. configJSON, err := json.Marshal(testCase.config)
  570. if err != nil {
  571. t.Errorf("failed to marshal configuration: %s", err.Error())
  572. }
  573. log.Info(string(configJSON))
  574. unmarshalledConfig := &AthenaConfiguration{}
  575. err = json.Unmarshal(configJSON, unmarshalledConfig)
  576. if err != nil {
  577. t.Errorf("failed to unmarshal configuration: %s", err.Error())
  578. }
  579. if !testCase.config.Equals(unmarshalledConfig) {
  580. t.Error("config does not equal unmarshalled config")
  581. }
  582. })
  583. }
  584. }