go.temporal.io/server@v1.23.0/common/persistence/tests/history_store.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 tests 26 27 import ( 28 "context" 29 "math/rand" 30 "testing" 31 "time" 32 33 "github.com/pborman/uuid" 34 "github.com/stretchr/testify/require" 35 "github.com/stretchr/testify/suite" 36 "google.golang.org/protobuf/types/known/timestamppb" 37 38 enumspb "go.temporal.io/api/enums/v1" 39 historypb "go.temporal.io/api/history/v1" 40 41 persistencespb "go.temporal.io/server/api/persistence/v1" 42 "go.temporal.io/server/common" 43 "go.temporal.io/server/common/debug" 44 "go.temporal.io/server/common/dynamicconfig" 45 "go.temporal.io/server/common/log" 46 p "go.temporal.io/server/common/persistence" 47 "go.temporal.io/server/common/persistence/serialization" 48 "go.temporal.io/server/common/testing/protorequire" 49 ) 50 51 // TODO add UT for the following 52 // * DeleteHistoryBranch 53 // * GetHistoryTree 54 // * GetAllHistoryTreeBranches 55 56 type ( 57 HistoryEventsPacket struct { 58 nodeID int64 59 transactionID int64 60 prevTransactionID int64 61 events []*historypb.HistoryEvent 62 } 63 64 HistoryEventsSuite struct { 65 suite.Suite 66 *require.Assertions 67 protorequire.ProtoAssertions 68 69 store p.ExecutionManager 70 serializer serialization.Serializer 71 logger log.Logger 72 73 Ctx context.Context 74 Cancel context.CancelFunc 75 } 76 ) 77 78 func NewHistoryEventsSuite( 79 t *testing.T, 80 store p.ExecutionStore, 81 logger log.Logger, 82 ) *HistoryEventsSuite { 83 eventSerializer := serialization.NewSerializer() 84 return &HistoryEventsSuite{ 85 Assertions: require.New(t), 86 ProtoAssertions: protorequire.New(t), 87 store: p.NewExecutionManager( 88 store, 89 eventSerializer, 90 nil, 91 logger, 92 dynamicconfig.GetIntPropertyFn(4*1024*1024), 93 ), 94 serializer: eventSerializer, 95 logger: logger, 96 } 97 } 98 99 func (s *HistoryEventsSuite) SetupSuite() { 100 101 } 102 103 func (s *HistoryEventsSuite) TearDownSuite() { 104 105 } 106 107 func (s *HistoryEventsSuite) SetupTest() { 108 s.Assertions = require.New(s.T()) 109 s.ProtoAssertions = protorequire.New(s.T()) 110 s.Ctx, s.Cancel = context.WithTimeout(context.Background(), 30*time.Second*debug.TimeoutMultiplier) 111 } 112 113 func (s *HistoryEventsSuite) TearDownTest() { 114 s.Cancel() 115 } 116 117 func (s *HistoryEventsSuite) TestAppendSelect_First() { 118 shardID := rand.Int31() 119 treeID := uuid.New() 120 branchID := uuid.New() 121 branchToken, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 122 uuid.New(), 123 uuid.New(), 124 uuid.New(), 125 treeID, 126 &branchID, 127 []*persistencespb.HistoryBranchRange{}, 128 time.Duration(0), 129 time.Duration(0), 130 time.Duration(0), 131 ) 132 s.NoError(err) 133 134 eventsPacket := s.newHistoryEvents( 135 []int64{1, 2, 3}, 136 rand.Int63(), 137 0, 138 ) 139 s.appendHistoryEvents(shardID, branchToken, eventsPacket) 140 141 protorequire.ProtoSliceEqual(s.T(), eventsPacket.events, s.listHistoryEvents(shardID, branchToken, common.FirstEventID, 4)) 142 protorequire.ProtoSliceEqual(s.T(), eventsPacket.events, s.listAllHistoryEvents(shardID, branchToken)) 143 } 144 145 func (s *HistoryEventsSuite) TestAppendSelect_NonShadowing() { 146 shardID := rand.Int31() 147 treeID := uuid.New() 148 branchID := uuid.New() 149 branchToken, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 150 uuid.New(), 151 uuid.New(), 152 uuid.New(), 153 treeID, 154 &branchID, 155 []*persistencespb.HistoryBranchRange{}, 156 time.Duration(0), 157 time.Duration(0), 158 time.Duration(0), 159 ) 160 s.NoError(err) 161 var events []*historypb.HistoryEvent 162 163 eventsPacket0 := s.newHistoryEvents( 164 []int64{1, 2, 3}, 165 rand.Int63(), 166 0, 167 ) 168 s.appendHistoryEvents(shardID, branchToken, eventsPacket0) 169 events = append(events, eventsPacket0.events...) 170 171 eventsPacket1 := s.newHistoryEvents( 172 []int64{4, 5}, 173 eventsPacket0.transactionID+1, 174 eventsPacket0.transactionID, 175 ) 176 s.appendHistoryEvents(shardID, branchToken, eventsPacket1) 177 events = append(events, eventsPacket1.events...) 178 179 protorequire.ProtoSliceEqual(s.T(), eventsPacket0.events, s.listHistoryEvents(shardID, branchToken, common.FirstEventID, 4)) 180 protorequire.ProtoSliceEqual(s.T(), eventsPacket1.events, s.listHistoryEvents(shardID, branchToken, 4, 6)) 181 protorequire.ProtoSliceEqual(s.T(), events, s.listAllHistoryEvents(shardID, branchToken)) 182 } 183 184 func (s *HistoryEventsSuite) TestAppendSelect_Shadowing() { 185 shardID := rand.Int31() 186 treeID := uuid.New() 187 branchID := uuid.New() 188 branchToken, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 189 uuid.New(), 190 uuid.New(), 191 uuid.New(), 192 treeID, 193 &branchID, 194 []*persistencespb.HistoryBranchRange{}, 195 time.Duration(0), 196 time.Duration(0), 197 time.Duration(0), 198 ) 199 s.NoError(err) 200 var events0 []*historypb.HistoryEvent 201 var events1 []*historypb.HistoryEvent 202 203 eventsPacket0 := s.newHistoryEvents( 204 []int64{1, 2, 3}, 205 rand.Int63(), 206 0, 207 ) 208 s.appendHistoryEvents(shardID, branchToken, eventsPacket0) 209 events0 = append(events0, eventsPacket0.events...) 210 events1 = append(events1, eventsPacket0.events...) 211 212 eventsPacket10 := s.newHistoryEvents( 213 []int64{4, 5}, 214 eventsPacket0.transactionID+1, 215 eventsPacket0.transactionID, 216 ) 217 s.appendHistoryEvents(shardID, branchToken, eventsPacket10) 218 events0 = append(events0, eventsPacket10.events...) 219 220 protorequire.ProtoSliceEqual(s.T(), events0, s.listAllHistoryEvents(shardID, branchToken)) 221 222 eventsPacket11 := s.newHistoryEvents( 223 []int64{4, 5}, 224 eventsPacket0.transactionID+2, 225 eventsPacket0.transactionID, 226 ) 227 s.appendHistoryEvents(shardID, branchToken, eventsPacket11) 228 events1 = append(events1, eventsPacket11.events...) 229 230 protorequire.ProtoSliceEqual(s.T(), eventsPacket0.events, s.listHistoryEvents(shardID, branchToken, common.FirstEventID, 4)) 231 protorequire.ProtoSliceEqual(s.T(), eventsPacket11.events, s.listHistoryEvents(shardID, branchToken, 4, 6)) 232 protorequire.ProtoSliceEqual(s.T(), events1, s.listAllHistoryEvents(shardID, branchToken)) 233 } 234 235 func (s *HistoryEventsSuite) TestAppendForkSelect_NoShadowing() { 236 shardID := rand.Int31() 237 treeID := uuid.New() 238 branchID := uuid.New() 239 branchToken, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 240 uuid.New(), 241 uuid.New(), 242 uuid.New(), 243 treeID, 244 &branchID, 245 []*persistencespb.HistoryBranchRange{}, 246 time.Duration(0), 247 time.Duration(0), 248 time.Duration(0), 249 ) 250 s.NoError(err) 251 var events0 []*historypb.HistoryEvent 252 var events1 []*historypb.HistoryEvent 253 254 eventsPacket0 := s.newHistoryEvents( 255 []int64{1, 2, 3}, 256 rand.Int63(), 257 0, 258 ) 259 s.appendHistoryEvents(shardID, branchToken, eventsPacket0) 260 events0 = append(events0, eventsPacket0.events...) 261 events1 = append(events1, eventsPacket0.events...) 262 263 eventsPacket10 := s.newHistoryEvents( 264 []int64{4, 5}, 265 eventsPacket0.transactionID+1, 266 eventsPacket0.transactionID, 267 ) 268 s.appendHistoryEvents(shardID, branchToken, eventsPacket10) 269 events0 = append(events0, eventsPacket10.events...) 270 271 newBranchToken := s.forkHistoryBranch(shardID, branchToken, 4) 272 eventsPacket11 := s.newHistoryEvents( 273 []int64{4, 5}, 274 eventsPacket0.transactionID+2, 275 eventsPacket0.transactionID, 276 ) 277 s.appendHistoryEvents(shardID, newBranchToken, eventsPacket11) 278 events1 = append(events1, eventsPacket11.events...) 279 280 protorequire.ProtoSliceEqual(s.T(), eventsPacket0.events, s.listHistoryEvents(shardID, branchToken, common.FirstEventID, 4)) 281 protorequire.ProtoSliceEqual(s.T(), eventsPacket0.events, s.listHistoryEvents(shardID, newBranchToken, common.FirstEventID, 4)) 282 protorequire.ProtoSliceEqual(s.T(), eventsPacket10.events, s.listHistoryEvents(shardID, branchToken, 4, 6)) 283 protorequire.ProtoSliceEqual(s.T(), eventsPacket11.events, s.listHistoryEvents(shardID, newBranchToken, 4, 6)) 284 protorequire.ProtoSliceEqual(s.T(), events0, s.listAllHistoryEvents(shardID, branchToken)) 285 protorequire.ProtoSliceEqual(s.T(), events1, s.listAllHistoryEvents(shardID, newBranchToken)) 286 } 287 288 func (s *HistoryEventsSuite) TestAppendForkSelect_Shadowing_NonLastBranch() { 289 shardID := rand.Int31() 290 treeID := uuid.New() 291 branchID := uuid.New() 292 branchToken, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 293 uuid.New(), 294 uuid.New(), 295 uuid.New(), 296 treeID, 297 &branchID, 298 []*persistencespb.HistoryBranchRange{}, 299 time.Duration(0), 300 time.Duration(0), 301 time.Duration(0), 302 ) 303 s.NoError(err) 304 var events0 []*historypb.HistoryEvent 305 var events1 []*historypb.HistoryEvent 306 307 eventsPacket0 := s.newHistoryEvents( 308 []int64{1, 2, 3}, 309 rand.Int63(), 310 0, 311 ) 312 s.appendHistoryEvents(shardID, branchToken, eventsPacket0) 313 events0 = append(events0, eventsPacket0.events...) 314 events1 = append(events1, eventsPacket0.events...) 315 316 s.appendHistoryEvents(shardID, branchToken, s.newHistoryEvents( 317 []int64{4, 5}, 318 eventsPacket0.transactionID+1, 319 eventsPacket0.transactionID, 320 )) 321 322 eventsPacket1 := s.newHistoryEvents( 323 []int64{4, 5}, 324 eventsPacket0.transactionID+2, 325 eventsPacket0.transactionID, 326 ) 327 s.appendHistoryEvents(shardID, branchToken, eventsPacket1) 328 events0 = append(events0, eventsPacket1.events...) 329 events1 = append(events1, eventsPacket1.events...) 330 331 eventsPacket20 := s.newHistoryEvents( 332 []int64{6}, 333 eventsPacket1.transactionID+1, 334 eventsPacket1.transactionID, 335 ) 336 s.appendHistoryEvents(shardID, branchToken, eventsPacket20) 337 events0 = append(events0, eventsPacket20.events...) 338 339 newBranchToken := s.forkHistoryBranch(shardID, branchToken, 6) 340 eventsPacket21 := s.newHistoryEvents( 341 []int64{6}, 342 eventsPacket1.transactionID+2, 343 eventsPacket1.transactionID, 344 ) 345 s.appendHistoryEvents(shardID, newBranchToken, eventsPacket21) 346 events1 = append(events1, eventsPacket21.events...) 347 348 protorequire.ProtoSliceEqual(s.T(), eventsPacket0.events, s.listHistoryEvents(shardID, branchToken, common.FirstEventID, 4)) 349 protorequire.ProtoSliceEqual(s.T(), eventsPacket0.events, s.listHistoryEvents(shardID, newBranchToken, common.FirstEventID, 4)) 350 protorequire.ProtoSliceEqual(s.T(), eventsPacket1.events, s.listHistoryEvents(shardID, branchToken, 4, 6)) 351 protorequire.ProtoSliceEqual(s.T(), eventsPacket1.events, s.listHistoryEvents(shardID, newBranchToken, 4, 6)) 352 protorequire.ProtoSliceEqual(s.T(), eventsPacket20.events, s.listHistoryEvents(shardID, branchToken, 6, 7)) 353 protorequire.ProtoSliceEqual(s.T(), eventsPacket21.events, s.listHistoryEvents(shardID, newBranchToken, 6, 7)) 354 protorequire.ProtoSliceEqual(s.T(), events0, s.listAllHistoryEvents(shardID, branchToken)) 355 protorequire.ProtoSliceEqual(s.T(), events1, s.listAllHistoryEvents(shardID, newBranchToken)) 356 } 357 358 func (s *HistoryEventsSuite) TestAppendForkSelect_Shadowing_LastBranch() { 359 shardID := rand.Int31() 360 treeID := uuid.New() 361 branchID := uuid.New() 362 branchToken, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 363 uuid.New(), 364 uuid.New(), 365 uuid.New(), 366 treeID, 367 &branchID, 368 []*persistencespb.HistoryBranchRange{}, 369 time.Duration(0), 370 time.Duration(0), 371 time.Duration(0), 372 ) 373 s.NoError(err) 374 var events0 []*historypb.HistoryEvent 375 var events1 []*historypb.HistoryEvent 376 377 eventsPacket0 := s.newHistoryEvents( 378 []int64{1, 2, 3}, 379 rand.Int63(), 380 0, 381 ) 382 s.appendHistoryEvents(shardID, branchToken, eventsPacket0) 383 events0 = append(events0, eventsPacket0.events...) 384 events1 = append(events1, eventsPacket0.events...) 385 386 s.appendHistoryEvents(shardID, branchToken, s.newHistoryEvents( 387 []int64{4, 5}, 388 eventsPacket0.transactionID+1, 389 eventsPacket0.transactionID, 390 )) 391 392 newBranchToken := s.forkHistoryBranch(shardID, branchToken, 4) 393 eventsPacket20 := s.newHistoryEvents( 394 []int64{4, 5}, 395 eventsPacket0.transactionID+2, 396 eventsPacket0.transactionID, 397 ) 398 s.appendHistoryEvents(shardID, newBranchToken, eventsPacket20) 399 events0 = append(events0, eventsPacket20.events...) 400 401 protorequire.ProtoSliceEqual(s.T(), eventsPacket0.events, s.listHistoryEvents(shardID, newBranchToken, common.FirstEventID, 4)) 402 protorequire.ProtoSliceEqual(s.T(), eventsPacket20.events, s.listHistoryEvents(shardID, newBranchToken, 4, 6)) 403 protorequire.ProtoSliceEqual(s.T(), events0, s.listAllHistoryEvents(shardID, newBranchToken)) 404 405 eventsPacket21 := s.newHistoryEvents( 406 []int64{4, 5}, 407 eventsPacket0.transactionID+3, 408 eventsPacket0.transactionID, 409 ) 410 s.appendHistoryEvents(shardID, newBranchToken, eventsPacket21) 411 events1 = append(events1, eventsPacket21.events...) 412 413 protorequire.ProtoSliceEqual(s.T(), eventsPacket0.events, s.listHistoryEvents(shardID, newBranchToken, common.FirstEventID, 4)) 414 protorequire.ProtoSliceEqual(s.T(), eventsPacket21.events, s.listHistoryEvents(shardID, newBranchToken, 4, 6)) 415 protorequire.ProtoSliceEqual(s.T(), events1, s.listAllHistoryEvents(shardID, newBranchToken)) 416 } 417 418 func (s *HistoryEventsSuite) TestAppendSelectTrim() { 419 shardID := rand.Int31() 420 treeID := uuid.New() 421 branchID := uuid.New() 422 branchToken, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 423 uuid.New(), 424 uuid.New(), 425 uuid.New(), 426 treeID, 427 &branchID, 428 []*persistencespb.HistoryBranchRange{}, 429 time.Duration(0), 430 time.Duration(0), 431 time.Duration(0), 432 ) 433 s.NoError(err) 434 var events []*historypb.HistoryEvent 435 436 eventsPacket0 := s.newHistoryEvents( 437 []int64{1, 2, 3}, 438 rand.Int63(), 439 0, 440 ) 441 s.appendHistoryEvents(shardID, branchToken, eventsPacket0) 442 events = append(events, eventsPacket0.events...) 443 444 eventsPacket1 := s.newHistoryEvents( 445 []int64{4, 5}, 446 eventsPacket0.transactionID+1, 447 eventsPacket0.transactionID, 448 ) 449 s.appendHistoryEvents(shardID, branchToken, eventsPacket1) 450 events = append(events, eventsPacket1.events...) 451 452 s.appendHistoryEvents(shardID, branchToken, s.newHistoryEvents( 453 []int64{4, 5}, 454 eventsPacket0.transactionID+2, 455 eventsPacket0.transactionID, 456 )) 457 458 s.trimHistoryBranch(shardID, branchToken, eventsPacket1.nodeID, eventsPacket1.transactionID) 459 460 protorequire.ProtoSliceEqual(s.T(), events, s.listAllHistoryEvents(shardID, branchToken)) 461 } 462 463 func (s *HistoryEventsSuite) TestAppendForkSelectTrim_NonLastBranch() { 464 shardID := rand.Int31() 465 treeID := uuid.New() 466 branchID := uuid.New() 467 branchToken, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 468 uuid.New(), 469 uuid.New(), 470 uuid.New(), 471 treeID, 472 &branchID, 473 []*persistencespb.HistoryBranchRange{}, 474 time.Duration(0), 475 time.Duration(0), 476 time.Duration(0), 477 ) 478 s.NoError(err) 479 var events0 []*historypb.HistoryEvent 480 var events1 []*historypb.HistoryEvent 481 482 eventsPacket0 := s.newHistoryEvents( 483 []int64{1, 2, 3}, 484 rand.Int63(), 485 0, 486 ) 487 s.appendHistoryEvents(shardID, branchToken, eventsPacket0) 488 events0 = append(events0, eventsPacket0.events...) 489 events1 = append(events1, eventsPacket0.events...) 490 491 eventsPacket1 := s.newHistoryEvents( 492 []int64{4, 5}, 493 eventsPacket0.transactionID+1, 494 eventsPacket0.transactionID, 495 ) 496 s.appendHistoryEvents(shardID, branchToken, eventsPacket1) 497 events0 = append(events0, eventsPacket1.events...) 498 events1 = append(events1, eventsPacket1.events...) 499 500 s.appendHistoryEvents(shardID, branchToken, s.newHistoryEvents( 501 []int64{4, 5}, 502 eventsPacket0.transactionID+2, 503 eventsPacket0.transactionID, 504 )) 505 506 eventsPacket20 := s.newHistoryEvents( 507 []int64{6}, 508 eventsPacket1.transactionID+2, 509 eventsPacket1.transactionID, 510 ) 511 s.appendHistoryEvents(shardID, branchToken, eventsPacket20) 512 events0 = append(events0, eventsPacket20.events...) 513 514 newBranchToken := s.forkHistoryBranch(shardID, branchToken, 6) 515 eventsPacket21 := s.newHistoryEvents( 516 []int64{6}, 517 eventsPacket1.transactionID+3, 518 eventsPacket1.transactionID, 519 ) 520 s.appendHistoryEvents(shardID, newBranchToken, eventsPacket21) 521 events1 = append(events1, eventsPacket21.events...) 522 523 if rand.Intn(2)%2 == 0 { 524 s.trimHistoryBranch(shardID, branchToken, eventsPacket20.nodeID, eventsPacket20.transactionID) 525 } else { 526 s.trimHistoryBranch(shardID, newBranchToken, eventsPacket21.nodeID, eventsPacket21.transactionID) 527 } 528 529 protorequire.ProtoSliceEqual(s.T(), events0, s.listAllHistoryEvents(shardID, branchToken)) 530 protorequire.ProtoSliceEqual(s.T(), events1, s.listAllHistoryEvents(shardID, newBranchToken)) 531 } 532 533 func (s *HistoryEventsSuite) TestAppendForkSelectTrim_LastBranch() { 534 shardID := rand.Int31() 535 treeID := uuid.New() 536 branchID := uuid.New() 537 branchToken, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 538 uuid.New(), 539 uuid.New(), 540 uuid.New(), 541 treeID, 542 &branchID, 543 []*persistencespb.HistoryBranchRange{}, 544 time.Duration(0), 545 time.Duration(0), 546 time.Duration(0), 547 ) 548 s.NoError(err) 549 var events []*historypb.HistoryEvent 550 551 eventsPacket0 := s.newHistoryEvents( 552 []int64{1, 2, 3}, 553 rand.Int63(), 554 0, 555 ) 556 s.appendHistoryEvents(shardID, branchToken, eventsPacket0) 557 events = append(events, eventsPacket0.events...) 558 559 s.appendHistoryEvents(shardID, branchToken, s.newHistoryEvents( 560 []int64{4, 5}, 561 eventsPacket0.transactionID+1, 562 eventsPacket0.transactionID, 563 )) 564 565 newBranchToken := s.forkHistoryBranch(shardID, branchToken, 4) 566 eventsPacket1 := s.newHistoryEvents( 567 []int64{4, 5}, 568 eventsPacket0.transactionID+2, 569 eventsPacket0.transactionID, 570 ) 571 s.appendHistoryEvents(shardID, newBranchToken, eventsPacket1) 572 events = append(events, eventsPacket1.events...) 573 574 s.appendHistoryEvents(shardID, newBranchToken, s.newHistoryEvents( 575 []int64{4, 5}, 576 eventsPacket0.transactionID+3, 577 eventsPacket0.transactionID, 578 )) 579 580 s.trimHistoryBranch(shardID, newBranchToken, eventsPacket1.nodeID, eventsPacket1.transactionID) 581 582 protorequire.ProtoSliceEqual(s.T(), events, s.listAllHistoryEvents(shardID, newBranchToken)) 583 } 584 585 func (s *HistoryEventsSuite) TestAppendBatches() { 586 shardID := rand.Int31() 587 treeID := uuid.New() 588 branchID := uuid.New() 589 branchToken, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 590 uuid.New(), 591 uuid.New(), 592 uuid.New(), 593 treeID, 594 &branchID, 595 []*persistencespb.HistoryBranchRange{}, 596 time.Duration(0), 597 time.Duration(0), 598 time.Duration(0), 599 ) 600 s.NoError(err) 601 602 eventsPacket1 := s.newHistoryEvents( 603 []int64{1, 2, 3}, 604 rand.Int63(), 605 0, 606 ) 607 eventsPacket2 := s.newHistoryEvents( 608 []int64{4, 5}, 609 eventsPacket1.transactionID+100, 610 eventsPacket1.transactionID, 611 ) 612 eventsPacket3 := s.newHistoryEvents( 613 []int64{6}, 614 eventsPacket2.transactionID+100, 615 eventsPacket2.transactionID, 616 ) 617 618 s.appendRawHistoryBatches(shardID, branchToken, eventsPacket1) 619 s.appendRawHistoryBatches(shardID, branchToken, eventsPacket2) 620 s.appendRawHistoryBatches(shardID, branchToken, eventsPacket3) 621 protorequire.ProtoSliceEqual(s.T(), eventsPacket1.events, s.listHistoryEvents(shardID, branchToken, common.FirstEventID, 4)) 622 expectedEvents := append(eventsPacket1.events, append(eventsPacket2.events, eventsPacket3.events...)...) 623 events := s.listAllHistoryEvents(shardID, branchToken) 624 protorequire.ProtoSliceEqual(s.T(), expectedEvents, events) 625 } 626 627 func (s *HistoryEventsSuite) TestForkDeleteBranch_DeleteBaseBranchFirst() { 628 shardID := rand.Int31() 629 treeID := uuid.New() 630 branchID := uuid.New() 631 br1Token, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 632 uuid.New(), 633 uuid.New(), 634 uuid.New(), 635 treeID, 636 &branchID, 637 []*persistencespb.HistoryBranchRange{}, 638 time.Duration(0), 639 time.Duration(0), 640 time.Duration(0), 641 ) 642 s.NoError(err) 643 644 eventsPacket0 := s.newHistoryEvents( 645 []int64{1, 2, 3}, 646 rand.Int63(), 647 0, 648 ) 649 s.appendHistoryEvents(shardID, br1Token, eventsPacket0) 650 651 s.appendHistoryEvents(shardID, br1Token, s.newHistoryEvents( 652 []int64{4, 5}, 653 eventsPacket0.transactionID+1, 654 eventsPacket0.transactionID, 655 )) 656 657 br2Token := s.forkHistoryBranch(shardID, br1Token, 4) 658 eventsPacket1 := s.newHistoryEvents( 659 []int64{4, 5}, 660 eventsPacket0.transactionID+2, 661 eventsPacket0.transactionID, 662 ) 663 s.appendHistoryEvents(shardID, br2Token, eventsPacket1) 664 665 // delete branch1, should only delete branch1:[4,5], keep branch1:[1,2,3] as it is used as ancestor by branch2 666 s.deleteHistoryBranch(shardID, br1Token) 667 // verify branch1:[1,2,3] still remains 668 protorequire.ProtoSliceEqual(s.T(), eventsPacket0.events, s.listAllHistoryEvents(shardID, br1Token)) 669 // verify branch2 is not affected 670 protorequire.ProtoSliceEqual(s.T(), append(eventsPacket0.events, eventsPacket1.events...), s.listAllHistoryEvents(shardID, br2Token)) 671 672 // delete branch2, should delete branch2:[4,5], and also should delete ancestor branch1:[1,2,3] as it is no longer 673 // used by anyone 674 s.deleteHistoryBranch(shardID, br2Token) 675 676 // at this point, both branch1 and branch2 are deleted. 677 _, err = s.store.ReadHistoryBranch(s.Ctx, &p.ReadHistoryBranchRequest{ 678 ShardID: shardID, 679 BranchToken: br1Token, 680 MinEventID: common.FirstEventID, 681 MaxEventID: common.LastEventID, 682 PageSize: 1, 683 }) 684 s.Error(err, "Workflow execution history not found.") 685 686 _, err = s.store.ReadHistoryBranch(s.Ctx, &p.ReadHistoryBranchRequest{ 687 ShardID: shardID, 688 BranchToken: br2Token, 689 MinEventID: common.FirstEventID, 690 MaxEventID: common.LastEventID, 691 PageSize: 1, 692 }) 693 s.Error(err, "Workflow execution history not found.") 694 } 695 696 func (s *HistoryEventsSuite) TestForkDeleteBranch_DeleteForkedBranchFirst() { 697 shardID := rand.Int31() 698 treeID := uuid.New() 699 branchID := uuid.New() 700 br1Token, err := s.store.GetHistoryBranchUtil().NewHistoryBranch( 701 uuid.New(), 702 uuid.New(), 703 uuid.New(), 704 treeID, 705 &branchID, 706 []*persistencespb.HistoryBranchRange{}, 707 time.Duration(0), 708 time.Duration(0), 709 time.Duration(0), 710 ) 711 s.NoError(err) 712 713 transactionID := rand.Int63() 714 eventsPacket0 := s.newHistoryEvents( 715 []int64{1, 2, 3}, 716 transactionID, 717 0, 718 ) 719 s.appendHistoryEvents(shardID, br1Token, eventsPacket0) 720 eventsPacket1 := s.newHistoryEvents( 721 []int64{4, 5}, 722 transactionID+1, 723 transactionID, 724 ) 725 s.appendHistoryEvents(shardID, br1Token, eventsPacket1) 726 727 br2Token := s.forkHistoryBranch(shardID, br1Token, 4) 728 s.appendHistoryEvents(shardID, br2Token, s.newHistoryEvents( 729 []int64{4, 5}, 730 transactionID+2, 731 transactionID, 732 )) 733 734 // delete branch2, should only delete branch2:[4,5], keep branch1:[1,2,3] [4,5] as it is by branch1 735 s.deleteHistoryBranch(shardID, br2Token) 736 // verify branch1 is not affected 737 protorequire.ProtoSliceEqual(s.T(), append(eventsPacket0.events, eventsPacket1.events...), s.listAllHistoryEvents(shardID, br1Token)) 738 739 // branch2:[4,5] should be deleted 740 _, err = s.store.ReadHistoryBranch(s.Ctx, &p.ReadHistoryBranchRequest{ 741 ShardID: shardID, 742 BranchToken: br2Token, 743 MinEventID: 4, 744 MaxEventID: common.LastEventID, 745 PageSize: 1, 746 }) 747 s.Error(err, "Workflow execution history not found.") 748 749 // delete branch1, should delete branch1:[1,2,3] [4,5] 750 s.deleteHistoryBranch(shardID, br1Token) 751 752 // branch1 should be deleted 753 _, err = s.store.ReadHistoryBranch(s.Ctx, &p.ReadHistoryBranchRequest{ 754 ShardID: shardID, 755 BranchToken: br1Token, 756 MinEventID: common.FirstEventID, 757 MaxEventID: common.LastEventID, 758 PageSize: 1, 759 }) 760 s.Error(err, "Workflow execution history not found.") 761 } 762 763 func (s *HistoryEventsSuite) appendHistoryEvents( 764 shardID int32, 765 branchToken []byte, 766 packet HistoryEventsPacket, 767 ) { 768 _, err := s.store.AppendHistoryNodes(s.Ctx, &p.AppendHistoryNodesRequest{ 769 ShardID: shardID, 770 BranchToken: branchToken, 771 Events: packet.events, 772 TransactionID: packet.transactionID, 773 PrevTransactionID: packet.prevTransactionID, 774 IsNewBranch: packet.nodeID == common.FirstEventID, 775 Info: "", 776 }) 777 s.NoError(err) 778 } 779 780 func (s *HistoryEventsSuite) appendRawHistoryBatches( 781 shardID int32, 782 branchToken []byte, 783 packet HistoryEventsPacket, 784 ) { 785 blob, err := s.serializer.SerializeEvents(packet.events, enumspb.ENCODING_TYPE_PROTO3) 786 s.NoError(err) 787 _, err = s.store.AppendRawHistoryNodes(s.Ctx, &p.AppendRawHistoryNodesRequest{ 788 ShardID: shardID, 789 BranchToken: branchToken, 790 NodeID: packet.nodeID, 791 TransactionID: packet.transactionID, 792 PrevTransactionID: packet.prevTransactionID, 793 IsNewBranch: packet.nodeID == common.FirstEventID, 794 Info: "", 795 History: blob, 796 }) 797 s.NoError(err) 798 } 799 800 func (s *HistoryEventsSuite) forkHistoryBranch( 801 shardID int32, 802 branchToken []byte, 803 newNodeID int64, 804 ) []byte { 805 resp, err := s.store.ForkHistoryBranch(s.Ctx, &p.ForkHistoryBranchRequest{ 806 ShardID: shardID, 807 NamespaceID: uuid.New(), 808 ForkBranchToken: branchToken, 809 ForkNodeID: newNodeID, 810 Info: "", 811 }) 812 s.NoError(err) 813 return resp.NewBranchToken 814 } 815 816 func (s *HistoryEventsSuite) deleteHistoryBranch( 817 shardID int32, 818 branchToken []byte, 819 ) { 820 err := s.store.DeleteHistoryBranch(s.Ctx, &p.DeleteHistoryBranchRequest{ 821 ShardID: shardID, 822 BranchToken: branchToken, 823 }) 824 s.NoError(err) 825 } 826 827 func (s *HistoryEventsSuite) trimHistoryBranch( 828 shardID int32, 829 branchToken []byte, 830 nodeID int64, 831 transactionID int64, 832 ) { 833 _, err := s.store.TrimHistoryBranch(s.Ctx, &p.TrimHistoryBranchRequest{ 834 ShardID: shardID, 835 BranchToken: branchToken, 836 NodeID: nodeID, 837 TransactionID: transactionID, 838 }) 839 s.NoError(err) 840 } 841 842 func (s *HistoryEventsSuite) listHistoryEvents( 843 shardID int32, 844 branchToken []byte, 845 startEventID int64, 846 endEventID int64, 847 ) []*historypb.HistoryEvent { 848 var token []byte 849 var events []*historypb.HistoryEvent 850 for doContinue := true; doContinue; doContinue = len(token) > 0 { 851 resp, err := s.store.ReadHistoryBranch(s.Ctx, &p.ReadHistoryBranchRequest{ 852 ShardID: shardID, 853 BranchToken: branchToken, 854 MinEventID: startEventID, 855 MaxEventID: endEventID, 856 PageSize: 1, // use 1 here for better testing exp 857 NextPageToken: token, 858 }) 859 s.NoError(err) 860 token = resp.NextPageToken 861 events = append(events, resp.HistoryEvents...) 862 } 863 return events 864 } 865 866 func (s *HistoryEventsSuite) listAllHistoryEvents( 867 shardID int32, 868 branchToken []byte, 869 ) []*historypb.HistoryEvent { 870 var token []byte 871 var events []*historypb.HistoryEvent 872 for doContinue := true; doContinue; doContinue = len(token) > 0 { 873 resp, err := s.store.ReadHistoryBranch(s.Ctx, &p.ReadHistoryBranchRequest{ 874 ShardID: shardID, 875 BranchToken: branchToken, 876 MinEventID: common.FirstEventID, 877 MaxEventID: common.LastEventID, 878 PageSize: 1, // use 1 here for better testing exp 879 NextPageToken: token, 880 }) 881 s.NoError(err) 882 token = resp.NextPageToken 883 events = append(events, resp.HistoryEvents...) 884 } 885 return events 886 } 887 888 func (s *HistoryEventsSuite) newHistoryEvents( 889 eventIDs []int64, 890 transactionID int64, 891 prevTransactionID int64, 892 ) HistoryEventsPacket { 893 894 events := make([]*historypb.HistoryEvent, len(eventIDs)) 895 for index, eventID := range eventIDs { 896 events[index] = &historypb.HistoryEvent{ 897 EventId: eventID, 898 EventTime: timestamppb.New(time.Unix(0, rand.Int63()).UTC()), 899 } 900 } 901 902 return HistoryEventsPacket{ 903 nodeID: eventIDs[0], 904 transactionID: transactionID, 905 prevTransactionID: prevTransactionID, 906 events: events, 907 } 908 }