Files
es-demo/operations/index/template_unit_test.go
mouseleee fc14798af5 feat: 增加ism管理接口
test: 索引模板和ism的单元测试和集成测试
2025-11-16 23:00:31 +08:00

293 lines
6.3 KiB
Go

package index
import (
"context"
"encoding/json"
"testing"
"es-demo/client"
"es-demo/config"
)
// TestPutTemplate_Validation tests template validation in PutTemplate
func TestPutTemplate_Validation(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}
// 加载真实配置用于集成测试
if err := config.Load(".env"); err != nil {
t.Logf("warning: failed to load .env file: %v", err)
}
config.Init()
cfg := &client.Config{
Endpoint: config.Endpoint,
Region: config.Region,
AccessKey: config.AccessKey,
SecretKey: config.SecretKey,
}
c, err := client.NewClient(cfg)
if err != nil {
t.Fatalf("failed to create client: %v", err)
}
ctx := context.Background()
tests := []struct {
name string
tmplName string
template *Template
wantErr bool
}{
{
name: "empty template name",
tmplName: "",
template: &Template{
IndexPatterns: []string{"test-*"},
},
wantErr: true,
},
{
name: "nil template",
tmplName: "test",
template: nil,
wantErr: true,
},
{
name: "empty index patterns",
tmplName: "test",
template: &Template{
IndexPatterns: []string{},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := PutTemplate(ctx, c, tt.tmplName, tt.template)
if (err != nil) != tt.wantErr {
t.Errorf("PutTemplate() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
// TestGetTemplate_NotFound tests GetTemplate when template doesn't exist
func TestGetTemplate_NotFound(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}
if err := config.Load(".env"); err != nil {
t.Logf("warning: failed to load .env file: %v", err)
}
config.Init()
cfg := &client.Config{
Endpoint: config.Endpoint,
Region: config.Region,
AccessKey: config.AccessKey,
SecretKey: config.SecretKey,
}
c, err := client.NewClient(cfg)
if err != nil {
t.Fatalf("failed to create client: %v", err)
}
ctx := context.Background()
// 尝试获取不存在的模板
_, err = GetTemplate(ctx, c, "non-existent-template-12345")
if err == nil {
t.Error("GetTemplate() should return error for non-existent template")
}
}
// TestDeleteTemplate_NotFound tests DeleteTemplate when template doesn't exist
func TestDeleteTemplate_NotFound(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}
if err := config.Load(".env"); err != nil {
t.Logf("warning: failed to load .env file: %v", err)
}
config.Init()
cfg := &client.Config{
Endpoint: config.Endpoint,
Region: config.Region,
AccessKey: config.AccessKey,
SecretKey: config.SecretKey,
}
c, err := client.NewClient(cfg)
if err != nil {
t.Fatalf("failed to create client: %v", err)
}
ctx := context.Background()
// 尝试删除不存在的模板
err = DeleteTemplate(ctx, c, "non-existent-template-12345")
if err == nil {
t.Error("DeleteTemplate() should return error for non-existent template")
}
}
// TestValidateTemplate_EdgeCases tests edge cases in template validation
func TestValidateTemplate_EdgeCases(t *testing.T) {
tests := []struct {
name string
template *Template
wantErr bool
}{
{
name: "nil template",
template: nil,
wantErr: true,
},
{
name: "empty index patterns",
template: &Template{
IndexPatterns: []string{},
},
wantErr: true,
},
{
name: "nil index patterns",
template: &Template{
IndexPatterns: nil,
},
wantErr: true,
},
{
name: "valid minimal template",
template: &Template{
IndexPatterns: []string{"test-*"},
},
wantErr: false,
},
{
name: "valid template with settings",
template: &Template{
IndexPatterns: []string{"logs-*", "metrics-*"},
Settings: map[string]any{
"number_of_shards": 2,
},
},
wantErr: false,
},
{
name: "valid template with all fields",
template: &Template{
IndexPatterns: []string{"app-*"},
Settings: map[string]any{
"number_of_shards": 1,
},
Mappings: map[string]any{
"properties": map[string]any{
"timestamp": map[string]any{
"type": "date",
},
},
},
Aliases: map[string]any{
"my-alias": map[string]any{},
},
Priority: 100,
Version: 1,
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateTemplate(tt.template)
if (err != nil) != tt.wantErr {
t.Errorf("validateTemplate() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
// TestListTemplates_EmptyResponse tests ListTemplates with no templates
func TestListTemplates_EmptyResponse(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}
if err := config.Load(".env"); err != nil {
t.Logf("warning: failed to load .env file: %v", err)
}
config.Init()
cfg := &client.Config{
Endpoint: config.Endpoint,
Region: config.Region,
AccessKey: config.AccessKey,
SecretKey: config.SecretKey,
}
c, err := client.NewClient(cfg)
if err != nil {
t.Fatalf("failed to create client: %v", err)
}
ctx := context.Background()
// ListTemplates 应该始终返回至少一个空的 map
templates, err := ListTemplates(ctx, c)
if err != nil {
t.Fatalf("ListTemplates() error = %v", err)
}
if templates == nil {
t.Error("ListTemplates() should not return nil map")
}
}
// TestTemplate_JSONMarshaling tests template JSON marshaling
func TestTemplate_JSONMarshaling(t *testing.T) {
template := &Template{
IndexPatterns: []string{"test-*"},
Settings: map[string]any{
"number_of_shards": 1,
},
Mappings: map[string]any{
"properties": map[string]any{
"field1": map[string]any{
"type": "text",
},
},
},
Priority: 100,
}
// Marshal
data, err := json.Marshal(template)
if err != nil {
t.Fatalf("json.Marshal() error = %v", err)
}
// Unmarshal
var decoded Template
if err := json.Unmarshal(data, &decoded); err != nil {
t.Fatalf("json.Unmarshal() error = %v", err)
}
// Verify
if len(decoded.IndexPatterns) != len(template.IndexPatterns) {
t.Errorf("IndexPatterns length = %d, want %d", len(decoded.IndexPatterns), len(template.IndexPatterns))
}
if decoded.Priority != template.Priority {
t.Errorf("Priority = %d, want %d", decoded.Priority, template.Priority)
}
}