add unit tests for multisecrets

Signed-off-by: shipengqi <pooky.shipengqi@gmail.com>
pull/12277/head
shipengqi 2 years ago committed by Vincent
parent 9c7b862c57
commit b411b5e6a3

@ -252,6 +252,92 @@ func (mock *MockSecretsInterface) Delete(_ context.Context, name string, _ metav
return nil
}
// newTestFixtureMultiSecrets initializes a MockMultiSecretsInterface.
// MultiSecrets are created for each release provided.
func newTestFixtureMultiSecrets(t *testing.T, releases ...*rspb.Release) *MultiSecrets {
var mock MockMultiSecretsInterface
mock.Init(t, releases...)
return NewMultiSecrets(&mock)
}
// MockMultiSecretsInterface mocks a kubernetes SecretsInterface
type MockMultiSecretsInterface struct {
corev1.SecretInterface
objects map[string]*v1.Secret
}
// Init initializes the MockMultiSecretsInterface with the set of releases.
func (mock *MockMultiSecretsInterface) Init(t *testing.T, releases ...*rspb.Release) {
mock.objects = map[string]*v1.Secret{}
for _, rls := range releases {
objkey := testKey(rls.Name, rls.Version)
secrets, err := newMultiSecretsObject(objkey, rls, nil, -1)
if err != nil {
t.Fatalf("Failed to create secrets: %s", err)
}
mock.objects[objkey] = &(*secrets)[0]
}
}
// Get returns the Secret by name.
func (mock *MockMultiSecretsInterface) Get(_ context.Context, name string, _ metav1.GetOptions) (*v1.Secret, error) {
object, ok := mock.objects[name]
if !ok {
return nil, apierrors.NewNotFound(v1.Resource("tests"), name)
}
return object, nil
}
// List returns the a of Secret.
func (mock *MockMultiSecretsInterface) List(_ context.Context, opts metav1.ListOptions) (*v1.SecretList, error) {
var list v1.SecretList
labelSelector, err := kblabels.Parse(opts.LabelSelector)
if err != nil {
return nil, err
}
for _, secret := range mock.objects {
if labelSelector.Matches(kblabels.Set(secret.ObjectMeta.Labels)) {
list.Items = append(list.Items, *secret)
}
}
return &list, nil
}
// Create creates a new Secret.
func (mock *MockMultiSecretsInterface) Create(_ context.Context, secret *v1.Secret, _ metav1.CreateOptions) (*v1.Secret, error) {
name := secret.ObjectMeta.Name
if object, ok := mock.objects[name]; ok {
return object, apierrors.NewAlreadyExists(v1.Resource("tests"), name)
}
mock.objects[name] = secret
return secret, nil
}
// Update updates a Secret.
func (mock *MockMultiSecretsInterface) Update(_ context.Context, secret *v1.Secret, _ metav1.UpdateOptions) (*v1.Secret, error) {
name := secret.ObjectMeta.Name
if _, ok := mock.objects[name]; !ok {
return nil, apierrors.NewNotFound(v1.Resource("tests"), name)
}
mock.objects[name] = secret
return secret, nil
}
// Delete deletes a Secret by name.
func (mock *MockMultiSecretsInterface) Delete(_ context.Context, name string, _ metav1.DeleteOptions) error {
if _, ok := mock.objects[name]; !ok {
return apierrors.NewNotFound(v1.Resource("tests"), name)
}
delete(mock.objects, name)
return nil
}
// newTestFixtureSQL mocks the SQL database (for testing purposes)
func newTestFixtureSQL(t *testing.T, _ ...*rspb.Release) (*SQL, sqlmock.Sqlmock) {
sqlDB, mock, err := sqlmock.New()

@ -0,0 +1,241 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package driver
import (
"encoding/base64"
"encoding/json"
"reflect"
"testing"
v1 "k8s.io/api/core/v1"
rspb "helm.sh/helm/v3/pkg/release"
)
func TestMultiSecretsName(t *testing.T) {
c := newTestFixtureMultiSecrets(t)
if c.Name() != MultiSecretsDriverName {
t.Errorf("Expected name to be %q, got %q", MultiSecretsDriverName, c.Name())
}
}
func TestMultiSecretsGet(t *testing.T) {
vers := 1
name := "smug-pigeon"
namespace := "default"
key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.StatusDeployed)
secrets := newTestFixtureMultiSecrets(t, []*rspb.Release{rel}...)
// get release with key
got, err := secrets.Get(key)
if err != nil {
t.Fatalf("Failed to get release: %s", err)
}
// compare fetched release with original
if !reflect.DeepEqual(rel, got) {
t.Errorf("Expected {%v}, got {%v}", rel, got)
}
}
func TestUNcompressedMultiSecretsGet(t *testing.T) {
vers := 1
name := "smug-pigeon"
namespace := "default"
key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.StatusDeployed)
// Create a test fixture which contains an uncompressed release
secret, err := newSecretsObject(key, rel, nil)
if err != nil {
t.Fatalf("Failed to create secret: %s", err)
}
b, err := json.Marshal(rel)
if err != nil {
t.Fatalf("Failed to marshal release: %s", err)
}
secret.Data["release"] = []byte(base64.StdEncoding.EncodeToString(b))
var mock MockSecretsInterface
mock.objects = map[string]*v1.Secret{key: secret}
secrets := NewSecrets(&mock)
// get release with key
got, err := secrets.Get(key)
if err != nil {
t.Fatalf("Failed to get release: %s", err)
}
// compare fetched release with original
if !reflect.DeepEqual(rel, got) {
t.Errorf("Expected {%v}, got {%v}", rel, got)
}
}
func TestMultiSecretsList(t *testing.T) {
secrets := newTestFixtureMultiSecrets(t, []*rspb.Release{
releaseStub("key-1", 1, "default", rspb.StatusUninstalled),
releaseStub("key-2", 1, "default", rspb.StatusUninstalled),
releaseStub("key-3", 1, "default", rspb.StatusDeployed),
releaseStub("key-4", 1, "default", rspb.StatusDeployed),
releaseStub("key-5", 1, "default", rspb.StatusSuperseded),
releaseStub("key-6", 1, "default", rspb.StatusSuperseded),
}...)
// list all deleted releases
del, err := secrets.List(func(rel *rspb.Release) bool {
return rel.Info.Status == rspb.StatusUninstalled
})
// check
if err != nil {
t.Errorf("Failed to list deleted: %s", err)
}
if len(del) != 2 {
t.Errorf("Expected 2 deleted, got %d:\n%v\n", len(del), del)
}
// list all deployed releases
dpl, err := secrets.List(func(rel *rspb.Release) bool {
return rel.Info.Status == rspb.StatusDeployed
})
// check
if err != nil {
t.Errorf("Failed to list deployed: %s", err)
}
if len(dpl) != 2 {
t.Errorf("Expected 2 deployed, got %d", len(dpl))
}
// list all superseded releases
ssd, err := secrets.List(func(rel *rspb.Release) bool {
return rel.Info.Status == rspb.StatusSuperseded
})
// check
if err != nil {
t.Errorf("Failed to list superseded: %s", err)
}
if len(ssd) != 2 {
t.Errorf("Expected 2 superseded, got %d", len(ssd))
}
}
func TestMultiSecretsQuery(t *testing.T) {
secrets := newTestFixtureMultiSecrets(t, []*rspb.Release{
releaseStub("key-1", 1, "default", rspb.StatusUninstalled),
releaseStub("key-2", 1, "default", rspb.StatusUninstalled),
releaseStub("key-3", 1, "default", rspb.StatusDeployed),
releaseStub("key-4", 1, "default", rspb.StatusDeployed),
releaseStub("key-5", 1, "default", rspb.StatusSuperseded),
releaseStub("key-6", 1, "default", rspb.StatusSuperseded),
}...)
rls, err := secrets.Query(map[string]string{"status": "deployed"})
if err != nil {
t.Fatalf("Failed to query: %s", err)
}
if len(rls) != 2 {
t.Fatalf("Expected 2 results, actual %d", len(rls))
}
_, err = secrets.Query(map[string]string{"name": "notExist"})
if err != ErrReleaseNotFound {
t.Errorf("Expected {%v}, got {%v}", ErrReleaseNotFound, err)
}
}
func TestMultiSecretsCreate(t *testing.T) {
secrets := newTestFixtureMultiSecrets(t)
vers := 1
name := "smug-pigeon"
namespace := "default"
key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.StatusDeployed)
// store the release in a secret
if err := secrets.Create(key, rel); err != nil {
t.Fatalf("Failed to create release with key %q: %s", key, err)
}
// get the release back
got, err := secrets.Get(key)
if err != nil {
t.Fatalf("Failed to get release with key %q: %s", key, err)
}
// compare created release with original
if !reflect.DeepEqual(rel, got) {
t.Errorf("Expected {%v}, got {%v}", rel, got)
}
}
func TestMultiSecretsUpdate(t *testing.T) {
vers := 1
name := "smug-pigeon"
namespace := "default"
key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.StatusDeployed)
secrets := newTestFixtureMultiSecrets(t, []*rspb.Release{rel}...)
// modify release status code
rel.Info.Status = rspb.StatusSuperseded
// perform the update
if err := secrets.Update(key, rel); err != nil {
t.Fatalf("Failed to update release: %s", err)
}
// fetch the updated release
got, err := secrets.Get(key)
if err != nil {
t.Fatalf("Failed to get release with key %q: %s", key, err)
}
// check release has actually been updated by comparing modified fields
if rel.Info.Status != got.Info.Status {
t.Errorf("Expected status %s, got status %s", rel.Info.Status.String(), got.Info.Status.String())
}
}
func TestMultiSecretsDelete(t *testing.T) {
vers := 1
name := "smug-pigeon"
namespace := "default"
key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.StatusDeployed)
secrets := newTestFixtureMultiSecrets(t, []*rspb.Release{rel}...)
// perform the delete on a non-existing release
_, err := secrets.Delete("nonexistent")
if err != ErrReleaseNotFound {
t.Fatalf("Expected ErrReleaseNotFound, got: {%v}", err)
}
// perform the delete
rls, err := secrets.Delete(key)
if err != nil {
t.Fatalf("Failed to delete release with key %q: %s", key, err)
}
if !reflect.DeepEqual(rel, rls) {
t.Errorf("Expected {%v}, got {%v}", rel, rls)
}
// fetch the deleted release
_, err = secrets.Get(key)
if !reflect.DeepEqual(ErrReleaseNotFound, err) {
t.Errorf("Expected {%v}, got {%v}", ErrReleaseNotFound, err)
}
}
Loading…
Cancel
Save