github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/storageprovisioner/caasworker_test.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package storageprovisioner_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/clock/testclock"
    10  	"github.com/juju/errors"
    11  	"github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	"github.com/juju/utils"
    14  	gc "gopkg.in/check.v1"
    15  	"gopkg.in/juju/names.v2"
    16  	"gopkg.in/juju/worker.v1"
    17  	"gopkg.in/juju/worker.v1/workertest"
    18  
    19  	"github.com/juju/juju/apiserver/params"
    20  	"github.com/juju/juju/environs/context"
    21  	"github.com/juju/juju/storage"
    22  	coretesting "github.com/juju/juju/testing"
    23  	"github.com/juju/juju/worker/storageprovisioner"
    24  )
    25  
    26  type WorkerSuite struct {
    27  	testing.IsolationSuite
    28  
    29  	config              storageprovisioner.Config
    30  	applicationsWatcher *mockApplicationsWatcher
    31  	lifeGetter          *mockLifecycleManager
    32  
    33  	applicationChanges chan []string
    34  
    35  	clock *testclock.Clock
    36  }
    37  
    38  var _ = gc.Suite(&WorkerSuite{})
    39  
    40  func (s *WorkerSuite) SetUpTest(c *gc.C) {
    41  	s.IsolationSuite.SetUpTest(c)
    42  
    43  	s.applicationChanges = make(chan []string)
    44  	s.applicationsWatcher = newMockApplicationsWatcher(s.applicationChanges)
    45  	s.lifeGetter = &mockLifecycleManager{}
    46  
    47  	s.config = storageprovisioner.Config{
    48  		Model:            coretesting.ModelTag,
    49  		Scope:            coretesting.ModelTag,
    50  		Applications:     s.applicationsWatcher,
    51  		Volumes:          newMockVolumeAccessor(),
    52  		Filesystems:      newMockFilesystemAccessor(),
    53  		Life:             s.lifeGetter,
    54  		Status:           &mockStatusSetter{},
    55  		Clock:            &mockClock{},
    56  		Registry:         storage.StaticProviderRegistry{},
    57  		CloudCallContext: context.NewCloudCallContext(),
    58  	}
    59  }
    60  
    61  func (s *WorkerSuite) TestValidateConfig(c *gc.C) {
    62  	s.testValidateConfig(c, func(config *storageprovisioner.Config) {
    63  		config.Scope = names.NewApplicationTag("mariadb")
    64  		config.Applications = nil
    65  	}, `nil Applications not valid`)
    66  }
    67  
    68  func (s *WorkerSuite) testValidateConfig(c *gc.C, f func(*storageprovisioner.Config), expect string) {
    69  	config := s.config
    70  	f(&config)
    71  	w, err := storageprovisioner.NewCaasWorker(config)
    72  	if err == nil {
    73  		workertest.DirtyKill(c, w)
    74  	}
    75  	c.Check(err, gc.ErrorMatches, expect)
    76  }
    77  
    78  func (s *WorkerSuite) TestStartStop(c *gc.C) {
    79  	w, err := storageprovisioner.NewCaasWorker(s.config)
    80  	c.Assert(err, jc.ErrorIsNil)
    81  	workertest.CheckAlive(c, w)
    82  	workertest.CleanKill(c, w)
    83  }
    84  
    85  func (s *WorkerSuite) setupNewUnitScenario(c *gc.C) worker.Worker {
    86  	w, err := storageprovisioner.NewCaasWorker(s.config)
    87  	c.Assert(err, jc.ErrorIsNil)
    88  
    89  	select {
    90  	case s.applicationChanges <- []string{"mariadb"}:
    91  	case <-time.After(coretesting.LongWait):
    92  		c.Fatal("timed out sending applications change")
    93  	}
    94  	return w
    95  }
    96  
    97  func (s *WorkerSuite) TestWatchApplicationDead(c *gc.C) {
    98  	w, err := storageprovisioner.NewCaasWorker(s.config)
    99  	c.Assert(err, jc.ErrorIsNil)
   100  	defer workertest.CleanKill(c, w)
   101  
   102  	select {
   103  	case s.applicationChanges <- []string{"postgresql"}:
   104  	case <-time.After(coretesting.LongWait):
   105  		c.Fatal("timed out sending applications change")
   106  	}
   107  
   108  	// Given the worker time to startup.
   109  	shortAttempt := &utils.AttemptStrategy{
   110  		Total: coretesting.LongWait,
   111  		Delay: 10 * time.Millisecond,
   112  	}
   113  	for a := shortAttempt.Start(); a.Next(); {
   114  		if len(s.config.Filesystems.(*mockFilesystemAccessor).Calls()) > 0 {
   115  			break
   116  		}
   117  	}
   118  
   119  	workertest.CleanKill(c, w)
   120  	// Only call is to watch model.
   121  	s.config.Filesystems.(*mockFilesystemAccessor).CheckCallNames(c, "WatchFilesystems")
   122  	s.config.Filesystems.(*mockFilesystemAccessor).CheckCall(c, 0, "WatchFilesystems", coretesting.ModelTag)
   123  }
   124  
   125  func (s *WorkerSuite) TestRemoveApplicationStopsWatchingApplication(c *gc.C) {
   126  	w, err := storageprovisioner.NewCaasWorker(s.config)
   127  	c.Assert(err, jc.ErrorIsNil)
   128  	defer workertest.CleanKill(c, w)
   129  
   130  	select {
   131  	case s.applicationChanges <- []string{"mariadb"}:
   132  	case <-time.After(coretesting.LongWait):
   133  		c.Fatal("timed out sending applications change")
   134  	}
   135  
   136  	// Check that the worker is running or not;
   137  	// given it time to startup.
   138  	shortAttempt := &utils.AttemptStrategy{
   139  		Total: coretesting.LongWait,
   140  		Delay: 10 * time.Millisecond,
   141  	}
   142  	running := false
   143  	for a := shortAttempt.Start(); a.Next(); {
   144  		_, running = storageprovisioner.StorageWorker(w, "mariadb")
   145  		if running {
   146  			break
   147  		}
   148  	}
   149  	c.Assert(running, jc.IsTrue)
   150  
   151  	// Add an additional app worker so we can check that the correct one is accessed.
   152  	storageprovisioner.NewStorageWorker(w, "postgresql")
   153  
   154  	s.lifeGetter.err = &params.Error{Code: params.CodeNotFound}
   155  	select {
   156  	case s.applicationChanges <- []string{"postgresql"}:
   157  	case <-time.After(coretesting.LongWait):
   158  		c.Fatal("timed out sending applications change")
   159  	}
   160  
   161  	// The mariadb worker should still be running.
   162  	_, ok := storageprovisioner.StorageWorker(w, "mariadb")
   163  	c.Assert(ok, jc.IsTrue)
   164  
   165  	// Check that the postgresql worker is running or not;
   166  	// given it time to shutdown.
   167  	running = true
   168  	for a := shortAttempt.Start(); a.Next(); {
   169  		_, running = storageprovisioner.StorageWorker(w, "postgresql")
   170  		if !running {
   171  			break
   172  		}
   173  	}
   174  	c.Assert(running, jc.IsFalse)
   175  	workertest.CleanKill(c, w)
   176  	workertest.CheckKilled(c, s.applicationsWatcher.watcher)
   177  }
   178  
   179  func (s *WorkerSuite) TestWatcherErrorStopsWorker(c *gc.C) {
   180  	w, err := storageprovisioner.NewCaasWorker(s.config)
   181  	c.Assert(err, jc.ErrorIsNil)
   182  	defer workertest.DirtyKill(c, w)
   183  
   184  	select {
   185  	case s.applicationChanges <- []string{"mariadb"}:
   186  	case <-time.After(coretesting.LongWait):
   187  		c.Fatal("timed out sending applications change")
   188  	}
   189  
   190  	s.applicationsWatcher.watcher.KillErr(errors.New("splat"))
   191  	workertest.CheckKilled(c, s.applicationsWatcher.watcher)
   192  	err = workertest.CheckKilled(c, w)
   193  	c.Assert(err, gc.ErrorMatches, "splat")
   194  }