stackube/pkg/kubecrd/crdclient_fake.go
mozhulee 7fed3d210b Add fake CRD client
Change-Id: I4748ce465b2886098cfab37277a18cc0b571c22b
Implements: blueprint enhance-unit-testing
Signed-off-by: mozhuli <21621232@zju.edu.cn>
2017-08-26 12:09:10 +08:00

246 lines
5.7 KiB
Go

/*
Copyright (c) 2017 OpenStack Foundation.
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 kubecrd
import (
"fmt"
"sync"
crv1 "git.openstack.org/openstack/stackube/pkg/apis/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
)
// CalledDetail is the struct contains called function name and arguments.
type CalledDetail struct {
// Name of the function called.
Name string
// Argument of the function called.
Argument interface{}
}
// FakeCRDClient is a simple fake CRD client, so that stackube
// can be run for testing without requiring a real kubernetes setup.
type FakeCRDClient struct {
sync.Mutex
called []CalledDetail
errors map[string]error
Tenants map[string]*crv1.Tenant
Networks map[string]*crv1.Network
scheme *runtime.Scheme
}
var _ = Interface(&FakeCRDClient{})
// NewFake creates a new FakeCRDClient.
func NewFake() (*FakeCRDClient, error) {
scheme := runtime.NewScheme()
if err := crv1.AddToScheme(scheme); err != nil {
return nil, err
}
return &FakeCRDClient{
errors: make(map[string]error),
Tenants: make(map[string]*crv1.Tenant),
Networks: make(map[string]*crv1.Network),
scheme: scheme,
}, nil
}
func (f *FakeCRDClient) getError(op string) error {
err, ok := f.errors[op]
if ok {
delete(f.errors, op)
return err
}
return nil
}
// InjectError inject error for call
func (f *FakeCRDClient) InjectError(fn string, err error) {
f.Lock()
defer f.Unlock()
f.errors[fn] = err
}
// InjectErrors inject errors for calls
func (f *FakeCRDClient) InjectErrors(errs map[string]error) {
f.Lock()
defer f.Unlock()
for fn, err := range errs {
f.errors[fn] = err
}
}
// ClearErrors clear errors for call
func (f *FakeCRDClient) ClearErrors() {
f.Lock()
defer f.Unlock()
f.errors = make(map[string]error)
}
func (f *FakeCRDClient) appendCalled(name string, argument interface{}) {
call := CalledDetail{Name: name, Argument: argument}
f.called = append(f.called, call)
}
// GetCalledNames get names of call
func (f *FakeCRDClient) GetCalledNames() []string {
f.Lock()
defer f.Unlock()
names := []string{}
for _, detail := range f.called {
names = append(names, detail.Name)
}
return names
}
// GetCalledDetails get detail of each call.
func (f *FakeCRDClient) GetCalledDetails() []CalledDetail {
f.Lock()
defer f.Unlock()
// Copy the list and return.
return append([]CalledDetail{}, f.called...)
}
// SetTenants injects fake tenant.
func (f *FakeCRDClient) SetTenants(tenants []*crv1.Tenant) {
f.Lock()
defer f.Unlock()
for _, tenant := range tenants {
f.Tenants[tenant.Name] = tenant
}
}
// SetNetworks injects fake network.
func (f *FakeCRDClient) SetNetworks(networks []*crv1.Network) {
f.Lock()
defer f.Unlock()
for _, network := range networks {
f.Networks[network.Name] = network
}
}
// Client is a test implementation of Interface.Client.
func (f *FakeCRDClient) Client() *rest.RESTClient {
return nil
}
// Scheme is a test implementation of Interface.Scheme.
func (f *FakeCRDClient) Scheme() *runtime.Scheme {
return f.scheme
}
// AddTenant is a test implementation of Interface.AddTenant.
func (f *FakeCRDClient) AddTenant(tenant *crv1.Tenant) error {
f.Lock()
defer f.Unlock()
f.appendCalled("AddTenant", tenant)
if err := f.getError("AddTenant"); err != nil {
return err
}
if _, ok := f.Tenants[tenant.Name]; ok {
return nil
}
f.Tenants[tenant.Name] = tenant
return nil
}
// GetTenant is a test implementation of Interface.GetTenant.
func (f *FakeCRDClient) GetTenant(tenantName string) (*crv1.Tenant, error) {
f.Lock()
defer f.Unlock()
f.appendCalled("GetTenant", tenantName)
if err := f.getError("GetTenant"); err != nil {
return nil, err
}
tenant, ok := f.Tenants[tenantName]
if !ok {
return nil, fmt.Errorf("Tenant %s not found", tenantName)
}
return tenant, nil
}
// AddNetwork is a test implementation of Interface.AddNetwork.
func (f *FakeCRDClient) AddNetwork(network *crv1.Network) error {
f.Lock()
defer f.Unlock()
f.appendCalled("AddNetwork", network)
if err := f.getError("AddNetwork"); err != nil {
return err
}
if _, ok := f.Networks[network.Name]; ok {
return nil
}
f.Networks[network.Name] = network
return nil
}
// UpdateTenant is a test implementation of Interface.UpdateTenant.
func (f *FakeCRDClient) UpdateTenant(tenant *crv1.Tenant) error {
f.Lock()
defer f.Unlock()
f.appendCalled("UpdateTenant", tenant)
if err := f.getError("UpdateTenant"); err != nil {
return err
}
if _, ok := f.Tenants[tenant.Name]; !ok {
return fmt.Errorf("Tenant %s not exist", tenant.Name)
}
f.Tenants[tenant.Name] = tenant
return nil
}
// UpdateNetwork is a test implementation of Interface.UpdateNetwork.
func (f *FakeCRDClient) UpdateNetwork(network *crv1.Network) error {
f.Lock()
defer f.Unlock()
f.appendCalled("UpdateNetwork", network)
if err := f.getError("UpdateNetwork"); err != nil {
return err
}
if _, ok := f.Networks[network.Name]; !ok {
return fmt.Errorf("Network %s not exist", network.Name)
}
f.Networks[network.Name] = network
return nil
}
// DeleteNetwork is a test implementation of Interface.DeleteNetwork.
func (f *FakeCRDClient) DeleteNetwork(networkName string) error {
f.Lock()
defer f.Unlock()
f.appendCalled("DeleteNetwork", networkName)
if err := f.getError("DeleteNetwork"); err != nil {
return err
}
delete(f.Networks, networkName)
return nil
}