Files
tasks/tests/links_test.go
zeekay 5a601d081b rebrand: go.temporal.io/server -> github.com/hanzoai/tasks
Full module path rebrand from Temporal to Hanzo Tasks:
- go.mod module: github.com/hanzoai/tasks
- All internal Go imports updated (1906 files)
- cmd/server renamed to cmd/tasksd
- Binary name: tasksd (was temporal-server)
- Docker images: hanzoai/tasks (was temporalio/server)
- README rewritten with Hanzo Tasks branding
- LLM.md created with integration notes
- Makefile, goreleaser, CI workflows updated
- go.temporal.io/sdk and go.temporal.io/api imports preserved (separate repos)

Fork of Temporal.io (MIT license).
2026-03-19 10:36:40 -07:00

197 lines
5.6 KiB
Go

package tests
import (
"context"
"testing"
"time"
"github.com/google/uuid"
"github.com/stretchr/testify/suite"
commonpb "go.temporal.io/api/common/v1"
enumspb "go.temporal.io/api/enums/v1"
taskqueuepb "go.temporal.io/api/taskqueue/v1"
"go.temporal.io/api/workflowservice/v1"
"go.temporal.io/sdk/client"
"github.com/hanzoai/tasks/common/testing/protorequire"
"github.com/hanzoai/tasks/tests/testcore"
)
type LinksSuite struct {
testcore.FunctionalTestBase
}
func TestLinksTestSuite(t *testing.T) {
suite.Run(t, new(LinksSuite))
}
var links = []*commonpb.Link{
{
Variant: &commonpb.Link_WorkflowEvent_{
WorkflowEvent: &commonpb.Link_WorkflowEvent{
Namespace: "dont-care",
WorkflowId: "whatever",
RunId: uuid.NewString(),
},
},
},
}
func (s *LinksSuite) TestTerminateWorkflow_LinksAttachedToEvent() {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
run, err := s.SdkClient().ExecuteWorkflow(
ctx,
client.StartWorkflowOptions{
TaskQueue: "dont-care",
},
"test-workflow-type",
)
s.NoError(err)
// TODO(bergundy): Use SdkClient if and when it exposes links on TerminateWorkflow.
_, err = s.FrontendClient().TerminateWorkflowExecution(ctx, &workflowservice.TerminateWorkflowExecutionRequest{
Namespace: s.Namespace().String(),
WorkflowExecution: &commonpb.WorkflowExecution{
WorkflowId: run.GetID(),
},
Reason: "test",
Links: links,
})
s.NoError(err)
history := s.SdkClient().GetWorkflowHistory(ctx, run.GetID(), "", false, enumspb.HISTORY_EVENT_FILTER_TYPE_CLOSE_EVENT)
event, err := history.Next()
s.NoError(err)
protorequire.ProtoSliceEqual(s.T(), links, event.Links)
}
func (s *LinksSuite) TestRequestCancelWorkflow_LinksAttachedToEvent() {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
run, err := s.SdkClient().ExecuteWorkflow(
ctx,
client.StartWorkflowOptions{
TaskQueue: "dont-care",
},
"test-workflow-type",
)
s.NoError(err)
// TODO(bergundy): Use SdkClient if and when it exposes links on CancelWorkflow.
_, err = s.FrontendClient().RequestCancelWorkflowExecution(ctx, &workflowservice.RequestCancelWorkflowExecutionRequest{
Namespace: s.Namespace().String(),
WorkflowExecution: &commonpb.WorkflowExecution{
WorkflowId: run.GetID(),
},
Reason: "test",
Links: links,
})
s.NoError(err)
history := s.SdkClient().GetWorkflowHistory(ctx, run.GetID(), "", false, enumspb.HISTORY_EVENT_FILTER_TYPE_ALL_EVENT)
foundEvent := false
for history.HasNext() {
event, err := history.Next()
s.NoError(err)
if event.EventType != enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_CANCEL_REQUESTED {
continue
}
foundEvent = true
protorequire.ProtoSliceEqual(s.T(), links, event.Links)
}
s.True(foundEvent)
}
func (s *LinksSuite) TestSignalWorkflowExecution_LinksAttachedToEvent() {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
run, err := s.SdkClient().ExecuteWorkflow(
ctx,
client.StartWorkflowOptions{
TaskQueue: "dont-care",
},
"test-workflow-type",
)
s.NoError(err)
// TODO(bergundy): Use SdkClient if and when it exposes links on SignalWorkflow.
_, err = s.FrontendClient().SignalWorkflowExecution(ctx, &workflowservice.SignalWorkflowExecutionRequest{
Namespace: s.Namespace().String(),
WorkflowExecution: &commonpb.WorkflowExecution{
WorkflowId: run.GetID(),
},
SignalName: "dont-care",
Identity: "test",
RequestId: uuid.NewString(),
Links: links,
})
s.NoError(err)
history := s.SdkClient().GetWorkflowHistory(ctx, run.GetID(), "", false, enumspb.HISTORY_EVENT_FILTER_TYPE_ALL_EVENT)
foundEvent := false
for history.HasNext() {
event, err := history.Next()
s.NoError(err)
if event.EventType != enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED {
continue
}
foundEvent = true
protorequire.ProtoSliceEqual(s.T(), links, event.Links)
}
s.True(foundEvent)
}
func (s *LinksSuite) TestSignalWithStartWorkflowExecution_LinksAttachedToRelevantEvents() {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
workflowID := testcore.RandomizeStr(s.T().Name())
// TODO(bergundy): Use SdkClient if and when it exposes links on SignalWithStartWorkflow.
request := &workflowservice.SignalWithStartWorkflowExecutionRequest{
Namespace: s.Namespace().String(),
WorkflowId: workflowID,
WorkflowType: &commonpb.WorkflowType{
Name: "dont-care",
},
SignalName: "dont-care",
Identity: "test",
TaskQueue: &taskqueuepb.TaskQueue{
Name: "dont-care",
},
RequestId: uuid.NewString(),
Links: links,
}
_, err := s.FrontendClient().SignalWithStartWorkflowExecution(ctx, request)
s.NoError(err)
// Send a second request and verify that the new signal has links attached to it too.
request.RequestId = uuid.NewString()
_, err = s.FrontendClient().SignalWithStartWorkflowExecution(ctx, request)
s.NoError(err)
history := s.SdkClient().GetWorkflowHistory(ctx, workflowID, "", false, enumspb.HISTORY_EVENT_FILTER_TYPE_ALL_EVENT)
foundStartEvent := false
foundFirstSignal := false
foundSecondSignal := false
for history.HasNext() {
event, err := history.Next()
s.NoError(err)
if event.EventType == enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED {
if foundFirstSignal {
foundSecondSignal = true
} else {
foundFirstSignal = true
}
protorequire.ProtoSliceEqual(s.T(), links, event.Links)
}
if event.EventType == enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_STARTED {
foundStartEvent = true
protorequire.ProtoSliceEqual(s.T(), links, event.Links)
}
}
s.True(foundStartEvent)
s.True(foundFirstSignal)
s.True(foundSecondSignal)
}