Просмотр исходного кода

Add tests for ConvertAwsAthenaInfoToConfig function

Add comprehensive test coverage for the ConvertAwsAthenaInfoToConfig
function which is now used by QueryAthenaPaginated for IRSA support.

Tests cover:
- Empty config returns nil
- Athena config with access key credentials
- Athena config with service account (IRSA) when credentials empty
- Athena config with assume role wrapping access key
- Athena config with assume role wrapping service account (IRSA)
- S3 config variants
- Workgroup, catalog, and CUR version handling
- Authorizer CreateAWSConfig validation

Signed-off-by: Claude <noreply@anthropic.com>
Signed-off-by: Warwick Peatey <warwick.peatey@ibm.com>
Claude 4 месяцев назад
Родитель
Сommit
3919fcbe3a
1 измененных файлов с 328 добавлено и 0 удалено
  1. 328 0
      pkg/cloud/aws/athenaconfiguration_test.go

+ 328 - 0
pkg/cloud/aws/athenaconfiguration_test.go

@@ -827,3 +827,331 @@ func TestAthenaConfiguration_JSON(t *testing.T) {
 		})
 	}
 }
+
+func TestConvertAwsAthenaInfoToConfig(t *testing.T) {
+	testCases := map[string]struct {
+		input          AwsAthenaInfo
+		expectNil      bool
+		expectType     string
+		expectAuthType string
+	}{
+		"empty config returns nil": {
+			input:     AwsAthenaInfo{},
+			expectNil: true,
+		},
+		"athena config with access key": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AthenaDatabase:   "test-db",
+				AthenaTable:      "test-table",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "access-key-id",
+				ServiceKeySecret: "secret-key",
+			},
+			expectNil:      false,
+			expectType:     "AthenaConfiguration",
+			expectAuthType: "AccessKey",
+		},
+		"athena config with service account (IRSA) - empty credentials": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AthenaDatabase:   "test-db",
+				AthenaTable:      "test-table",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "",
+				ServiceKeySecret: "",
+			},
+			expectNil:      false,
+			expectType:     "AthenaConfiguration",
+			expectAuthType: "ServiceAccount",
+		},
+		"athena config with assume role wrapping access key": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AthenaDatabase:   "test-db",
+				AthenaTable:      "test-table",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "access-key-id",
+				ServiceKeySecret: "secret-key",
+				MasterPayerARN:   "arn:aws:iam::987654321098:role/cross-account-role",
+			},
+			expectNil:      false,
+			expectType:     "AthenaConfiguration",
+			expectAuthType: "AssumeRole",
+		},
+		"athena config with assume role wrapping service account (IRSA)": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AthenaDatabase:   "test-db",
+				AthenaTable:      "test-table",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "",
+				ServiceKeySecret: "",
+				MasterPayerARN:   "arn:aws:iam::987654321098:role/cross-account-role",
+			},
+			expectNil:      false,
+			expectType:     "AthenaConfiguration",
+			expectAuthType: "AssumeRole",
+		},
+		"s3 config (no table/database) with access key": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "access-key-id",
+				ServiceKeySecret: "secret-key",
+			},
+			expectNil:      false,
+			expectType:     "S3Configuration",
+			expectAuthType: "AccessKey",
+		},
+		"s3 config with service account (IRSA)": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "",
+				ServiceKeySecret: "",
+			},
+			expectNil:      false,
+			expectType:     "S3Configuration",
+			expectAuthType: "ServiceAccount",
+		},
+		"athena config with workgroup and catalog": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AthenaDatabase:   "test-db",
+				AthenaTable:      "test-table",
+				AthenaCatalog:    "test-catalog",
+				AthenaWorkgroup:  "test-workgroup",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "",
+				ServiceKeySecret: "",
+			},
+			expectNil:      false,
+			expectType:     "AthenaConfiguration",
+			expectAuthType: "ServiceAccount",
+		},
+		"athena config with CUR version 1.0": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AthenaDatabase:   "test-db",
+				AthenaTable:      "test-table",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "",
+				ServiceKeySecret: "",
+				CURVersion:       "1.0",
+			},
+			expectNil:      false,
+			expectType:     "AthenaConfiguration",
+			expectAuthType: "ServiceAccount",
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			result := ConvertAwsAthenaInfoToConfig(tc.input)
+
+			if tc.expectNil {
+				if result != nil {
+					t.Errorf("expected nil result, got %T", result)
+				}
+				return
+			}
+
+			if result == nil {
+				t.Fatal("expected non-nil result, got nil")
+			}
+
+			switch tc.expectType {
+			case "AthenaConfiguration":
+				ac, ok := result.(*AthenaConfiguration)
+				if !ok {
+					t.Errorf("expected *AthenaConfiguration, got %T", result)
+					return
+				}
+
+				// Verify fields were copied correctly
+				if ac.Bucket != tc.input.AthenaBucketName {
+					t.Errorf("bucket mismatch: expected %s, got %s", tc.input.AthenaBucketName, ac.Bucket)
+				}
+				if ac.Region != tc.input.AthenaRegion {
+					t.Errorf("region mismatch: expected %s, got %s", tc.input.AthenaRegion, ac.Region)
+				}
+				if ac.Database != tc.input.AthenaDatabase {
+					t.Errorf("database mismatch: expected %s, got %s", tc.input.AthenaDatabase, ac.Database)
+				}
+				if ac.Table != tc.input.AthenaTable {
+					t.Errorf("table mismatch: expected %s, got %s", tc.input.AthenaTable, ac.Table)
+				}
+				if ac.Catalog != tc.input.AthenaCatalog {
+					t.Errorf("catalog mismatch: expected %s, got %s", tc.input.AthenaCatalog, ac.Catalog)
+				}
+				if ac.Workgroup != tc.input.AthenaWorkgroup {
+					t.Errorf("workgroup mismatch: expected %s, got %s", tc.input.AthenaWorkgroup, ac.Workgroup)
+				}
+				if ac.Account != tc.input.AccountID {
+					t.Errorf("account mismatch: expected %s, got %s", tc.input.AccountID, ac.Account)
+				}
+
+				// Check CUR version
+				expectedCURVersion := tc.input.CURVersion
+				if expectedCURVersion == "" {
+					expectedCURVersion = "2.0"
+				}
+				if ac.CURVersion != expectedCURVersion {
+					t.Errorf("CURVersion mismatch: expected %s, got %s", expectedCURVersion, ac.CURVersion)
+				}
+
+				// Verify authorizer type
+				verifyAuthorizerType(t, ac.Authorizer, tc.expectAuthType, tc.input)
+
+			case "S3Configuration":
+				sc, ok := result.(*S3Configuration)
+				if !ok {
+					t.Errorf("expected *S3Configuration, got %T", result)
+					return
+				}
+
+				// Verify fields were copied correctly
+				if sc.Bucket != tc.input.AthenaBucketName {
+					t.Errorf("bucket mismatch: expected %s, got %s", tc.input.AthenaBucketName, sc.Bucket)
+				}
+				if sc.Region != tc.input.AthenaRegion {
+					t.Errorf("region mismatch: expected %s, got %s", tc.input.AthenaRegion, sc.Region)
+				}
+				if sc.Account != tc.input.AccountID {
+					t.Errorf("account mismatch: expected %s, got %s", tc.input.AccountID, sc.Account)
+				}
+
+				// Verify authorizer type
+				verifyAuthorizerType(t, sc.Authorizer, tc.expectAuthType, tc.input)
+
+			default:
+				t.Errorf("unexpected type: %s", tc.expectType)
+			}
+		})
+	}
+}
+
+func verifyAuthorizerType(t *testing.T, auth Authorizer, expectType string, input AwsAthenaInfo) {
+	t.Helper()
+
+	switch expectType {
+	case "AccessKey":
+		ak, ok := auth.(*AccessKey)
+		if !ok {
+			t.Errorf("expected *AccessKey authorizer, got %T", auth)
+			return
+		}
+		if ak.ID != input.ServiceKeyName {
+			t.Errorf("access key ID mismatch: expected %s, got %s", input.ServiceKeyName, ak.ID)
+		}
+		if ak.Secret != input.ServiceKeySecret {
+			t.Errorf("access key secret mismatch: expected %s, got %s", input.ServiceKeySecret, ak.Secret)
+		}
+
+	case "ServiceAccount":
+		_, ok := auth.(*ServiceAccount)
+		if !ok {
+			t.Errorf("expected *ServiceAccount authorizer, got %T", auth)
+		}
+
+	case "AssumeRole":
+		ar, ok := auth.(*AssumeRole)
+		if !ok {
+			t.Errorf("expected *AssumeRole authorizer, got %T", auth)
+			return
+		}
+		if ar.RoleARN != input.MasterPayerARN {
+			t.Errorf("role ARN mismatch: expected %s, got %s", input.MasterPayerARN, ar.RoleARN)
+		}
+
+		// Check the wrapped authorizer
+		if input.ServiceKeyName == "" && input.ServiceKeySecret == "" {
+			if _, ok := ar.Authorizer.(*ServiceAccount); !ok {
+				t.Errorf("expected wrapped *ServiceAccount authorizer in AssumeRole, got %T", ar.Authorizer)
+			}
+		} else {
+			if _, ok := ar.Authorizer.(*AccessKey); !ok {
+				t.Errorf("expected wrapped *AccessKey authorizer in AssumeRole, got %T", ar.Authorizer)
+			}
+		}
+
+	default:
+		t.Errorf("unexpected authorizer type: %s", expectType)
+	}
+}
+
+func TestConvertAwsAthenaInfoToConfig_AuthorizerCreateAWSConfig(t *testing.T) {
+	// Test that the converted config's authorizer can create AWS configs
+	testCases := map[string]struct {
+		input       AwsAthenaInfo
+		expectError bool
+	}{
+		"access key authorizer creates config": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AthenaDatabase:   "test-db",
+				AthenaTable:      "test-table",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "AKIAIOSFODNN7EXAMPLE",
+				ServiceKeySecret: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
+			},
+			expectError: false,
+		},
+		"service account authorizer creates config": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AthenaDatabase:   "test-db",
+				AthenaTable:      "test-table",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "",
+				ServiceKeySecret: "",
+			},
+			expectError: false,
+		},
+		"invalid access key fails validation": {
+			input: AwsAthenaInfo{
+				AthenaBucketName: "test-bucket",
+				AthenaRegion:     "us-east-1",
+				AthenaDatabase:   "test-db",
+				AthenaTable:      "test-table",
+				AccountID:        "123456789012",
+				ServiceKeyName:   "only-id-no-secret",
+				ServiceKeySecret: "",
+			},
+			expectError: true,
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			result := ConvertAwsAthenaInfoToConfig(tc.input)
+			if result == nil {
+				t.Fatal("expected non-nil result")
+			}
+
+			ac, ok := result.(*AthenaConfiguration)
+			if !ok {
+				t.Fatalf("expected *AthenaConfiguration, got %T", result)
+			}
+
+			_, err := ac.Authorizer.CreateAWSConfig(tc.input.AthenaRegion)
+			if tc.expectError && err == nil {
+				t.Error("expected error but got nil")
+			}
+			if !tc.expectError && err != nil {
+				t.Errorf("unexpected error: %v", err)
+			}
+		})
+	}
+}