diff --git a/test/s3tables/client.go b/test/s3tables/client.go index 638682b5d..cf3f689cc 100644 --- a/test/s3tables/client.go +++ b/test/s3tables/client.go @@ -236,6 +236,40 @@ func (c *S3TablesClient) DeleteTableBucketPolicy(bucketARN string) error { return c.doRequestAndDecode("DeleteTableBucketPolicy", req, nil) } +// Table Policy operations + +func (c *S3TablesClient) PutTablePolicy(bucketARN string, namespace []string, name, policy string) error { + req := &s3tables.PutTablePolicyRequest{ + TableBucketARN: bucketARN, + Namespace: namespace, + Name: name, + ResourcePolicy: policy, + } + return c.doRequestAndDecode("PutTablePolicy", req, nil) +} + +func (c *S3TablesClient) GetTablePolicy(bucketARN string, namespace []string, name string) (*s3tables.GetTablePolicyResponse, error) { + req := &s3tables.GetTablePolicyRequest{ + TableBucketARN: bucketARN, + Namespace: namespace, + Name: name, + } + var result s3tables.GetTablePolicyResponse + if err := c.doRequestAndDecode("GetTablePolicy", req, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (c *S3TablesClient) DeleteTablePolicy(bucketARN string, namespace []string, name string) error { + req := &s3tables.DeleteTablePolicyRequest{ + TableBucketARN: bucketARN, + Namespace: namespace, + Name: name, + } + return c.doRequestAndDecode("DeleteTablePolicy", req, nil) +} + // Tagging operations func (c *S3TablesClient) TagResource(resourceARN string, tags map[string]string) error { diff --git a/test/s3tables/s3tables_integration_test.go b/test/s3tables/s3tables_integration_test.go index 27eb953d5..ffcab9b33 100644 --- a/test/s3tables/s3tables_integration_test.go +++ b/test/s3tables/s3tables_integration_test.go @@ -57,6 +57,10 @@ func TestS3TablesIntegration(t *testing.T) { testTableBucketPolicy(t, client) }) + t.Run("TablePolicy", func(t *testing.T) { + testTablePolicy(t, client) + }) + t.Run("Tagging", func(t *testing.T) { testTagging(t, client) }) @@ -244,6 +248,69 @@ func testTableBucketPolicy(t *testing.T, client *S3TablesClient) { assert.Error(t, err, "Policy should not exist after deletion") } +func testTablePolicy(t *testing.T, client *S3TablesClient) { + bucketName := "test-table-policy-bucket-" + randomString(8) + namespaceName := "test_ns" + tableName := "test_table" + + // Create table bucket + createBucketResp, err := client.CreateTableBucket(bucketName, nil) + require.NoError(t, err, "Failed to create table bucket") + defer client.DeleteTableBucket(createBucketResp.ARN) + + bucketARN := createBucketResp.ARN + + // Create namespace + _, err = client.CreateNamespace(bucketARN, []string{namespaceName}) + require.NoError(t, err, "Failed to create namespace") + defer client.DeleteNamespace(bucketARN, []string{namespaceName}) + + // Create table + icebergMetadata := &s3tables.TableMetadata{ + Iceberg: &s3tables.IcebergMetadata{ + Schema: s3tables.IcebergSchema{ + Fields: []s3tables.IcebergSchemaField{ + {Name: "id", Type: "int", Required: true}, + {Name: "name", Type: "string"}, + }, + }, + }, + } + + createTableResp, err := client.CreateTable(bucketARN, []string{namespaceName}, tableName, "ICEBERG", icebergMetadata, nil) + require.NoError(t, err, "Failed to create table") + defer client.DeleteTable(bucketARN, []string{namespaceName}, tableName) + + t.Logf("✓ Created table: %s", createTableResp.TableARN) + + // Verify no policy exists initially + _, err = client.GetTablePolicy(bucketARN, []string{namespaceName}, tableName) + assert.Error(t, err, "Policy should not exist initially") + t.Logf("✓ Verified no policy exists initially") + + // Put table policy + policy := `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":"*","Action":"s3tables:*","Resource":"*"}]}` + err = client.PutTablePolicy(bucketARN, []string{namespaceName}, tableName, policy) + require.NoError(t, err, "Failed to put table policy") + t.Logf("✓ Put table policy") + + // Get table policy + getPolicyResp, err := client.GetTablePolicy(bucketARN, []string{namespaceName}, tableName) + require.NoError(t, err, "Failed to get table policy") + assert.Equal(t, policy, getPolicyResp.ResourcePolicy) + t.Logf("✓ Got table policy") + + // Delete table policy + err = client.DeleteTablePolicy(bucketARN, []string{namespaceName}, tableName) + require.NoError(t, err, "Failed to delete table policy") + t.Logf("✓ Deleted table policy") + + // Verify policy is deleted + _, err = client.GetTablePolicy(bucketARN, []string{namespaceName}, tableName) + assert.Error(t, err, "Policy should not exist after deletion") + t.Logf("✓ Verified policy deletion") +} + func testTagging(t *testing.T, client *S3TablesClient) { bucketName := "test-tag-bucket-" + randomString(8)