github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/lorry/engines/postgres/query_test.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package postgres 21 22 import ( 23 "context" 24 "fmt" 25 "testing" 26 27 "github.com/pashagolub/pgxmock/v2" 28 "github.com/stretchr/testify/assert" 29 30 "github.com/1aal/kubeblocks/pkg/lorry/dcs" 31 ) 32 33 const ( 34 execTest = "create database test" 35 queryTest = "select 1" 36 ) 37 38 func TestQuery(t *testing.T) { 39 ctx := context.TODO() 40 manager, mock, _ := MockDatabase(t) 41 defer mock.Close() 42 43 t.Run("query success", func(t *testing.T) { 44 sql := queryTest 45 mock.ExpectQuery("select"). 46 WillReturnRows(pgxmock.NewRows([]string{"1"})) 47 48 _, err := manager.Query(ctx, sql) 49 assert.Nil(t, err) 50 }) 51 52 t.Run("query failed", func(t *testing.T) { 53 sql := queryTest 54 mock.ExpectQuery("select"). 55 WillReturnError(fmt.Errorf("some error")) 56 57 _, err := manager.Query(ctx, sql) 58 assert.NotNil(t, err) 59 }) 60 61 t.Run("parse rows failed", func(t *testing.T) { 62 sql := queryTest 63 var val chan string 64 mock.ExpectQuery("select"). 65 WillReturnRows(pgxmock.NewRows([]string{"1"}).AddRow(val)) 66 _, err := manager.Query(ctx, sql) 67 assert.NotNil(t, err) 68 }) 69 70 t.Run("can't connect db", func(t *testing.T) { 71 sql := queryTest 72 resp, err := manager.QueryWithHost(ctx, sql, "localhost") 73 assert.NotNil(t, err) 74 assert.Nil(t, resp) 75 }) 76 77 t.Run("query leader success", func(t *testing.T) { 78 sql := queryTest 79 mock.ExpectQuery("select"). 80 WillReturnRows(pgxmock.NewRows([]string{"1"}).AddRow("1")) 81 cluster := &dcs.Cluster{ 82 Leader: &dcs.Leader{ 83 Name: manager.CurrentMemberName, 84 }, 85 } 86 cluster.Members = append(cluster.Members, dcs.Member{ 87 Name: manager.CurrentMemberName, 88 }) 89 90 resp, err := manager.QueryLeader(ctx, sql, cluster) 91 if err != nil { 92 t.Errorf("expect query leader success but failed") 93 } 94 95 assert.Equal(t, []byte(`[{"1":"1"}]`), resp) 96 }) 97 98 t.Run("query leader failed, cluster has no leader", func(t *testing.T) { 99 sql := queryTest 100 cluster := &dcs.Cluster{} 101 102 _, err := manager.QueryLeader(ctx, sql, cluster) 103 if err == nil { 104 t.Errorf("expect query leader success but failed") 105 } 106 107 assert.ErrorIs(t, ClusterHasNoLeader, err) 108 }) 109 110 if err := mock.ExpectationsWereMet(); err != nil { 111 t.Errorf("there were unfulfilled expectations: %v", err) 112 } 113 } 114 115 func TestParseQuery(t *testing.T) { 116 t.Run("parse query success", func(t *testing.T) { 117 data := []byte(`[{"current_setting":"off"}]`) 118 resMap, err := ParseQuery(string(data)) 119 assert.NotNil(t, resMap) 120 assert.Nil(t, err) 121 assert.Equal(t, 1, len(resMap)) 122 assert.Equal(t, "off", resMap[0]["current_setting"].(string)) 123 }) 124 125 t.Run("parse query failed", func(t *testing.T) { 126 data := []byte(`{"current_setting":"off"}`) 127 resMap, err := ParseQuery(string(data)) 128 assert.NotNil(t, err) 129 assert.Nil(t, resMap) 130 }) 131 } 132 133 func TestExec(t *testing.T) { 134 ctx := context.TODO() 135 manager, mock, _ := MockDatabase(t) 136 defer mock.Close() 137 138 t.Run("exec success", func(t *testing.T) { 139 sql := execTest 140 141 mock.ExpectExec("create database"). 142 WillReturnResult(pgxmock.NewResult("CREATE DATABASE", 1)) 143 144 _, err := manager.Exec(ctx, sql) 145 assert.Nil(t, err) 146 }) 147 148 t.Run("exec failed", func(t *testing.T) { 149 sql := execTest 150 151 mock.ExpectExec("create database"). 152 WillReturnError(fmt.Errorf("some error")) 153 154 _, err := manager.Exec(ctx, sql) 155 assert.NotNil(t, err) 156 }) 157 158 t.Run("can't connect db", func(t *testing.T) { 159 sql := execTest 160 resp, err := manager.ExecWithHost(ctx, sql, "test") 161 if err == nil { 162 t.Errorf("expect query failed, but success") 163 } 164 assert.Equal(t, int64(0), resp) 165 }) 166 167 t.Run("exec leader success", func(t *testing.T) { 168 sql := execTest 169 mock.ExpectExec("create"). 170 WillReturnResult(pgxmock.NewResult("CREATE", 1)) 171 cluster := &dcs.Cluster{ 172 Leader: &dcs.Leader{ 173 Name: manager.CurrentMemberName, 174 }, 175 } 176 cluster.Members = append(cluster.Members, dcs.Member{ 177 Name: manager.CurrentMemberName, 178 }) 179 180 resp, err := manager.ExecLeader(ctx, sql, cluster) 181 if err != nil { 182 t.Errorf("expect exec leader success but failed") 183 } 184 assert.Equal(t, int64(1), resp) 185 }) 186 187 t.Run("exec leader failed, cluster has no leader", func(t *testing.T) { 188 sql := execTest 189 cluster := &dcs.Cluster{} 190 191 _, err := manager.ExecLeader(ctx, sql, cluster) 192 if err == nil { 193 t.Errorf("expect exec leader success but failed") 194 } 195 196 assert.ErrorIs(t, ClusterHasNoLeader, err) 197 }) 198 199 if err := mock.ExpectationsWereMet(); err != nil { 200 t.Errorf("there were unfulfilled expectations: %v", err) 201 } 202 } 203 204 func TestGetPgCurrentSetting(t *testing.T) { 205 ctx := context.TODO() 206 manager, mock, _ := MockDatabase(t) 207 defer mock.Close() 208 209 t.Run("query failed", func(t *testing.T) { 210 mock.ExpectQuery("select"). 211 WillReturnError(fmt.Errorf("some error")) 212 213 res, err := manager.GetPgCurrentSetting(ctx, "test") 214 assert.NotNil(t, err) 215 assert.Equal(t, "", res) 216 }) 217 218 t.Run("parse query failed", func(t *testing.T) { 219 mock.ExpectQuery("select"). 220 WillReturnRows(pgxmock.NewRows([]string{"current_setting"})) 221 222 res, err := manager.GetPgCurrentSetting(ctx, "test") 223 assert.NotNil(t, err) 224 assert.Equal(t, "", res) 225 }) 226 227 t.Run("query success", func(t *testing.T) { 228 mock.ExpectQuery("select"). 229 WillReturnRows(pgxmock.NewRows([]string{"current_setting"}).AddRow("test")) 230 231 res, err := manager.GetPgCurrentSetting(ctx, "test") 232 assert.Nil(t, err) 233 assert.Equal(t, "test", res) 234 }) 235 236 if err := mock.ExpectationsWereMet(); err != nil { 237 t.Errorf("there were unfulfilled expectations: %v", err) 238 } 239 }