diff --git a/config/dynamicconfig/development-sql.yaml b/config/dynamicconfig/development-sql.yaml index 85a3c355591..3fec3a08d9e 100644 --- a/config/dynamicconfig/development-sql.yaml +++ b/config/dynamicconfig/development-sql.yaml @@ -43,7 +43,7 @@ ### END of Worker Versioning Replay Test configs limit.maxIDLength: - - value: 255 + - value: 1000 constraints: {} frontend.workerVersioningDataAPIs: - value: true diff --git a/schema/mysql/v8/temporal/schema.sql b/schema/mysql/v8/temporal/schema.sql index 56448ce0e90..0085293efd3 100644 --- a/schema/mysql/v8/temporal/schema.sql +++ b/schema/mysql/v8/temporal/schema.sql @@ -30,7 +30,7 @@ CREATE TABLE shards ( CREATE TABLE executions( shard_id INT NOT NULL, namespace_id BINARY(16) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, run_id BINARY(16) NOT NULL, -- next_event_id BIGINT NOT NULL, @@ -46,7 +46,7 @@ CREATE TABLE executions( CREATE TABLE current_executions( shard_id INT NOT NULL, namespace_id BINARY(16) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, -- run_id BINARY(16) NOT NULL, create_request_id VARCHAR(255) NOT NULL, @@ -83,7 +83,7 @@ CREATE TABLE current_chasm_executions( CREATE TABLE buffered_events ( shard_id INT NOT NULL, namespace_id BINARY(16) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, run_id BINARY(16) NOT NULL, id BIGINT AUTO_INCREMENT NOT NULL UNIQUE, -- @@ -227,7 +227,7 @@ CREATE TABLE activity_info_maps ( -- each row corresponds to one key of one map shard_id INT NOT NULL, namespace_id BINARY(16) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, run_id BINARY(16) NOT NULL, schedule_id BIGINT NOT NULL, -- @@ -239,7 +239,7 @@ CREATE TABLE activity_info_maps ( CREATE TABLE timer_info_maps ( shard_id INT NOT NULL, namespace_id BINARY(16) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, run_id BINARY(16) NOT NULL, timer_id VARCHAR(255) NOT NULL, -- @@ -251,7 +251,7 @@ CREATE TABLE timer_info_maps ( CREATE TABLE child_execution_info_maps ( shard_id INT NOT NULL, namespace_id BINARY(16) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, run_id BINARY(16) NOT NULL, initiated_id BIGINT NOT NULL, -- @@ -263,7 +263,7 @@ CREATE TABLE child_execution_info_maps ( CREATE TABLE request_cancel_info_maps ( shard_id INT NOT NULL, namespace_id BINARY(16) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, run_id BINARY(16) NOT NULL, initiated_id BIGINT NOT NULL, -- @@ -275,7 +275,7 @@ CREATE TABLE request_cancel_info_maps ( CREATE TABLE signal_info_maps ( shard_id INT NOT NULL, namespace_id BINARY(16) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, run_id BINARY(16) NOT NULL, initiated_id BIGINT NOT NULL, -- @@ -287,7 +287,7 @@ CREATE TABLE signal_info_maps ( CREATE TABLE signals_requested_sets ( shard_id INT NOT NULL, namespace_id BINARY(16) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, run_id BINARY(16) NOT NULL, signal_id VARCHAR(255) NOT NULL, -- @@ -297,7 +297,7 @@ CREATE TABLE signals_requested_sets ( CREATE TABLE chasm_node_maps ( shard_id INT NOT NULL, namespace_id BINARY(16) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, run_id BINARY(16) NOT NULL, chasm_path VARBINARY(1536) NOT NULL, -- diff --git a/schema/mysql/v8/temporal/versioned/v1.20/alter_workflow_id_columns.sql b/schema/mysql/v8/temporal/versioned/v1.20/alter_workflow_id_columns.sql new file mode 100644 index 00000000000..213a6a5f289 --- /dev/null +++ b/schema/mysql/v8/temporal/versioned/v1.20/alter_workflow_id_columns.sql @@ -0,0 +1,10 @@ +ALTER TABLE executions MODIFY workflow_id VARBINARY(1000) NOT NULL; +ALTER TABLE current_executions MODIFY workflow_id VARBINARY(1000) NOT NULL; +ALTER TABLE buffered_events MODIFY workflow_id VARBINARY(1000) NOT NULL; +ALTER TABLE activity_info_maps MODIFY workflow_id VARBINARY(1000) NOT NULL; +ALTER TABLE timer_info_maps MODIFY workflow_id VARBINARY(1000) NOT NULL; +ALTER TABLE child_execution_info_maps MODIFY workflow_id VARBINARY(1000) NOT NULL; +ALTER TABLE request_cancel_info_maps MODIFY workflow_id VARBINARY(1000) NOT NULL; +ALTER TABLE signal_info_maps MODIFY workflow_id VARBINARY(1000) NOT NULL; +ALTER TABLE signals_requested_sets MODIFY workflow_id VARBINARY(1000) NOT NULL; +ALTER TABLE chasm_node_maps MODIFY workflow_id VARBINARY(1000) NOT NULL; diff --git a/schema/mysql/v8/temporal/versioned/v1.20/manifest.json b/schema/mysql/v8/temporal/versioned/v1.20/manifest.json new file mode 100644 index 00000000000..ef8c2e2a059 --- /dev/null +++ b/schema/mysql/v8/temporal/versioned/v1.20/manifest.json @@ -0,0 +1,8 @@ +{ + "CurrVersion": "1.20", + "MinCompatibleVersion": "1.0", + "Description": "Increase workflow ID columns to 1000 bytes", + "SchemaUpdateCqlFiles": [ + "alter_workflow_id_columns.sql" + ] +} diff --git a/schema/mysql/v8/version.go b/schema/mysql/v8/version.go index a7cfc51791f..36add9c5252 100644 --- a/schema/mysql/v8/version.go +++ b/schema/mysql/v8/version.go @@ -3,7 +3,7 @@ package v8 // NOTE: whenever there is a new database schema update, plz update the following versions // Version is the MySQL database release version -const Version = "1.19" +const Version = "1.20" // VisibilityVersion is the MySQL visibility database release version -const VisibilityVersion = "1.14" +const VisibilityVersion = "1.15" diff --git a/schema/mysql/v8/visibility/schema.sql b/schema/mysql/v8/visibility/schema.sql index 68eedf53957..78dd6b1165b 100644 --- a/schema/mysql/v8/visibility/schema.sql +++ b/schema/mysql/v8/visibility/schema.sql @@ -4,7 +4,7 @@ CREATE TABLE executions_visibility ( _version BIGINT NOT NULL DEFAULT 0, -- increasing version, used to reject upserts which are out of order start_time DATETIME(6) NOT NULL, execution_time DATETIME(6) NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARBINARY(1000) NOT NULL, workflow_type_name VARCHAR(255) NOT NULL, status INT NOT NULL, -- enum WorkflowExecutionStatus {RUNNING, COMPLETED, FAILED, CANCELED, TERMINATED, CONTINUED_AS_NEW, TIMED_OUT} close_time DATETIME(6) NULL, @@ -16,9 +16,9 @@ CREATE TABLE executions_visibility ( encoding VARCHAR(64) NOT NULL, task_queue VARCHAR(255) NOT NULL DEFAULT '', search_attributes JSON NULL, - parent_workflow_id VARCHAR(255) NULL, + parent_workflow_id VARBINARY(1000) NULL, parent_run_id VARCHAR(255) NULL, - root_workflow_id VARCHAR(255) NOT NULL DEFAULT '', + root_workflow_id VARBINARY(1000) NOT NULL DEFAULT '', root_run_id VARCHAR(255) NOT NULL DEFAULT '', -- Each search attribute has its own generated column. diff --git a/schema/mysql/v8/visibility/versioned/v1.15/alter_workflow_id_columns.sql b/schema/mysql/v8/visibility/versioned/v1.15/alter_workflow_id_columns.sql new file mode 100644 index 00000000000..f6ffa491058 --- /dev/null +++ b/schema/mysql/v8/visibility/versioned/v1.15/alter_workflow_id_columns.sql @@ -0,0 +1,3 @@ +ALTER TABLE executions_visibility MODIFY workflow_id VARBINARY(1000) NOT NULL; +ALTER TABLE executions_visibility MODIFY parent_workflow_id VARBINARY(1000) NULL; +ALTER TABLE executions_visibility MODIFY root_workflow_id VARBINARY(1000) NOT NULL DEFAULT ''; diff --git a/schema/mysql/v8/visibility/versioned/v1.15/manifest.json b/schema/mysql/v8/visibility/versioned/v1.15/manifest.json new file mode 100644 index 00000000000..513cbf5396d --- /dev/null +++ b/schema/mysql/v8/visibility/versioned/v1.15/manifest.json @@ -0,0 +1,8 @@ +{ + "CurrVersion": "1.15", + "MinCompatibleVersion": "0.1", + "Description": "Increase workflow ID columns to 1000 bytes", + "SchemaUpdateCqlFiles": [ + "alter_workflow_id_columns.sql" + ] +} diff --git a/schema/postgresql/v12/temporal/schema.sql b/schema/postgresql/v12/temporal/schema.sql index b0f4874b3cd..5407334abbc 100644 --- a/schema/postgresql/v12/temporal/schema.sql +++ b/schema/postgresql/v12/temporal/schema.sql @@ -30,7 +30,7 @@ CREATE TABLE shards ( CREATE TABLE executions( shard_id INTEGER NOT NULL, namespace_id BYTEA NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, run_id BYTEA NOT NULL, -- next_event_id BIGINT NOT NULL, @@ -46,7 +46,7 @@ CREATE TABLE executions( CREATE TABLE current_executions( shard_id INTEGER NOT NULL, namespace_id BYTEA NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, -- run_id BYTEA NOT NULL, create_request_id VARCHAR(255) NOT NULL, @@ -83,7 +83,7 @@ CREATE TABLE current_chasm_executions( CREATE TABLE buffered_events ( shard_id INTEGER NOT NULL, namespace_id BYTEA NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, run_id BYTEA NOT NULL, id BIGSERIAL NOT NULL UNIQUE, -- @@ -227,7 +227,7 @@ CREATE TABLE activity_info_maps ( -- each row corresponds to one key of one map shard_id INTEGER NOT NULL, namespace_id BYTEA NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, run_id BYTEA NOT NULL, schedule_id BIGINT NOT NULL, -- @@ -239,7 +239,7 @@ CREATE TABLE activity_info_maps ( CREATE TABLE timer_info_maps ( shard_id INTEGER NOT NULL, namespace_id BYTEA NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, run_id BYTEA NOT NULL, timer_id VARCHAR(255) NOT NULL, -- @@ -251,7 +251,7 @@ CREATE TABLE timer_info_maps ( CREATE TABLE child_execution_info_maps ( shard_id INTEGER NOT NULL, namespace_id BYTEA NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, run_id BYTEA NOT NULL, initiated_id BIGINT NOT NULL, -- @@ -263,7 +263,7 @@ CREATE TABLE child_execution_info_maps ( CREATE TABLE request_cancel_info_maps ( shard_id INTEGER NOT NULL, namespace_id BYTEA NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, run_id BYTEA NOT NULL, initiated_id BIGINT NOT NULL, -- @@ -275,7 +275,7 @@ CREATE TABLE request_cancel_info_maps ( CREATE TABLE signal_info_maps ( shard_id INTEGER NOT NULL, namespace_id BYTEA NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, run_id BYTEA NOT NULL, initiated_id BIGINT NOT NULL, -- @@ -287,7 +287,7 @@ CREATE TABLE signal_info_maps ( CREATE TABLE signals_requested_sets ( shard_id INTEGER NOT NULL, namespace_id BYTEA NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, run_id BYTEA NOT NULL, signal_id VARCHAR(255) NOT NULL, -- @@ -297,7 +297,7 @@ CREATE TABLE signals_requested_sets ( CREATE TABLE chasm_node_maps ( shard_id INTEGER NOT NULL, namespace_id BYTEA NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, run_id BYTEA NOT NULL, chasm_path BYTEA NOT NULL, -- diff --git a/schema/postgresql/v12/temporal/versioned/v1.20/alter_workflow_id_columns.sql b/schema/postgresql/v12/temporal/versioned/v1.20/alter_workflow_id_columns.sql new file mode 100644 index 00000000000..c89e4a230a2 --- /dev/null +++ b/schema/postgresql/v12/temporal/versioned/v1.20/alter_workflow_id_columns.sql @@ -0,0 +1,10 @@ +ALTER TABLE executions ALTER COLUMN workflow_id TYPE VARCHAR(1000); +ALTER TABLE current_executions ALTER COLUMN workflow_id TYPE VARCHAR(1000); +ALTER TABLE buffered_events ALTER COLUMN workflow_id TYPE VARCHAR(1000); +ALTER TABLE activity_info_maps ALTER COLUMN workflow_id TYPE VARCHAR(1000); +ALTER TABLE timer_info_maps ALTER COLUMN workflow_id TYPE VARCHAR(1000); +ALTER TABLE child_execution_info_maps ALTER COLUMN workflow_id TYPE VARCHAR(1000); +ALTER TABLE request_cancel_info_maps ALTER COLUMN workflow_id TYPE VARCHAR(1000); +ALTER TABLE signal_info_maps ALTER COLUMN workflow_id TYPE VARCHAR(1000); +ALTER TABLE signals_requested_sets ALTER COLUMN workflow_id TYPE VARCHAR(1000); +ALTER TABLE chasm_node_maps ALTER COLUMN workflow_id TYPE VARCHAR(1000); diff --git a/schema/postgresql/v12/temporal/versioned/v1.20/manifest.json b/schema/postgresql/v12/temporal/versioned/v1.20/manifest.json new file mode 100644 index 00000000000..9c1792efb8f --- /dev/null +++ b/schema/postgresql/v12/temporal/versioned/v1.20/manifest.json @@ -0,0 +1,8 @@ +{ + "CurrVersion": "1.20", + "MinCompatibleVersion": "1.0", + "Description": "Increase workflow ID columns to 1000 characters", + "SchemaUpdateCqlFiles": [ + "alter_workflow_id_columns.sql" + ] +} diff --git a/schema/postgresql/v12/version.go b/schema/postgresql/v12/version.go index 77e0f761e09..b49c46a096f 100644 --- a/schema/postgresql/v12/version.go +++ b/schema/postgresql/v12/version.go @@ -4,8 +4,8 @@ package v12 // Version is the Postgres database release version // Temporal supports both MySQL and Postgres officially, so upgrade should be performed for both MySQL and Postgres -const Version = "1.19" +const Version = "1.20" // VisibilityVersion is the Postgres visibility database release version // Temporal supports both MySQL and Postgres officially, so upgrade should be performed for both MySQL and Postgres -const VisibilityVersion = "1.14" +const VisibilityVersion = "1.15" diff --git a/schema/postgresql/v12/visibility/schema.sql b/schema/postgresql/v12/visibility/schema.sql index 501612b857b..f885189a862 100644 --- a/schema/postgresql/v12/visibility/schema.sql +++ b/schema/postgresql/v12/visibility/schema.sql @@ -19,7 +19,7 @@ CREATE TABLE executions_visibility ( _version BIGINT NOT NULL DEFAULT 0, -- increasing version, used to reject upserts which are out of order start_time TIMESTAMP NOT NULL, execution_time TIMESTAMP NOT NULL, - workflow_id VARCHAR(255) NOT NULL, + workflow_id VARCHAR(1000) NOT NULL, workflow_type_name VARCHAR(255) NOT NULL, status INTEGER NOT NULL, -- enum WorkflowExecutionStatus {RUNNING, COMPLETED, FAILED, CANCELED, TERMINATED, CONTINUED_AS_NEW, TIMED_OUT} close_time TIMESTAMP NULL, @@ -31,9 +31,9 @@ CREATE TABLE executions_visibility ( encoding VARCHAR(64) NOT NULL, task_queue VARCHAR(255) NOT NULL DEFAULT '', search_attributes JSONB NULL, - parent_workflow_id VARCHAR(255) NULL, + parent_workflow_id VARCHAR(1000) NULL, parent_run_id VARCHAR(255) NULL, - root_workflow_id VARCHAR(255) NOT NULL DEFAULT '', + root_workflow_id VARCHAR(1000) NOT NULL DEFAULT '', root_run_id VARCHAR(255) NOT NULL DEFAULT '', -- Each search attribute has its own generated column. @@ -187,4 +187,4 @@ CREATE INDEX by_temporal_keyword_03 ON executions_visibility (na CREATE INDEX by_temporal_keyword_04 ON executions_visibility (namespace_id, TemporalKeyword04, (COALESCE(close_time, '9999-12-31 23:59:59')) DESC, start_time DESC, run_id); CREATE INDEX by_temporal_low_cardinality_keyword_01 ON executions_visibility (namespace_id, TemporalLowCardinalityKeyword01, (COALESCE(close_time, '9999-12-31 23:59:59')) DESC, start_time DESC, run_id); CREATE INDEX by_temporal_keyword_list_01 ON executions_visibility USING GIN (namespace_id, TemporalKeywordList01 jsonb_path_ops); -CREATE INDEX by_temporal_keyword_list_02 ON executions_visibility USING GIN (namespace_id, TemporalKeywordList02 jsonb_path_ops); \ No newline at end of file +CREATE INDEX by_temporal_keyword_list_02 ON executions_visibility USING GIN (namespace_id, TemporalKeywordList02 jsonb_path_ops); diff --git a/schema/postgresql/v12/visibility/versioned/v1.15/alter_workflow_id_columns.sql b/schema/postgresql/v12/visibility/versioned/v1.15/alter_workflow_id_columns.sql new file mode 100644 index 00000000000..69405423b66 --- /dev/null +++ b/schema/postgresql/v12/visibility/versioned/v1.15/alter_workflow_id_columns.sql @@ -0,0 +1,3 @@ +ALTER TABLE executions_visibility ALTER COLUMN workflow_id TYPE VARCHAR(1000); +ALTER TABLE executions_visibility ALTER COLUMN parent_workflow_id TYPE VARCHAR(1000); +ALTER TABLE executions_visibility ALTER COLUMN root_workflow_id TYPE VARCHAR(1000); diff --git a/schema/postgresql/v12/visibility/versioned/v1.15/manifest.json b/schema/postgresql/v12/visibility/versioned/v1.15/manifest.json new file mode 100644 index 00000000000..1c298511a1b --- /dev/null +++ b/schema/postgresql/v12/visibility/versioned/v1.15/manifest.json @@ -0,0 +1,8 @@ +{ + "CurrVersion": "1.15", + "MinCompatibleVersion": "0.1", + "Description": "Increase workflow ID columns to 1000 characters", + "SchemaUpdateCqlFiles": [ + "alter_workflow_id_columns.sql" + ] +} diff --git a/service/history/api/command_attr_validator_test.go b/service/history/api/command_attr_validator_test.go index 208e1c6fbae..9a8e2567f79 100644 --- a/service/history/api/command_attr_validator_test.go +++ b/service/history/api/command_attr_validator_test.go @@ -3,6 +3,7 @@ package api import ( "fmt" "math/rand" + "strings" "testing" "time" @@ -842,6 +843,57 @@ func (s *commandAttrValidatorSuite) TestValidateStartChildExecutionAttributes_In } } +func (s *commandAttrValidatorSuite) TestValidateStartChildExecutionAttributes_WorkflowIDLengthLimit() { + parentInfo := &persistencespb.WorkflowExecutionInfo{ + TaskQueue: "test-parent-task-queue", + WorkflowId: "test-parent-wf-id", + WorkflowTypeName: "test-parent-wf-type", + } + + for _, tt := range []struct { + name string + workflowID string + expectError bool + }{ + { + name: "limit accepted", + workflowID: strings.Repeat("a", 1000), + }, + { + name: "over limit rejected", + workflowID: strings.Repeat("a", 1001), + expectError: true, + }, + } { + s.Run(tt.name, func() { + attributes := &commandpb.StartChildWorkflowExecutionCommandAttributes{ + WorkflowId: tt.workflowID, + WorkflowType: &commonpb.WorkflowType{ + Name: "test-child-wf-type", + }, + TaskQueue: &taskqueuepb.TaskQueue{ + Name: "test-child-task-queue", + }, + Namespace: "test-ns", + } + _, err := s.validator.ValidateStartChildExecutionAttributes( + s.testNamespaceID, + s.testNamespaceID, + namespace.Name("test-ns"), + attributes, + parentInfo, + dynamicconfig.GetDurationPropertyFnFilteredByNamespace(time.Second), + ) + + if tt.expectError { + s.ErrorContains(err, "WorkflowId on StartChildWorkflowExecutionCommand exceeds length limit") + } else { + s.NoError(err) + } + }) + } +} + func (s *commandAttrValidatorSuite) TestValidateActivityScheduleAttributes_WorkflowTaskQueue() { testCases := []struct { name string diff --git a/tests/child_workflow_test.go b/tests/child_workflow_test.go index 148d13abacf..2ef23a34457 100644 --- a/tests/child_workflow_test.go +++ b/tests/child_workflow_test.go @@ -3,6 +3,7 @@ package tests import ( "fmt" "sort" + "strings" "testing" "time" @@ -1244,3 +1245,81 @@ func (s *ChildWorkflowSuite) TestStartChildWorkflowWithInternalTaskQueue_Blocked } s.True(foundTaskFailed, "WorkflowTaskFailed event should be recorded") } + +func (s *ChildWorkflowSuite) TestStartChildWorkflowWithMaxLengthWorkflowID() { + parentID := testcore.RandomizeStr(s.T().Name()) + childID := strings.Repeat("w", 1000) + wtParent := "test-child-workflow-max-id-parent-type" + wtChild := "test-child-workflow-max-id-child-type" + tlParent := "test-child-workflow-max-id-parent-taskqueue" + tlChild := "test-child-workflow-max-id-child-taskqueue" + identity := "worker1" + + parentWorkflowType := &commonpb.WorkflowType{Name: wtParent} + childWorkflowType := &commonpb.WorkflowType{Name: wtChild} + taskQueueParent := &taskqueuepb.TaskQueue{Name: tlParent, Kind: enumspb.TASK_QUEUE_KIND_NORMAL} + taskQueueChild := &taskqueuepb.TaskQueue{Name: tlChild, Kind: enumspb.TASK_QUEUE_KIND_NORMAL} + + request := &workflowservice.StartWorkflowExecutionRequest{ + RequestId: uuid.NewString(), + Namespace: s.Namespace().String(), + WorkflowId: parentID, + WorkflowType: parentWorkflowType, + TaskQueue: taskQueueParent, + Input: nil, + WorkflowRunTimeout: durationpb.New(100 * time.Second), + WorkflowTaskTimeout: durationpb.New(10 * time.Second), + Identity: identity, + } + + we, err := s.FrontendClient().StartWorkflowExecution(testcore.NewContext(), request) + s.NoError(err) + s.Logger.Info("StartWorkflowExecution", tag.WorkflowRunID(we.RunId)) + + childExecutionStarted := false + wtHandlerParent := func(task *workflowservice.PollWorkflowTaskQueueResponse) (*workflowservice.RespondWorkflowTaskCompletedRequest, error) { + for _, event := range task.GetHistory().GetEvents() { + if event.GetEventType() == enumspb.EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_STARTED { + attrs := event.GetChildWorkflowExecutionStartedEventAttributes() + s.Equal(childID, attrs.GetWorkflowExecution().GetWorkflowId()) + childExecutionStarted = true + return &workflowservice.RespondWorkflowTaskCompletedRequest{}, nil + } + } + + return &workflowservice.RespondWorkflowTaskCompletedRequest{ + Commands: []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_START_CHILD_WORKFLOW_EXECUTION, + Attributes: &commandpb.Command_StartChildWorkflowExecutionCommandAttributes{ + StartChildWorkflowExecutionCommandAttributes: &commandpb.StartChildWorkflowExecutionCommandAttributes{ + WorkflowId: childID, + WorkflowType: childWorkflowType, + TaskQueue: taskQueueChild, + Input: payloads.EncodeString("child-workflow-input"), + WorkflowRunTimeout: durationpb.New(200 * time.Second), + WorkflowTaskTimeout: durationpb.New(2 * time.Second), + }, + }, + }}, + }, nil + } + + pollerParent := taskpoller.New(s.T(), s.FrontendClient(), s.Namespace().String()) + tvParent := testvars.New(s.T()).WithWorkflowID(parentID).WithTaskQueue(tlParent) + + _, err = pollerParent.PollAndHandleWorkflowTask(tvParent, wtHandlerParent) + s.NoError(err) + _, err = pollerParent.PollAndHandleWorkflowTask(tvParent, wtHandlerParent, taskpoller.WithTimeout(15*time.Second)) + s.NoError(err) + s.True(childExecutionStarted) + + describeResp, err := s.FrontendClient().DescribeWorkflowExecution(testcore.NewContext(), &workflowservice.DescribeWorkflowExecutionRequest{ + Namespace: s.Namespace().String(), + Execution: &commonpb.WorkflowExecution{ + WorkflowId: childID, + }, + }) + s.NoError(err) + s.Equal(childID, describeResp.GetWorkflowExecutionInfo().GetExecution().GetWorkflowId()) + s.Equal(enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING, describeResp.GetWorkflowExecutionInfo().GetStatus()) +}