github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/credentialvalidator/worker_test.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package credentialvalidator_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/loggo"
    11  	"github.com/juju/names/v5"
    12  	"github.com/juju/testing"
    13  	jc "github.com/juju/testing/checkers"
    14  	"github.com/juju/worker/v3/workertest"
    15  	gc "gopkg.in/check.v1"
    16  
    17  	"github.com/juju/juju/api/base"
    18  	"github.com/juju/juju/core/watcher/watchertest"
    19  	coretesting "github.com/juju/juju/testing"
    20  	"github.com/juju/juju/worker/credentialvalidator"
    21  )
    22  
    23  type WorkerSuite struct {
    24  	testing.IsolationSuite
    25  
    26  	facade                 *mockFacade
    27  	config                 credentialvalidator.Config
    28  	credentialChanges      chan struct{}
    29  	modelCredentialChanges chan struct{}
    30  
    31  	credential *base.StoredCredential
    32  	exists     bool
    33  }
    34  
    35  var _ = gc.Suite(&WorkerSuite{})
    36  
    37  func (s *WorkerSuite) SetUpTest(c *gc.C) {
    38  	s.IsolationSuite.SetUpTest(c)
    39  
    40  	s.credential = &base.StoredCredential{credentialTag, true}
    41  	s.credentialChanges = make(chan struct{})
    42  	s.exists = true
    43  	s.modelCredentialChanges = make(chan struct{})
    44  	s.facade = &mockFacade{
    45  		Stub:         &testing.Stub{},
    46  		credential:   s.credential,
    47  		exists:       s.exists,
    48  		watcher:      watchertest.NewMockNotifyWatcher(s.credentialChanges),
    49  		modelWatcher: watchertest.NewMockNotifyWatcher(s.modelCredentialChanges),
    50  	}
    51  
    52  	s.config = credentialvalidator.Config{
    53  		Facade: s.facade,
    54  		Logger: loggo.GetLogger("test"),
    55  	}
    56  }
    57  
    58  func (s *WorkerSuite) TestStartStop(c *gc.C) {
    59  	w, err := testWorker(s.config)
    60  	c.Assert(err, jc.ErrorIsNil)
    61  	workertest.CheckAlive(c, w)
    62  	workertest.CleanKill(c, w)
    63  
    64  	err = workertest.CheckKilled(c, w)
    65  	c.Assert(err, jc.ErrorIsNil)
    66  	err = workertest.CheckKilled(c, s.facade.watcher)
    67  	c.Assert(err, jc.ErrorIsNil)
    68  	err = workertest.CheckKilled(c, s.facade.modelWatcher)
    69  	c.Assert(err, jc.ErrorIsNil)
    70  	s.facade.CheckCallNames(c, "ModelCredential", "WatchModelCredential", "WatchCredential")
    71  }
    72  
    73  func (s *WorkerSuite) TestStartStopNoCredential(c *gc.C) {
    74  	s.facade.setupModelHasNoCredential()
    75  	w, err := testWorker(s.config)
    76  	c.Assert(err, jc.ErrorIsNil)
    77  	workertest.CheckAlive(c, w)
    78  	workertest.CleanKill(c, w)
    79  
    80  	err = workertest.CheckKilled(c, w)
    81  	c.Assert(err, jc.ErrorIsNil)
    82  	workertest.CheckNilOrKill(c, s.facade.watcher)
    83  	err = workertest.CheckKilled(c, s.facade.modelWatcher)
    84  	c.Assert(err, jc.ErrorIsNil)
    85  	s.facade.CheckCallNames(c, "ModelCredential", "WatchModelCredential")
    86  }
    87  
    88  func (s *WorkerSuite) TestModelCredentialError(c *gc.C) {
    89  	s.facade.SetErrors(errors.New("mc fail"))
    90  
    91  	worker, err := testWorker(s.config)
    92  	c.Check(err, gc.ErrorMatches, "mc fail")
    93  	c.Assert(worker, gc.IsNil)
    94  	s.facade.CheckCallNames(c, "ModelCredential")
    95  }
    96  
    97  func (s *WorkerSuite) TestModelCredentialWatcherError(c *gc.C) {
    98  	s.facade.SetErrors(nil, // ModelCredential call
    99  		errors.New("mcw fail"), // WatchModelCredential call
   100  	)
   101  
   102  	worker, err := testWorker(s.config)
   103  	c.Check(err, gc.ErrorMatches, "mcw fail")
   104  	c.Assert(worker, gc.IsNil)
   105  	s.facade.CheckCallNames(c, "ModelCredential", "WatchModelCredential")
   106  }
   107  
   108  func (s *WorkerSuite) TestWatchError(c *gc.C) {
   109  	s.facade.SetErrors(nil, // ModelCredential call
   110  		nil,                      // WatchModelCredential call
   111  		errors.New("watch fail"), // WatchCredential call
   112  	)
   113  
   114  	worker, err := testWorker(s.config)
   115  	c.Assert(err, gc.ErrorMatches, "watch fail")
   116  	c.Assert(worker, gc.IsNil)
   117  	s.facade.CheckCallNames(c, "ModelCredential", "WatchModelCredential", "WatchCredential")
   118  }
   119  
   120  func (s *WorkerSuite) TestModelCredentialNotNeeded(c *gc.C) {
   121  	s.facade.setupModelHasNoCredential()
   122  	worker, err := testWorker(s.config)
   123  	c.Assert(err, jc.ErrorIsNil)
   124  
   125  	workertest.CheckAlive(c, worker)
   126  	workertest.CleanKill(c, worker)
   127  	s.facade.CheckCallNames(c, "ModelCredential", "WatchModelCredential")
   128  }
   129  
   130  func (s *WorkerSuite) TestCredentialChangeToInvalid(c *gc.C) {
   131  	worker, err := testWorker(s.config)
   132  	c.Assert(err, jc.ErrorIsNil)
   133  
   134  	s.facade.credential.Valid = false
   135  	s.sendChange(c)
   136  
   137  	err = workertest.CheckKilled(c, worker)
   138  	c.Check(err, gc.Equals, credentialvalidator.ErrValidityChanged)
   139  	s.facade.CheckCallNames(c, "ModelCredential", "WatchModelCredential", "WatchCredential", "ModelCredential")
   140  }
   141  
   142  func (s *WorkerSuite) TestCredentialChangeFromInvalid(c *gc.C) {
   143  	s.facade.credential.Valid = false
   144  	worker, err := testWorker(s.config)
   145  	c.Assert(err, jc.ErrorIsNil)
   146  
   147  	s.facade.credential.Valid = true
   148  	s.sendChange(c)
   149  
   150  	err = workertest.CheckKilled(c, worker)
   151  	c.Check(err, gc.Equals, credentialvalidator.ErrValidityChanged)
   152  	s.facade.CheckCallNames(c, "ModelCredential", "WatchModelCredential", "WatchCredential", "ModelCredential")
   153  }
   154  
   155  func (s *WorkerSuite) TestNoRelevantCredentialChange(c *gc.C) {
   156  	worker, err := testWorker(s.config)
   157  	c.Assert(err, jc.ErrorIsNil)
   158  
   159  	s.sendChange(c)
   160  	s.sendChange(c)
   161  
   162  	workertest.CheckAlive(c, worker)
   163  	workertest.CleanKill(c, worker)
   164  	s.facade.CheckCallNames(c, "ModelCredential", "WatchModelCredential", "WatchCredential", "ModelCredential", "ModelCredential")
   165  }
   166  
   167  func (s *WorkerSuite) TestModelCredentialNoChanged(c *gc.C) {
   168  	worker, err := testWorker(s.config)
   169  	c.Assert(err, jc.ErrorIsNil)
   170  
   171  	s.sendModelChange(c)
   172  
   173  	workertest.CheckAlive(c, worker)
   174  	workertest.CleanKill(c, worker)
   175  	s.facade.CheckCallNames(c, "ModelCredential", "WatchModelCredential", "WatchCredential", "ModelCredential")
   176  }
   177  
   178  func (s *WorkerSuite) TestModelCredentialChanged(c *gc.C) {
   179  	worker, err := testWorker(s.config)
   180  	c.Assert(err, jc.ErrorIsNil)
   181  
   182  	s.facade.credential.CloudCredential = names.NewCloudCredentialTag("cloud/anotheruser/credential").String()
   183  	s.sendModelChange(c)
   184  
   185  	err = workertest.CheckKilled(c, worker)
   186  	c.Check(err, gc.Equals, credentialvalidator.ErrModelCredentialChanged)
   187  	s.facade.CheckCallNames(c, "ModelCredential", "WatchModelCredential", "WatchCredential", "ModelCredential")
   188  }
   189  
   190  func (s *WorkerSuite) sendModelChange(c *gc.C) {
   191  	select {
   192  	case s.modelCredentialChanges <- struct{}{}:
   193  	case <-time.After(coretesting.LongWait):
   194  		c.Fatal("timed out sending model credential change")
   195  	}
   196  }
   197  
   198  func (s *WorkerSuite) sendChange(c *gc.C) {
   199  	select {
   200  	case s.credentialChanges <- struct{}{}:
   201  	case <-time.After(coretesting.LongWait):
   202  		c.Fatal("timed out sending credential change")
   203  	}
   204  }
   205  
   206  var testWorker = credentialvalidator.NewWorker