github.com/ecodeclub/eorm@v0.0.2-0.20231001112437-dae71da914d0/internal/integration/sharding_delay_transaction_test.go (about) 1 // Copyright 2021 ecodeclub 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build e2e 16 17 package integration 18 19 import ( 20 "context" 21 "database/sql" 22 "testing" 23 24 "github.com/ecodeclub/eorm/internal/datasource/masterslave" 25 "github.com/ecodeclub/eorm/internal/datasource/transaction" 26 27 "github.com/ecodeclub/eorm" 28 "github.com/ecodeclub/eorm/internal/test" 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31 "github.com/stretchr/testify/suite" 32 ) 33 34 type ShardingDelayTxTestSuite struct { 35 ShardingSelectUpdateInsertSuite 36 } 37 38 func (s *ShardingDelayTxTestSuite) TestDoubleShardingSelect() { 39 t := s.T() 40 testCases := []struct { 41 name string 42 wantErr error 43 querySet []*test.OrderDetail 44 txFunc func(t *testing.T) *eorm.Tx 45 }{ 46 { 47 name: "double select", 48 querySet: []*test.OrderDetail{ 49 {OrderId: 8, ItemId: 6, UsingCol1: "Kobe", UsingCol2: "Bryant"}, 50 {OrderId: 11, ItemId: 8, UsingCol1: "James", UsingCol2: "Harden"}, 51 {OrderId: 234, ItemId: 12, UsingCol1: "Kevin", UsingCol2: "Durant"}, 52 {OrderId: 253, ItemId: 8, UsingCol1: "Stephen", UsingCol2: "Curry"}, 53 {OrderId: 181, ItemId: 11, UsingCol1: "Kawhi", UsingCol2: "Leonard"}, 54 }, 55 txFunc: func(t *testing.T) *eorm.Tx { 56 tx, er := s.shardingDB.BeginTx( 57 transaction.UsingTxType(context.Background(), transaction.Delay), &sql.TxOptions{}) 58 require.NoError(t, er) 59 return tx 60 }, 61 }, 62 } 63 for _, tc := range testCases { 64 t.Run(tc.name, func(t *testing.T) { 65 tx := tc.txFunc(t) 66 defer tx.Commit() 67 querySet, err := eorm.NewShardingSelector[test.OrderDetail](tx). 68 Where(eorm.C("OrderId").NEQ(123)). 69 GetMulti(masterslave.UseMaster(context.Background())) 70 require.NoError(t, err) 71 assert.ElementsMatch(t, tc.querySet, querySet) 72 73 querySet, err = eorm.NewShardingSelector[test.OrderDetail](tx). 74 Where(eorm.C("OrderId").NEQ(123)). 75 GetMulti(masterslave.UseMaster(context.Background())) 76 require.NoError(t, err) 77 assert.ElementsMatch(t, tc.querySet, querySet) 78 }) 79 } 80 } 81 82 func (s *ShardingDelayTxTestSuite) TestShardingSelectUpdateInsert_Commit_Or_Rollback() { 83 t := s.T() 84 testCases := []struct { 85 name string 86 updateAffected int64 87 insertAffected int64 88 target *test.OrderDetail 89 upPre eorm.Predicate 90 insertValues []*test.OrderDetail 91 querySet []*test.OrderDetail 92 upQuerySet []*test.OrderDetail 93 txFunc func(t *testing.T) *eorm.Tx 94 afterFunc func(t *testing.T, tx *eorm.Tx, values []*test.OrderDetail) 95 }{ 96 { 97 name: "select insert update commit", 98 upPre: eorm.C("OrderId").EQ(181), 99 updateAffected: 1, 100 insertAffected: 2, 101 target: &test.OrderDetail{UsingCol1: "Jordan"}, 102 insertValues: []*test.OrderDetail{ 103 {OrderId: 33, ItemId: 100, UsingCol1: "Nikolai", UsingCol2: "Jokic"}, 104 {OrderId: 288, ItemId: 101, UsingCol1: "Jimmy", UsingCol2: "Butler"}, 105 }, 106 querySet: []*test.OrderDetail{ 107 {OrderId: 8, ItemId: 6, UsingCol1: "Kobe", UsingCol2: "Bryant"}, 108 {OrderId: 11, ItemId: 8, UsingCol1: "James", UsingCol2: "Harden"}, 109 {OrderId: 181, ItemId: 11, UsingCol1: "Kawhi", UsingCol2: "Leonard"}, 110 {OrderId: 234, ItemId: 12, UsingCol1: "Kevin", UsingCol2: "Durant"}, 111 {OrderId: 253, ItemId: 8, UsingCol1: "Stephen", UsingCol2: "Curry"}, 112 }, 113 upQuerySet: []*test.OrderDetail{ 114 {OrderId: 8, ItemId: 6, UsingCol1: "Kobe", UsingCol2: "Bryant"}, 115 {OrderId: 11, ItemId: 8, UsingCol1: "James", UsingCol2: "Harden"}, 116 {OrderId: 33, ItemId: 100, UsingCol1: "Nikolai", UsingCol2: "Jokic"}, 117 {OrderId: 181, ItemId: 11, UsingCol1: "Jordan", UsingCol2: "Leonard"}, 118 {OrderId: 234, ItemId: 12, UsingCol1: "Kevin", UsingCol2: "Durant"}, 119 {OrderId: 253, ItemId: 8, UsingCol1: "Stephen", UsingCol2: "Curry"}, 120 {OrderId: 288, ItemId: 101, UsingCol1: "Jimmy", UsingCol2: "Butler"}, 121 }, 122 txFunc: func(t *testing.T) *eorm.Tx { 123 tx, er := s.shardingDB.BeginTx( 124 transaction.UsingTxType(context.Background(), transaction.Delay), &sql.TxOptions{}) 125 require.NoError(t, er) 126 return tx 127 }, 128 afterFunc: func(t *testing.T, tx *eorm.Tx, values []*test.OrderDetail) { 129 err := tx.Commit() 130 require.NoError(t, err) 131 132 queryVal := s.findTgt(t, values) 133 assert.ElementsMatch(t, values, queryVal) 134 }, 135 }, 136 { 137 name: "select insert update broadcast commit", 138 upPre: eorm.C("OrderId").GTEQ(253), 139 updateAffected: 2, 140 insertAffected: 2, 141 target: &test.OrderDetail{UsingCol1: "Jordan"}, 142 insertValues: []*test.OrderDetail{ 143 {OrderId: 199, ItemId: 100, UsingCol1: "Jason", UsingCol2: "Tatum"}, 144 {OrderId: 299, ItemId: 101, UsingCol1: "Paul", UsingCol2: "George"}, 145 }, 146 querySet: []*test.OrderDetail{ 147 {OrderId: 8, ItemId: 6, UsingCol1: "Kobe", UsingCol2: "Bryant"}, 148 {OrderId: 11, ItemId: 8, UsingCol1: "James", UsingCol2: "Harden"}, 149 {OrderId: 33, ItemId: 100, UsingCol1: "Nikolai", UsingCol2: "Jokic"}, 150 {OrderId: 181, ItemId: 11, UsingCol1: "Jordan", UsingCol2: "Leonard"}, 151 {OrderId: 234, ItemId: 12, UsingCol1: "Kevin", UsingCol2: "Durant"}, 152 {OrderId: 253, ItemId: 8, UsingCol1: "Stephen", UsingCol2: "Curry"}, 153 {OrderId: 288, ItemId: 101, UsingCol1: "Jimmy", UsingCol2: "Butler"}, 154 }, 155 upQuerySet: []*test.OrderDetail{ 156 {OrderId: 8, ItemId: 6, UsingCol1: "Kobe", UsingCol2: "Bryant"}, 157 {OrderId: 11, ItemId: 8, UsingCol1: "James", UsingCol2: "Harden"}, 158 {OrderId: 33, ItemId: 100, UsingCol1: "Nikolai", UsingCol2: "Jokic"}, 159 {OrderId: 181, ItemId: 11, UsingCol1: "Jordan", UsingCol2: "Leonard"}, 160 {OrderId: 199, ItemId: 100, UsingCol1: "Jason", UsingCol2: "Tatum"}, 161 {OrderId: 234, ItemId: 12, UsingCol1: "Kevin", UsingCol2: "Durant"}, 162 {OrderId: 253, ItemId: 8, UsingCol1: "Jordan", UsingCol2: "Curry"}, 163 {OrderId: 288, ItemId: 101, UsingCol1: "Jordan", UsingCol2: "Butler"}, 164 {OrderId: 299, ItemId: 101, UsingCol1: "Paul", UsingCol2: "George"}, 165 }, 166 txFunc: func(t *testing.T) *eorm.Tx { 167 tx, er := s.shardingDB.BeginTx( 168 transaction.UsingTxType(context.Background(), transaction.Delay), &sql.TxOptions{}) 169 require.NoError(t, er) 170 return tx 171 }, 172 afterFunc: func(t *testing.T, tx *eorm.Tx, values []*test.OrderDetail) { 173 err := tx.Commit() 174 require.NoError(t, err) 175 176 queryVal := s.findTgt(t, values) 177 assert.ElementsMatch(t, values, queryVal) 178 }, 179 }, 180 { 181 name: "select insert update rollback", 182 upPre: eorm.C("OrderId").EQ(299), 183 updateAffected: 1, 184 insertAffected: 1, 185 target: &test.OrderDetail{UsingCol1: "Jordan"}, 186 insertValues: []*test.OrderDetail{ 187 {OrderId: 48, ItemId: 100}, 188 }, 189 querySet: []*test.OrderDetail{ 190 {OrderId: 8, ItemId: 6, UsingCol1: "Kobe", UsingCol2: "Bryant"}, 191 {OrderId: 11, ItemId: 8, UsingCol1: "James", UsingCol2: "Harden"}, 192 {OrderId: 33, ItemId: 100, UsingCol1: "Nikolai", UsingCol2: "Jokic"}, 193 {OrderId: 181, ItemId: 11, UsingCol1: "Jordan", UsingCol2: "Leonard"}, 194 {OrderId: 199, ItemId: 100, UsingCol1: "Jason", UsingCol2: "Tatum"}, 195 {OrderId: 234, ItemId: 12, UsingCol1: "Kevin", UsingCol2: "Durant"}, 196 {OrderId: 253, ItemId: 8, UsingCol1: "Jordan", UsingCol2: "Curry"}, 197 {OrderId: 288, ItemId: 101, UsingCol1: "Jordan", UsingCol2: "Butler"}, 198 {OrderId: 299, ItemId: 101, UsingCol1: "Paul", UsingCol2: "George"}, 199 }, 200 upQuerySet: []*test.OrderDetail{ 201 {OrderId: 8, ItemId: 6, UsingCol1: "Kobe", UsingCol2: "Bryant"}, 202 {OrderId: 11, ItemId: 8, UsingCol1: "James", UsingCol2: "Harden"}, 203 {OrderId: 33, ItemId: 100, UsingCol1: "Nikolai", UsingCol2: "Jokic"}, 204 {OrderId: 181, ItemId: 11, UsingCol1: "Jordan", UsingCol2: "Leonard"}, 205 {OrderId: 199, ItemId: 100, UsingCol1: "Jason", UsingCol2: "Tatum"}, 206 {OrderId: 234, ItemId: 12, UsingCol1: "Kevin", UsingCol2: "Durant"}, 207 {OrderId: 253, ItemId: 8, UsingCol1: "Jordan", UsingCol2: "Curry"}, 208 {OrderId: 288, ItemId: 101, UsingCol1: "Jordan", UsingCol2: "Butler"}, 209 {OrderId: 299, ItemId: 101, UsingCol1: "Paul", UsingCol2: "George"}, 210 }, 211 txFunc: func(t *testing.T) *eorm.Tx { 212 tx, er := s.shardingDB.BeginTx( 213 transaction.UsingTxType(context.Background(), transaction.Delay), &sql.TxOptions{}) 214 require.NoError(t, er) 215 return tx 216 }, 217 afterFunc: func(t *testing.T, tx *eorm.Tx, values []*test.OrderDetail) { 218 err := tx.Rollback() 219 require.NoError(t, err) 220 221 queryVal := s.findTgt(t, values) 222 assert.ElementsMatch(t, values, queryVal) 223 }, 224 }, 225 } 226 for _, tc := range testCases { 227 t.Run(tc.name, func(t *testing.T) { 228 tx := tc.txFunc(t) 229 querySet, err := eorm.NewShardingSelector[test.OrderDetail](tx). 230 Where(eorm.C("OrderId").NEQ(123)). 231 GetMulti(masterslave.UseMaster(context.Background())) 232 require.NoError(t, err) 233 assert.ElementsMatch(t, tc.querySet, querySet) 234 235 res := eorm.NewShardingUpdater[test.OrderDetail](tx).Update(tc.target). 236 Set(eorm.C("UsingCol1")).Where(tc.upPre).Exec(context.Background()) 237 affected, err := res.RowsAffected() 238 require.NoError(t, err) 239 assert.Equal(t, tc.updateAffected, affected) 240 241 res = eorm.NewShardingInsert[test.OrderDetail](tx). 242 Values(tc.insertValues).Exec(context.Background()) 243 affected, err = res.RowsAffected() 244 require.NoError(t, err) 245 assert.Equal(t, tc.insertAffected, affected) 246 247 tc.afterFunc(t, tx, tc.upQuerySet) 248 }) 249 } 250 } 251 252 func TestMySQL8ShardingDelayTxTestSuite(t *testing.T) { 253 suite.Run(t, &ShardingDelayTxTestSuite{ 254 ShardingSelectUpdateInsertSuite: newShardingSelectUpdateInsertSuite(), 255 }) 256 }