/connection/connection_test.go
https://github.com/knocknote/octillery · Go · 486 lines · 437 code · 49 blank · 0 comment · 103 complexity · b52ceef38a0750fa12c44f0ba43ed6aa MD5 · raw file
- package connection
- import (
- "context"
- "database/sql"
- "database/sql/driver"
- "path/filepath"
- "testing"
- "time"
- "go.knocknote.io/octillery/config"
- "go.knocknote.io/octillery/connection/adapter"
- "go.knocknote.io/octillery/path"
- )
- type TestAdapter struct {
- }
- func (t *TestAdapter) CurrentSequenceID(conn *sql.DB, tableName string) (int64, error) {
- return 1, nil
- }
- func (t *TestAdapter) NextSequenceID(conn *sql.DB, tableName string) (int64, error) {
- return 2, nil
- }
- func (t *TestAdapter) ExecDDL(config *config.DatabaseConfig) error {
- return nil
- }
- func (t *TestAdapter) OpenConnection(config *config.DatabaseConfig, queryValues string) (*sql.DB, error) {
- return sql.Open("sqlite3", "")
- }
- func (t *TestAdapter) CreateSequencerTableIfNotExists(conn *sql.DB, tableName string) error {
- return nil
- }
- func (t *TestAdapter) InsertRowToSequencerIfNotExists(conn *sql.DB, tableName string) error {
- return nil
- }
- type TestDriver struct {
- }
- func (t *TestDriver) Open(name string) (driver.Conn, error) {
- return &TestConn{}, nil
- }
- type TestConn struct {
- }
- func (t *TestConn) Prepare(query string) (driver.Stmt, error) {
- return &TestStmt{}, nil
- }
- func (t *TestConn) Begin() (driver.Tx, error) {
- return &TestTx{}, nil
- }
- func (t *TestConn) Close() error {
- return nil
- }
- func (t *TestConn) Query(query string, args []driver.Value) (driver.Rows, error) {
- return &TestRows{}, nil
- }
- type TestStmt struct {
- }
- func (t *TestStmt) Close() error {
- return nil
- }
- func (t *TestStmt) NumInput() int {
- return 0
- }
- func (t *TestStmt) Exec(args []driver.Value) (driver.Result, error) {
- return &TestResult{}, nil
- }
- func (t *TestStmt) Query(args []driver.Value) (driver.Rows, error) {
- return &TestRows{}, nil
- }
- type TestResult struct {
- }
- func (t *TestResult) LastInsertId() (int64, error) {
- return 0, nil
- }
- func (t *TestResult) RowsAffected() (int64, error) {
- return 0, nil
- }
- type TestRows struct {
- }
- func (t *TestRows) Columns() []string {
- return []string{}
- }
- func (t *TestRows) Close() error {
- return nil
- }
- func (t *TestRows) Next(dest []driver.Value) error {
- return nil
- }
- type TestTx struct {
- }
- func (t *TestTx) Commit() error {
- return nil
- }
- func (t *TestTx) Rollback() error {
- return nil
- }
- func checkErr(t *testing.T, err error) {
- if err != nil {
- t.Fatalf("%+v\n", err)
- }
- }
- func init() {
- adapter.Register("sqlite3", &TestAdapter{})
- sql.Register("sqlite3", &TestDriver{})
- confPath := filepath.Join(path.ThisDirPath(), "..", "test_databases.yml")
- cfg, err := config.Load(confPath)
- if err != nil {
- panic(err)
- }
- if err := SetConfig(cfg); err != nil {
- panic(err)
- }
- }
- func TestSetQueryString(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- if err := mgr.SetQueryString("?#%"); err == nil {
- t.Fatal("cannot handle error")
- }
- checkErr(t, mgr.SetQueryString(""))
- checkErr(t, mgr.SetQueryString("?parseTime=true&loc=Asia%2FTokyo"))
- }
- func TestGetConnection(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- t.Run("connection by users table", func(t *testing.T) {
- conn, err := mgr.ConnectionByTableName("users")
- checkErr(t, err)
- if c, _ := mgr.ConnectionByTableName("users"); c != conn {
- t.Fatal("cannot fetch same instance")
- }
- if conn.ShardConnections.ShardNum() != 2 {
- t.Fatal("cannot get shard num")
- }
- if len(conn.ShardConnections.AllShard()) != 2 {
- t.Fatal("cannot get all shard")
- }
- shardConn := conn.ShardConnections.ShardConnectionByName("user_shard_1")
- if shardConn == nil {
- t.Fatal("cannot get shard connection by name")
- }
- shardConnByIndex := conn.ShardConnections.ShardConnectionByIndex(0)
- if shardConnByIndex == nil {
- t.Fatal("cannot get shard connection by index")
- }
- if _, err := mgr.SequencerConnectionByTableName("users"); err != nil {
- t.Fatalf("%+v\n", err)
- }
- })
- t.Run("connection by user_stages table", func(t *testing.T) {
- if _, err := mgr.ConnectionByTableName("user_stages"); err != nil {
- t.Fatalf("%+v\n", err)
- }
- })
- }
- func TestSetSettings(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- mgr.SetMaxIdleConns(10)
- mgr.SetMaxOpenConns(10)
- mgr.SetConnMaxLifetime(10 * time.Second)
- }
- func TestCurrentSequenceID(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- id, err := mgr.CurrentSequenceID("users")
- checkErr(t, err)
- if id != 1 {
- t.Fatal("cannot get current sequence id")
- }
- }
- func TestNextSequenceID(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- id, err := mgr.NextSequenceID("users")
- checkErr(t, err)
- if id != 2 {
- t.Fatal("cannot get next sequence id")
- }
- {
- conn, err := mgr.ConnectionByTableName("users")
- checkErr(t, err)
- id, err := conn.NextSequenceID("users")
- checkErr(t, err)
- if id != 2 {
- t.Fatal("cannot get next sequence id")
- }
- }
- }
- func TestIsShardTable(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- if !mgr.IsShardTable("users") {
- t.Fatal("cannot set is_shard configuration")
- }
- if mgr.IsShardTable("user_stages") {
- t.Fatal("cannot set is_shard configuration")
- }
- }
- func TestEqualDSN(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- conn, err := mgr.ConnectionByTableName("users")
- checkErr(t, err)
- t.Run("same instance", func(t *testing.T) {
- if !conn.EqualDSN(conn) {
- t.Fatal("cannot work equal dsn")
- }
- })
- t.Run("another instance", func(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- anotherConn, err := mgr.ConnectionByTableName("users")
- checkErr(t, err)
- if !conn.EqualDSN(anotherConn) {
- t.Fatal("cannot work equal dsn")
- }
- })
- }
- func TestIsEqualShardColumnToShardKeyColumn(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- if !mgr.IsEqualShardColumnToShardKeyColumn("users") {
- t.Fatal("cannot set shard_column and shard_key")
- }
- if mgr.IsEqualShardColumnToShardKeyColumn("user_items") {
- t.Fatal("cannot set shard_column and shard_key")
- }
- if mgr.IsEqualShardColumnToShardKeyColumn("user_decks") {
- t.Fatal("cannot set shard_column and shard_key")
- }
- if !mgr.IsEqualShardColumnToShardKeyColumn("user_stages") {
- t.Fatal("cannot set shard_column and shard_key")
- }
- conn, err := mgr.ConnectionByTableName("users")
- checkErr(t, err)
- if !conn.IsEqualShardColumnToShardKeyColumn() {
- t.Fatal("cannot set shard_column and shard_key")
- }
- }
- func TestShardConnectionByID(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- conn, err := mgr.ConnectionByTableName("users")
- checkErr(t, err)
- {
- shardConn, err := conn.ShardConnectionByID(1)
- checkErr(t, err)
- if shardConn.ShardName != "user_shard_2" {
- t.Fatal("invalid shard connection by id")
- }
- }
- {
- shardConn, err := conn.ShardConnectionByID(2)
- checkErr(t, err)
- if shardConn.ShardName != "user_shard_1" {
- t.Fatal("invalid shard connection by id")
- }
- }
- }
- func TestShardColumnName(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- if mgr.ShardColumnName("users") != "id" {
- t.Fatal("cannot get shard_column name")
- }
- if mgr.ShardColumnName("user_items") != "" {
- t.Fatal("cannot get shard_column name")
- }
- if mgr.ShardColumnName("user_decks") != "id" {
- t.Fatal("cannot get shard_column name")
- }
- if mgr.ShardColumnName("user_stages") != "" {
- t.Fatal("cannot get shard_column name")
- }
- }
- func TestShardKeyColumnName(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- if mgr.ShardKeyColumnName("users") != "id" {
- t.Fatal("cannot get shard_key name")
- }
- if mgr.ShardKeyColumnName("user_items") != "user_id" {
- t.Fatal("cannot get shard_key name")
- }
- if mgr.ShardKeyColumnName("user_decks") != "user_id" {
- t.Fatal("cannot get shard_key name")
- }
- if mgr.ShardKeyColumnName("user_stages") != "" {
- t.Fatal("cannot get shard_key name")
- }
- }
- func TestQuery(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- t.Run("not sharding table", func(t *testing.T) {
- conn, err := mgr.ConnectionByTableName("user_stages")
- checkErr(t, err)
- t.Run("without context", func(t *testing.T) {
- rows, err := conn.Query(nil, "select * from user_stages")
- checkErr(t, err)
- if columns, _ := rows.Columns(); len(columns) != 0 {
- t.Fatal("unknown rows")
- }
- })
- t.Run("with context", func(t *testing.T) {
- rows, err := conn.Query(ctx, "select * from user_stages")
- checkErr(t, err)
- if columns, _ := rows.Columns(); len(columns) != 0 {
- t.Fatal("unknown rows")
- }
- })
- })
- }
- func TestQueryRow(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- t.Run("not sharding table", func(t *testing.T) {
- conn, err := mgr.ConnectionByTableName("user_stages")
- checkErr(t, err)
- t.Run("without context", func(t *testing.T) {
- conn.QueryRow(nil, "select * from user_stages where user_id = 1")
- })
- t.Run("with context", func(t *testing.T) {
- conn.QueryRow(ctx, "select * from user_stages where user_id = 1")
- })
- })
- }
- func TestPrepare(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- t.Run("not sharding table", func(t *testing.T) {
- conn, err := mgr.ConnectionByTableName("user_stages")
- checkErr(t, err)
- t.Run("without context", func(t *testing.T) {
- stmt, err := conn.Prepare(nil, "select * from user_stages where user_id = ?")
- checkErr(t, err)
- checkErr(t, stmt.Close())
- })
- t.Run("with context", func(t *testing.T) {
- stmt, err := conn.Prepare(ctx, "select * from user_stages where user_id = ?")
- checkErr(t, err)
- checkErr(t, stmt.Close())
- })
- })
- }
- func TestExec(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- t.Run("not sharding table", func(t *testing.T) {
- conn, err := mgr.ConnectionByTableName("user_stages")
- checkErr(t, err)
- t.Run("without context", func(t *testing.T) {
- result, err := conn.Exec(nil, "update user_stages set name = 'alice' where user_id = ?")
- checkErr(t, err)
- affected, err := result.RowsAffected()
- checkErr(t, err)
- if affected != 0 {
- t.Fatal("cannot get rows affected")
- }
- })
- t.Run("with context", func(t *testing.T) {
- result, err := conn.Exec(ctx, "update user_stages set name = 'alice' where user_id = ?")
- checkErr(t, err)
- affected, err := result.RowsAffected()
- checkErr(t, err)
- if affected != 0 {
- t.Fatal("cannot get rows affected")
- }
- })
- })
- }
- func TestTransaction(t *testing.T) {
- mgr, err := NewConnectionManager()
- checkErr(t, err)
- defer mgr.Close()
- conn, err := mgr.ConnectionByTableName("user_stages")
- checkErr(t, err)
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- t.Run("without context", func(t *testing.T) {
- tx := conn.Begin(nil, nil)
- stmt, err := tx.Prepare(nil, conn, "select * from user_stages where id = ?")
- checkErr(t, err)
- if _, err := tx.Stmt(nil, conn, stmt); err != nil {
- t.Fatalf("%+v\n", err)
- }
- if _, err := tx.QueryRow(nil, conn, "select * from user_stages where id = 1"); err != nil {
- t.Fatalf("%+v\n", err)
- }
- if _, err := tx.Query(nil, conn, "select * from user_stages"); err != nil {
- t.Fatalf("%+v\n", err)
- }
- if _, err := tx.Exec(nil, conn, "delete from user_stages where id = 1"); err != nil {
- t.Fatalf("%+v\n", err)
- }
- checkErr(t, tx.Commit())
- })
- t.Run("with context", func(t *testing.T) {
- tx := conn.Begin(ctx, nil)
- stmt, err := tx.Prepare(ctx, conn, "select * from user_stages where id = ?")
- checkErr(t, err)
- if _, err := tx.Stmt(ctx, conn, stmt); err != nil {
- t.Fatalf("%+v\n", err)
- }
- if _, err := tx.QueryRow(ctx, conn, "select * from user_stages where id = 1"); err != nil {
- t.Fatalf("%+v\n", err)
- }
- if _, err := tx.Query(ctx, conn, "select * from user_stages"); err != nil {
- t.Fatalf("%+v\n", err)
- }
- if _, err := tx.Exec(ctx, conn, "delete from user_stages where id = 1"); err != nil {
- t.Fatalf("%+v\n", err)
- }
- checkErr(t, tx.Rollback())
- })
- }