Files
temporal/chasm/search_attribute_test.go
Rodrigo Zhou 3023d860eb CHASM Visibility support for Text type search attribute (#10347)
## What changed?
CHASM Visibility support for Text type search attribute

## Why?
Full support for all search attributes types.

## How did you test it?
- [x] built
- [ ] run locally and tested manually
- [ ] covered by existing tests
- [x] added new unit test(s)
- [ ] added new functional test(s)

## Potential risks
2026-06-11 16:38:04 -07:00

189 lines
6.2 KiB
Go

package chasm
import (
"testing"
"time"
"github.com/stretchr/testify/require"
commonpb "go.temporal.io/api/common/v1"
enumspb "go.temporal.io/api/enums/v1"
"go.temporal.io/server/common/searchattribute/sadefs"
)
var textField01 = newSearchAttributeFieldText(1)
func TestSearchAttributesMap_Get(t *testing.T) {
// Define test search attributes
boolAttr := NewSearchAttributeBool("completed", SearchAttributeFieldBool01)
intAttr := NewSearchAttributeInt("count", SearchAttributeFieldInt01)
doubleAttr := NewSearchAttributeDouble("score", SearchAttributeFieldDouble01)
keywordAttr := NewSearchAttributeKeyword("status", SearchAttributeFieldKeyword01)
datetimeAttr := NewSearchAttributeDateTime("timestamp", SearchAttributeFieldDateTime01)
keywordListAttr := NewSearchAttributeKeywordList("tags", SearchAttributeFieldKeywordList01)
textAttr := NewSearchAttributeText("summary", textField01)
now := time.Now()
// Create map with test values
values := map[string]VisibilityValue{
"completed": VisibilityValueBool(true),
"count": VisibilityValueInt64(42),
"score": VisibilityValueFloat64(3.14),
"status": VisibilityValueKeyword("active"),
"timestamp": VisibilityValueTime(now),
"tags": VisibilityValueStringSlice([]string{"tag1", "tag2"}),
"summary": VisibilityValueText("foo bar"),
}
m := NewSearchAttributesMap(values)
t.Run("GetBool", func(t *testing.T) {
val, ok := SearchAttributeValue(m, boolAttr)
require.True(t, ok)
require.True(t, val)
})
t.Run("GetInt64", func(t *testing.T) {
val, ok := SearchAttributeValue(m, intAttr)
require.True(t, ok)
require.Equal(t, int64(42), val)
})
t.Run("GetFloat64", func(t *testing.T) {
val, ok := SearchAttributeValue(m, doubleAttr)
require.True(t, ok)
require.InDelta(t, 3.14, val, 0.0001)
})
t.Run("GetString", func(t *testing.T) {
val, ok := SearchAttributeValue(m, keywordAttr)
require.True(t, ok)
require.Equal(t, "active", val)
})
t.Run("GetTime", func(t *testing.T) {
val, ok := SearchAttributeValue(m, datetimeAttr)
require.True(t, ok)
require.True(t, now.Equal(val))
})
t.Run("GetStringSlice", func(t *testing.T) {
val, ok := SearchAttributeValue(m, keywordListAttr)
require.True(t, ok)
require.Equal(t, []string{"tag1", "tag2"}, val)
})
t.Run("GetText", func(t *testing.T) {
val, ok := SearchAttributeValue(m, textAttr)
require.True(t, ok)
require.Equal(t, "foo bar", val)
})
t.Run("NotFound", func(t *testing.T) {
missingAttr := NewSearchAttributeBool("missing", SearchAttributeFieldBool02)
val, ok := SearchAttributeValue(m, missingAttr)
require.False(t, ok)
require.False(t, val)
})
t.Run("NilMap", func(t *testing.T) {
emptyMap := NewSearchAttributesMap(nil)
val, ok := SearchAttributeValue(emptyMap, boolAttr)
require.False(t, ok)
require.False(t, val)
})
}
func TestNewSearchAttributesMapFromProto(t *testing.T) {
t.Run("NilSearchAttributes", func(t *testing.T) {
m, err := newSearchAttributesMapFromProto(nil)
require.NoError(t, err)
require.Empty(t, m.values)
})
t.Run("EmptyIndexedFields", func(t *testing.T) {
m, err := newSearchAttributesMapFromProto(&commonpb.SearchAttributes{
IndexedFields: map[string]*commonpb.Payload{},
})
require.NoError(t, err)
require.Empty(t, m.values)
})
t.Run("SingleBoolValue", func(t *testing.T) {
sa := &commonpb.SearchAttributes{
IndexedFields: map[string]*commonpb.Payload{
"completed": sadefs.MustEncodeValue(true, enumspb.INDEXED_VALUE_TYPE_BOOL),
},
}
m, err := newSearchAttributesMapFromProto(sa)
require.NoError(t, err)
boolAttr := NewSearchAttributeBool("completed", SearchAttributeFieldBool01)
val, ok := SearchAttributeValue(m, boolAttr)
require.True(t, ok)
require.True(t, val)
})
t.Run("MultipleValueTypes", func(t *testing.T) {
now := time.Now().UTC().Truncate(time.Millisecond)
sa := &commonpb.SearchAttributes{
IndexedFields: map[string]*commonpb.Payload{
"completed": sadefs.MustEncodeValue(true, enumspb.INDEXED_VALUE_TYPE_BOOL),
"count": sadefs.MustEncodeValue(int64(42), enumspb.INDEXED_VALUE_TYPE_INT),
"score": sadefs.MustEncodeValue(3.14, enumspb.INDEXED_VALUE_TYPE_DOUBLE),
"status": sadefs.MustEncodeValue("active", enumspb.INDEXED_VALUE_TYPE_KEYWORD),
"timestamp": sadefs.MustEncodeValue(now, enumspb.INDEXED_VALUE_TYPE_DATETIME),
"tags": sadefs.MustEncodeValue([]string{"tag1", "tag2"}, enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST),
"summary": sadefs.MustEncodeValue("foo bar", enumspb.INDEXED_VALUE_TYPE_TEXT),
},
}
m, err := newSearchAttributesMapFromProto(sa)
require.NoError(t, err)
boolAttr := NewSearchAttributeBool("completed", SearchAttributeFieldBool01)
boolVal, ok := SearchAttributeValue(m, boolAttr)
require.True(t, ok)
require.True(t, boolVal)
intAttr := NewSearchAttributeInt("count", SearchAttributeFieldInt01)
intVal, ok := SearchAttributeValue(m, intAttr)
require.True(t, ok)
require.Equal(t, int64(42), intVal)
doubleAttr := NewSearchAttributeDouble("score", SearchAttributeFieldDouble01)
doubleVal, ok := SearchAttributeValue(m, doubleAttr)
require.True(t, ok)
require.InDelta(t, 3.14, doubleVal, 0.0001)
keywordAttr := NewSearchAttributeKeyword("status", SearchAttributeFieldKeyword01)
keywordVal, ok := SearchAttributeValue(m, keywordAttr)
require.True(t, ok)
require.Equal(t, "active", keywordVal)
datetimeAttr := NewSearchAttributeDateTime("timestamp", SearchAttributeFieldDateTime01)
timeVal, ok := SearchAttributeValue(m, datetimeAttr)
require.True(t, ok)
require.True(t, now.Equal(timeVal))
keywordListAttr := NewSearchAttributeKeywordList("tags", SearchAttributeFieldKeywordList01)
listVal, ok := SearchAttributeValue(m, keywordListAttr)
require.True(t, ok)
require.Equal(t, []string{"tag1", "tag2"}, listVal)
textAttr := NewSearchAttributeText("summary", textField01)
textVal, ok := SearchAttributeValue(m, textAttr)
require.True(t, ok)
require.Equal(t, "foo bar", textVal)
})
t.Run("InvalidPayload", func(t *testing.T) {
sa := &commonpb.SearchAttributes{
IndexedFields: map[string]*commonpb.Payload{
"bad": {Data: []byte("not valid")},
},
}
_, err := newSearchAttributesMapFromProto(sa)
require.Error(t, err)
})
}