github.com/latiif/helm@v2.15.0+incompatible/pkg/storage/driver/mock_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 // import "k8s.io/helm/pkg/storage/driver"
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	sqlmock "github.com/DATA-DOG/go-sqlmock"
    24  	"github.com/jmoiron/sqlx"
    25  	"k8s.io/api/core/v1"
    26  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"k8s.io/apimachinery/pkg/runtime/schema"
    29  	corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
    30  
    31  	rspb "k8s.io/helm/pkg/proto/hapi/release"
    32  )
    33  
    34  func releaseStub(name string, vers int32, namespace string, code rspb.Status_Code) *rspb.Release {
    35  	return &rspb.Release{
    36  		Name:      name,
    37  		Version:   vers,
    38  		Namespace: namespace,
    39  		Info:      &rspb.Info{Status: &rspb.Status{Code: code}},
    40  	}
    41  }
    42  
    43  func shallowReleaseEqual(r1 *rspb.Release, r2 *rspb.Release) bool {
    44  	if r1.Name != r2.Name ||
    45  		r1.Namespace != r2.Namespace ||
    46  		r1.Version != r2.Version ||
    47  		r1.Manifest != r2.Manifest {
    48  		return false
    49  	}
    50  	return true
    51  }
    52  
    53  func testKey(name string, vers int32) string {
    54  	return fmt.Sprintf("%s.v%d", name, vers)
    55  }
    56  
    57  func tsFixtureMemory(t *testing.T) *Memory {
    58  	hs := []*rspb.Release{
    59  		// rls-a
    60  		releaseStub("rls-a", 4, "default", rspb.Status_DEPLOYED),
    61  		releaseStub("rls-a", 1, "default", rspb.Status_SUPERSEDED),
    62  		releaseStub("rls-a", 3, "default", rspb.Status_SUPERSEDED),
    63  		releaseStub("rls-a", 2, "default", rspb.Status_SUPERSEDED),
    64  		// rls-b
    65  		releaseStub("rls-b", 4, "default", rspb.Status_DEPLOYED),
    66  		releaseStub("rls-b", 1, "default", rspb.Status_SUPERSEDED),
    67  		releaseStub("rls-b", 3, "default", rspb.Status_SUPERSEDED),
    68  		releaseStub("rls-b", 2, "default", rspb.Status_SUPERSEDED),
    69  	}
    70  
    71  	mem := NewMemory()
    72  	for _, tt := range hs {
    73  		err := mem.Create(testKey(tt.Name, tt.Version), tt)
    74  		if err != nil {
    75  			t.Fatalf("Test setup failed to create: %s\n", err)
    76  		}
    77  	}
    78  	return mem
    79  }
    80  
    81  // newTestFixture initializes a MockConfigMapsInterface.
    82  // ConfigMaps are created for each release provided.
    83  func newTestFixtureCfgMaps(t *testing.T, releases ...*rspb.Release) *ConfigMaps {
    84  	var mock MockConfigMapsInterface
    85  	mock.Init(t, releases...)
    86  
    87  	return NewConfigMaps(&mock)
    88  }
    89  
    90  // MockConfigMapsInterface mocks a kubernetes ConfigMapsInterface
    91  type MockConfigMapsInterface struct {
    92  	corev1.ConfigMapInterface
    93  
    94  	objects map[string]*v1.ConfigMap
    95  }
    96  
    97  // Init initializes the MockConfigMapsInterface with the set of releases.
    98  func (mock *MockConfigMapsInterface) Init(t *testing.T, releases ...*rspb.Release) {
    99  	mock.objects = map[string]*v1.ConfigMap{}
   100  
   101  	for _, rls := range releases {
   102  		objkey := testKey(rls.Name, rls.Version)
   103  
   104  		cfgmap, err := newConfigMapsObject(objkey, rls, nil)
   105  		if err != nil {
   106  			t.Fatalf("Failed to create configmap: %s", err)
   107  		}
   108  		mock.objects[objkey] = cfgmap
   109  	}
   110  }
   111  
   112  // Get returns the ConfigMap by name.
   113  func (mock *MockConfigMapsInterface) Get(name string, options metav1.GetOptions) (*v1.ConfigMap, error) {
   114  	object, ok := mock.objects[name]
   115  	if !ok {
   116  		return nil, apierrors.NewNotFound(schema.GroupResource{Resource: "tests"}, name)
   117  	}
   118  	return object, nil
   119  }
   120  
   121  // List returns the a of ConfigMaps.
   122  func (mock *MockConfigMapsInterface) List(opts metav1.ListOptions) (*v1.ConfigMapList, error) {
   123  	var list v1.ConfigMapList
   124  	for _, cfgmap := range mock.objects {
   125  		list.Items = append(list.Items, *cfgmap)
   126  	}
   127  	return &list, nil
   128  }
   129  
   130  // Create creates a new ConfigMap.
   131  func (mock *MockConfigMapsInterface) Create(cfgmap *v1.ConfigMap) (*v1.ConfigMap, error) {
   132  	name := cfgmap.ObjectMeta.Name
   133  	if object, ok := mock.objects[name]; ok {
   134  		return object, apierrors.NewAlreadyExists(schema.GroupResource{Resource: "tests"}, name)
   135  	}
   136  	mock.objects[name] = cfgmap
   137  	return cfgmap, nil
   138  }
   139  
   140  // Update updates a ConfigMap.
   141  func (mock *MockConfigMapsInterface) Update(cfgmap *v1.ConfigMap) (*v1.ConfigMap, error) {
   142  	name := cfgmap.ObjectMeta.Name
   143  	if _, ok := mock.objects[name]; !ok {
   144  		return nil, apierrors.NewNotFound(v1.Resource("tests"), name)
   145  	}
   146  	mock.objects[name] = cfgmap
   147  	return cfgmap, nil
   148  }
   149  
   150  // Delete deletes a ConfigMap by name.
   151  func (mock *MockConfigMapsInterface) Delete(name string, opts *metav1.DeleteOptions) error {
   152  	if _, ok := mock.objects[name]; !ok {
   153  		return apierrors.NewNotFound(v1.Resource("tests"), name)
   154  	}
   155  	delete(mock.objects, name)
   156  	return nil
   157  }
   158  
   159  // newTestFixture initializes a MockSecretsInterface.
   160  // Secrets are created for each release provided.
   161  func newTestFixtureSecrets(t *testing.T, releases ...*rspb.Release) *Secrets {
   162  	var mock MockSecretsInterface
   163  	mock.Init(t, releases...)
   164  
   165  	return NewSecrets(&mock)
   166  }
   167  
   168  // MockSecretsInterface mocks a kubernetes SecretsInterface
   169  type MockSecretsInterface struct {
   170  	corev1.SecretInterface
   171  
   172  	objects map[string]*v1.Secret
   173  }
   174  
   175  // Init initializes the MockSecretsInterface with the set of releases.
   176  func (mock *MockSecretsInterface) Init(t *testing.T, releases ...*rspb.Release) {
   177  	mock.objects = map[string]*v1.Secret{}
   178  
   179  	for _, rls := range releases {
   180  		objkey := testKey(rls.Name, rls.Version)
   181  
   182  		secret, err := newSecretsObject(objkey, rls, nil)
   183  		if err != nil {
   184  			t.Fatalf("Failed to create secret: %s", err)
   185  		}
   186  		mock.objects[objkey] = secret
   187  	}
   188  }
   189  
   190  // Get returns the Secret by name.
   191  func (mock *MockSecretsInterface) Get(name string, options metav1.GetOptions) (*v1.Secret, error) {
   192  	object, ok := mock.objects[name]
   193  	if !ok {
   194  		return nil, apierrors.NewNotFound(schema.GroupResource{Resource: "tests"}, name)
   195  	}
   196  	return object, nil
   197  }
   198  
   199  // List returns the a of Secret.
   200  func (mock *MockSecretsInterface) List(opts metav1.ListOptions) (*v1.SecretList, error) {
   201  	var list v1.SecretList
   202  	for _, secret := range mock.objects {
   203  		list.Items = append(list.Items, *secret)
   204  	}
   205  	return &list, nil
   206  }
   207  
   208  // Create creates a new Secret.
   209  func (mock *MockSecretsInterface) Create(secret *v1.Secret) (*v1.Secret, error) {
   210  	name := secret.ObjectMeta.Name
   211  	if object, ok := mock.objects[name]; ok {
   212  		return object, apierrors.NewAlreadyExists(schema.GroupResource{Resource: "tests"}, name)
   213  	}
   214  	mock.objects[name] = secret
   215  	return secret, nil
   216  }
   217  
   218  // Update updates a Secret.
   219  func (mock *MockSecretsInterface) Update(secret *v1.Secret) (*v1.Secret, error) {
   220  	name := secret.ObjectMeta.Name
   221  	if _, ok := mock.objects[name]; !ok {
   222  		return nil, apierrors.NewNotFound(schema.GroupResource{Resource: "tests"}, name)
   223  	}
   224  	mock.objects[name] = secret
   225  	return secret, nil
   226  }
   227  
   228  // Delete deletes a Secret by name.
   229  func (mock *MockSecretsInterface) Delete(name string, opts *metav1.DeleteOptions) error {
   230  	if _, ok := mock.objects[name]; !ok {
   231  		return apierrors.NewNotFound(schema.GroupResource{Resource: "tests"}, name)
   232  	}
   233  	delete(mock.objects, name)
   234  	return nil
   235  }
   236  
   237  // newTestFixtureSQL mocks the SQL database (for testing purposes)
   238  func newTestFixtureSQL(t *testing.T, releases ...*rspb.Release) (*SQL, sqlmock.Sqlmock) {
   239  	sqlDB, mock, err := sqlmock.New()
   240  	if err != nil {
   241  		t.Fatalf("error when opening stub database connection: %v", err)
   242  	}
   243  
   244  	sqlxDB := sqlx.NewDb(sqlDB, "sqlmock")
   245  	return &SQL{
   246  		db:  sqlxDB,
   247  		Log: func(_ string, _ ...interface{}) {},
   248  	}, mock
   249  }