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