github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/storage/base_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package storage_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	jc "github.com/juju/testing/checkers"
     9  	gc "gopkg.in/check.v1"
    10  	"gopkg.in/juju/names.v2"
    11  
    12  	"github.com/juju/juju/apiserver/common"
    13  	"github.com/juju/juju/apiserver/params"
    14  	"github.com/juju/juju/apiserver/storage"
    15  	"github.com/juju/juju/apiserver/testing"
    16  	"github.com/juju/juju/state"
    17  	jujustorage "github.com/juju/juju/storage"
    18  	coretesting "github.com/juju/juju/testing"
    19  )
    20  
    21  type baseStorageSuite struct {
    22  	coretesting.BaseSuite
    23  
    24  	resources  *common.Resources
    25  	authorizer testing.FakeAuthorizer
    26  
    27  	api   *storage.API
    28  	state *mockState
    29  
    30  	storageTag      names.StorageTag
    31  	storageInstance *mockStorageInstance
    32  	unitTag         names.UnitTag
    33  	machineTag      names.MachineTag
    34  
    35  	volumeTag            names.VolumeTag
    36  	volume               *mockVolume
    37  	volumeAttachment     *mockVolumeAttachment
    38  	filesystemTag        names.FilesystemTag
    39  	filesystem           *mockFilesystem
    40  	filesystemAttachment *mockFilesystemAttachment
    41  	calls                []string
    42  
    43  	registry    jujustorage.StaticProviderRegistry
    44  	poolManager *mockPoolManager
    45  	pools       map[string]*jujustorage.Config
    46  
    47  	blocks map[state.BlockType]state.Block
    48  }
    49  
    50  func (s *baseStorageSuite) SetUpTest(c *gc.C) {
    51  	s.BaseSuite.SetUpTest(c)
    52  	s.resources = common.NewResources()
    53  	s.authorizer = testing.FakeAuthorizer{Tag: names.NewUserTag("admin"), EnvironManager: true}
    54  	s.calls = []string{}
    55  	s.state = s.constructState()
    56  
    57  	s.registry = jujustorage.StaticProviderRegistry{map[jujustorage.ProviderType]jujustorage.Provider{}}
    58  	s.pools = make(map[string]*jujustorage.Config)
    59  	s.poolManager = s.constructPoolManager()
    60  
    61  	var err error
    62  	s.api, err = storage.NewAPI(s.state, s.registry, s.poolManager, s.resources, s.authorizer)
    63  	c.Assert(err, jc.ErrorIsNil)
    64  }
    65  
    66  func (s *baseStorageSuite) assertCalls(c *gc.C, expectedCalls []string) {
    67  	c.Assert(s.calls, jc.SameContents, expectedCalls)
    68  }
    69  
    70  const (
    71  	allStorageInstancesCall                 = "allStorageInstances"
    72  	storageInstanceAttachmentsCall          = "storageInstanceAttachments"
    73  	unitAssignedMachineCall                 = "UnitAssignedMachine"
    74  	storageInstanceCall                     = "StorageInstance"
    75  	storageInstanceFilesystemCall           = "StorageInstanceFilesystem"
    76  	storageInstanceFilesystemAttachmentCall = "storageInstanceFilesystemAttachment"
    77  	storageInstanceVolumeCall               = "storageInstanceVolume"
    78  	volumeCall                              = "volumeCall"
    79  	machineVolumeAttachmentsCall            = "machineVolumeAttachments"
    80  	volumeAttachmentsCall                   = "volumeAttachments"
    81  	allVolumesCall                          = "allVolumes"
    82  	filesystemCall                          = "filesystemCall"
    83  	machineFilesystemAttachmentsCall        = "machineFilesystemAttachments"
    84  	filesystemAttachmentsCall               = "filesystemAttachments"
    85  	allFilesystemsCall                      = "allFilesystems"
    86  	addStorageForUnitCall                   = "addStorageForUnit"
    87  	getBlockForTypeCall                     = "getBlockForType"
    88  	volumeAttachmentCall                    = "volumeAttachment"
    89  )
    90  
    91  func (s *baseStorageSuite) constructState() *mockState {
    92  	s.unitTag = names.NewUnitTag("mysql/0")
    93  	s.storageTag = names.NewStorageTag("data/0")
    94  
    95  	s.storageInstance = &mockStorageInstance{
    96  		kind:       state.StorageKindFilesystem,
    97  		owner:      s.unitTag,
    98  		storageTag: s.storageTag,
    99  	}
   100  
   101  	storageInstanceAttachment := &mockStorageAttachment{storage: s.storageInstance}
   102  
   103  	s.machineTag = names.NewMachineTag("66")
   104  	s.filesystemTag = names.NewFilesystemTag("104")
   105  	s.volumeTag = names.NewVolumeTag("22")
   106  	s.filesystem = &mockFilesystem{
   107  		tag:     s.filesystemTag,
   108  		storage: &s.storageTag,
   109  	}
   110  	s.filesystemAttachment = &mockFilesystemAttachment{
   111  		filesystem: s.filesystemTag,
   112  		machine:    s.machineTag,
   113  	}
   114  	s.volume = &mockVolume{tag: s.volumeTag, storage: &s.storageTag}
   115  	s.volumeAttachment = &mockVolumeAttachment{
   116  		VolumeTag:  s.volumeTag,
   117  		MachineTag: s.machineTag,
   118  	}
   119  
   120  	s.blocks = make(map[state.BlockType]state.Block)
   121  	return &mockState{
   122  		allStorageInstances: func() ([]state.StorageInstance, error) {
   123  			s.calls = append(s.calls, allStorageInstancesCall)
   124  			return []state.StorageInstance{s.storageInstance}, nil
   125  		},
   126  		storageInstance: func(sTag names.StorageTag) (state.StorageInstance, error) {
   127  			s.calls = append(s.calls, storageInstanceCall)
   128  			if sTag == s.storageTag {
   129  				return s.storageInstance, nil
   130  			}
   131  			return nil, errors.NotFoundf("%s", names.ReadableString(sTag))
   132  		},
   133  		storageInstanceAttachments: func(tag names.StorageTag) ([]state.StorageAttachment, error) {
   134  			s.calls = append(s.calls, storageInstanceAttachmentsCall)
   135  			if tag == s.storageTag {
   136  				return []state.StorageAttachment{storageInstanceAttachment}, nil
   137  			}
   138  			return nil, errors.NotFoundf("%s", names.ReadableString(tag))
   139  		},
   140  		storageInstanceFilesystem: func(sTag names.StorageTag) (state.Filesystem, error) {
   141  			s.calls = append(s.calls, storageInstanceFilesystemCall)
   142  			if sTag == s.storageTag {
   143  				return s.filesystem, nil
   144  			}
   145  			return nil, errors.NotFoundf("%s", names.ReadableString(sTag))
   146  		},
   147  		storageInstanceFilesystemAttachment: func(m names.MachineTag, f names.FilesystemTag) (state.FilesystemAttachment, error) {
   148  			s.calls = append(s.calls, storageInstanceFilesystemAttachmentCall)
   149  			if m == s.machineTag && f == s.filesystemTag {
   150  				return s.filesystemAttachment, nil
   151  			}
   152  			return nil, errors.NotFoundf("filesystem attachment %s:%s", m, f)
   153  		},
   154  		storageInstanceVolume: func(t names.StorageTag) (state.Volume, error) {
   155  			s.calls = append(s.calls, storageInstanceVolumeCall)
   156  			if t == s.storageTag {
   157  				return s.volume, nil
   158  			}
   159  			return nil, errors.NotFoundf("%s", names.ReadableString(t))
   160  		},
   161  		volumeAttachment: func(names.MachineTag, names.VolumeTag) (state.VolumeAttachment, error) {
   162  			s.calls = append(s.calls, volumeAttachmentCall)
   163  			return s.volumeAttachment, nil
   164  		},
   165  		unitAssignedMachine: func(u names.UnitTag) (names.MachineTag, error) {
   166  			s.calls = append(s.calls, unitAssignedMachineCall)
   167  			if u == s.unitTag {
   168  				return s.machineTag, nil
   169  			}
   170  			return names.MachineTag{}, errors.NotFoundf("%s", names.ReadableString(u))
   171  		},
   172  		volume: func(tag names.VolumeTag) (state.Volume, error) {
   173  			s.calls = append(s.calls, volumeCall)
   174  			if tag == s.volumeTag {
   175  				return s.volume, nil
   176  			}
   177  			return nil, errors.NotFoundf("%s", names.ReadableString(tag))
   178  		},
   179  		machineVolumeAttachments: func(machine names.MachineTag) ([]state.VolumeAttachment, error) {
   180  			s.calls = append(s.calls, machineVolumeAttachmentsCall)
   181  			if machine == s.machineTag {
   182  				return []state.VolumeAttachment{s.volumeAttachment}, nil
   183  			}
   184  			return nil, nil
   185  		},
   186  		volumeAttachments: func(volume names.VolumeTag) ([]state.VolumeAttachment, error) {
   187  			s.calls = append(s.calls, volumeAttachmentsCall)
   188  			if volume == s.volumeTag {
   189  				return []state.VolumeAttachment{s.volumeAttachment}, nil
   190  			}
   191  			return nil, nil
   192  		},
   193  		allVolumes: func() ([]state.Volume, error) {
   194  			s.calls = append(s.calls, allVolumesCall)
   195  			return []state.Volume{s.volume}, nil
   196  		},
   197  		filesystem: func(tag names.FilesystemTag) (state.Filesystem, error) {
   198  			s.calls = append(s.calls, filesystemCall)
   199  			if tag == s.filesystemTag {
   200  				return s.filesystem, nil
   201  			}
   202  			return nil, errors.NotFoundf("%s", names.ReadableString(tag))
   203  		},
   204  		machineFilesystemAttachments: func(machine names.MachineTag) ([]state.FilesystemAttachment, error) {
   205  			s.calls = append(s.calls, machineFilesystemAttachmentsCall)
   206  			if machine == s.machineTag {
   207  				return []state.FilesystemAttachment{s.filesystemAttachment}, nil
   208  			}
   209  			return nil, nil
   210  		},
   211  		filesystemAttachments: func(filesystem names.FilesystemTag) ([]state.FilesystemAttachment, error) {
   212  			s.calls = append(s.calls, filesystemAttachmentsCall)
   213  			if filesystem == s.filesystemTag {
   214  				return []state.FilesystemAttachment{s.filesystemAttachment}, nil
   215  			}
   216  			return nil, nil
   217  		},
   218  		allFilesystems: func() ([]state.Filesystem, error) {
   219  			s.calls = append(s.calls, allFilesystemsCall)
   220  			return []state.Filesystem{s.filesystem}, nil
   221  		},
   222  		modelName: "storagetest",
   223  		addStorageForUnit: func(u names.UnitTag, name string, cons state.StorageConstraints) error {
   224  			s.calls = append(s.calls, addStorageForUnitCall)
   225  			return nil
   226  		},
   227  		getBlockForType: func(t state.BlockType) (state.Block, bool, error) {
   228  			s.calls = append(s.calls, getBlockForTypeCall)
   229  			val, found := s.blocks[t]
   230  			return val, found, nil
   231  		},
   232  	}
   233  }
   234  
   235  func (s *baseStorageSuite) addBlock(c *gc.C, t state.BlockType, msg string) {
   236  	s.blocks[t] = mockBlock{
   237  		t:   t,
   238  		msg: msg,
   239  	}
   240  }
   241  
   242  func (s *baseStorageSuite) blockAllChanges(c *gc.C, msg string) {
   243  	s.addBlock(c, state.ChangeBlock, msg)
   244  }
   245  
   246  func (s *baseStorageSuite) blockDestroyEnvironment(c *gc.C, msg string) {
   247  	s.addBlock(c, state.DestroyBlock, msg)
   248  }
   249  
   250  func (s *baseStorageSuite) blockRemoveObject(c *gc.C, msg string) {
   251  	s.addBlock(c, state.RemoveBlock, msg)
   252  }
   253  
   254  func (s *baseStorageSuite) assertBlocked(c *gc.C, err error, msg string) {
   255  	c.Assert(params.IsCodeOperationBlocked(err), jc.IsTrue)
   256  	c.Assert(err, gc.ErrorMatches, msg)
   257  }
   258  
   259  func (s *baseStorageSuite) constructPoolManager() *mockPoolManager {
   260  	return &mockPoolManager{
   261  		getPool: func(name string) (*jujustorage.Config, error) {
   262  			if one, ok := s.pools[name]; ok {
   263  				return one, nil
   264  			}
   265  			return nil, errors.NotFoundf("mock pool manager: get pool %v", name)
   266  		},
   267  		createPool: func(name string, providerType jujustorage.ProviderType, attrs map[string]interface{}) (*jujustorage.Config, error) {
   268  			pool, err := jujustorage.NewConfig(name, providerType, attrs)
   269  			s.pools[name] = pool
   270  			return pool, err
   271  		},
   272  		deletePool: func(name string) error {
   273  			delete(s.pools, name)
   274  			return nil
   275  		},
   276  		listPools: func() ([]*jujustorage.Config, error) {
   277  			result := make([]*jujustorage.Config, len(s.pools))
   278  			i := 0
   279  			for _, v := range s.pools {
   280  				result[i] = v
   281  				i++
   282  			}
   283  			return result, nil
   284  		},
   285  	}
   286  }