github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/watcher_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package apiserver_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names/v5"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/apiserver"
    13  	"github.com/juju/juju/apiserver/common"
    14  	apiservererrors "github.com/juju/juju/apiserver/errors"
    15  	"github.com/juju/juju/apiserver/facade"
    16  	"github.com/juju/juju/apiserver/facade/facadetest"
    17  	apiservertesting "github.com/juju/juju/apiserver/testing"
    18  	"github.com/juju/juju/controller"
    19  	"github.com/juju/juju/core/migration"
    20  	"github.com/juju/juju/core/network"
    21  	"github.com/juju/juju/rpc/params"
    22  	"github.com/juju/juju/state"
    23  	"github.com/juju/juju/testing"
    24  )
    25  
    26  type watcherSuite struct {
    27  	testing.BaseSuite
    28  	resources  *common.Resources
    29  	authorizer apiservertesting.FakeAuthorizer
    30  }
    31  
    32  var _ = gc.Suite(&watcherSuite{})
    33  
    34  func (s *watcherSuite) SetUpTest(c *gc.C) {
    35  	s.BaseSuite.SetUpTest(c)
    36  	s.resources = common.NewResources()
    37  	s.AddCleanup(func(*gc.C) {
    38  		s.resources.StopAll()
    39  	})
    40  	s.authorizer = apiservertesting.FakeAuthorizer{}
    41  }
    42  
    43  func (s *watcherSuite) getFacade(
    44  	c *gc.C,
    45  	name string,
    46  	version int,
    47  	id string,
    48  	dispose func(),
    49  ) interface{} {
    50  	factory := getFacadeFactory(c, name, version)
    51  	facade, err := factory(s.facadeContext(id, dispose))
    52  	c.Assert(err, jc.ErrorIsNil)
    53  	return facade
    54  }
    55  
    56  func (s *watcherSuite) facadeContext(id string, dispose func()) facadetest.Context {
    57  	return facadetest.Context{
    58  		Resources_: s.resources,
    59  		Auth_:      s.authorizer,
    60  		ID_:        id,
    61  		Dispose_:   dispose,
    62  	}
    63  }
    64  
    65  func getFacadeFactory(c *gc.C, name string, version int) facade.Factory {
    66  	factory, err := apiserver.AllFacades().GetFactory(name, version)
    67  	c.Assert(err, jc.ErrorIsNil)
    68  	return factory
    69  }
    70  
    71  func (s *watcherSuite) TestVolumeAttachmentsWatcher(c *gc.C) {
    72  	ch := make(chan []string, 1)
    73  	id := s.resources.Register(&fakeStringsWatcher{ch: ch})
    74  	s.authorizer.Tag = names.NewMachineTag("123")
    75  
    76  	ch <- []string{"0:1", "1:2"}
    77  	facade := s.getFacade(c, "VolumeAttachmentsWatcher", 2, id, nopDispose).(machineStorageIdsWatcher)
    78  	result, err := facade.Next()
    79  	c.Assert(err, jc.ErrorIsNil)
    80  
    81  	c.Assert(result, jc.DeepEquals, params.MachineStorageIdsWatchResult{
    82  		Changes: []params.MachineStorageId{
    83  			{MachineTag: "machine-0", AttachmentTag: "volume-1"},
    84  			{MachineTag: "machine-1", AttachmentTag: "volume-2"},
    85  		},
    86  	})
    87  }
    88  
    89  func (s *watcherSuite) TestFilesystemAttachmentsWatcher(c *gc.C) {
    90  	ch := make(chan []string, 1)
    91  	id := s.resources.Register(&fakeStringsWatcher{ch: ch})
    92  	s.authorizer.Tag = names.NewMachineTag("123")
    93  
    94  	ch <- []string{"0:1", "1:2"}
    95  	facade := s.getFacade(c, "FilesystemAttachmentsWatcher", 2, id, nopDispose).(machineStorageIdsWatcher)
    96  	result, err := facade.Next()
    97  	c.Assert(err, jc.ErrorIsNil)
    98  
    99  	c.Assert(result, jc.DeepEquals, params.MachineStorageIdsWatchResult{
   100  		Changes: []params.MachineStorageId{
   101  			{MachineTag: "machine-0", AttachmentTag: "filesystem-1"},
   102  			{MachineTag: "machine-1", AttachmentTag: "filesystem-2"},
   103  		},
   104  	})
   105  }
   106  
   107  func (s *watcherSuite) TestMigrationStatusWatcher(c *gc.C) {
   108  	w := apiservertesting.NewFakeNotifyWatcher()
   109  	id := s.resources.Register(w)
   110  	s.authorizer.Tag = names.NewMachineTag("12")
   111  	apiserver.PatchGetMigrationBackend(s, new(fakeMigrationBackend), new(fakeMigrationBackend))
   112  	apiserver.PatchGetControllerCACert(s, "no worries")
   113  
   114  	facade := s.getFacade(c, "MigrationStatusWatcher", 1, id, nopDispose).(migrationStatusWatcher)
   115  	defer c.Check(facade.Stop(), jc.ErrorIsNil)
   116  	result, err := facade.Next()
   117  	c.Assert(err, jc.ErrorIsNil)
   118  	c.Assert(result, jc.DeepEquals, params.MigrationStatus{
   119  		MigrationId:    "id",
   120  		Attempt:        2,
   121  		Phase:          "IMPORT",
   122  		SourceAPIAddrs: []string{"1.2.3.4:5", "2.3.4.5:6", "3.4.5.6:7"},
   123  		SourceCACert:   "no worries",
   124  		TargetAPIAddrs: []string{"1.2.3.4:5555"},
   125  		TargetCACert:   "trust me",
   126  	})
   127  }
   128  
   129  func (s *watcherSuite) TestMigrationStatusWatcherNoMigration(c *gc.C) {
   130  	w := apiservertesting.NewFakeNotifyWatcher()
   131  	id := s.resources.Register(w)
   132  	s.authorizer.Tag = names.NewMachineTag("12")
   133  	backend := &fakeMigrationBackend{noMigration: true}
   134  	apiserver.PatchGetMigrationBackend(s, backend, backend)
   135  
   136  	facade := s.getFacade(c, "MigrationStatusWatcher", 1, id, nopDispose).(migrationStatusWatcher)
   137  	defer c.Check(facade.Stop(), jc.ErrorIsNil)
   138  	result, err := facade.Next()
   139  	c.Assert(err, jc.ErrorIsNil)
   140  	c.Assert(result, jc.DeepEquals, params.MigrationStatus{
   141  		Phase: "NONE",
   142  	})
   143  }
   144  
   145  func (s *watcherSuite) TestMigrationStatusWatcherNotAgent(c *gc.C) {
   146  	id := s.resources.Register(apiservertesting.NewFakeNotifyWatcher())
   147  	s.authorizer.Tag = names.NewUserTag("frogdog")
   148  
   149  	factory, err := apiserver.AllFacades().GetFactory("MigrationStatusWatcher", 1)
   150  	c.Assert(err, jc.ErrorIsNil)
   151  	_, err = factory(facadetest.Context{
   152  		Resources_: s.resources,
   153  		Auth_:      s.authorizer,
   154  		ID_:        id,
   155  	})
   156  	c.Assert(err, gc.Equals, apiservererrors.ErrPerm)
   157  }
   158  
   159  type machineStorageIdsWatcher interface {
   160  	Next() (params.MachineStorageIdsWatchResult, error)
   161  }
   162  
   163  type fakeStringsWatcher struct {
   164  	state.StringsWatcher
   165  	ch chan []string
   166  }
   167  
   168  func (w *fakeStringsWatcher) Changes() <-chan []string {
   169  	return w.ch
   170  }
   171  
   172  func (w *fakeStringsWatcher) Stop() error {
   173  	return nil
   174  }
   175  
   176  type fakeMigrationBackend struct {
   177  	noMigration bool
   178  }
   179  
   180  func (b *fakeMigrationBackend) LatestMigration() (state.ModelMigration, error) {
   181  	if b.noMigration {
   182  		return nil, errors.NotFoundf("migration")
   183  	}
   184  	return new(fakeModelMigration), nil
   185  }
   186  
   187  func (b *fakeMigrationBackend) APIHostPortsForClients() ([]network.SpaceHostPorts, error) {
   188  	return []network.SpaceHostPorts{
   189  		{
   190  			network.SpaceHostPort{SpaceAddress: network.NewSpaceAddress("1.2.3.4"), NetPort: 5},
   191  			network.SpaceHostPort{SpaceAddress: network.NewSpaceAddress("2.3.4.5"), NetPort: 6},
   192  		}, {
   193  			network.SpaceHostPort{SpaceAddress: network.NewSpaceAddress("3.4.5.6"), NetPort: 7},
   194  		},
   195  	}, nil
   196  }
   197  
   198  func (b *fakeMigrationBackend) ControllerModel() (*state.Model, error) {
   199  	return nil, nil
   200  }
   201  
   202  func (b *fakeMigrationBackend) ControllerConfig() (controller.Config, error) {
   203  	return nil, nil
   204  }
   205  
   206  type fakeModelMigration struct {
   207  	state.ModelMigration
   208  }
   209  
   210  func (m *fakeModelMigration) Id() string {
   211  	return "id"
   212  }
   213  
   214  func (m *fakeModelMigration) Attempt() int {
   215  	return 2
   216  }
   217  
   218  func (m *fakeModelMigration) Phase() (migration.Phase, error) {
   219  	return migration.IMPORT, nil
   220  }
   221  
   222  func (m *fakeModelMigration) TargetInfo() (*migration.TargetInfo, error) {
   223  	return &migration.TargetInfo{
   224  		ControllerTag: names.NewControllerTag("uuid"),
   225  		Addrs:         []string{"1.2.3.4:5555"},
   226  		CACert:        "trust me",
   227  		AuthTag:       names.NewUserTag("admin"),
   228  		Password:      "sekret",
   229  	}, nil
   230  }
   231  
   232  type migrationStatusWatcher interface {
   233  	Next() (params.MigrationStatus, error)
   234  	Stop() error
   235  }
   236  
   237  func nopDispose() {}