Files
tasks/common/namespace/replication_resolver_test.go
zeekay 40351cce6f rip: delete temporal fork — native ZAP-only tasksd
Goes from 135 MB binary with 1153 files importing go.temporal.io and 224
importing google.golang.org/grpc to a 10 MB native binary with ZERO of
either.

Deleted:
- tasks/, tasktests/, service/, chasm/, client/, api/, proto/, tools/
- cmd/tools/, components/, docker/
- schema/{cassandra,elasticsearch,mysql,postgresql,sqlite}/
- 40 tainted common/ subdirs + 7 top-level common files
- tests/testutils (no longer referenced after surviving deps drop common)

New cmd/tasksd (~100 lines) boots tasks.Embed (zap.Node) + http.Server.
New pkg/tasks/embed.go registers ZAP handlers for the SDK opcode surface
(0x0060-0x00A5). Workflow handlers return a 501 "not yet implemented"
envelope; native engine lands behind this contract.

Build:  go build ./cmd/tasksd → 10 MB
Vet:    go vet ./... → clean
Boot:   tasksd --zap-port 9999 --http :7243
Probes: /healthz, /v1/tasks/health → 200
UI:     /_/tasks/, / → 200 (embedded Vite bundle)
ZAP:    _tasks._tcp on :9999 (mDNS disabled; direct connect)

go.mod: tidy. No go.temporal.io. No google.golang.org/grpc.
2026-04-26 14:06:21 -07:00

418 lines
13 KiB
Go

package namespace_test
import (
"testing"
"github.com/stretchr/testify/require"
enumspb "go.temporal.io/api/enums/v1"
persistencespb "go.temporal.io/server/api/persistence/v1"
"go.temporal.io/server/common/namespace"
)
func TestNewDefaultReplicationResolverFactory(t *testing.T) {
factory := namespace.NewDefaultReplicationResolverFactory()
require.NotNil(t, factory)
detail := &persistencespb.NamespaceDetail{
ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "active-cluster",
Clusters: []string{"cluster1", "cluster2", "cluster3"},
State: enumspb.REPLICATION_STATE_NORMAL,
},
}
resolver := factory(detail)
require.NotNil(t, resolver)
require.Equal(t, "active-cluster", resolver.ActiveClusterName(namespace.RoutingKey{}))
require.Equal(t, []string{"cluster1", "cluster2", "cluster3"}, resolver.ClusterNames(namespace.EmptyBusinessID))
require.Equal(t, enumspb.REPLICATION_STATE_NORMAL, resolver.ReplicationState(namespace.EmptyBusinessID))
}
func TestDefaultReplicationResolver_ActiveClusterName(t *testing.T) {
tests := []struct {
name string
replicationConfig *persistencespb.NamespaceReplicationConfig
want string
}{
{
name: "returns active cluster name",
replicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-a", "cluster-b"},
},
want: "cluster-a",
},
{
name: "returns active cluster name for cluster-b",
replicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-b",
Clusters: []string{"cluster-a", "cluster-b"},
},
want: "cluster-b",
},
{
name: "returns empty string when replication config is nil",
replicationConfig: nil,
want: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
factory := namespace.NewDefaultReplicationResolverFactory()
detail := &persistencespb.NamespaceDetail{
ReplicationConfig: tt.replicationConfig,
}
resolver := factory(detail)
got := resolver.ActiveClusterName(namespace.RoutingKey{})
require.Equal(t, tt.want, got)
})
}
}
func TestDefaultReplicationResolver_ClusterNames(t *testing.T) {
tests := []struct {
name string
replicationConfig *persistencespb.NamespaceReplicationConfig
want []string
}{
{
name: "returns cluster names",
replicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-a", "cluster-b", "cluster-c"},
},
want: []string{"cluster-a", "cluster-b", "cluster-c"},
},
{
name: "returns cluster names for multiple clusters",
replicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-1", "cluster-2"},
},
want: []string{"cluster-1", "cluster-2"},
},
{
name: "returns nil when replication config is nil",
replicationConfig: nil,
want: nil,
},
{
name: "returns empty slice when clusters is empty",
replicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{},
},
want: []string{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
factory := namespace.NewDefaultReplicationResolverFactory()
detail := &persistencespb.NamespaceDetail{
ReplicationConfig: tt.replicationConfig,
}
resolver := factory(detail)
got := resolver.ClusterNames(namespace.EmptyBusinessID)
require.Equal(t, tt.want, got)
// Verify immutability - modifying returned slice shouldn't affect subsequent calls
if len(got) > 0 {
got[0] = "modified"
got2 := resolver.ClusterNames(namespace.EmptyBusinessID)
if len(tt.want) > 0 {
require.Equal(t, tt.want[0], got2[0], "ClusterNames should return a copy to preserve immutability")
}
}
})
}
}
func TestDefaultReplicationResolver_ReplicationState(t *testing.T) {
tests := []struct {
name string
replicationConfig *persistencespb.NamespaceReplicationConfig
want enumspb.ReplicationState
}{
{
name: "returns normal state",
replicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-a", "cluster-b"},
State: enumspb.REPLICATION_STATE_NORMAL,
},
want: enumspb.REPLICATION_STATE_NORMAL,
},
{
name: "returns handover state",
replicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-a", "cluster-b"},
State: enumspb.REPLICATION_STATE_HANDOVER,
},
want: enumspb.REPLICATION_STATE_HANDOVER,
},
{
name: "returns unspecified when replication config is nil",
replicationConfig: nil,
want: enumspb.REPLICATION_STATE_UNSPECIFIED,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
factory := namespace.NewDefaultReplicationResolverFactory()
detail := &persistencespb.NamespaceDetail{
ReplicationConfig: tt.replicationConfig,
}
resolver := factory(detail)
got := resolver.ReplicationState(namespace.EmptyBusinessID)
require.Equal(t, tt.want, got)
})
}
}
func TestDefaultReplicationResolver_MultipleCalls(t *testing.T) {
// Test that resolver state is consistent across multiple calls
factory := namespace.NewDefaultReplicationResolverFactory()
detail := &persistencespb.NamespaceDetail{
ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "primary",
Clusters: []string{"primary", "secondary", "tertiary"},
State: enumspb.REPLICATION_STATE_NORMAL,
},
}
resolver := factory(detail)
// Call multiple times and verify consistency
for range 5 {
require.Equal(t, "primary", resolver.ActiveClusterName(namespace.RoutingKey{}))
require.Equal(t, []string{"primary", "secondary", "tertiary"}, resolver.ClusterNames(namespace.EmptyBusinessID))
require.Equal(t, enumspb.REPLICATION_STATE_NORMAL, resolver.ReplicationState(namespace.EmptyBusinessID))
}
}
func TestDefaultReplicationResolver_IsGlobalNamespace(t *testing.T) {
factory := namespace.NewDefaultReplicationResolverFactory()
tests := []struct {
name string
detail *persistencespb.NamespaceDetail
setGlobal bool
want bool
}{
{
name: "global namespace",
detail: &persistencespb.NamespaceDetail{
ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-a", "cluster-b"},
},
},
setGlobal: true,
want: true,
},
{
name: "local namespace",
detail: &persistencespb.NamespaceDetail{
ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-a"},
},
},
setGlobal: false,
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create resolver directly
resolver := factory(tt.detail)
// The isGlobalNamespace is false by default in the factory
// This tests the default behavior - to test mutations, we'd need to test through Namespace
// For this test, we verify it returns false by default (as set in factory)
require.False(t, resolver.IsGlobalNamespace())
})
}
}
func TestDefaultReplicationResolver_FailoverVersion(t *testing.T) {
factory := namespace.NewDefaultReplicationResolverFactory()
tests := []struct {
name string
failoverVersion int64
want int64
}{
{
name: "positive version",
failoverVersion: 12345,
want: 12345,
},
{
name: "zero version",
failoverVersion: 0,
want: 0,
},
{
name: "negative version",
failoverVersion: -1,
want: -1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
detail := &persistencespb.NamespaceDetail{
FailoverVersion: tt.failoverVersion,
}
resolver := factory(detail)
require.Equal(t, tt.want, resolver.FailoverVersion(namespace.EmptyBusinessID))
})
}
}
func TestDefaultReplicationResolver_FailoverNotificationVersion(t *testing.T) {
factory := namespace.NewDefaultReplicationResolverFactory()
tests := []struct {
name string
failoverNotificationVersion int64
want int64
}{
{
name: "positive version",
failoverNotificationVersion: 54321,
want: 54321,
},
{
name: "zero version",
failoverNotificationVersion: 0,
want: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
detail := &persistencespb.NamespaceDetail{
FailoverNotificationVersion: tt.failoverNotificationVersion,
}
resolver := factory(detail)
require.Equal(t, tt.want, resolver.FailoverNotificationVersion())
})
}
}
func TestDefaultReplicationResolver_ActiveInCluster(t *testing.T) {
factory := namespace.NewDefaultReplicationResolverFactory()
tests := []struct {
name string
detail *persistencespb.NamespaceDetail
clusterName string
want bool
}{
{
name: "local namespace returns true for any cluster",
detail: &persistencespb.NamespaceDetail{
ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-a"},
},
FailoverVersion: 0, // local namespace
},
clusterName: "cluster-b",
want: true,
},
{
name: "local namespace returns true for active cluster",
detail: &persistencespb.NamespaceDetail{
ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-a"},
},
FailoverVersion: 0, // local namespace
},
clusterName: "cluster-a",
want: true,
},
{
name: "global namespace returns true for active cluster",
detail: &persistencespb.NamespaceDetail{
ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-a", "cluster-b"},
},
FailoverVersion: 1, // global namespace
},
clusterName: "cluster-a",
want: true,
},
{
name: "global namespace returns false for non-active cluster",
detail: &persistencespb.NamespaceDetail{
ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-a",
Clusters: []string{"cluster-a", "cluster-b"},
},
FailoverVersion: 1, // global namespace
},
clusterName: "cluster-b",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resolver := factory(tt.detail)
got := resolver.ActiveInCluster(tt.clusterName)
require.Equal(t, tt.want, got)
})
}
}
func TestDefaultReplicationResolver_Clone(t *testing.T) {
factory := namespace.NewDefaultReplicationResolverFactory()
originalConfig := &persistencespb.NamespaceReplicationConfig{
ActiveClusterName: "cluster-primary",
Clusters: []string{"cluster-primary", "cluster-secondary"},
State: enumspb.REPLICATION_STATE_NORMAL,
}
detail := &persistencespb.NamespaceDetail{
ReplicationConfig: originalConfig,
FailoverVersion: 123,
FailoverNotificationVersion: 456,
}
resolver := factory(detail)
// Clone the resolver
cloned := resolver.Clone()
// Verify the cloned resolver has the same values
require.Equal(t, resolver.ActiveClusterName(namespace.RoutingKey{}), cloned.ActiveClusterName(namespace.RoutingKey{}))
require.Equal(t, resolver.ClusterNames(namespace.EmptyBusinessID), cloned.ClusterNames(namespace.EmptyBusinessID))
require.Equal(t, resolver.IsGlobalNamespace(), cloned.IsGlobalNamespace())
require.Equal(t, resolver.FailoverVersion(namespace.EmptyBusinessID), cloned.FailoverVersion(namespace.EmptyBusinessID))
require.Equal(t, resolver.FailoverNotificationVersion(), cloned.FailoverNotificationVersion())
require.Equal(t, resolver.ReplicationState(namespace.EmptyBusinessID), cloned.ReplicationState(namespace.EmptyBusinessID))
// Verify that modifying the cloned resolver doesn't affect the original
cloned.SetActiveCluster("cluster-tertiary")
require.Equal(t, "cluster-primary", resolver.ActiveClusterName(namespace.RoutingKey{}))
require.Equal(t, "cluster-tertiary", cloned.ActiveClusterName(namespace.RoutingKey{}))
// Verify deep copy of clusters slice
clonedClusters := cloned.ClusterNames(namespace.EmptyBusinessID)
if len(clonedClusters) > 0 {
clonedClusters[0] = "modified"
require.Equal(t, "cluster-primary", cloned.ClusterNames(namespace.EmptyBusinessID)[0], "Modifying returned slice should not affect resolver")
}
}