authorizer_test.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. package alibaba
  2. import (
  3. "fmt"
  4. "testing"
  5. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
  6. "github.com/opencost/opencost/core/pkg/util/json"
  7. "github.com/opencost/opencost/pkg/cloud"
  8. )
  9. func TestSelectAuthorizerByType(t *testing.T) {
  10. testCases := map[string]struct {
  11. typeStr string
  12. expectedError bool
  13. expectedType string
  14. }{
  15. "valid AccessKey type": {
  16. typeStr: AccessKeyAuthorizerType,
  17. expectedError: false,
  18. expectedType: "*alibaba.AccessKey",
  19. },
  20. "invalid type": {
  21. typeStr: "InvalidType",
  22. expectedError: true,
  23. expectedType: "",
  24. },
  25. "empty type": {
  26. typeStr: "",
  27. expectedError: true,
  28. expectedType: "",
  29. },
  30. }
  31. for name, testCase := range testCases {
  32. t.Run(name, func(t *testing.T) {
  33. authorizer, err := SelectAuthorizerByType(testCase.typeStr)
  34. if testCase.expectedError {
  35. if err == nil {
  36. t.Errorf("expected error but got none")
  37. }
  38. if authorizer != nil {
  39. t.Errorf("expected nil authorizer but got %T", authorizer)
  40. }
  41. } else {
  42. if err != nil {
  43. t.Errorf("unexpected error: %v", err)
  44. }
  45. if authorizer == nil {
  46. t.Errorf("expected authorizer but got nil")
  47. }
  48. // Check the type
  49. if testCase.expectedType != "" {
  50. actualType := fmt.Sprintf("%T", authorizer)
  51. if actualType != testCase.expectedType {
  52. t.Errorf("expected type %s but got %s", testCase.expectedType, actualType)
  53. }
  54. }
  55. }
  56. })
  57. }
  58. }
  59. func TestAccessKey_MarshalJSON(t *testing.T) {
  60. testCases := map[string]struct {
  61. accessKey AccessKey
  62. expectedFields map[string]interface{}
  63. }{
  64. "complete AccessKey": {
  65. accessKey: AccessKey{
  66. AccessKeyID: "test-id",
  67. AccessKeySecret: "test-secret",
  68. },
  69. expectedFields: map[string]interface{}{
  70. cloud.AuthorizerTypeProperty: AccessKeyAuthorizerType,
  71. "accessKeyID": "test-id",
  72. "accessKeySecret": "test-secret",
  73. },
  74. },
  75. "empty AccessKey": {
  76. accessKey: AccessKey{},
  77. expectedFields: map[string]interface{}{
  78. cloud.AuthorizerTypeProperty: AccessKeyAuthorizerType,
  79. "accessKeyID": "",
  80. "accessKeySecret": "",
  81. },
  82. },
  83. }
  84. for name, testCase := range testCases {
  85. t.Run(name, func(t *testing.T) {
  86. data, err := testCase.accessKey.MarshalJSON()
  87. if err != nil {
  88. t.Errorf("unexpected error: %v", err)
  89. }
  90. var result map[string]interface{}
  91. err = json.Unmarshal(data, &result)
  92. if err != nil {
  93. t.Errorf("failed to unmarshal JSON: %v", err)
  94. }
  95. for key, expectedValue := range testCase.expectedFields {
  96. if actualValue, exists := result[key]; !exists {
  97. t.Errorf("missing field %s", key)
  98. } else if actualValue != expectedValue {
  99. t.Errorf("field %s: expected %v, got %v", key, expectedValue, actualValue)
  100. }
  101. }
  102. })
  103. }
  104. }
  105. func TestAccessKey_Validate(t *testing.T) {
  106. testCases := map[string]struct {
  107. accessKey AccessKey
  108. expectedError bool
  109. errorMessage string
  110. }{
  111. "valid AccessKey": {
  112. accessKey: AccessKey{
  113. AccessKeyID: "test-id",
  114. AccessKeySecret: "test-secret",
  115. },
  116. expectedError: false,
  117. },
  118. "missing AccessKeyID": {
  119. accessKey: AccessKey{
  120. AccessKeySecret: "test-secret",
  121. },
  122. expectedError: true,
  123. errorMessage: "AccessKey: missing Access key ID",
  124. },
  125. "missing AccessKeySecret": {
  126. accessKey: AccessKey{
  127. AccessKeyID: "test-id",
  128. },
  129. expectedError: true,
  130. errorMessage: "AccessKey: missing Access Key secret",
  131. },
  132. "both fields missing": {
  133. accessKey: AccessKey{},
  134. expectedError: true,
  135. errorMessage: "AccessKey: missing Access key ID",
  136. },
  137. }
  138. for name, testCase := range testCases {
  139. t.Run(name, func(t *testing.T) {
  140. err := testCase.accessKey.Validate()
  141. if testCase.expectedError {
  142. if err == nil {
  143. t.Errorf("expected error but got none")
  144. } else if testCase.errorMessage != "" && err.Error() != testCase.errorMessage {
  145. t.Errorf("expected error message '%s' but got '%s'", testCase.errorMessage, err.Error())
  146. }
  147. } else {
  148. if err != nil {
  149. t.Errorf("unexpected error: %v", err)
  150. }
  151. }
  152. })
  153. }
  154. }
  155. func TestAccessKey_Equals(t *testing.T) {
  156. testCases := map[string]struct {
  157. left AccessKey
  158. right cloud.Config
  159. expected bool
  160. }{
  161. "matching AccessKey": {
  162. left: AccessKey{
  163. AccessKeyID: "id1",
  164. AccessKeySecret: "secret1",
  165. },
  166. right: &AccessKey{
  167. AccessKeyID: "id1",
  168. AccessKeySecret: "secret1",
  169. },
  170. expected: true,
  171. },
  172. "different AccessKeyID": {
  173. left: AccessKey{
  174. AccessKeyID: "id1",
  175. AccessKeySecret: "secret1",
  176. },
  177. right: &AccessKey{
  178. AccessKeyID: "id2",
  179. AccessKeySecret: "secret1",
  180. },
  181. expected: false,
  182. },
  183. "different AccessKeySecret": {
  184. left: AccessKey{
  185. AccessKeyID: "id1",
  186. AccessKeySecret: "secret1",
  187. },
  188. right: &AccessKey{
  189. AccessKeyID: "id1",
  190. AccessKeySecret: "secret2",
  191. },
  192. expected: false,
  193. },
  194. "nil config": {
  195. left: AccessKey{
  196. AccessKeyID: "id1",
  197. AccessKeySecret: "secret1",
  198. },
  199. right: nil,
  200. expected: false,
  201. },
  202. "different config type": {
  203. left: AccessKey{
  204. AccessKeyID: "id1",
  205. AccessKeySecret: "secret1",
  206. },
  207. right: &BOAConfiguration{},
  208. expected: false,
  209. },
  210. "empty AccessKey": {
  211. left: AccessKey{},
  212. right: &AccessKey{},
  213. expected: true,
  214. },
  215. }
  216. for name, testCase := range testCases {
  217. t.Run(name, func(t *testing.T) {
  218. result := testCase.left.Equals(testCase.right)
  219. if result != testCase.expected {
  220. t.Errorf("expected %t but got %t", testCase.expected, result)
  221. }
  222. })
  223. }
  224. }
  225. func TestAccessKey_Sanitize(t *testing.T) {
  226. original := AccessKey{
  227. AccessKeyID: "original-id",
  228. AccessKeySecret: "original-secret",
  229. }
  230. sanitized := original.Sanitize()
  231. sanitizedAccessKey, ok := sanitized.(*AccessKey)
  232. if !ok {
  233. t.Fatalf("expected *AccessKey but got %T", sanitized)
  234. }
  235. // Check that AccessKeyID remains unchanged
  236. if sanitizedAccessKey.AccessKeyID != original.AccessKeyID {
  237. t.Errorf("AccessKeyID should remain unchanged: expected %s, got %s",
  238. original.AccessKeyID, sanitizedAccessKey.AccessKeyID)
  239. }
  240. // Check that AccessKeySecret is redacted
  241. if sanitizedAccessKey.AccessKeySecret != cloud.Redacted {
  242. t.Errorf("AccessKeySecret should be redacted: expected %s, got %s",
  243. cloud.Redacted, sanitizedAccessKey.AccessKeySecret)
  244. }
  245. // Verify original is not modified
  246. if original.AccessKeySecret != "original-secret" {
  247. t.Errorf("original AccessKey should not be modified")
  248. }
  249. }
  250. func TestAccessKey_GetCredentials(t *testing.T) {
  251. testCases := map[string]struct {
  252. accessKey AccessKey
  253. expectedError bool
  254. checkCreds func(*credentials.AccessKeyCredential) bool
  255. }{
  256. "valid credentials": {
  257. accessKey: AccessKey{
  258. AccessKeyID: "test-id",
  259. AccessKeySecret: "test-secret",
  260. },
  261. expectedError: false,
  262. checkCreds: func(creds *credentials.AccessKeyCredential) bool {
  263. return creds.AccessKeyId == "test-id" && creds.AccessKeySecret == "test-secret"
  264. },
  265. },
  266. "invalid credentials - missing ID": {
  267. accessKey: AccessKey{
  268. AccessKeySecret: "test-secret",
  269. },
  270. expectedError: true,
  271. },
  272. "invalid credentials - missing secret": {
  273. accessKey: AccessKey{
  274. AccessKeyID: "test-id",
  275. },
  276. expectedError: true,
  277. },
  278. }
  279. for name, testCase := range testCases {
  280. t.Run(name, func(t *testing.T) {
  281. creds, err := testCase.accessKey.GetCredentials()
  282. if testCase.expectedError {
  283. if err == nil {
  284. t.Errorf("expected error but got none")
  285. }
  286. if creds != nil {
  287. t.Errorf("expected nil credentials but got %v", creds)
  288. }
  289. } else {
  290. if err != nil {
  291. t.Errorf("unexpected error: %v", err)
  292. }
  293. if creds == nil {
  294. t.Errorf("expected credentials but got nil")
  295. }
  296. accessKeyCreds, ok := creds.(*credentials.AccessKeyCredential)
  297. if !ok {
  298. t.Errorf("expected *credentials.AccessKeyCredential but got %T", creds)
  299. }
  300. if testCase.checkCreds != nil && !testCase.checkCreds(accessKeyCreds) {
  301. t.Errorf("credentials validation failed")
  302. }
  303. }
  304. })
  305. }
  306. }
  307. func TestAccessKey_JSONRoundTrip(t *testing.T) {
  308. original := AccessKey{
  309. AccessKeyID: "test-id",
  310. AccessKeySecret: "test-secret",
  311. }
  312. // Marshal to JSON
  313. data, err := json.Marshal(original)
  314. if err != nil {
  315. t.Fatalf("failed to marshal: %v", err)
  316. }
  317. // Unmarshal back
  318. var unmarshaled AccessKey
  319. err = json.Unmarshal(data, &unmarshaled)
  320. if err != nil {
  321. t.Fatalf("failed to unmarshal: %v", err)
  322. }
  323. // Check equality
  324. if !original.Equals(&unmarshaled) {
  325. t.Errorf("round-trip JSON marshaling failed: original %+v, unmarshaled %+v", original, unmarshaled)
  326. }
  327. }