mirror of
https://github.com/helm/helm.git
synced 2026-08-07 00:21:27 +00:00
configmap tests & some reduction in driver complexity
This commit is contained in:
@@ -17,21 +17,19 @@ limitations under the License.
|
||||
package driver // import "k8s.io/helm/pkg/storage/driver"
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"time"
|
||||
//"strconv"
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/satori/go.uuid"
|
||||
|
||||
rspb "k8s.io/helm/pkg/proto/hapi/release"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
kberrs "k8s.io/kubernetes/pkg/api/errors"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
)
|
||||
|
||||
var b64 = base64.StdEncoding
|
||||
@@ -54,15 +52,20 @@ func (cfgmaps *ConfigMaps) Get(key string) (*rspb.Release, error) {
|
||||
// fetch the configmap holding the release named by key
|
||||
obj, err := cfgmaps.impl.Get(key)
|
||||
if err != nil {
|
||||
logerrf(err, "configmaps: failed to get %q", key)
|
||||
if kberrs.IsNotFound(err) {
|
||||
return nil, ErrReleaseNotFound
|
||||
}
|
||||
|
||||
logerrf(err, "get: failed to get %q", key)
|
||||
return nil, err
|
||||
}
|
||||
// found the configmap, decode the base64 data string
|
||||
r, err := decodeRelease(obj.Data[key])
|
||||
r, err := decodeRelease(obj.Data["release"])
|
||||
if err != nil {
|
||||
logerrf(err, "configmaps: failed to decode data %q", key)
|
||||
logerrf(err, "get: failed to decode data %q", key)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// return the release object
|
||||
return r, nil
|
||||
}
|
||||
@@ -76,12 +79,13 @@ func (cfgmaps *ConfigMaps) List(filter func(*rspb.Release) bool) ([]*rspb.Releas
|
||||
// initialize list options to return all configmaps. TODO: Apply appropriate labels
|
||||
var lbls labels.Set
|
||||
|
||||
objs, err := cfgmaps.impl.List(api.ListOptions{LabelSelector: lbls.AsSelector()})
|
||||
objs, err := cfgmaps.impl.List(api.ListOptions{
|
||||
LabelSelector: lbls.AsSelector(),
|
||||
})
|
||||
if err != nil {
|
||||
logerrf(err, "configmaps: failed to list")
|
||||
logerrf(err, "list: failed to list")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: apply filter here
|
||||
var list []*rspb.Release
|
||||
_ = objs
|
||||
@@ -89,20 +93,23 @@ func (cfgmaps *ConfigMaps) List(filter func(*rspb.Release) bool) ([]*rspb.Releas
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// Create creates a ConfigMap and stores the release. An error
|
||||
// is returned if the rls already exists.
|
||||
func (cfgmaps *ConfigMaps) Create(rls *rspb.Release) error {
|
||||
// create a new configmap object from the release
|
||||
obj, err := newConfigMapsObject(rls)
|
||||
if err != nil {
|
||||
logerrf(err, "configmaps: failed to encode release %q", rls.Name)
|
||||
logerrf(err, "create: failed to encode release %q", rls.Name)
|
||||
return err
|
||||
}
|
||||
// push the configmap object out into the kubiverse
|
||||
if _, err := cfgmaps.impl.Create(obj); err != nil {
|
||||
logerrf(err, "configmaps: failed to create")
|
||||
if kberrs.IsAlreadyExists(err) {
|
||||
return ErrReleaseExists
|
||||
}
|
||||
|
||||
logerrf(err, "create: failed to create")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -112,25 +119,28 @@ func (cfgmaps *ConfigMaps) Update(rls *rspb.Release) error {
|
||||
// create a new configmap object from the release
|
||||
obj, err := newConfigMapsObject(rls)
|
||||
if err != nil {
|
||||
logerrf(err, "configmaps: update failed to encode release %q", rls.Name)
|
||||
logerrf(err, "update: failed to encode release %q", rls.Name)
|
||||
return err
|
||||
}
|
||||
// push the configmap object out into the kubiverse
|
||||
if _, err = cfgmaps.impl.Create(obj); err != nil {
|
||||
if !kberrs.IsAlreadyExists(err) {
|
||||
logerrf(err, "configmaps: update failed to create")
|
||||
return err
|
||||
}
|
||||
}
|
||||
// try update
|
||||
_, err = cfgmaps.impl.Update(obj)
|
||||
return err
|
||||
if err != nil {
|
||||
logerrf(err, "update: failed to update")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes the ConfigMap holding the release named by key.
|
||||
func (cfgmaps *ConfigMaps) Delete(key string) (rls *rspb.Release, err error) {
|
||||
// fetch the release
|
||||
// fetch the release to check existence
|
||||
if rls, err = cfgmaps.Get(key); err != nil {
|
||||
if kberrs.IsNotFound(err) {
|
||||
return nil, ErrReleaseNotFound
|
||||
}
|
||||
|
||||
logerrf(err, "delete: failed to get release %q", rls.Name)
|
||||
return nil, err
|
||||
}
|
||||
// delete the release
|
||||
@@ -161,22 +171,10 @@ func newConfigMapsObject(rls *rspb.Release) (*api.ConfigMap, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// default labels applied to the configmap
|
||||
var labels = map[string]string{
|
||||
"MODIFIED_AT": time.Now().String(),
|
||||
"CREATED_AT": time.Now().String(),
|
||||
"VERSION": strconv.Itoa(int(rls.Version)), // release version
|
||||
"OWNER": owner, // release owner
|
||||
"NAME": rls.Name, // release name
|
||||
}
|
||||
|
||||
// create and return configmap object
|
||||
return &api.ConfigMap{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: genObjKey(rls.Name, rls.Namespace),
|
||||
Labels: labels,
|
||||
},
|
||||
Data: map[string]string{rls.Name: s},
|
||||
ObjectMeta: api.ObjectMeta{Name: rls.Name},
|
||||
Data: map[string]string{"release": s},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -210,14 +208,7 @@ func decodeRelease(data string) (*rspb.Release, error) {
|
||||
return &rls, nil
|
||||
}
|
||||
|
||||
// genObjKey generates a key to identify a configmap.
|
||||
// The resulting key is a composition of the release name,
|
||||
// the namespace of the release, and a v4 uuid.
|
||||
func genObjKey(rls string, ns string) string {
|
||||
return fmt.Sprintf("%s.%s.%s", rls, ns, uuid.NewV4())
|
||||
}
|
||||
|
||||
// for debugging
|
||||
func logerrf(err error, format string, args ...interface{}) {
|
||||
log.Println("%s: %s", fmt.Sprintf(format, args...), err)
|
||||
}
|
||||
log.Printf("configmaps: %s: %s\n", fmt.Sprintf(format, args...), err)
|
||||
}
|
||||
145
pkg/storage/driver/cfgmaps_test.go
Normal file
145
pkg/storage/driver/cfgmaps_test.go
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 (
|
||||
"testing"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
rspb "k8s.io/helm/pkg/proto/hapi/release"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
|
||||
)
|
||||
|
||||
func TestConfigMapGet(t *testing.T) {
|
||||
// test release
|
||||
key := "key-1"
|
||||
rls := &rspb.Release{Name: key, Version: 1}
|
||||
|
||||
// create test fixture
|
||||
cfgmaps := newTestFixture(t, rls)
|
||||
|
||||
// get the release from configmaps
|
||||
got, err := cfgmaps.Get(key)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get release with key %q. %s", key, err)
|
||||
}
|
||||
|
||||
// compare fetched release with original
|
||||
if !reflect.DeepEqual(rls, got) {
|
||||
t.Errorf("expected {%q}, got {%q}", rls, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigMapList(t *testing.T) {
|
||||
t.Skip("ConfigMapList")
|
||||
}
|
||||
|
||||
func TestConfigMapCreate(t *testing.T) {
|
||||
// setup
|
||||
key := "key-1"
|
||||
rls := &rspb.Release{Name: "key-1", Version: 1}
|
||||
|
||||
// create test fixture
|
||||
cfgmaps := newTestFixture(t, rls)
|
||||
|
||||
// store the release in a configmap
|
||||
if err := cfgmaps.Create(rls); err != nil {
|
||||
t.Fatalf("failed to create release: %s", key, err)
|
||||
}
|
||||
|
||||
if err := cfgmaps.Create(rls); err != nil {
|
||||
t.Fatalf("failed to create release: %s", key, err)
|
||||
}
|
||||
|
||||
// get the release back
|
||||
got, err := cfgmaps.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(rls, got) {
|
||||
t.Errorf("expected {%q}, got {%q}", rls, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigMapDelete(t *testing.T) {
|
||||
// setup
|
||||
key := "key-1"
|
||||
rls := &rspb.Release{Name: "key-1", Version: 1}
|
||||
|
||||
// create test fixture
|
||||
cfgmaps := newTestFixture(t, rls)
|
||||
|
||||
// delete the release
|
||||
got, err := cfgmaps.Delete(key)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to delete release with key %q: %s", key, err)
|
||||
}
|
||||
|
||||
// compare deleted release with original
|
||||
if !reflect.DeepEqual(rls, got) {
|
||||
t.Errorf("expected {%q}, got {%q}", rls, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigMapUpdate(t *testing.T) {
|
||||
// setup
|
||||
key := "key-1"
|
||||
rls := &rspb.Release{Name: "key-1", Version: 1}
|
||||
|
||||
// create test fixture
|
||||
cfgmaps := newTestFixture(t, rls)
|
||||
|
||||
// update release version
|
||||
rls.Version = 2
|
||||
|
||||
// update the release
|
||||
if err := cfgmaps.Update(rls); err != nil {
|
||||
t.Fatalf("failed to update release with key %q: %s", key, err)
|
||||
}
|
||||
|
||||
// fetch the updated release
|
||||
got, err := cfgmaps.Get(key)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get release with key %q: %s", key, err)
|
||||
}
|
||||
|
||||
// validate the version was update correctly
|
||||
if rls.Version != got.Version {
|
||||
t.Fatalf("expected version %d, got version %d", rls.Version, got.Version)
|
||||
}
|
||||
}
|
||||
|
||||
// newTestFixture prepopulates a mock implementation of a kubernetes
|
||||
// ConfigMapsInterface returning an initialized driver.ConfigMaps.
|
||||
func newTestFixture(t *testing.T, list ...*rspb.Release) *ConfigMaps {
|
||||
var objs []runtime.Object
|
||||
|
||||
for i := range list {
|
||||
obj, err := newConfigMapsObject(list[i])
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create object: %s", err)
|
||||
}
|
||||
objs = append(objs, obj)
|
||||
}
|
||||
|
||||
return NewConfigMaps(&testclient.FakeConfigMaps{
|
||||
Fake: testclient.NewSimpleFake(objs...),
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user