github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/apiserver/diskformatter/diskformatter_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package diskformatter_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/api/watcher"
    13  	"github.com/juju/juju/apiserver/common"
    14  	"github.com/juju/juju/apiserver/diskformatter"
    15  	"github.com/juju/juju/apiserver/params"
    16  	apiservertesting "github.com/juju/juju/apiserver/testing"
    17  	"github.com/juju/juju/state"
    18  	"github.com/juju/juju/storage"
    19  	coretesting "github.com/juju/juju/testing"
    20  )
    21  
    22  var _ = gc.Suite(&DiskFormatterSuite{})
    23  
    24  type DiskFormatterSuite struct {
    25  	coretesting.BaseSuite
    26  	resources  *common.Resources
    27  	authorizer *apiservertesting.FakeAuthorizer
    28  	tag        names.UnitTag
    29  	st         *mockState
    30  	api        *diskformatter.DiskFormatterAPI
    31  }
    32  
    33  func (s *DiskFormatterSuite) SetUpTest(c *gc.C) {
    34  	s.BaseSuite.SetUpTest(c)
    35  	s.resources = common.NewResources()
    36  	s.tag = names.NewUnitTag("service/0")
    37  	s.authorizer = &apiservertesting.FakeAuthorizer{Tag: s.tag}
    38  	s.st = &mockState{}
    39  	diskformatter.PatchState(s, s.st)
    40  
    41  	var err error
    42  	s.api, err = diskformatter.NewDiskFormatterAPI(nil, s.resources, s.authorizer)
    43  	c.Assert(err, jc.ErrorIsNil)
    44  }
    45  
    46  func (s *DiskFormatterSuite) TestWatchBlockDevices(c *gc.C) {
    47  	results, err := s.api.WatchBlockDevices(params.Entities{
    48  		Entities: []params.Entity{
    49  			{Tag: "unit-service-0"},
    50  			{Tag: "disk-1"},
    51  		},
    52  	})
    53  	c.Assert(err, jc.ErrorIsNil)
    54  	c.Assert(results, gc.DeepEquals, params.StringsWatchResults{
    55  		Results: []params.StringsWatchResult{
    56  			{Error: &params.Error{Message: "WatchUnitMachineBlockDevices fails", Code: ""}},
    57  			// disk-1 does not exist, so we get ErrPerm.
    58  			{Error: &params.Error{Message: "permission denied", Code: "unauthorized access"}},
    59  		},
    60  	})
    61  	c.Assert(s.st.calls, gc.DeepEquals, []string{"WatchUnitMachineBlockDevices"})
    62  	c.Assert(s.st.unitTags, gc.DeepEquals, []names.UnitTag{s.tag})
    63  }
    64  
    65  func (s *DiskFormatterSuite) TestBlockDevices(c *gc.C) {
    66  	s.st.devices = map[string]state.BlockDevice{
    67  		"0": &mockBlockDevice{
    68  			name:            "0",
    69  			storageInstance: "storage/0",
    70  			info:            &state.BlockDeviceInfo{},
    71  			attached:        true,
    72  		},
    73  		"1": &mockBlockDevice{
    74  			storageInstance: "storage/1",
    75  			attached:        true,
    76  		},
    77  		"2": &mockBlockDevice{
    78  			attached: true,
    79  		},
    80  		"3": &mockBlockDevice{
    81  			name:            "3",
    82  			storageInstance: "storage/0",
    83  			attached:        true,
    84  		},
    85  		"4": &mockBlockDevice{
    86  			attached: false,
    87  		},
    88  	}
    89  	s.st.storageInstances = map[string]state.StorageInstance{
    90  		"storage/0": &mockStorageInstance{owner: s.tag},
    91  		"storage/1": &mockStorageInstance{owner: names.NewServiceTag("mysql")},
    92  	}
    93  
    94  	results, err := s.api.BlockDevices(params.Entities{
    95  		Entities: []params.Entity{
    96  			{Tag: "disk-0"},
    97  			{Tag: "disk-1"}, // different owner
    98  			{Tag: "disk-2"}, // no storage instance
    99  			{Tag: "disk-3"}, // not provisioned
   100  			{Tag: "disk-4"}, // unattached
   101  			{Tag: "disk-5"}, // missing
   102  		},
   103  	})
   104  	c.Assert(err, jc.ErrorIsNil)
   105  	c.Assert(results, gc.DeepEquals, params.BlockDeviceResults{
   106  		Results: []params.BlockDeviceResult{
   107  			{Result: storage.BlockDevice{Name: "0"}},
   108  			{Error: &params.Error{Message: "permission denied", Code: "unauthorized access"}},
   109  			{Error: &params.Error{Message: "permission denied", Code: "unauthorized access"}},
   110  			{Error: &params.Error{Message: `block device "3" not provisioned`, Code: "not provisioned"}},
   111  			{Error: &params.Error{Message: "permission denied", Code: "unauthorized access"}},
   112  			{Error: &params.Error{Message: "permission denied", Code: "unauthorized access"}},
   113  		},
   114  	})
   115  	c.Assert(s.st.calls, gc.DeepEquals, []string{
   116  		"BlockDevice", "StorageInstance",
   117  		"BlockDevice", "StorageInstance",
   118  		"BlockDevice", // no storage instance
   119  		"BlockDevice", "StorageInstance",
   120  		"BlockDevice", // unattached
   121  		"BlockDevice", // missing
   122  	})
   123  	c.Assert(s.st.blockDeviceNames, gc.DeepEquals, []string{
   124  		"0", "1", "2", "3", "4", "5",
   125  	})
   126  	c.Assert(s.st.storageInstanceIds, gc.DeepEquals, []string{
   127  		"storage/0", "storage/1", "storage/0",
   128  	})
   129  }
   130  
   131  func (s *DiskFormatterSuite) TestBlockDeviceStorageInstances(c *gc.C) {
   132  	s.st.devices = map[string]state.BlockDevice{
   133  		"0": &mockBlockDevice{
   134  			name:            "0",
   135  			storageInstance: "storage/0",
   136  			info:            &state.BlockDeviceInfo{},
   137  			attached:        true,
   138  		},
   139  		"1": &mockBlockDevice{
   140  			name:            "1",
   141  			storageInstance: "storage/1",
   142  			info:            &state.BlockDeviceInfo{},
   143  			attached:        true,
   144  		},
   145  	}
   146  	s.st.storageInstances = map[string]state.StorageInstance{
   147  		"storage/0": &mockStorageInstance{
   148  			id:    "storage/0",
   149  			owner: s.tag,
   150  			kind:  state.StorageKindBlock,
   151  		},
   152  		"storage/1": &mockStorageInstance{
   153  			id:    "storage/1",
   154  			owner: s.tag,
   155  			kind:  state.StorageKindFilesystem,
   156  		},
   157  	}
   158  
   159  	results, err := s.api.BlockDeviceStorageInstances(params.Entities{
   160  		Entities: []params.Entity{{Tag: "disk-0"}, {Tag: "disk-1"}},
   161  	})
   162  	c.Assert(err, jc.ErrorIsNil)
   163  	c.Assert(results, gc.DeepEquals, params.StorageInstanceResults{
   164  		Results: []params.StorageInstanceResult{
   165  			{Result: storage.StorageInstance{
   166  				Id:   "storage/0",
   167  				Kind: storage.StorageKindBlock,
   168  			}},
   169  			{Result: storage.StorageInstance{
   170  				Id:   "storage/1",
   171  				Kind: storage.StorageKindFilesystem,
   172  			}},
   173  		},
   174  	})
   175  	c.Assert(s.st.calls, gc.DeepEquals, []string{
   176  		"BlockDevice", "StorageInstance",
   177  		"BlockDevice", "StorageInstance",
   178  	})
   179  	c.Assert(s.st.blockDeviceNames, gc.DeepEquals, []string{
   180  		"0", "1",
   181  	})
   182  	c.Assert(s.st.storageInstanceIds, gc.DeepEquals, []string{
   183  		"storage/0", "storage/1",
   184  	})
   185  }
   186  
   187  type mockState struct {
   188  	calls            []string
   189  	devices          map[string]state.BlockDevice
   190  	storageInstances map[string]state.StorageInstance
   191  
   192  	unitTags           []names.UnitTag
   193  	blockDeviceNames   []string
   194  	storageInstanceIds []string
   195  }
   196  
   197  func (st *mockState) WatchUnitMachineBlockDevices(tag names.UnitTag) (watcher.StringsWatcher, error) {
   198  	st.calls = append(st.calls, "WatchUnitMachineBlockDevices")
   199  	st.unitTags = append(st.unitTags, tag)
   200  	return nil, errors.New("WatchUnitMachineBlockDevices fails")
   201  }
   202  
   203  func (st *mockState) BlockDevice(name string) (state.BlockDevice, error) {
   204  	st.calls = append(st.calls, "BlockDevice")
   205  	st.blockDeviceNames = append(st.blockDeviceNames, name)
   206  	blockDevice, ok := st.devices[name]
   207  	if !ok {
   208  		return nil, errors.NotFoundf("block device %q", name)
   209  	}
   210  	return blockDevice, nil
   211  }
   212  
   213  func (st *mockState) StorageInstance(id string) (state.StorageInstance, error) {
   214  	st.calls = append(st.calls, "StorageInstance")
   215  	st.storageInstanceIds = append(st.storageInstanceIds, id)
   216  	storageInstance, ok := st.storageInstances[id]
   217  	if !ok {
   218  		return nil, errors.NotFoundf("storage instance %q", id)
   219  	}
   220  	return storageInstance, nil
   221  }
   222  
   223  type mockBlockDevice struct {
   224  	state.BlockDevice
   225  	name            string
   226  	storageInstance string
   227  	attached        bool
   228  	info            *state.BlockDeviceInfo
   229  }
   230  
   231  func (d *mockBlockDevice) Name() string {
   232  	return d.name
   233  }
   234  
   235  func (d *mockBlockDevice) Attached() bool {
   236  	return d.attached
   237  }
   238  
   239  func (d *mockBlockDevice) Info() (state.BlockDeviceInfo, error) {
   240  	if d.info == nil {
   241  		return state.BlockDeviceInfo{}, errors.NotProvisionedf("block device %q", d.name)
   242  	}
   243  	return *d.info, nil
   244  }
   245  
   246  func (d *mockBlockDevice) StorageInstance() (string, bool) {
   247  	return d.storageInstance, d.storageInstance != ""
   248  }
   249  
   250  type mockStorageInstance struct {
   251  	state.StorageInstance
   252  	id    string
   253  	owner names.Tag
   254  	kind  state.StorageKind
   255  }
   256  
   257  func (d *mockStorageInstance) Id() string {
   258  	return d.id
   259  }
   260  
   261  func (d *mockStorageInstance) Owner() names.Tag {
   262  	return d.owner
   263  }
   264  
   265  func (d *mockStorageInstance) Kind() state.StorageKind {
   266  	return d.kind
   267  }