Skip to content

Commit

Permalink
IWF-103: Require every commandId to exist for ANY_COMMAND_COMBINATION…
Browse files Browse the repository at this point in the history
…_COMPLETED (#423)
  • Loading branch information
lwolczynski authored Sep 23, 2024
1 parent 75845b9 commit 997a5d4
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
31 changes: 31 additions & 0 deletions service/interpreter/activityImpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"io"
"net/http"
"os"
"slices"
)

// StateStart is Deprecated, will be removed in next release
Expand Down Expand Up @@ -224,12 +225,42 @@ func checkCommandRequestFromWaitUntilResponse(resp *iwfidl.WorkflowStateStartRes
return err
}
}
// Check if each command in the combinations has a matching command in one of the lists
if !areAllCommandCombinationsIdsValid(commandReq) {
return fmt.Errorf("ANY_COMMAND_COMBINATION_COMPLETED can only be used when every command has an commandId that is found in TimerCommands, SignalCommands or InternalChannelCommand")
}
}
}
// NOTE: we don't require decider trigger type when there is no commands
return nil
}

func areAllCommandCombinationsIdsValid(commandReq *iwfidl.CommandRequest) bool {
timerSignalInternalChannelCmdIds := listTimerSignalInternalChannelCommandIds(commandReq)
for _, commandCombo := range commandReq.GetCommandCombinations() {
for _, cmdId := range commandCombo.GetCommandIds() {
if !slices.Contains(timerSignalInternalChannelCmdIds, cmdId) {
return false
}
}
}
return true
}

func listTimerSignalInternalChannelCommandIds(commandReq *iwfidl.CommandRequest) []string {
var ids []string
for _, timerCmd := range commandReq.GetTimerCommands() {
ids = append(ids, timerCmd.GetCommandId())
}
for _, signalCmd := range commandReq.GetSignalCommands() {
ids = append(ids, signalCmd.GetCommandId())
}
for _, internalChannelCmd := range commandReq.GetInterStateChannelCommands() {
ids = append(ids, internalChannelCmd.GetCommandId())
}
return ids
}

func DumpWorkflowInternal(
ctx context.Context, backendType service.BackendType, req iwfidl.WorkflowDumpRequest,
) (*iwfidl.WorkflowDumpResponse, error) {
Expand Down
90 changes: 90 additions & 0 deletions service/interpreter/activityImpl_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package interpreter

import (
"github.com/indeedeng/iwf/gen/iwfidl"
"github.com/indeedeng/iwf/service/common/ptr"
"github.com/stretchr/testify/assert"
"testing"
"time"
)

func TestInvalidAnyCommandCombination(t *testing.T) {
validTimerCommands, validSignalCommands, internalCommands := createCommands()

resp := iwfidl.WorkflowStateStartResponse{
CommandRequest: &iwfidl.CommandRequest{
SignalCommands: validSignalCommands,
TimerCommands: validTimerCommands,
InterStateChannelCommands: internalCommands,
DeciderTriggerType: iwfidl.ANY_COMMAND_COMBINATION_COMPLETED.Ptr(),
CommandCombinations: []iwfidl.CommandCombination{
{
CommandIds: []string{
"timer-cmd1", "signal-cmd1",
},
},
{
CommandIds: []string{
"timer-cmd1", "invalid",
},
},
},
},
}

err := checkCommandRequestFromWaitUntilResponse(&resp)

assert.Error(t, err)
assert.Equal(t, err.Error(), "ANY_COMMAND_COMBINATION_COMPLETED can only be used when every command has an commandId that is found in TimerCommands, SignalCommands or InternalChannelCommand")
}

func TestValidAnyCommandCombination(t *testing.T) {
validTimerCommands, validSignalCommands, internalCommands := createCommands()

resp := iwfidl.WorkflowStateStartResponse{
CommandRequest: &iwfidl.CommandRequest{
SignalCommands: validSignalCommands,
TimerCommands: validTimerCommands,
InterStateChannelCommands: internalCommands,
DeciderTriggerType: iwfidl.ANY_COMMAND_COMBINATION_COMPLETED.Ptr(),
CommandCombinations: []iwfidl.CommandCombination{
{
CommandIds: []string{
"timer-cmd1", "signal-cmd1",
},
},
{
CommandIds: []string{
"timer-cmd1", "internal-cmd1",
},
},
},
},
}

err := checkCommandRequestFromWaitUntilResponse(&resp)

assert.NoError(t, err)
}

func createCommands() ([]iwfidl.TimerCommand, []iwfidl.SignalCommand, []iwfidl.InterStateChannelCommand) {
validTimerCommands := []iwfidl.TimerCommand{
{
CommandId: ptr.Any("timer-cmd1"),
FiringUnixTimestampSeconds: iwfidl.PtrInt64(time.Now().Unix() + 86400*365), // one year later
},
}
validSignalCommands := []iwfidl.SignalCommand{
{
CommandId: ptr.Any("signal-cmd1"),
SignalChannelName: "test-signal-name1",
},
}
internalCommands := []iwfidl.InterStateChannelCommand{
{
CommandId: ptr.Any("internal-cmd1"),
ChannelName: "test-internal-name1",
},
}
return validTimerCommands, validSignalCommands, internalCommands
}

0 comments on commit 997a5d4

Please sign in to comment.