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  }