mirror of
https://github.com/hanzoai/tasks.git
synced 2026-10-04 02:04:03 +00:00
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.
418 lines
13 KiB
Go
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")
|
|
}
|
|
}
|