go.temporal.io/server@v1.23.0/common/persistence/tests/postgresql_test_util.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 "fmt" 29 "net" 30 "path/filepath" 31 "strconv" 32 "testing" 33 34 "go.uber.org/zap/zaptest" 35 36 "go.temporal.io/server/common/config" 37 "go.temporal.io/server/common/log" 38 p "go.temporal.io/server/common/persistence" 39 "go.temporal.io/server/common/persistence/sql" 40 "go.temporal.io/server/common/persistence/sql/sqlplugin" 41 "go.temporal.io/server/common/resolver" 42 "go.temporal.io/server/common/shuffle" 43 "go.temporal.io/server/environment" 44 ) 45 46 // TODO merge the initialization with existing persistence setup 47 const ( 48 testPostgreSQLClusterName = "temporal_postgresql_cluster" 49 50 testPostgreSQLUser = "temporal" 51 testPostgreSQLPassword = "temporal" 52 testPostgreSQLConnectionProtocol = "tcp" 53 testPostgreSQLDatabaseNamePrefix = "test_" 54 testPostgreSQLDatabaseNameSuffix = "temporal_persistence" 55 56 // TODO hard code this dir for now 57 // need to merge persistence test config / initialization in one place 58 testPostgreSQLExecutionSchema = "../../../schema/postgresql/v12/temporal/schema.sql" 59 testPostgreSQLVisibilitySchema = "../../../schema/postgresql/v12/visibility/schema.sql" 60 ) 61 62 type ( 63 PostgreSQLTestData struct { 64 Cfg *config.SQL 65 Factory *sql.Factory 66 Logger log.Logger 67 } 68 ) 69 70 func setUpPostgreSQLTest(t *testing.T, pluginName string) (PostgreSQLTestData, func()) { 71 var testData PostgreSQLTestData 72 testData.Cfg = NewPostgreSQLConfig(pluginName) 73 testData.Logger = log.NewZapLogger(zaptest.NewLogger(t)) 74 SetupPostgreSQLDatabase(testData.Cfg) 75 SetupPostgreSQLSchema(testData.Cfg) 76 77 testData.Factory = sql.NewFactory( 78 *testData.Cfg, 79 resolver.NewNoopResolver(), 80 testPostgreSQLClusterName, 81 testData.Logger, 82 ) 83 84 tearDown := func() { 85 testData.Factory.Close() 86 TearDownPostgreSQLDatabase(testData.Cfg) 87 } 88 89 return testData, tearDown 90 } 91 92 // NewPostgreSQLConfig returns a new MySQL config for test 93 func NewPostgreSQLConfig(pluginName string) *config.SQL { 94 return &config.SQL{ 95 User: testPostgreSQLUser, 96 Password: testPostgreSQLPassword, 97 ConnectAddr: net.JoinHostPort( 98 environment.GetPostgreSQLAddress(), 99 strconv.Itoa(environment.GetPostgreSQLPort()), 100 ), 101 ConnectProtocol: testPostgreSQLConnectionProtocol, 102 PluginName: pluginName, 103 DatabaseName: testPostgreSQLDatabaseNamePrefix + shuffle.String(testPostgreSQLDatabaseNameSuffix), 104 } 105 } 106 107 func SetupPostgreSQLDatabase(cfg *config.SQL) { 108 adminCfg := *cfg 109 // NOTE need to connect with empty name to create new database 110 adminCfg.DatabaseName = "" 111 112 db, err := sql.NewSQLAdminDB(sqlplugin.DbKindUnknown, &adminCfg, resolver.NewNoopResolver()) 113 if err != nil { 114 panic(fmt.Sprintf("unable to create PostgreSQL admin DB: %v", err)) 115 } 116 defer func() { _ = db.Close() }() 117 118 err = db.CreateDatabase(cfg.DatabaseName) 119 if err != nil { 120 panic(fmt.Sprintf("unable to create PostgreSQL database: %v", err)) 121 } 122 } 123 124 func SetupPostgreSQLSchema(cfg *config.SQL) { 125 db, err := sql.NewSQLAdminDB(sqlplugin.DbKindUnknown, cfg, resolver.NewNoopResolver()) 126 if err != nil { 127 panic(fmt.Sprintf("unable to create PostgreSQL admin DB: %v", err)) 128 } 129 defer func() { _ = db.Close() }() 130 131 schemaPath, err := filepath.Abs(testPostgreSQLExecutionSchema) 132 if err != nil { 133 panic(err) 134 } 135 136 statements, err := p.LoadAndSplitQuery([]string{schemaPath}) 137 if err != nil { 138 panic(err) 139 } 140 141 for _, stmt := range statements { 142 if err = db.Exec(stmt); err != nil { 143 panic(err) 144 } 145 } 146 147 schemaPath, err = filepath.Abs(testPostgreSQLVisibilitySchema) 148 if err != nil { 149 panic(err) 150 } 151 152 statements, err = p.LoadAndSplitQuery([]string{schemaPath}) 153 if err != nil { 154 panic(err) 155 } 156 157 for _, stmt := range statements { 158 if err = db.Exec(stmt); err != nil { 159 panic(err) 160 } 161 } 162 } 163 164 func TearDownPostgreSQLDatabase(cfg *config.SQL) { 165 adminCfg := *cfg 166 // NOTE need to connect with empty name to create new database 167 adminCfg.DatabaseName = "" 168 169 db, err := sql.NewSQLAdminDB(sqlplugin.DbKindUnknown, &adminCfg, resolver.NewNoopResolver()) 170 if err != nil { 171 panic(fmt.Sprintf("unable to create PostgreSQL admin DB: %v", err)) 172 } 173 defer func() { _ = db.Close() }() 174 175 err = db.DropDatabase(cfg.DatabaseName) 176 if err != nil { 177 panic(fmt.Sprintf("unable to drop PostgreSQL database: %v", err)) 178 } 179 }