mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			364 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			364 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2015 The Kubernetes 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 flocker
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"k8s.io/apimachinery/pkg/types"
 | 
						|
	utiltesting "k8s.io/client-go/util/testing"
 | 
						|
	"k8s.io/kubernetes/pkg/api/v1"
 | 
						|
	"k8s.io/kubernetes/pkg/util/mount"
 | 
						|
	"k8s.io/kubernetes/pkg/volume"
 | 
						|
	volumetest "k8s.io/kubernetes/pkg/volume/testing"
 | 
						|
 | 
						|
	flockerapi "github.com/clusterhq/flocker-go"
 | 
						|
	"github.com/stretchr/testify/assert"
 | 
						|
)
 | 
						|
 | 
						|
const pluginName = "kubernetes.io/flocker"
 | 
						|
const datasetOneID = "11111111-1111-1111-1111-111111111100"
 | 
						|
const nodeOneID = "11111111-1111-1111-1111-111111111111"
 | 
						|
const nodeTwoID = "22222222-2222-2222-2222-222222222222"
 | 
						|
 | 
						|
var _ flockerapi.Clientable = &fakeFlockerClient{}
 | 
						|
 | 
						|
type fakeFlockerClient struct {
 | 
						|
	DatasetID string
 | 
						|
	Primary   string
 | 
						|
	Deleted   bool
 | 
						|
	Metadata  map[string]string
 | 
						|
	Nodes     []flockerapi.NodeState
 | 
						|
	Error     error
 | 
						|
}
 | 
						|
 | 
						|
func newFakeFlockerClient() *fakeFlockerClient {
 | 
						|
	return &fakeFlockerClient{
 | 
						|
		DatasetID: datasetOneID,
 | 
						|
		Primary:   nodeOneID,
 | 
						|
		Deleted:   false,
 | 
						|
		Metadata:  map[string]string{"Name": "dataset-one"},
 | 
						|
		Nodes: []flockerapi.NodeState{
 | 
						|
			{
 | 
						|
				Host: "1.2.3.4",
 | 
						|
				UUID: nodeOneID,
 | 
						|
			},
 | 
						|
			{
 | 
						|
				Host: "4.5.6.7",
 | 
						|
				UUID: nodeTwoID,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *fakeFlockerClient) CreateDataset(options *flockerapi.CreateDatasetOptions) (*flockerapi.DatasetState, error) {
 | 
						|
 | 
						|
	if c.Error != nil {
 | 
						|
		return nil, c.Error
 | 
						|
	}
 | 
						|
 | 
						|
	return &flockerapi.DatasetState{
 | 
						|
		DatasetID: c.DatasetID,
 | 
						|
	}, nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *fakeFlockerClient) DeleteDataset(datasetID string) error {
 | 
						|
	c.DatasetID = datasetID
 | 
						|
	c.Deleted = true
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *fakeFlockerClient) GetDatasetState(datasetID string) (*flockerapi.DatasetState, error) {
 | 
						|
	return &flockerapi.DatasetState{}, nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *fakeFlockerClient) GetDatasetID(metaName string) (datasetID string, err error) {
 | 
						|
	if val, ok := c.Metadata["Name"]; !ok {
 | 
						|
		return val, nil
 | 
						|
	}
 | 
						|
	return "", fmt.Errorf("No dataset with metadata X found")
 | 
						|
}
 | 
						|
 | 
						|
func (c *fakeFlockerClient) GetPrimaryUUID() (primaryUUID string, err error) {
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
func (c *fakeFlockerClient) ListNodes() (nodes []flockerapi.NodeState, err error) {
 | 
						|
	return c.Nodes, nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *fakeFlockerClient) UpdatePrimaryForDataset(primaryUUID, datasetID string) (*flockerapi.DatasetState, error) {
 | 
						|
	return &flockerapi.DatasetState{}, nil
 | 
						|
}
 | 
						|
 | 
						|
type fakeFlockerUtil struct {
 | 
						|
}
 | 
						|
 | 
						|
func (fake *fakeFlockerUtil) CreateVolume(c *flockerVolumeProvisioner) (datasetUUID string, volumeSizeGB int, labels map[string]string, err error) {
 | 
						|
	labels = make(map[string]string)
 | 
						|
	labels["fakeflockerutil"] = "yes"
 | 
						|
	return "test-flocker-volume-uuid", 3, labels, nil
 | 
						|
}
 | 
						|
 | 
						|
func (fake *fakeFlockerUtil) DeleteVolume(cd *flockerVolumeDeleter) error {
 | 
						|
	if cd.datasetUUID != "test-flocker-volume-uuid" {
 | 
						|
		return fmt.Errorf("Deleter got unexpected datasetUUID: %s", cd.datasetUUID)
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func newInitializedVolumePlugMgr(t *testing.T) (*volume.VolumePluginMgr, string) {
 | 
						|
	plugMgr := &volume.VolumePluginMgr{}
 | 
						|
	dir, err := utiltesting.MkTmpdir("flocker")
 | 
						|
	assert.NoError(t, err)
 | 
						|
	plugMgr.InitPlugins(ProbeVolumePlugins(), volumetest.NewFakeVolumeHost(dir, nil, nil))
 | 
						|
	return plugMgr, dir
 | 
						|
}
 | 
						|
 | 
						|
func TestPlugin(t *testing.T) {
 | 
						|
	tmpDir, err := utiltesting.MkTmpdir("flockerTest")
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("can't make a temp dir: %v", err)
 | 
						|
	}
 | 
						|
	defer os.RemoveAll(tmpDir)
 | 
						|
	plugMgr := volume.VolumePluginMgr{}
 | 
						|
	plugMgr.InitPlugins(ProbeVolumePlugins(), volumetest.NewFakeVolumeHost(tmpDir, nil, nil))
 | 
						|
 | 
						|
	plug, err := plugMgr.FindPluginByName("kubernetes.io/flocker")
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("Can't find the plugin by name")
 | 
						|
	}
 | 
						|
	spec := &v1.Volume{
 | 
						|
		Name: "vol1",
 | 
						|
		VolumeSource: v1.VolumeSource{
 | 
						|
			Flocker: &v1.FlockerVolumeSource{
 | 
						|
				DatasetUUID: "uuid1",
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	fakeManager := &fakeFlockerUtil{}
 | 
						|
	fakeMounter := &mount.FakeMounter{}
 | 
						|
	mounter, err := plug.(*flockerPlugin).newMounterInternal(volume.NewSpecFromVolume(spec), types.UID("poduid"), fakeManager, fakeMounter)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("Failed to make a new Mounter: %v", err)
 | 
						|
	}
 | 
						|
	if mounter == nil {
 | 
						|
		t.Errorf("Got a nil Mounter")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestGetByName(t *testing.T) {
 | 
						|
	assert := assert.New(t)
 | 
						|
	plugMgr, dir := newInitializedVolumePlugMgr(t)
 | 
						|
	defer os.RemoveAll(dir)
 | 
						|
 | 
						|
	plug, err := plugMgr.FindPluginByName(pluginName)
 | 
						|
	assert.NotNil(plug, "Can't find the plugin by name")
 | 
						|
	assert.NoError(err)
 | 
						|
}
 | 
						|
 | 
						|
func TestCanSupport(t *testing.T) {
 | 
						|
	assert := assert.New(t)
 | 
						|
	plugMgr, dir := newInitializedVolumePlugMgr(t)
 | 
						|
	defer os.RemoveAll(dir)
 | 
						|
 | 
						|
	plug, err := plugMgr.FindPluginByName(pluginName)
 | 
						|
	assert.NoError(err)
 | 
						|
 | 
						|
	specs := map[*volume.Spec]bool{
 | 
						|
		&volume.Spec{
 | 
						|
			Volume: &v1.Volume{
 | 
						|
				VolumeSource: v1.VolumeSource{
 | 
						|
					Flocker: &v1.FlockerVolumeSource{},
 | 
						|
				},
 | 
						|
			},
 | 
						|
		}: true,
 | 
						|
		&volume.Spec{
 | 
						|
			PersistentVolume: &v1.PersistentVolume{
 | 
						|
				Spec: v1.PersistentVolumeSpec{
 | 
						|
					PersistentVolumeSource: v1.PersistentVolumeSource{
 | 
						|
						Flocker: &v1.FlockerVolumeSource{},
 | 
						|
					},
 | 
						|
				},
 | 
						|
			},
 | 
						|
		}: true,
 | 
						|
		&volume.Spec{
 | 
						|
			Volume: &v1.Volume{
 | 
						|
				VolumeSource: v1.VolumeSource{},
 | 
						|
			},
 | 
						|
		}: false,
 | 
						|
	}
 | 
						|
 | 
						|
	for spec, expected := range specs {
 | 
						|
		actual := plug.CanSupport(spec)
 | 
						|
		assert.Equal(expected, actual)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestGetFlockerVolumeSource(t *testing.T) {
 | 
						|
	assert := assert.New(t)
 | 
						|
 | 
						|
	p := flockerPlugin{}
 | 
						|
 | 
						|
	spec := &volume.Spec{
 | 
						|
		Volume: &v1.Volume{
 | 
						|
			VolumeSource: v1.VolumeSource{
 | 
						|
				Flocker: &v1.FlockerVolumeSource{},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	vs, ro := p.getFlockerVolumeSource(spec)
 | 
						|
	assert.False(ro)
 | 
						|
	assert.Equal(spec.Volume.Flocker, vs)
 | 
						|
 | 
						|
	spec = &volume.Spec{
 | 
						|
		PersistentVolume: &v1.PersistentVolume{
 | 
						|
			Spec: v1.PersistentVolumeSpec{
 | 
						|
				PersistentVolumeSource: v1.PersistentVolumeSource{
 | 
						|
					Flocker: &v1.FlockerVolumeSource{},
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	vs, ro = p.getFlockerVolumeSource(spec)
 | 
						|
	assert.False(ro)
 | 
						|
	assert.Equal(spec.PersistentVolume.Spec.Flocker, vs)
 | 
						|
}
 | 
						|
 | 
						|
func TestNewMounterDatasetName(t *testing.T) {
 | 
						|
	assert := assert.New(t)
 | 
						|
 | 
						|
	plugMgr, dir := newInitializedVolumePlugMgr(t)
 | 
						|
	defer os.RemoveAll(dir)
 | 
						|
	plug, err := plugMgr.FindPluginByName(pluginName)
 | 
						|
	assert.NoError(err)
 | 
						|
 | 
						|
	spec := &volume.Spec{
 | 
						|
		Volume: &v1.Volume{
 | 
						|
			VolumeSource: v1.VolumeSource{
 | 
						|
				Flocker: &v1.FlockerVolumeSource{
 | 
						|
					DatasetName: "something",
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	_, err = plug.NewMounter(spec, &v1.Pod{}, volume.VolumeOptions{})
 | 
						|
	assert.NoError(err)
 | 
						|
}
 | 
						|
 | 
						|
func TestNewMounterDatasetUUID(t *testing.T) {
 | 
						|
	assert := assert.New(t)
 | 
						|
 | 
						|
	plugMgr, dir := newInitializedVolumePlugMgr(t)
 | 
						|
	defer os.RemoveAll(dir)
 | 
						|
	plug, err := plugMgr.FindPluginByName(pluginName)
 | 
						|
	assert.NoError(err)
 | 
						|
 | 
						|
	spec := &volume.Spec{
 | 
						|
		Volume: &v1.Volume{
 | 
						|
			VolumeSource: v1.VolumeSource{
 | 
						|
				Flocker: &v1.FlockerVolumeSource{
 | 
						|
					DatasetUUID: "uuid1",
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	mounter, err := plug.NewMounter(spec, &v1.Pod{}, volume.VolumeOptions{})
 | 
						|
	assert.NoError(err)
 | 
						|
	assert.NotNil(mounter, "got a nil mounter")
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
func TestNewUnmounter(t *testing.T) {
 | 
						|
	t.Skip("broken")
 | 
						|
	assert := assert.New(t)
 | 
						|
 | 
						|
	p := flockerPlugin{}
 | 
						|
 | 
						|
	unmounter, err := p.NewUnmounter("", types.UID(""))
 | 
						|
	assert.Nil(unmounter)
 | 
						|
	assert.NoError(err)
 | 
						|
}
 | 
						|
 | 
						|
func TestIsReadOnly(t *testing.T) {
 | 
						|
	b := &flockerVolumeMounter{readOnly: true}
 | 
						|
	assert.True(t, b.GetAttributes().ReadOnly)
 | 
						|
}
 | 
						|
 | 
						|
type mockFlockerClient struct {
 | 
						|
	datasetID, primaryUUID, path string
 | 
						|
	datasetState                 *flockerapi.DatasetState
 | 
						|
}
 | 
						|
 | 
						|
func newMockFlockerClient(mockDatasetID, mockPrimaryUUID, mockPath string) *mockFlockerClient {
 | 
						|
	return &mockFlockerClient{
 | 
						|
		datasetID:   mockDatasetID,
 | 
						|
		primaryUUID: mockPrimaryUUID,
 | 
						|
		path:        mockPath,
 | 
						|
		datasetState: &flockerapi.DatasetState{
 | 
						|
			Path:      mockPath,
 | 
						|
			DatasetID: mockDatasetID,
 | 
						|
			Primary:   mockPrimaryUUID,
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (m mockFlockerClient) CreateDataset(metaName string) (*flockerapi.DatasetState, error) {
 | 
						|
	return m.datasetState, nil
 | 
						|
}
 | 
						|
func (m mockFlockerClient) GetDatasetState(datasetID string) (*flockerapi.DatasetState, error) {
 | 
						|
	return m.datasetState, nil
 | 
						|
}
 | 
						|
func (m mockFlockerClient) GetDatasetID(metaName string) (string, error) {
 | 
						|
	return m.datasetID, nil
 | 
						|
}
 | 
						|
func (m mockFlockerClient) GetPrimaryUUID() (string, error) {
 | 
						|
	return m.primaryUUID, nil
 | 
						|
}
 | 
						|
func (m mockFlockerClient) UpdatePrimaryForDataset(primaryUUID, datasetID string) (*flockerapi.DatasetState, error) {
 | 
						|
	return m.datasetState, nil
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
TODO: reenable after refactor
 | 
						|
func TestSetUpAtInternal(t *testing.T) {
 | 
						|
	const dir = "dir"
 | 
						|
	mockPath := "expected-to-be-set-properly" // package var
 | 
						|
	expectedPath := mockPath
 | 
						|
 | 
						|
	assert := assert.New(t)
 | 
						|
 | 
						|
	plugMgr, rootDir := newInitializedVolumePlugMgr(t)
 | 
						|
	if rootDir != "" {
 | 
						|
		defer os.RemoveAll(rootDir)
 | 
						|
	}
 | 
						|
	plug, err := plugMgr.FindPluginByName(flockerPluginName)
 | 
						|
	assert.NoError(err)
 | 
						|
 | 
						|
	pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
 | 
						|
	b := flockerVolumeMounter{flockerVolume: &flockerVolume{pod: pod, plugin: plug.(*flockerPlugin)}}
 | 
						|
	b.client = newMockFlockerClient("dataset-id", "primary-uid", mockPath)
 | 
						|
 | 
						|
	assert.NoError(b.SetUpAt(dir, nil))
 | 
						|
	assert.Equal(expectedPath, b.flocker.path)
 | 
						|
}
 | 
						|
*/
 |