go.temporal.io/server@v1.23.0/common/persistence/history_node_util_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 "math/rand" 29 "testing" 30 31 "github.com/pborman/uuid" 32 "github.com/stretchr/testify/require" 33 "github.com/stretchr/testify/suite" 34 35 "go.temporal.io/server/common" 36 37 persistencespb "go.temporal.io/server/api/persistence/v1" 38 ) 39 40 type ( 41 historyNodeMetadataSuite struct { 42 suite.Suite 43 *require.Assertions 44 } 45 ) 46 47 func TestHistoryNodeMetadataSuite(t *testing.T) { 48 s := new(historyNodeMetadataSuite) 49 suite.Run(t, s) 50 } 51 52 func (s *historyNodeMetadataSuite) SetupSuite() { 53 } 54 55 func (s *historyNodeMetadataSuite) TearDownSuite() { 56 57 } 58 59 func (s *historyNodeMetadataSuite) SetupTest() { 60 s.Assertions = require.New(s.T()) 61 } 62 63 func (s *historyNodeMetadataSuite) TearDownTest() { 64 65 } 66 67 func (s *historyNodeMetadataSuite) TestIndexNodeIDToNode() { 68 branch := &persistencespb.HistoryBranch{ 69 TreeId: uuid.New(), 70 BranchId: uuid.New(), 71 } 72 numNodeIDs := 10 73 nodePerNodeID := 10 74 75 prevTransactionID := int64(0) 76 transactionIDToNode := map[int64]historyNodeMetadata{} 77 for nodeID := common.FirstEventID; nodeID < int64(numNodeIDs+1); nodeID++ { 78 var nextTransactionID *int64 79 for i := 0; i < nodePerNodeID; i++ { 80 transactionID := rand.Int63() 81 if nextTransactionID == nil || *nextTransactionID < transactionID { 82 nextTransactionID = &transactionID 83 } 84 node := s.newRandomHistoryNodeMetadata(branch, nodeID, transactionID, prevTransactionID) 85 transactionIDToNode[node.transactionID] = node 86 } 87 prevTransactionID = *nextTransactionID 88 } 89 90 nodeIDToNode := indexNodeIDToNode(transactionIDToNode) 91 for nodeID := common.FirstEventID; nodeID < int64(numNodeIDs+1); nodeID++ { 92 nodes := nodeIDToNode[int64(nodeID)] 93 for i := 1; i < nodePerNodeID; i++ { 94 s.True(nodes[i-1].transactionID >= nodes[i].transactionID) 95 } 96 } 97 } 98 99 func (s *historyNodeMetadataSuite) TestReverselyLinkNode() { 100 branch := &persistencespb.HistoryBranch{ 101 TreeId: uuid.New(), 102 BranchId: uuid.New(), 103 } 104 numNodeIDs := 10 105 nodePerNodeID := 10 106 107 var expectedNodes []historyNodeMetadata 108 prevTransactionID := int64(0) 109 transactionIDToNode := map[int64]historyNodeMetadata{} 110 for nodeID := common.FirstEventID; nodeID < int64(numNodeIDs+1); nodeID++ { 111 var nextTransactionID *int64 112 for i := 0; i < nodePerNodeID; i++ { 113 transactionID := rand.Int63() 114 if nextTransactionID == nil || *nextTransactionID < transactionID { 115 nextTransactionID = &transactionID 116 } 117 node := s.newRandomHistoryNodeMetadata(branch, nodeID, transactionID, prevTransactionID) 118 transactionIDToNode[node.transactionID] = node 119 } 120 prevTransactionID = *nextTransactionID 121 expectedNodes = append([]historyNodeMetadata{transactionIDToNode[prevTransactionID]}, expectedNodes...) 122 } 123 lastValidNode := s.newRandomHistoryNodeMetadata(branch, int64(numNodeIDs+1), rand.Int63(), prevTransactionID) 124 transactionIDToNode[lastValidNode.transactionID] = lastValidNode 125 expectedNodes = append([]historyNodeMetadata{lastValidNode}, expectedNodes...) 126 127 nodes, err := reverselyLinkNode(lastValidNode.nodeID, lastValidNode.transactionID, transactionIDToNode) 128 s.NoError(err) 129 s.Equal(expectedNodes, nodes) 130 } 131 132 func (s *historyNodeMetadataSuite) TestTrimNodes() { 133 branch := &persistencespb.HistoryBranch{ 134 TreeId: uuid.New(), 135 BranchId: uuid.New(), 136 } 137 138 node1Valid := s.newRandomHistoryNodeMetadata(branch, 1, rand.Int63(), 0) 139 node1Stale0 := s.newRandomHistoryNodeMetadata(branch, 1, node1Valid.transactionID-11, 0) 140 node1Stale1 := s.newRandomHistoryNodeMetadata(branch, 1, node1Valid.transactionID-22, 0) 141 node1Trim0 := s.newRandomHistoryNodeMetadata(branch, 1, node1Valid.transactionID+33, 0) 142 node1Trim1 := s.newRandomHistoryNodeMetadata(branch, 1, node1Valid.transactionID+44, 0) 143 // reverse sort by transaction ID 144 node1s := []historyNodeMetadata{node1Trim1, node1Trim0, node1Valid, node1Stale0, node1Stale1} 145 146 node2Valid := s.newRandomHistoryNodeMetadata(branch, 2, rand.Int63(), 0) 147 // reverse sort by transaction ID 148 node2s := []historyNodeMetadata{node2Valid} 149 150 node3Valid := s.newRandomHistoryNodeMetadata(branch, 3, rand.Int63(), 0) 151 node3Stale0 := s.newRandomHistoryNodeMetadata(branch, 3, node3Valid.transactionID-100, 0) 152 node3Stale1 := s.newRandomHistoryNodeMetadata(branch, 3, node3Valid.transactionID-200, 0) 153 // reverse sort by transaction ID 154 node3s := []historyNodeMetadata{node3Valid, node3Stale0, node3Stale1} 155 156 node4Valid := s.newRandomHistoryNodeMetadata(branch, 4, rand.Int63(), 0) 157 node4Trim0 := s.newRandomHistoryNodeMetadata(branch, 4, node4Valid.transactionID+1024, 0) 158 node4Trim1 := s.newRandomHistoryNodeMetadata(branch, 4, node4Valid.transactionID+2048, 0) 159 // reverse sort by transaction ID 160 node4s := []historyNodeMetadata{node4Trim1, node4Trim0, node4Valid} 161 162 nodeIDToNodes := map[int64][]historyNodeMetadata{ 163 1: node1s, 164 2: node2s, 165 3: node3s, 166 4: node4s, 167 } 168 169 nodesToTrim := trimNodes(nodeIDToNodes, []historyNodeMetadata{node4Valid, node3Valid, node2Valid, node1Valid}) 170 s.Equal([]historyNodeMetadata{node4Trim1, node4Trim0, node1Trim1, node1Trim0}, nodesToTrim) 171 } 172 173 func (s *historyNodeMetadataSuite) newRandomHistoryNodeMetadata( 174 branch *persistencespb.HistoryBranch, 175 nodeID int64, 176 transactionID int64, 177 prevTransactionID int64, 178 ) historyNodeMetadata { 179 return historyNodeMetadata{ 180 branchInfo: branch, 181 nodeID: nodeID, 182 transactionID: transactionID, 183 prevTransactionID: prevTransactionID, 184 } 185 }