go.temporal.io/server@v1.23.0/common/persistence/operation_mode_validator_test.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package persistence 26 27 import ( 28 "fmt" 29 "testing" 30 31 "github.com/stretchr/testify/suite" 32 33 enumsspb "go.temporal.io/server/api/enums/v1" 34 persistencespb "go.temporal.io/server/api/persistence/v1" 35 ) 36 37 type ( 38 validateOperationWorkflowModeStateSuite struct { 39 suite.Suite 40 } 41 ) 42 43 func TestValidateOperationWorkflowModeStateSuite(t *testing.T) { 44 s := new(validateOperationWorkflowModeStateSuite) 45 suite.Run(t, s) 46 } 47 48 func (s *validateOperationWorkflowModeStateSuite) SetupSuite() { 49 } 50 51 func (s *validateOperationWorkflowModeStateSuite) TearDownSuite() { 52 53 } 54 55 func (s *validateOperationWorkflowModeStateSuite) SetupTest() { 56 57 } 58 59 func (s *validateOperationWorkflowModeStateSuite) TearDownTest() { 60 61 } 62 63 func (s *validateOperationWorkflowModeStateSuite) TestCreateMode_UpdateCurrent() { 64 65 stateToError := map[enumsspb.WorkflowExecutionState]bool{ 66 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: false, 67 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: false, 68 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 69 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: true, 70 } 71 72 creatModes := []CreateWorkflowMode{ 73 CreateWorkflowModeBrandNew, 74 CreateWorkflowModeUpdateCurrent, 75 } 76 77 for state, expectError := range stateToError { 78 testSnapshot := s.newTestWorkflowSnapshot(state) 79 for _, createMode := range creatModes { 80 err := ValidateCreateWorkflowModeState(createMode, testSnapshot) 81 if !expectError { 82 s.NoError(err, err) 83 } else { 84 s.Error(err, err) 85 } 86 } 87 } 88 } 89 90 func (s *validateOperationWorkflowModeStateSuite) TestCreateMode_BypassCurrent() { 91 92 stateToError := map[enumsspb.WorkflowExecutionState]bool{ 93 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 94 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 95 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 96 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: false, 97 } 98 99 for state, expectError := range stateToError { 100 testSnapshot := s.newTestWorkflowSnapshot(state) 101 err := ValidateCreateWorkflowModeState(CreateWorkflowModeBypassCurrent, testSnapshot) 102 if !expectError { 103 s.NoError(err, err) 104 } else { 105 s.Error(err, err) 106 } 107 } 108 } 109 110 func (s *validateOperationWorkflowModeStateSuite) TestUpdateMode_UpdateCurrent() { 111 112 // only current workflow 113 stateToError := map[enumsspb.WorkflowExecutionState]bool{ 114 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: false, 115 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: false, 116 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 117 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: true, 118 } 119 for state, expectError := range stateToError { 120 testCurrentMutation := s.newTestWorkflowMutation(state) 121 err := ValidateUpdateWorkflowModeState( 122 UpdateWorkflowModeUpdateCurrent, 123 testCurrentMutation, 124 nil, 125 ) 126 if !expectError { 127 s.NoError(err, err) 128 } else { 129 s.Error(err, err) 130 } 131 } 132 133 // current workflow & new workflow 134 currentStateToError := map[enumsspb.WorkflowExecutionState]bool{ 135 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 136 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 137 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 138 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: false, 139 } 140 newStateToError := map[enumsspb.WorkflowExecutionState]bool{ 141 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: false, 142 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: false, 143 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 144 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: true, 145 } 146 for currentState, currentExpectError := range currentStateToError { 147 for newState, newExpectError := range newStateToError { 148 testCurrentMutation := s.newTestWorkflowMutation(currentState) 149 testNewSnapshot := s.newTestWorkflowSnapshot(newState) 150 err := ValidateUpdateWorkflowModeState( 151 UpdateWorkflowModeUpdateCurrent, 152 testCurrentMutation, 153 &testNewSnapshot, 154 ) 155 if currentExpectError || newExpectError { 156 s.Error(err, err) 157 } else { 158 s.NoError(err, err) 159 } 160 } 161 } 162 } 163 164 func (s *validateOperationWorkflowModeStateSuite) TestUpdateMode_BypassCurrent() { 165 166 // only current workflow 167 stateToError := map[enumsspb.WorkflowExecutionState]bool{ 168 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 169 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 170 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 171 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: false, 172 } 173 for state, expectError := range stateToError { 174 testMutation := s.newTestWorkflowMutation(state) 175 err := ValidateUpdateWorkflowModeState( 176 UpdateWorkflowModeBypassCurrent, 177 testMutation, 178 nil, 179 ) 180 if !expectError { 181 s.NoError(err, err) 182 } else { 183 s.Error(err, err) 184 } 185 } 186 187 // current workflow & new workflow 188 currentStateToError := map[enumsspb.WorkflowExecutionState]bool{ 189 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 190 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 191 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 192 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: false, 193 } 194 newStateToError := map[enumsspb.WorkflowExecutionState]bool{ 195 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 196 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 197 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 198 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: false, 199 } 200 for currentState, currentExpectError := range currentStateToError { 201 for newState, newExpectError := range newStateToError { 202 testCurrentMutation := s.newTestWorkflowMutation(currentState) 203 testNewSnapshot := s.newTestWorkflowSnapshot(newState) 204 err := ValidateUpdateWorkflowModeState( 205 UpdateWorkflowModeBypassCurrent, 206 testCurrentMutation, 207 &testNewSnapshot, 208 ) 209 if currentExpectError || newExpectError { 210 s.Error(err, err) 211 } else { 212 s.NoError(err, err) 213 } 214 } 215 } 216 } 217 218 func (s *validateOperationWorkflowModeStateSuite) TestConflictResolveMode_UpdateCurrent() { 219 220 // only reset workflow 221 stateToError := map[enumsspb.WorkflowExecutionState]bool{ 222 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: false, 223 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: false, 224 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 225 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: true, 226 } 227 for state, expectError := range stateToError { 228 testSnapshot := s.newTestWorkflowSnapshot(state) 229 err := ValidateConflictResolveWorkflowModeState( 230 ConflictResolveWorkflowModeUpdateCurrent, 231 testSnapshot, 232 nil, 233 nil, 234 ) 235 if !expectError { 236 s.NoError(err, err) 237 } else { 238 s.Error(err, err) 239 } 240 } 241 242 // reset workflow & new workflow 243 resetStateToError := map[enumsspb.WorkflowExecutionState]bool{ 244 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 245 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 246 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 247 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: true, 248 } 249 newStateToError := map[enumsspb.WorkflowExecutionState]bool{ 250 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: false, 251 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: false, 252 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 253 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: true, 254 } 255 for resetState, resetExpectError := range resetStateToError { 256 for newState, newExpectError := range newStateToError { 257 testResetSnapshot := s.newTestWorkflowSnapshot(resetState) 258 testNewSnapshot := s.newTestWorkflowSnapshot(newState) 259 err := ValidateConflictResolveWorkflowModeState( 260 ConflictResolveWorkflowModeUpdateCurrent, 261 testResetSnapshot, 262 &testNewSnapshot, 263 nil, 264 ) 265 if resetExpectError || newExpectError { 266 s.Error(err, err) 267 } else { 268 s.NoError(err, err) 269 } 270 } 271 } 272 273 // reset workflow & current workflow 274 resetStateToError = map[enumsspb.WorkflowExecutionState]bool{ 275 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: false, 276 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: false, 277 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 278 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: true, 279 } 280 currentStateToError := map[enumsspb.WorkflowExecutionState]bool{ 281 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 282 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 283 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 284 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: false, 285 } 286 for resetState, resetExpectError := range resetStateToError { 287 for currentState, currentExpectError := range currentStateToError { 288 testResetSnapshot := s.newTestWorkflowSnapshot(resetState) 289 testCurrentSnapshot := s.newTestWorkflowMutation(currentState) 290 err := ValidateConflictResolveWorkflowModeState( 291 ConflictResolveWorkflowModeUpdateCurrent, 292 testResetSnapshot, 293 nil, 294 &testCurrentSnapshot, 295 ) 296 if resetExpectError || currentExpectError { 297 s.Error(err, err) 298 } else { 299 s.NoError(err, err) 300 } 301 } 302 } 303 304 // reset workflow & new workflow & current workflow 305 resetStateToError = map[enumsspb.WorkflowExecutionState]bool{ 306 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 307 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 308 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 309 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: true, 310 } 311 newStateToError = map[enumsspb.WorkflowExecutionState]bool{ 312 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: false, 313 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: false, 314 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 315 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: true, 316 } 317 currentStateToError = map[enumsspb.WorkflowExecutionState]bool{ 318 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 319 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 320 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 321 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: false, 322 } 323 for resetState, resetExpectError := range resetStateToError { 324 for newState, newExpectError := range newStateToError { 325 for currentState, currentExpectError := range currentStateToError { 326 testResetSnapshot := s.newTestWorkflowSnapshot(resetState) 327 testNewSnapshot := s.newTestWorkflowSnapshot(newState) 328 testCurrentSnapshot := s.newTestWorkflowMutation(currentState) 329 err := ValidateConflictResolveWorkflowModeState( 330 ConflictResolveWorkflowModeUpdateCurrent, 331 testResetSnapshot, 332 &testNewSnapshot, 333 &testCurrentSnapshot, 334 ) 335 if resetExpectError || newExpectError || currentExpectError { 336 s.Error(err, err) 337 } else { 338 s.NoError(err, err) 339 } 340 } 341 } 342 } 343 } 344 345 func (s *validateOperationWorkflowModeStateSuite) TestConflictResolveMode_BypassCurrent() { 346 347 // only reset workflow 348 stateToError := map[enumsspb.WorkflowExecutionState]bool{ 349 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 350 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 351 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 352 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: false, 353 } 354 for state, expectError := range stateToError { 355 testSnapshot := s.newTestWorkflowSnapshot(state) 356 err := ValidateConflictResolveWorkflowModeState( 357 ConflictResolveWorkflowModeBypassCurrent, 358 testSnapshot, 359 nil, 360 nil, 361 ) 362 if !expectError { 363 s.NoError(err, err) 364 } else { 365 s.Error(err, err) 366 } 367 } 368 369 // reset workflow & new workflow 370 resetStateToError := map[enumsspb.WorkflowExecutionState]bool{ 371 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 372 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 373 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: false, 374 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: true, 375 } 376 newStateToError := map[enumsspb.WorkflowExecutionState]bool{ 377 enumsspb.WORKFLOW_EXECUTION_STATE_CREATED: true, 378 enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING: true, 379 enumsspb.WORKFLOW_EXECUTION_STATE_COMPLETED: true, 380 enumsspb.WORKFLOW_EXECUTION_STATE_ZOMBIE: false, 381 } 382 for resetState, resetExpectError := range resetStateToError { 383 for newState, newExpectError := range newStateToError { 384 testResetSnapshot := s.newTestWorkflowSnapshot(resetState) 385 testNewSnapshot := s.newTestWorkflowSnapshot(newState) 386 err := ValidateConflictResolveWorkflowModeState( 387 ConflictResolveWorkflowModeBypassCurrent, 388 testResetSnapshot, 389 &testNewSnapshot, 390 nil, 391 ) 392 if resetExpectError || newExpectError { 393 if err == nil { 394 fmt.Print("##") 395 } 396 s.Error(err, err) 397 } else { 398 s.NoError(err, err) 399 } 400 } 401 } 402 } 403 404 func (s *validateOperationWorkflowModeStateSuite) newTestWorkflowSnapshot( 405 state enumsspb.WorkflowExecutionState, 406 ) WorkflowSnapshot { 407 return WorkflowSnapshot{ 408 ExecutionInfo: &persistencespb.WorkflowExecutionInfo{}, 409 ExecutionState: &persistencespb.WorkflowExecutionState{State: state}, 410 } 411 } 412 413 func (s *validateOperationWorkflowModeStateSuite) newTestWorkflowMutation( 414 state enumsspb.WorkflowExecutionState, 415 ) WorkflowMutation { 416 return WorkflowMutation{ 417 ExecutionInfo: &persistencespb.WorkflowExecutionInfo{}, 418 ExecutionState: &persistencespb.WorkflowExecutionState{State: state}, 419 } 420 }