backend/pkg/library/cassandra/sai_test.go

384 lines
10 KiB
Go
Raw Normal View History

2025-11-19 05:33:06 +00:00
package cassandra
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCreateSAIIndex(t *testing.T) {
tests := []struct {
name string
keyspace string
table string
column string
indexName string
options *SAIIndexOptions
description string
wantErr bool
validate func(*testing.T, error)
}{
{
name: "create basic SAI index",
keyspace: "test_keyspace",
table: "test_table",
column: "name",
indexName: "test_name_idx",
options: nil,
description: "should create a basic SAI index",
wantErr: false,
},
{
name: "create SAI index with auto-generated name",
keyspace: "test_keyspace",
table: "test_table",
column: "email",
indexName: "",
options: nil,
description: "should auto-generate index name",
wantErr: false,
},
{
name: "create SAI index with case insensitive option",
keyspace: "test_keyspace",
table: "test_table",
column: "title",
indexName: "test_title_idx",
options: &SAIIndexOptions{CaseSensitive: boolPtr(false)},
description: "should create index with case insensitive option",
wantErr: false,
},
{
name: "create SAI index with normalize option",
keyspace: "test_keyspace",
table: "test_table",
column: "content",
indexName: "test_content_idx",
options: &SAIIndexOptions{Normalize: boolPtr(true)},
description: "should create index with normalize option",
wantErr: false,
},
{
name: "create SAI index with analyzer",
keyspace: "test_keyspace",
table: "test_table",
column: "description",
indexName: "test_desc_idx",
options: &SAIIndexOptions{Analyzer: "StandardAnalyzer"},
description: "should create index with analyzer",
wantErr: false,
},
{
name: "create SAI index with all options",
keyspace: "test_keyspace",
table: "test_table",
column: "text",
indexName: "test_text_idx",
options: &SAIIndexOptions{CaseSensitive: boolPtr(false), Normalize: boolPtr(true), Analyzer: "StandardAnalyzer"},
description: "should create index with all options",
wantErr: false,
},
{
name: "missing keyspace",
keyspace: "",
table: "test_table",
column: "name",
indexName: "test_idx",
options: nil,
description: "should return error when keyspace is empty and no default",
wantErr: true,
validate: func(t *testing.T, err error) {
assert.Error(t, err)
var e *Error
if assert.ErrorAs(t, err, &e) {
assert.Equal(t, ErrCodeInvalidInput, e.Code)
}
},
},
{
name: "missing table",
keyspace: "test_keyspace",
table: "",
column: "name",
indexName: "test_idx",
options: nil,
description: "should return error when table is empty",
wantErr: true,
validate: func(t *testing.T, err error) {
assert.Error(t, err)
var e *Error
if assert.ErrorAs(t, err, &e) {
assert.Equal(t, ErrCodeInvalidInput, e.Code)
}
},
},
{
name: "missing column",
keyspace: "test_keyspace",
table: "test_table",
column: "",
indexName: "test_idx",
options: nil,
description: "should return error when column is empty",
wantErr: true,
validate: func(t *testing.T, err error) {
assert.Error(t, err)
var e *Error
if assert.ErrorAs(t, err, &e) {
assert.Equal(t, ErrCodeInvalidInput, e.Code)
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 注意:這需要一個有效的 DB 實例和 SAI 支援
// 在實際測試中,需要使用 testcontainers 或 mock
_ = tt
})
}
}
func TestDropSAIIndex(t *testing.T) {
tests := []struct {
name string
keyspace string
indexName string
description string
wantErr bool
validate func(*testing.T, error)
}{
{
name: "drop existing index",
keyspace: "test_keyspace",
indexName: "test_name_idx",
description: "should drop existing index",
wantErr: false,
},
{
name: "drop non-existent index",
keyspace: "test_keyspace",
indexName: "non_existent_idx",
description: "should not error when dropping non-existent index (IF EXISTS)",
wantErr: false,
},
{
name: "missing keyspace",
keyspace: "",
indexName: "test_idx",
description: "should return error when keyspace is empty and no default",
wantErr: true,
validate: func(t *testing.T, err error) {
assert.Error(t, err)
var e *Error
if assert.ErrorAs(t, err, &e) {
assert.Equal(t, ErrCodeInvalidInput, e.Code)
}
},
},
{
name: "missing index name",
keyspace: "test_keyspace",
indexName: "",
description: "should return error when index name is empty",
wantErr: true,
validate: func(t *testing.T, err error) {
assert.Error(t, err)
var e *Error
if assert.ErrorAs(t, err, &e) {
assert.Equal(t, ErrCodeInvalidInput, e.Code)
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 注意:這需要一個有效的 DB 實例和 SAI 支援
// 在實際測試中,需要使用 testcontainers 或 mock
_ = tt
})
}
}
func TestListSAIIndexes(t *testing.T) {
tests := []struct {
name string
keyspace string
table string
description string
wantErr bool
validate func(*testing.T, []SAIIndexInfo, error)
}{
{
name: "list all indexes in keyspace",
keyspace: "test_keyspace",
table: "",
description: "should list all SAI indexes in keyspace",
wantErr: false,
validate: func(t *testing.T, indexes []SAIIndexInfo, err error) {
require.NoError(t, err)
assert.NotNil(t, indexes)
},
},
{
name: "list indexes for specific table",
keyspace: "test_keyspace",
table: "test_table",
description: "should list SAI indexes for specific table",
wantErr: false,
validate: func(t *testing.T, indexes []SAIIndexInfo, err error) {
require.NoError(t, err)
assert.NotNil(t, indexes)
for _, idx := range indexes {
assert.Equal(t, "test_table", idx.TableName)
}
},
},
{
name: "missing keyspace",
keyspace: "",
table: "",
description: "should return error when keyspace is empty and no default",
wantErr: true,
validate: func(t *testing.T, indexes []SAIIndexInfo, err error) {
assert.Error(t, err)
assert.Nil(t, indexes)
var e *Error
if assert.ErrorAs(t, err, &e) {
assert.Equal(t, ErrCodeInvalidInput, e.Code)
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 注意:這需要一個有效的 DB 實例和 SAI 支援
// 在實際測試中,需要使用 testcontainers 或 mock
_ = tt
})
}
}
func TestGetSAIIndex(t *testing.T) {
tests := []struct {
name string
keyspace string
indexName string
description string
wantErr bool
validate func(*testing.T, *SAIIndexInfo, error)
}{
{
name: "get existing index",
keyspace: "test_keyspace",
indexName: "test_name_idx",
description: "should get existing SAI index",
wantErr: false,
validate: func(t *testing.T, index *SAIIndexInfo, err error) {
require.NoError(t, err)
assert.NotNil(t, index)
assert.Equal(t, "test_name_idx", index.IndexName)
},
},
{
name: "get non-existent index",
keyspace: "test_keyspace",
indexName: "non_existent_idx",
description: "should return ErrNotFound",
wantErr: true,
validate: func(t *testing.T, index *SAIIndexInfo, err error) {
assert.Error(t, err)
assert.Nil(t, index)
assert.True(t, IsNotFound(err))
},
},
{
name: "missing keyspace",
keyspace: "",
indexName: "test_idx",
description: "should return error when keyspace is empty and no default",
wantErr: true,
validate: func(t *testing.T, index *SAIIndexInfo, err error) {
assert.Error(t, err)
assert.Nil(t, index)
},
},
{
name: "missing index name",
keyspace: "test_keyspace",
indexName: "",
description: "should return error when index name is empty",
wantErr: true,
validate: func(t *testing.T, index *SAIIndexInfo, err error) {
assert.Error(t, err)
assert.Nil(t, index)
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 注意:這需要一個有效的 DB 實例和 SAI 支援
// 在實際測試中,需要使用 testcontainers 或 mock
_ = tt
})
}
}
func TestSAIIndexOptions(t *testing.T) {
t.Run("default options", func(t *testing.T) {
opts := &SAIIndexOptions{}
assert.Nil(t, opts.CaseSensitive)
assert.Nil(t, opts.Normalize)
assert.Empty(t, opts.Analyzer)
})
t.Run("with case sensitive", func(t *testing.T) {
caseSensitive := false
opts := &SAIIndexOptions{CaseSensitive: &caseSensitive}
assert.NotNil(t, opts.CaseSensitive)
assert.False(t, *opts.CaseSensitive)
})
t.Run("with normalize", func(t *testing.T) {
normalize := true
opts := &SAIIndexOptions{Normalize: &normalize}
assert.NotNil(t, opts.Normalize)
assert.True(t, *opts.Normalize)
})
t.Run("with analyzer", func(t *testing.T) {
opts := &SAIIndexOptions{Analyzer: "StandardAnalyzer"}
assert.Equal(t, "StandardAnalyzer", opts.Analyzer)
})
}
func TestSAIIndexInfo(t *testing.T) {
t.Run("index info structure", func(t *testing.T) {
info := SAIIndexInfo{
KeyspaceName: "test_keyspace",
TableName: "test_table",
IndexName: "test_idx",
ColumnName: "name",
IndexType: "sai",
Options: map[string]string{"target": "name"},
}
assert.Equal(t, "test_keyspace", info.KeyspaceName)
assert.Equal(t, "test_table", info.TableName)
assert.Equal(t, "test_idx", info.IndexName)
assert.Equal(t, "name", info.ColumnName)
assert.Equal(t, "sai", info.IndexType)
assert.NotNil(t, info.Options)
})
}
// Helper function
func boolPtr(b bool) *bool {
return &b
}