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 }