Files
seaweedfs/weed/s3api/iceberg/iceberg_rename_table_test.go
T
Chris Lu c95401b11a iceberg: support table rename (#10068)
* s3tables: add RenameTable operation

* iceberg: support table rename

* iceberg: test table rename

* s3tables: keep table data in place on rename

rename is catalog-only: drop the source's catalog xattrs in place instead of recursively deleting its directory, which wiped the metadata.json and data files the renamed destination still points at. treat a missing table-metadata xattr as NoSuchTable in GetTable so the soft-deleted source name stops resolving.

* s3tables: test rename preserves data

make the in-memory filer honor recursive data deletion and seed the source table's metadata/ and data/ children, then assert a rename leaves them intact, the source name resolves to NoSuchTable, and the destination resolves to the preserved location.

* iceberg: map rename errors through wrapped manager error

* s3tables: authorize rename destination namespace

rename moved a table into the destination namespace after only checking the source, letting a source-authorized caller place tables in namespaces they don't control. require CreateTable on the destination namespace and bucket before writing.

* s3tables: purge renamed table data on drop

* s3tables: test table data dir derivation
2026-06-23 20:18:11 -07:00

33 lines
1019 B
Go

package iceberg
import (
"net/http/httptest"
"strings"
"testing"
)
func TestHandleRenameTableRejectsIncompleteIdentifiers(t *testing.T) {
cases := []struct {
name string
body string
}{
{"missing source name", `{"source":{"namespace":["ns"]},"destination":{"namespace":["ns"],"name":"t2"}}`},
{"missing source namespace", `{"source":{"name":"t"},"destination":{"namespace":["ns"],"name":"t2"}}`},
{"missing destination name", `{"source":{"namespace":["ns"],"name":"t"},"destination":{"namespace":["ns"]}}`},
{"missing destination namespace", `{"source":{"namespace":["ns"],"name":"t"},"destination":{"name":"t2"}}`},
{"empty body", `{}`},
{"malformed json", `{`},
}
s := &Server{}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
r := httptest.NewRequest("POST", "/v1/tables/rename", strings.NewReader(tc.body))
w := httptest.NewRecorder()
s.handleRenameTable(w, r)
if w.Code != 400 {
t.Fatalf("handleRenameTable() status = %d, want 400", w.Code)
}
})
}
}