github.com/ecodeclub/eorm@v0.0.2-0.20231001112437-dae71da914d0/internal/integration/select_masterslave_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  	"testing"
    22  	"time"
    23  
    24  	"github.com/ecodeclub/eorm/internal/datasource/masterslave"
    25  
    26  	"github.com/ecodeclub/eorm"
    27  	"github.com/ecodeclub/eorm/internal/test"
    28  	"github.com/stretchr/testify/assert"
    29  )
    30  
    31  type MasterSlaveSelectTestSuite struct {
    32  	MasterSlaveSuite
    33  	data []*test.SimpleStruct
    34  }
    35  
    36  func (s *MasterSlaveSelectTestSuite) SetupSuite() {
    37  	s.MasterSlaveSuite.SetupSuite()
    38  	s.data = append(s.data, test.NewSimpleStruct(1))
    39  	s.data = append(s.data, test.NewSimpleStruct(2))
    40  	s.data = append(s.data, test.NewSimpleStruct(3))
    41  	res := eorm.NewInserter[test.SimpleStruct](s.orm).Values(s.data...).Exec(context.Background())
    42  	if res.Err() != nil {
    43  		s.T().Fatal(res.Err())
    44  	}
    45  	// 避免主从延迟
    46  	time.Sleep(time.Second * 10)
    47  }
    48  
    49  func (s *MasterSlaveSelectTestSuite) TearDownSuite() {
    50  	res := eorm.RawQuery[any](s.orm, "TRUNCATE TABLE `simple_struct`").Exec(context.Background())
    51  	if res.Err() != nil {
    52  		s.T().Fatal(res.Err())
    53  	}
    54  }
    55  
    56  func (s *MasterSlaveSelectTestSuite) TestMasterSlave() {
    57  	testcases := []struct {
    58  		name      string
    59  		i         *eorm.Selector[test.SimpleStruct]
    60  		wantErr   error
    61  		wantRes   []*test.SimpleStruct
    62  		wantSlave string
    63  		ctx       func() context.Context
    64  	}{
    65  		{
    66  			name:    "query use master",
    67  			i:       eorm.NewSelector[test.SimpleStruct](s.orm).Where(eorm.C("Id").LT(4)),
    68  			wantRes: s.data,
    69  			ctx: func() context.Context {
    70  				c := context.Background()
    71  				return masterslave.UseMaster(c)
    72  			},
    73  		},
    74  		// TODO 从库测试目前有查不到数据的bug
    75  		{
    76  			name:      "query use slave",
    77  			i:         eorm.NewSelector[test.SimpleStruct](s.orm).Where(eorm.C("Id").LT(4)),
    78  			wantSlave: "0",
    79  			wantRes:   s.data,
    80  			ctx: func() context.Context {
    81  				return context.Background()
    82  			},
    83  		},
    84  	}
    85  	for _, tc := range testcases {
    86  		s.T().Run(tc.name, func(t *testing.T) {
    87  			ctx := tc.ctx()
    88  			res, err := tc.i.GetMulti(ctx)
    89  			assert.Equal(t, tc.wantErr, err)
    90  			if err != nil {
    91  				return
    92  			}
    93  			assert.Equal(t, tc.wantRes, res)
    94  			slaveName := ""
    95  			select {
    96  			case slaveName = <-s.testSlaves.ch:
    97  			default:
    98  			}
    99  			assert.Equal(t, tc.wantSlave, slaveName)
   100  		})
   101  	}
   102  }
   103  
   104  //func TestMasterSlaveSelect(t *testing.T) {
   105  //	suite.Run(t, &MasterSlaveSelectTestSuite{
   106  //		MasterSlaveSuite: MasterSlaveSuite{
   107  //			driver:     "mysql",
   108  //			masterDsn:  "root:root@tcp(localhost:13307)/integration_test",
   109  //			slaveDsns:  []string{"root:root@tcp(localhost:13308)/integration_test"},
   110  //			initSlaves: newRoundRobinSlaves,
   111  //		},
   112  //	})
   113  //	suite.Run(t, &MasterSlaveDNSTestSuite{
   114  //		MasterSlaveSuite: MasterSlaveSuite{
   115  //			driver:     "mysql",
   116  //			masterDsn:  "root:root@tcp(localhost:13307)/integration_test",
   117  //			slaveDsns:  []string{"root:root@tcp(slave.a.com:13308)/integration_test"},
   118  //			initSlaves: newDnsSlaves,
   119  //		},
   120  //	})
   121  //}
   122  
   123  type MasterSlaveDNSTestSuite struct {
   124  	MasterSlaveSuite
   125  	data []*test.SimpleStruct
   126  }
   127  
   128  func (m *MasterSlaveDNSTestSuite) SetupSuite() {
   129  	m.MasterSlaveSuite.SetupSuite()
   130  	m.data = append(m.data, test.NewSimpleStruct(1))
   131  	m.data = append(m.data, test.NewSimpleStruct(2))
   132  	m.data = append(m.data, test.NewSimpleStruct(3))
   133  	res := eorm.NewInserter[test.SimpleStruct](m.orm).Values(m.data...).Exec(context.Background())
   134  	if res.Err() != nil {
   135  		m.T().Fatal(res.Err())
   136  	}
   137  	// 避免主从延迟
   138  	time.Sleep(time.Second * 10)
   139  }
   140  func (m *MasterSlaveDNSTestSuite) TearDownSuite() {
   141  	res := eorm.RawQuery[any](m.orm, "TRUNCATE TABLE `simple_struct`").Exec(context.Background())
   142  	if res.Err() != nil {
   143  		m.T().Fatal(res.Err())
   144  	}
   145  }
   146  
   147  func (m *MasterSlaveDNSTestSuite) TestDNSMasterSlave() {
   148  	testcases := []struct {
   149  		name      string
   150  		i         *eorm.Selector[test.SimpleStruct]
   151  		wantErr   error
   152  		wantRes   []*test.SimpleStruct
   153  		wantSlave string
   154  		ctx       func() context.Context
   155  	}{
   156  		// TODO 从库测试目前有查不到数据的bug
   157  		{
   158  			name:      "get slave with dns",
   159  			i:         eorm.NewSelector[test.SimpleStruct](m.orm).Where(eorm.C("Id").LT(4)),
   160  			wantSlave: "0",
   161  			wantRes:   m.data,
   162  			ctx: func() context.Context {
   163  				return context.Background()
   164  			},
   165  		},
   166  	}
   167  	for _, tc := range testcases {
   168  		m.T().Run(tc.name, func(t *testing.T) {
   169  			ctx := tc.ctx()
   170  			res, err := tc.i.GetMulti(ctx)
   171  			assert.Equal(t, tc.wantErr, err)
   172  			if err != nil {
   173  				return
   174  			}
   175  			assert.Equal(t, tc.wantRes, res)
   176  			slaveName := ""
   177  			select {
   178  			case slaveName = <-m.testSlaves.ch:
   179  			default:
   180  			}
   181  			assert.Equal(t, tc.wantSlave, slaveName)
   182  		})
   183  	}
   184  }