github.com/latiif/helm@v2.15.0+incompatible/pkg/storage/driver/sql_test.go (about) 1 /* 2 Copyright The Helm Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package driver 18 19 import ( 20 "fmt" 21 "regexp" 22 "testing" 23 "time" 24 25 sqlmock "github.com/DATA-DOG/go-sqlmock" 26 rspb "k8s.io/helm/pkg/proto/hapi/release" 27 ) 28 29 func TestSQLName(t *testing.T) { 30 sqlDriver, _ := newTestFixtureSQL(t) 31 if sqlDriver.Name() != SQLDriverName { 32 t.Errorf("Expected name to be %q, got %q", SQLDriverName, sqlDriver.Name()) 33 } 34 } 35 36 func TestSQLGet(t *testing.T) { 37 vers := int32(1) 38 name := "smug-pigeon" 39 namespace := "default" 40 key := testKey(name, vers) 41 rel := releaseStub(name, vers, namespace, rspb.Status_DEPLOYED) 42 43 body, err := encodeRelease(rel) 44 if err != nil { 45 t.Fatal(err) 46 } 47 48 sqlDriver, mock := newTestFixtureSQL(t) 49 mock. 50 ExpectQuery("SELECT body FROM releases WHERE key = ?"). 51 WithArgs(key). 52 WillReturnRows( 53 mock.NewRows([]string{ 54 "body", 55 }).AddRow( 56 body, 57 ), 58 ).RowsWillBeClosed() 59 60 got, err := sqlDriver.Get(key) 61 if err != nil { 62 t.Fatalf("Failed to get release: %v", err) 63 } 64 65 if !shallowReleaseEqual(rel, got) { 66 t.Errorf("Expected release {%q}, got {%q}", rel, got) 67 } 68 69 if err := mock.ExpectationsWereMet(); err != nil { 70 t.Errorf("sql expectations weren't met: %v", err) 71 } 72 } 73 74 func TestSQLList(t *testing.T) { 75 body1, _ := encodeRelease(releaseStub("key-1", 1, "default", rspb.Status_DELETED)) 76 body2, _ := encodeRelease(releaseStub("key-2", 1, "default", rspb.Status_DELETED)) 77 body3, _ := encodeRelease(releaseStub("key-3", 1, "default", rspb.Status_DEPLOYED)) 78 body4, _ := encodeRelease(releaseStub("key-4", 1, "default", rspb.Status_DEPLOYED)) 79 body5, _ := encodeRelease(releaseStub("key-5", 1, "default", rspb.Status_SUPERSEDED)) 80 body6, _ := encodeRelease(releaseStub("key-6", 1, "default", rspb.Status_SUPERSEDED)) 81 82 sqlDriver, mock := newTestFixtureSQL(t) 83 84 for i := 0; i < 3; i++ { 85 mock. 86 ExpectQuery("SELECT body FROM releases WHERE owner = 'TILLER'"). 87 WillReturnRows( 88 mock.NewRows([]string{ 89 "body", 90 }). 91 AddRow(body1). 92 AddRow(body2). 93 AddRow(body3). 94 AddRow(body4). 95 AddRow(body5). 96 AddRow(body6), 97 ).RowsWillBeClosed() 98 } 99 100 // list all deleted releases 101 del, err := sqlDriver.List(func(rel *rspb.Release) bool { 102 return rel.Info.Status.Code == rspb.Status_DELETED 103 }) 104 // check 105 if err != nil { 106 t.Errorf("Failed to list deleted: %v", err) 107 } 108 if len(del) != 2 { 109 t.Errorf("Expected 2 deleted, got %d:\n%v\n", len(del), del) 110 } 111 112 // list all deployed releases 113 dpl, err := sqlDriver.List(func(rel *rspb.Release) bool { 114 return rel.Info.Status.Code == rspb.Status_DEPLOYED 115 }) 116 // check 117 if err != nil { 118 t.Errorf("Failed to list deployed: %v", err) 119 } 120 if len(dpl) != 2 { 121 t.Errorf("Expected 2 deployed, got %d:\n%v\n", len(dpl), dpl) 122 } 123 124 // list all superseded releases 125 ssd, err := sqlDriver.List(func(rel *rspb.Release) bool { 126 return rel.Info.Status.Code == rspb.Status_SUPERSEDED 127 }) 128 // check 129 if err != nil { 130 t.Errorf("Failed to list superseded: %v", err) 131 } 132 if len(ssd) != 2 { 133 t.Errorf("Expected 2 superseded, got %d:\n%v\n", len(ssd), ssd) 134 } 135 136 if err := mock.ExpectationsWereMet(); err != nil { 137 t.Errorf("sql expectations weren't met: %v", err) 138 } 139 } 140 141 func TestSqlCreate(t *testing.T) { 142 vers := int32(1) 143 name := "smug-pigeon" 144 namespace := "default" 145 key := testKey(name, vers) 146 rel := releaseStub(name, vers, namespace, rspb.Status_DEPLOYED) 147 148 sqlDriver, mock := newTestFixtureSQL(t) 149 body, _ := encodeRelease(rel) 150 151 mock.ExpectBegin() 152 mock. 153 ExpectExec(regexp.QuoteMeta("INSERT INTO releases (key, body, name, version, status, owner, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)")). 154 WithArgs(key, body, rel.Name, int(rel.Version), rspb.Status_Code_name[int32(rel.Info.Status.Code)], "TILLER", int(time.Now().Unix())). 155 WillReturnResult(sqlmock.NewResult(1, 1)) 156 mock.ExpectCommit() 157 158 if err := sqlDriver.Create(key, rel); err != nil { 159 t.Fatalf("failed to create release with key %q: %v", key, err) 160 } 161 162 if err := mock.ExpectationsWereMet(); err != nil { 163 t.Errorf("sql expectations weren't met: %v", err) 164 } 165 } 166 167 func TestSqlCreateAlreadyExists(t *testing.T) { 168 vers := int32(1) 169 name := "smug-pigeon" 170 namespace := "default" 171 key := testKey(name, vers) 172 rel := releaseStub(name, vers, namespace, rspb.Status_DEPLOYED) 173 174 sqlDriver, mock := newTestFixtureSQL(t) 175 body, _ := encodeRelease(rel) 176 177 // Insert fails (primary key already exists) 178 mock.ExpectBegin() 179 mock. 180 ExpectExec(regexp.QuoteMeta("INSERT INTO releases (key, body, name, version, status, owner, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)")). 181 WithArgs(key, body, rel.Name, int(rel.Version), rspb.Status_Code_name[int32(rel.Info.Status.Code)], "TILLER", int(time.Now().Unix())). 182 WillReturnError(fmt.Errorf("dialect dependent SQL error")) 183 184 // Let's check that we do make sure the error is due to a release already existing 185 mock. 186 ExpectQuery(regexp.QuoteMeta("SELECT key FROM releases WHERE key = ?")). 187 WithArgs(key). 188 WillReturnRows( 189 mock.NewRows([]string{ 190 "body", 191 }).AddRow( 192 body, 193 ), 194 ).RowsWillBeClosed() 195 mock.ExpectRollback() 196 197 if err := sqlDriver.Create(key, rel); err == nil { 198 t.Fatalf("failed to create release with key %q: %v", key, err) 199 } 200 201 if err := mock.ExpectationsWereMet(); err != nil { 202 t.Errorf("sql expectations weren't met: %v", err) 203 } 204 } 205 206 func TestSqlUpdate(t *testing.T) { 207 vers := int32(1) 208 name := "smug-pigeon" 209 namespace := "default" 210 key := testKey(name, vers) 211 rel := releaseStub(name, vers, namespace, rspb.Status_DEPLOYED) 212 213 sqlDriver, mock := newTestFixtureSQL(t) 214 body, _ := encodeRelease(rel) 215 216 mock. 217 ExpectExec(regexp.QuoteMeta("UPDATE releases SET body=?, name=?, version=?, status=?, owner=?, modified_at=? WHERE key=?")). 218 WithArgs(body, rel.Name, int(rel.Version), rspb.Status_Code_name[int32(rel.Info.Status.Code)], "TILLER", int(time.Now().Unix()), key). 219 WillReturnResult(sqlmock.NewResult(0, 1)) 220 221 if err := sqlDriver.Update(key, rel); err != nil { 222 t.Fatalf("failed to update release with key %q: %v", key, err) 223 } 224 225 if err := mock.ExpectationsWereMet(); err != nil { 226 t.Errorf("sql expectations weren't met: %v", err) 227 } 228 } 229 230 func TestSqlQuery(t *testing.T) { 231 // Reflect actual use cases in ../storage.go 232 labelSetDeployed := map[string]string{ 233 "NAME": "smug-pigeon", 234 "OWNER": "TILLER", 235 "STATUS": "DEPLOYED", 236 } 237 labelSetAll := map[string]string{ 238 "NAME": "smug-pigeon", 239 "OWNER": "TILLER", 240 } 241 242 supersededRelease := releaseStub("smug-pigeon", 1, "default", rspb.Status_SUPERSEDED) 243 supersededReleaseBody, _ := encodeRelease(supersededRelease) 244 deployedRelease := releaseStub("smug-pigeon", 2, "default", rspb.Status_DEPLOYED) 245 deployedReleaseBody, _ := encodeRelease(deployedRelease) 246 247 // Let's actually start our test 248 sqlDriver, mock := newTestFixtureSQL(t) 249 250 mock. 251 ExpectQuery(regexp.QuoteMeta("SELECT body FROM releases WHERE name=? AND owner=? AND status=?")). 252 WithArgs("smug-pigeon", "TILLER", "DEPLOYED"). 253 WillReturnRows( 254 mock.NewRows([]string{ 255 "body", 256 }).AddRow( 257 deployedReleaseBody, 258 ), 259 ).RowsWillBeClosed() 260 261 mock. 262 ExpectQuery(regexp.QuoteMeta("SELECT body FROM releases WHERE name=? AND owner=?")). 263 WithArgs("smug-pigeon", "TILLER"). 264 WillReturnRows( 265 mock.NewRows([]string{ 266 "body", 267 }).AddRow( 268 supersededReleaseBody, 269 ).AddRow( 270 deployedReleaseBody, 271 ), 272 ).RowsWillBeClosed() 273 274 results, err := sqlDriver.Query(labelSetDeployed) 275 if err != nil { 276 t.Fatalf("failed to query for deployed smug-pigeon release: %v", err) 277 } 278 279 for _, res := range results { 280 if !shallowReleaseEqual(res, deployedRelease) { 281 t.Errorf("Expected release {%q}, got {%q}", deployedRelease, res) 282 } 283 } 284 285 results, err = sqlDriver.Query(labelSetAll) 286 if err != nil { 287 t.Fatalf("failed to query release history for smug-pigeon: %v", err) 288 } 289 290 if len(results) != 2 { 291 t.Errorf("expected a resultset of size 2, got %d", len(results)) 292 } 293 294 for _, res := range results { 295 if !shallowReleaseEqual(res, deployedRelease) && !shallowReleaseEqual(res, supersededRelease) { 296 t.Errorf("Expected release {%q} or {%q}, got {%q}", deployedRelease, supersededRelease, res) 297 } 298 } 299 300 if err := mock.ExpectationsWereMet(); err != nil { 301 t.Errorf("sql expectations weren't met: %v", err) 302 } 303 } 304 305 func TestSqlDelete(t *testing.T) { 306 vers := int32(1) 307 name := "smug-pigeon" 308 namespace := "default" 309 key := testKey(name, vers) 310 rel := releaseStub(name, vers, namespace, rspb.Status_DEPLOYED) 311 312 body, _ := encodeRelease(rel) 313 314 sqlDriver, mock := newTestFixtureSQL(t) 315 316 mock.ExpectBegin() 317 mock. 318 ExpectQuery("SELECT body FROM releases WHERE key = ?"). 319 WithArgs(key). 320 WillReturnRows( 321 mock.NewRows([]string{ 322 "body", 323 }).AddRow( 324 body, 325 ), 326 ).RowsWillBeClosed() 327 328 mock. 329 ExpectExec(regexp.QuoteMeta("DELETE FROM releases WHERE key = $1")). 330 WithArgs(key). 331 WillReturnResult(sqlmock.NewResult(0, 1)) 332 mock.ExpectCommit() 333 334 deletedRelease, err := sqlDriver.Delete(key) 335 if err != nil { 336 t.Fatalf("failed to delete release with key %q: %v", key, err) 337 } 338 339 if !shallowReleaseEqual(rel, deletedRelease) { 340 t.Errorf("Expected release {%q}, got {%q}", rel, deletedRelease) 341 } 342 343 if err := mock.ExpectationsWereMet(); err != nil { 344 t.Errorf("sql expectations weren't met: %v", err) 345 } 346 }