github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/agent/storageprovisioner/internal/filesystemwatcher/watchers_test.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package filesystemwatcher_test
     5  
     6  import (
     7  	"errors"
     8  
     9  	"github.com/juju/testing"
    10  	gc "gopkg.in/check.v1"
    11  	"gopkg.in/juju/names.v2"
    12  
    13  	"github.com/juju/juju/apiserver/facades/agent/storageprovisioner/internal/filesystemwatcher"
    14  	"github.com/juju/juju/state"
    15  	statetesting "github.com/juju/juju/state/testing"
    16  )
    17  
    18  var _ = gc.Suite(&WatchersSuite{})
    19  
    20  type WatchersSuite struct {
    21  	testing.IsolationSuite
    22  	backend  *mockBackend
    23  	watchers filesystemwatcher.Watchers
    24  }
    25  
    26  func (s *WatchersSuite) SetUpTest(c *gc.C) {
    27  	s.IsolationSuite.SetUpTest(c)
    28  	s.backend = &mockBackend{
    29  		machineFilesystemsW:           newStringsWatcher(),
    30  		unitFilesystemsW:              newStringsWatcher(),
    31  		machineFilesystemAttachmentsW: newStringsWatcher(),
    32  		unitFilesystemAttachmentsW:    newStringsWatcher(),
    33  		modelFilesystemsW:             newStringsWatcher(),
    34  		modelFilesystemAttachmentsW:   newStringsWatcher(),
    35  		modelVolumeAttachmentsW:       newStringsWatcher(),
    36  		filesystems: map[string]*mockFilesystem{
    37  			// filesystem 0 has no backing volume.
    38  			"0": {},
    39  			// filesystem 1 is backed by volume 1.
    40  			"1": {volume: names.NewVolumeTag("1")},
    41  			// filesystem 2 is backed by volume 2.
    42  			"2": {volume: names.NewVolumeTag("2")},
    43  		},
    44  		volumeAttachments: map[string]*mockVolumeAttachment{
    45  			"1": {life: state.Alive},
    46  			"2": {life: state.Alive},
    47  		},
    48  		volumeAttachmentRequested: make(chan names.VolumeTag, 10),
    49  	}
    50  	s.AddCleanup(func(*gc.C) {
    51  		s.backend.machineFilesystemsW.Stop()
    52  		s.backend.machineFilesystemAttachmentsW.Stop()
    53  		s.backend.modelFilesystemsW.Stop()
    54  		s.backend.modelFilesystemAttachmentsW.Stop()
    55  		s.backend.modelVolumeAttachmentsW.Stop()
    56  	})
    57  	s.watchers.Backend = s.backend
    58  }
    59  
    60  func (s *WatchersSuite) TestWatchModelManagedFilesystems(c *gc.C) {
    61  	w := s.watchers.WatchModelManagedFilesystems()
    62  	defer statetesting.AssertKillAndWait(c, w)
    63  	s.backend.modelFilesystemsW.C <- []string{"0", "1"}
    64  
    65  	// Filesystem 1 has a backing volume, so should not be reported.
    66  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
    67  	wc.AssertChangeInSingleEvent("0")
    68  	wc.AssertNoChange()
    69  }
    70  
    71  func (s *WatchersSuite) TestWatchModelManagedFilesystemsWatcherErrorsPropagate(c *gc.C) {
    72  	w := s.watchers.WatchModelManagedFilesystems()
    73  	s.backend.modelFilesystemsW.T.Kill(errors.New("rah"))
    74  	c.Assert(w.Wait(), gc.ErrorMatches, "rah")
    75  }
    76  
    77  func (s *WatchersSuite) TestWatchModelManagedFilesystemAttachments(c *gc.C) {
    78  	w := s.watchers.WatchModelManagedFilesystemAttachments()
    79  	defer statetesting.AssertKillAndWait(c, w)
    80  	s.backend.modelFilesystemAttachmentsW.C <- []string{"0:0", "0:1"}
    81  
    82  	// Filesystem 1 has a backing volume, so should not be reported.
    83  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
    84  	wc.AssertChangeInSingleEvent("0:0")
    85  	wc.AssertNoChange()
    86  }
    87  
    88  func (s *WatchersSuite) TestWatchModelManagedFilesystemAttachmentsWatcherErrorsPropagate(c *gc.C) {
    89  	w := s.watchers.WatchModelManagedFilesystemAttachments()
    90  	s.backend.modelFilesystemAttachmentsW.T.Kill(errors.New("rah"))
    91  	c.Assert(w.Wait(), gc.ErrorMatches, "rah")
    92  }
    93  
    94  func (s *WatchersSuite) TestWatchMachineManagedFilesystems(c *gc.C) {
    95  	w := s.watchers.WatchMachineManagedFilesystems(names.NewMachineTag("0"))
    96  	defer statetesting.AssertKillAndWait(c, w)
    97  	s.backend.modelFilesystemsW.C <- []string{"0", "1"}
    98  	s.backend.machineFilesystemsW.C <- []string{"0/2", "0/3"}
    99  	s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"}
   100  
   101  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
   102  	wc.AssertChangeInSingleEvent("0/2", "0/3", "1")
   103  	wc.AssertNoChange()
   104  }
   105  
   106  func (s *WatchersSuite) TestWatchMachineManagedFilesystemsErrorsPropagate(c *gc.C) {
   107  	w := s.watchers.WatchMachineManagedFilesystems(names.NewMachineTag("0"))
   108  	s.backend.modelFilesystemsW.T.Kill(errors.New("rah"))
   109  	c.Assert(w.Wait(), gc.ErrorMatches, "rah")
   110  }
   111  
   112  // TestWatchMachineManagedFilesystemsVolumeAttachedFirst is the same as
   113  // TestWatchMachineManagedFilesystems, but the order of volume attachment
   114  // and model filesystem events is swapped.
   115  func (s *WatchersSuite) TestWatchMachineManagedFilesystemsVolumeAttachedFirst(c *gc.C) {
   116  	w := s.watchers.WatchMachineManagedFilesystems(names.NewMachineTag("0"))
   117  	defer statetesting.AssertKillAndWait(c, w)
   118  	s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"}
   119  	s.backend.modelFilesystemsW.C <- []string{"0", "1"}
   120  	s.backend.machineFilesystemsW.C <- []string{"0/2", "0/3"}
   121  
   122  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
   123  	wc.AssertChangeInSingleEvent("0/2", "0/3", "1")
   124  	wc.AssertNoChange()
   125  }
   126  
   127  func (s *WatchersSuite) TestWatchMachineManagedFilesystemsVolumeAttachedLater(c *gc.C) {
   128  	w := s.watchers.WatchMachineManagedFilesystems(names.NewMachineTag("0"))
   129  	defer statetesting.AssertKillAndWait(c, w)
   130  	s.backend.modelFilesystemsW.C <- []string{"0", "1"}
   131  	s.backend.machineFilesystemsW.C <- []string{"0/2", "0/3"}
   132  	// No volumes are attached to begin with.
   133  	s.backend.modelVolumeAttachmentsW.C <- []string{}
   134  
   135  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
   136  	wc.AssertChangeInSingleEvent("0/2", "0/3")
   137  	wc.AssertNoChange()
   138  
   139  	s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"}
   140  	wc.AssertChangeInSingleEvent("1")
   141  	wc.AssertNoChange()
   142  }
   143  
   144  func (s *WatchersSuite) TestWatchMachineManagedFilesystemsVolumeAttachmentDead(c *gc.C) {
   145  	w := s.watchers.WatchMachineManagedFilesystems(names.NewMachineTag("0"))
   146  	defer statetesting.AssertKillAndWait(c, w)
   147  
   148  	s.backend.machineFilesystemsW.C <- []string{}
   149  	// Volume-backed filesystems 1 and 2 change.
   150  	s.backend.modelFilesystemsW.C <- []string{"1", "2"}
   151  	// The volumes are attached initially...
   152  	s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2"}
   153  	// ... but before the client consumes the event, the backing volume
   154  	// attachments 0:1 and 0:2 become Dead and removed respectively,
   155  	// negating the previous change.
   156  	<-s.backend.volumeAttachmentRequested
   157  	<-s.backend.volumeAttachmentRequested
   158  	s.backend.volumeAttachments["1"].life = state.Dead
   159  	delete(s.backend.volumeAttachments, "2")
   160  	s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2"}
   161  
   162  	// In order to not start the watcher until it has finished processing
   163  	// the previous event, we send another empty list through the channel
   164  	// which does nothing.
   165  	s.backend.modelVolumeAttachmentsW.C <- []string{}
   166  
   167  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
   168  	wc.AssertChangeInSingleEvent()
   169  	wc.AssertNoChange()
   170  }
   171  
   172  func (s *WatchersSuite) TestWatchMachineManagedFilesystemAttachments(c *gc.C) {
   173  	w := s.watchers.WatchMachineManagedFilesystemAttachments(names.NewMachineTag("0"))
   174  	defer statetesting.AssertKillAndWait(c, w)
   175  	s.backend.modelFilesystemAttachmentsW.C <- []string{"0:0", "0:1"}
   176  	s.backend.machineFilesystemAttachmentsW.C <- []string{"0:0/2", "0:0/3"}
   177  	s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"}
   178  
   179  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
   180  	wc.AssertChangeInSingleEvent("0:0/2", "0:0/3", "0:1")
   181  	wc.AssertNoChange()
   182  }
   183  
   184  func (s *WatchersSuite) TestWatchMachineManagedFilesystemAttachmentsErrorsPropagate(c *gc.C) {
   185  	w := s.watchers.WatchMachineManagedFilesystemAttachments(names.NewMachineTag("0"))
   186  	s.backend.modelFilesystemAttachmentsW.T.Kill(errors.New("rah"))
   187  	c.Assert(w.Wait(), gc.ErrorMatches, "rah")
   188  }
   189  
   190  // TestWatchMachineManagedFilesystemAttachmentsVolumeAttachedFirst is the same as
   191  // TestWatchMachineManagedFilesystemAttachments, but the order of volume attachment
   192  // and model filesystem attachment events is swapped.
   193  func (s *WatchersSuite) TestWatchMachineManagedFilesystemAttachmentsVolumeAttachedFirst(c *gc.C) {
   194  	w := s.watchers.WatchMachineManagedFilesystemAttachments(names.NewMachineTag("0"))
   195  	defer statetesting.AssertKillAndWait(c, w)
   196  	s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"}
   197  	s.backend.modelFilesystemAttachmentsW.C <- []string{"0:0", "0:1"}
   198  	s.backend.machineFilesystemAttachmentsW.C <- []string{"0:0/2", "0:0/3"}
   199  
   200  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
   201  	wc.AssertChangeInSingleEvent("0:0/2", "0:0/3", "0:1")
   202  	wc.AssertNoChange()
   203  }
   204  
   205  func (s *WatchersSuite) TestWatchMachineManagedFilesystemAttachmentsVolumeAttachedLater(c *gc.C) {
   206  	w := s.watchers.WatchMachineManagedFilesystemAttachments(names.NewMachineTag("0"))
   207  	defer statetesting.AssertKillAndWait(c, w)
   208  	s.backend.modelFilesystemAttachmentsW.C <- []string{"0:0", "0:1"}
   209  	s.backend.machineFilesystemAttachmentsW.C <- []string{"0:0/2", "0:0/3"}
   210  	// No volumes are attached to begin with.
   211  	s.backend.modelVolumeAttachmentsW.C <- []string{}
   212  
   213  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
   214  	wc.AssertChangeInSingleEvent("0:0/2", "0:0/3")
   215  	wc.AssertNoChange()
   216  
   217  	s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"}
   218  	wc.AssertChangeInSingleEvent("0:1")
   219  	wc.AssertNoChange()
   220  }
   221  
   222  func (s *WatchersSuite) TestWatchMachineManagedFilesystemAttachmentsVolumeAttachmentDead(c *gc.C) {
   223  	w := s.watchers.WatchMachineManagedFilesystemAttachments(names.NewMachineTag("0"))
   224  	defer statetesting.AssertKillAndWait(c, w)
   225  
   226  	s.backend.machineFilesystemAttachmentsW.C <- []string{}
   227  	// Volume-backed filesystems attachments 0:1 and 0:2 change.
   228  	s.backend.modelFilesystemAttachmentsW.C <- []string{"0:1", "0:2"}
   229  	// The volumes are attached initially...
   230  	s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2"}
   231  	// ... but before the client consumes the event, the backing volume
   232  	// attachments 0:1 and 0:2 become Dead and removed respectively,
   233  	// negating the previous change.
   234  	<-s.backend.volumeAttachmentRequested
   235  	<-s.backend.volumeAttachmentRequested
   236  	s.backend.volumeAttachments["1"].life = state.Dead
   237  	delete(s.backend.volumeAttachments, "2")
   238  	s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2"}
   239  
   240  	// In order to not start the watcher until it has finished processing
   241  	// the previous event, we send another empty list through the channel
   242  	// which does nothing.
   243  	s.backend.modelVolumeAttachmentsW.C <- []string{}
   244  
   245  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
   246  	wc.AssertChangeInSingleEvent()
   247  	wc.AssertNoChange()
   248  }
   249  
   250  func (s *WatchersSuite) TestWatchUnitManagedFilesystems(c *gc.C) {
   251  	w := s.watchers.WatchUnitManagedFilesystems(names.NewApplicationTag("mariadb"))
   252  	defer statetesting.AssertKillAndWait(c, w)
   253  	s.backend.modelFilesystemsW.C <- []string{"0", "1"}
   254  	s.backend.unitFilesystemsW.C <- []string{"mariadb/0/2", "mariadb/0/3"}
   255  	s.backend.modelVolumeAttachmentsW.C <- []string{"mariadb/0:1", "mariadb/0:2", "mysql/1:3"}
   256  
   257  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
   258  	wc.AssertChangeInSingleEvent("1", "mariadb/0/2", "mariadb/0/3")
   259  	wc.AssertNoChange()
   260  }
   261  
   262  func (s *WatchersSuite) TestWatchUnitManagedFilesystemsErrorsPropagate(c *gc.C) {
   263  	w := s.watchers.WatchUnitManagedFilesystems(names.NewApplicationTag("mariadb"))
   264  	s.backend.modelFilesystemsW.T.Kill(errors.New("rah"))
   265  	c.Assert(w.Wait(), gc.ErrorMatches, "rah")
   266  }
   267  
   268  func (s *WatchersSuite) TestWatchUnitManagedFilesystemAttachments(c *gc.C) {
   269  	w := s.watchers.WatchUnitManagedFilesystemAttachments(names.NewApplicationTag("mariadb"))
   270  	defer statetesting.AssertKillAndWait(c, w)
   271  	s.backend.modelFilesystemAttachmentsW.C <- []string{"mariadb/0:0", "mariadb/0:1"}
   272  	s.backend.unitFilesystemAttachmentsW.C <- []string{"mariadb/0:mariadb/0/2", "mariadb/0:mariadb/0/3"}
   273  	s.backend.modelVolumeAttachmentsW.C <- []string{"mariadb/0:1", "mariadb/0:2", "mysql/0:3"}
   274  
   275  	wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w)
   276  	wc.AssertChangeInSingleEvent("mariadb/0:mariadb/0/2", "mariadb/0:mariadb/0/3", "mariadb/0:1")
   277  	wc.AssertNoChange()
   278  }
   279  
   280  func (s *WatchersSuite) TestWatchUnitManagedFilesystemAttachmentsErrorsPropagate(c *gc.C) {
   281  	w := s.watchers.WatchUnitManagedFilesystemAttachments(names.NewApplicationTag("mariadb"))
   282  	s.backend.modelFilesystemAttachmentsW.T.Kill(errors.New("rah"))
   283  	c.Assert(w.Wait(), gc.ErrorMatches, "rah")
   284  }