@@ -3,8 +3,8 @@ package updateworkflowoptions
33import (
44 "context"
55 "testing"
6+ "time"
67
7- "github.com/stretchr/testify/assert"
88 "github.com/stretchr/testify/require"
99 "github.com/stretchr/testify/suite"
1010 commonpb "go.temporal.io/api/common/v1"
@@ -28,6 +28,7 @@ import (
2828 wcache "go.temporal.io/server/service/history/workflow/cache"
2929 "go.uber.org/mock/gomock"
3030 "google.golang.org/protobuf/proto"
31+ "google.golang.org/protobuf/types/known/durationpb"
3132 "google.golang.org/protobuf/types/known/fieldmaskpb"
3233)
3334
@@ -94,28 +95,28 @@ func TestMergeOptions_VersionOverrideMask(t *testing.T) {
9495 if err != nil {
9596 t .Error (err )
9697 }
97- assert .EqualExportedValues (t , unpinnedOverrideOptions , merged )
98+ require .EqualExportedValues (t , unpinnedOverrideOptions , merged )
9899
99100 // Merge pinned_A into unpinned options
100101 merged , err = mergeWorkflowExecutionOptions (input , pinnedOverrideOptionsA , updateMask )
101102 if err != nil {
102103 t .Error (err )
103104 }
104- assert .EqualExportedValues (t , pinnedOverrideOptionsA , merged )
105+ require .EqualExportedValues (t , pinnedOverrideOptionsA , merged )
105106
106107 // Merge pinned_B into pinned_A options
107108 merged , err = mergeWorkflowExecutionOptions (input , pinnedOverrideOptionsB , updateMask )
108109 if err != nil {
109110 t .Error (err )
110111 }
111- assert .EqualExportedValues (t , pinnedOverrideOptionsB , merged )
112+ require .EqualExportedValues (t , pinnedOverrideOptionsB , merged )
112113
113114 // Unset versioning override
114115 merged , err = mergeWorkflowExecutionOptions (input , emptyOptions , updateMask )
115116 if err != nil {
116117 t .Error (err )
117118 }
118- assert .EqualExportedValues (t , emptyOptions , merged )
119+ require .EqualExportedValues (t , emptyOptions , merged )
119120}
120121
121122func TestMergeOptions_PartialMask (t * testing.T ) {
@@ -124,14 +125,14 @@ func TestMergeOptions_PartialMask(t *testing.T) {
124125 deploymentOnlyUpdateMask := & fieldmaskpb.FieldMask {Paths : []string {"versioning_override.deployment" }}
125126
126127 _ , err := mergeWorkflowExecutionOptions (emptyOptions , unpinnedOverrideOptions , behaviorOnlyUpdateMask )
127- assert .Error (t , err )
128+ require .Error (t , err )
128129
129130 _ , err = mergeWorkflowExecutionOptions (emptyOptions , unpinnedOverrideOptions , deploymentOnlyUpdateMask )
130- assert .Error (t , err )
131+ require .Error (t , err )
131132
132133 merged , err := mergeWorkflowExecutionOptions (emptyOptions , unpinnedOverrideOptions , bothUpdateMask )
133- assert .NoError (t , err )
134- assert .EqualExportedValues (t , unpinnedOverrideOptions , merged )
134+ require .NoError (t , err )
135+ require .EqualExportedValues (t , unpinnedOverrideOptions , merged )
135136}
136137
137138func TestMergeOptions_EmptyMask (t * testing.T ) {
@@ -140,25 +141,113 @@ func TestMergeOptions_EmptyMask(t *testing.T) {
140141
141142 // Don't merge anything
142143 merged , err := mergeWorkflowExecutionOptions (input , pinnedOverrideOptionsA , emptyUpdateMask )
143- assert .NoError (t , err )
144- assert .EqualExportedValues (t , input , merged )
144+ require .NoError (t , err )
145+ require .EqualExportedValues (t , input , merged )
145146
146147 // Don't merge anything
147148 merged , err = mergeWorkflowExecutionOptions (input , nil , emptyUpdateMask )
148- assert .NoError (t , err )
149- assert .EqualExportedValues (t , input , merged )
149+ require .NoError (t , err )
150+ require .EqualExportedValues (t , input , merged )
150151}
151152
152153func TestMergeOptions_AsteriskMask (t * testing.T ) {
153154 asteriskUpdateMask := & fieldmaskpb.FieldMask {Paths : []string {"*" }}
154155 _ , err := mergeWorkflowExecutionOptions (emptyOptions , unpinnedOverrideOptions , asteriskUpdateMask )
155- assert .Error (t , err )
156+ require .Error (t , err )
156157}
157158
158159func TestMergeOptions_FooMask (t * testing.T ) {
159160 fooUpdateMask := & fieldmaskpb.FieldMask {Paths : []string {"foo" }}
160161 _ , err := mergeWorkflowExecutionOptions (emptyOptions , unpinnedOverrideOptions , fooUpdateMask )
161- assert .Error (t , err )
162+ require .Error (t , err )
163+ }
164+
165+ func TestMergeOptions_TimeSkippingConfig (t * testing.T ) {
166+ tscMask := & fieldmaskpb.FieldMask {Paths : []string {"time_skipping_config" }}
167+ cfgA := & workflowpb.TimeSkippingConfig {Enabled : true }
168+ cfgB := & workflowpb.TimeSkippingConfig {
169+ Enabled : true ,
170+ Bound : & workflowpb.TimeSkippingConfig_MaxSkippedDuration {MaxSkippedDuration : durationpb .New (time .Hour )},
171+ }
172+
173+ tcs := []struct {
174+ name string
175+ current * workflowpb.WorkflowExecutionOptions
176+ update * workflowpb.WorkflowExecutionOptions
177+ wantChanged bool
178+ wantConfig * workflowpb.TimeSkippingConfig
179+ }{
180+ // nil update means "don't touch" even when mask is present
181+ {
182+ name : "nil update - existing config preserved" ,
183+ current : & workflowpb.WorkflowExecutionOptions {TimeSkippingConfig : cfgA },
184+ update : & workflowpb.WorkflowExecutionOptions {},
185+ wantChanged : false ,
186+ wantConfig : cfgA ,
187+ },
188+ // non-nil update replaces and is detected as a change
189+ {
190+ name : "new config - changed" ,
191+ current : & workflowpb.WorkflowExecutionOptions {},
192+ update : & workflowpb.WorkflowExecutionOptions {TimeSkippingConfig : cfgB },
193+ wantChanged : true ,
194+ wantConfig : cfgB ,
195+ },
196+ // identical config is not detected as a change
197+ {
198+ name : "same config - no change" ,
199+ current : & workflowpb.WorkflowExecutionOptions {TimeSkippingConfig : cfgB },
200+ update : & workflowpb.WorkflowExecutionOptions {TimeSkippingConfig : cfgB },
201+ wantChanged : false ,
202+ wantConfig : cfgB ,
203+ },
204+ }
205+
206+ for _ , tc := range tcs {
207+ t .Run (tc .name , func (t * testing.T ) {
208+ original := proto .Clone (tc .current ).(* workflowpb.WorkflowExecutionOptions )
209+ merged , err := mergeWorkflowExecutionOptions (tc .current , tc .update , tscMask )
210+ require .NoError (t , err )
211+ require .True (t , proto .Equal (tc .wantConfig , merged .GetTimeSkippingConfig ()),
212+ "config mismatch: want %v, got %v" , tc .wantConfig , merged .GetTimeSkippingConfig ())
213+ require .Equal (t , tc .wantChanged , ! proto .Equal (merged , original ))
214+ })
215+ }
216+ }
217+
218+ func TestMergeAndApply_TimeSkippingConfig (t * testing.T ) {
219+ tscMask := & fieldmaskpb.FieldMask {Paths : []string {"time_skipping_config" }}
220+ cfg := & workflowpb.TimeSkippingConfig {
221+ Enabled : true ,
222+ Bound : & workflowpb.TimeSkippingConfig_MaxSkippedDuration {MaxSkippedDuration : durationpb .New (time .Hour )},
223+ }
224+
225+ t .Run ("same config - no event written" , func (t * testing.T ) {
226+ ctrl := gomock .NewController (t )
227+ ms := historyi .NewMockMutableState (ctrl )
228+ ms .EXPECT ().GetExecutionInfo ().Return (& persistencespb.WorkflowExecutionInfo {
229+ TimeSkippingInfo : & persistencespb.TimeSkippingInfo {Config : cfg },
230+ }).AnyTimes ()
231+
232+ merged , hasChanges , err := MergeAndApply (ms , & workflowpb.WorkflowExecutionOptions {TimeSkippingConfig : cfg }, tscMask , "" )
233+ require .NoError (t , err )
234+ require .False (t , hasChanges )
235+ require .True (t , proto .Equal (cfg , merged .GetTimeSkippingConfig ()))
236+ })
237+
238+ t .Run ("new config - event written with config" , func (t * testing.T ) {
239+ ctrl := gomock .NewController (t )
240+ ms := historyi .NewMockMutableState (ctrl )
241+ ms .EXPECT ().GetExecutionInfo ().Return (& persistencespb.WorkflowExecutionInfo {}).AnyTimes ()
242+ ms .EXPECT ().AddWorkflowExecutionOptionsUpdatedEvent (
243+ nil , true , "" , nil , nil , "" , nil , cfg ,
244+ ).Return (& historypb.HistoryEvent {}, nil )
245+
246+ merged , hasChanges , err := MergeAndApply (ms , & workflowpb.WorkflowExecutionOptions {TimeSkippingConfig : cfg }, tscMask , "" )
247+ require .NoError (t , err )
248+ require .True (t , hasChanges )
249+ require .True (t , proto .Equal (cfg , merged .GetTimeSkippingConfig ()))
250+ })
162251}
163252
164253type (
0 commit comments