github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/upgradeseries_test.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"github.com/juju/loggo"
     8  	jc "github.com/juju/testing/checkers"
     9  	gc "gopkg.in/check.v1"
    10  	"gopkg.in/juju/names.v2"
    11  	"gopkg.in/tomb.v2"
    12  
    13  	"github.com/golang/mock/gomock"
    14  	"github.com/juju/juju/apiserver/common"
    15  	"github.com/juju/juju/apiserver/common/mocks"
    16  	"github.com/juju/juju/apiserver/params"
    17  	apiservertesting "github.com/juju/juju/apiserver/testing"
    18  	"github.com/juju/juju/core/model"
    19  	"github.com/juju/juju/testing"
    20  )
    21  
    22  type upgradeSeriesSuite struct {
    23  	testing.BaseSuite
    24  
    25  	machineTag1 names.MachineTag
    26  	unitTag1    names.UnitTag
    27  	unitTag2    names.UnitTag
    28  }
    29  
    30  var _ = gc.Suite(&upgradeSeriesSuite{})
    31  
    32  func (s *upgradeSeriesSuite) SetUpTest(c *gc.C) {
    33  	s.machineTag1 = names.NewMachineTag("1")
    34  	s.unitTag1 = names.NewUnitTag("mysql/1")
    35  	s.unitTag2 = names.NewUnitTag("redis/1")
    36  }
    37  
    38  func (s *upgradeSeriesSuite) assertBackendApi(c *gc.C, tag names.Tag) (*common.UpgradeSeriesAPI, *gomock.Controller, *mocks.MockUpgradeSeriesBackend) {
    39  	resources := common.NewResources()
    40  	authorizer := apiservertesting.FakeAuthorizer{
    41  		Tag: tag,
    42  	}
    43  
    44  	ctrl := gomock.NewController(c)
    45  	mockBackend := mocks.NewMockUpgradeSeriesBackend(ctrl)
    46  
    47  	unitAuthFunc := func() (common.AuthFunc, error) {
    48  		return func(tag names.Tag) bool {
    49  			if tag.Id() == s.unitTag1.Id() {
    50  				return true
    51  			}
    52  			return false
    53  		}, nil
    54  	}
    55  
    56  	machineAuthFunc := func() (common.AuthFunc, error) {
    57  		return func(tag names.Tag) bool {
    58  			if tag.Id() == s.machineTag1.Id() {
    59  				return true
    60  			}
    61  			return false
    62  		}, nil
    63  	}
    64  
    65  	api := common.NewUpgradeSeriesAPI(
    66  		mockBackend, resources, authorizer, machineAuthFunc, unitAuthFunc, loggo.GetLogger("juju.apiserver.common"))
    67  	return api, ctrl, mockBackend
    68  }
    69  
    70  func (s *upgradeSeriesSuite) TestWatchUpgradeSeriesNotificationsUnitTag(c *gc.C) {
    71  	api, ctrl, mockBackend := s.assertBackendApi(c, s.unitTag1)
    72  	defer ctrl.Finish()
    73  
    74  	upgradeSeriesWatcher := &mockNotifyWatcher{
    75  		changes: make(chan struct{}, 1),
    76  	}
    77  	upgradeSeriesWatcher.changes <- struct{}{}
    78  
    79  	mockMachine1 := mocks.NewMockUpgradeSeriesMachine(ctrl)
    80  	mockUnit1 := mocks.NewMockUpgradeSeriesUnit(ctrl)
    81  
    82  	mockBackend.EXPECT().Machine(s.machineTag1.Id()).Return(mockMachine1, nil)
    83  	mockBackend.EXPECT().Unit(s.unitTag1.Id()).Return(mockUnit1, nil)
    84  	mockMachine1.EXPECT().WatchUpgradeSeriesNotifications().Return(upgradeSeriesWatcher, nil)
    85  	mockUnit1.EXPECT().AssignedMachineId().Return(s.machineTag1.Id(), nil)
    86  
    87  	args := params.Entities{Entities: []params.Entity{
    88  		{Tag: names.NewUnitTag("mysql/2").String()},
    89  		{Tag: s.unitTag1.String()},
    90  	}}
    91  	watches, err := api.WatchUpgradeSeriesNotifications(args)
    92  	c.Assert(err, jc.ErrorIsNil)
    93  	c.Assert(watches, gc.DeepEquals, params.NotifyWatchResults{
    94  		Results: []params.NotifyWatchResult{
    95  			{NotifyWatcherId: "", Error: &params.Error{Message: "permission denied", Code: "unauthorized access"}},
    96  			{NotifyWatcherId: "1", Error: nil},
    97  		},
    98  	})
    99  }
   100  
   101  func (s *upgradeSeriesSuite) TestWatchUpgradeSeriesNotificationsMachineTag(c *gc.C) {
   102  	api, ctrl, mockBackend := s.assertBackendApi(c, s.machineTag1)
   103  	defer ctrl.Finish()
   104  
   105  	mockMachine := mocks.NewMockUpgradeSeriesMachine(ctrl)
   106  
   107  	upgradeSeriesWatcher := &mockNotifyWatcher{
   108  		changes: make(chan struct{}, 1),
   109  	}
   110  	upgradeSeriesWatcher.changes <- struct{}{}
   111  
   112  	mockBackend.EXPECT().Machine(s.machineTag1.Id()).Return(mockMachine, nil)
   113  	mockMachine.EXPECT().WatchUpgradeSeriesNotifications().Return(upgradeSeriesWatcher, nil)
   114  
   115  	watches, err := api.WatchUpgradeSeriesNotifications(
   116  		params.Entities{
   117  			Entities: []params.Entity{
   118  				{Tag: s.machineTag1.String()},
   119  				{Tag: names.NewMachineTag("7").String()},
   120  			},
   121  		},
   122  	)
   123  	c.Assert(err, jc.ErrorIsNil)
   124  	c.Assert(watches, gc.DeepEquals, params.NotifyWatchResults{
   125  		Results: []params.NotifyWatchResult{
   126  			{NotifyWatcherId: "1"},
   127  			{NotifyWatcherId: "", Error: &params.Error{Message: "permission denied", Code: "unauthorized access"}},
   128  		},
   129  	})
   130  }
   131  
   132  func (s *upgradeSeriesSuite) TestSetUpgradeSeriesStatusUnitTag(c *gc.C) {
   133  	api, ctrl, mockBackend := s.assertBackendApi(c, s.unitTag1)
   134  	defer ctrl.Finish()
   135  
   136  	mockUnit := mocks.NewMockUpgradeSeriesUnit(ctrl)
   137  
   138  	mockBackend.EXPECT().Unit(s.unitTag1.Id()).Return(mockUnit, nil)
   139  	mockUnit.EXPECT().SetUpgradeSeriesStatus(model.UpgradeSeriesPrepareCompleted, gomock.Any()).Return(nil)
   140  
   141  	args := params.UpgradeSeriesStatusParams{
   142  		Params: []params.UpgradeSeriesStatusParam{
   143  			{
   144  				Entity: params.Entity{Tag: s.unitTag1.String()},
   145  				Status: model.UpgradeSeriesPrepareCompleted,
   146  			},
   147  			{
   148  				Entity: params.Entity{Tag: names.NewUnitTag("mysql/2").String()},
   149  				Status: model.UpgradeSeriesPrepareCompleted,
   150  			},
   151  		},
   152  	}
   153  	watches, err := api.SetUpgradeSeriesUnitStatus(args)
   154  	c.Assert(err, jc.ErrorIsNil)
   155  	c.Assert(watches, gc.DeepEquals, params.ErrorResults{
   156  		Results: []params.ErrorResult{
   157  			{Error: nil},
   158  			{Error: &params.Error{Message: "permission denied", Code: "unauthorized access"}},
   159  		},
   160  	})
   161  }
   162  
   163  func (s *upgradeSeriesSuite) TestUpgradeSeriesStatusUnitTag(c *gc.C) {
   164  	api, ctrl, mockBackend := s.assertBackendApi(c, s.unitTag1)
   165  	defer ctrl.Finish()
   166  
   167  	mockUnit := mocks.NewMockUpgradeSeriesUnit(ctrl)
   168  
   169  	mockBackend.EXPECT().Unit(s.unitTag1.Id()).Return(mockUnit, nil)
   170  	mockUnit.EXPECT().UpgradeSeriesStatus().Return(model.UpgradeSeriesPrepareCompleted, nil)
   171  
   172  	args := params.Entities{
   173  		Entities: []params.Entity{
   174  			{Tag: s.unitTag1.String()},
   175  			{Tag: names.NewUnitTag("mysql/2").String()},
   176  		},
   177  	}
   178  
   179  	results, err := api.UpgradeSeriesUnitStatus(args)
   180  	c.Assert(err, jc.ErrorIsNil)
   181  	c.Assert(results, gc.DeepEquals, params.UpgradeSeriesStatusResults{
   182  		Results: []params.UpgradeSeriesStatusResult{
   183  			{Status: model.UpgradeSeriesPrepareCompleted},
   184  			{Error: &params.Error{Message: "permission denied", Code: "unauthorized access"}},
   185  		},
   186  	})
   187  }
   188  
   189  type mockNotifyWatcher struct {
   190  	tomb    tomb.Tomb
   191  	changes chan struct{}
   192  }
   193  
   194  func (m *mockNotifyWatcher) Stop() error {
   195  	m.Kill()
   196  	return m.Wait()
   197  }
   198  
   199  func (m *mockNotifyWatcher) Kill() {
   200  	m.tomb.Kill(nil)
   201  }
   202  
   203  func (m *mockNotifyWatcher) Wait() error {
   204  	return m.tomb.Wait()
   205  }
   206  
   207  func (m *mockNotifyWatcher) Err() error {
   208  	return m.tomb.Err()
   209  }
   210  
   211  func (m *mockNotifyWatcher) Changes() <-chan struct{} {
   212  	return m.changes
   213  }