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  }