github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/core/cache/controller_test.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  package cache_test
     4  
     5  import (
     6  	"time"
     7  
     8  	"github.com/juju/errors"
     9  	"github.com/juju/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  	"gopkg.in/juju/worker.v1/workertest"
    13  
    14  	"github.com/juju/juju/core/cache"
    15  	"github.com/juju/juju/core/life"
    16  )
    17  
    18  type ControllerSuite struct {
    19  	baseSuite
    20  
    21  	changes chan interface{}
    22  	config  cache.ControllerConfig
    23  }
    24  
    25  var _ = gc.Suite(&ControllerSuite{})
    26  
    27  func (s *ControllerSuite) SetUpTest(c *gc.C) {
    28  	s.baseSuite.SetUpTest(c)
    29  	s.changes = make(chan interface{})
    30  	s.config = cache.ControllerConfig{
    31  		Changes: s.changes,
    32  	}
    33  }
    34  
    35  func (s *ControllerSuite) TestConfigValid(c *gc.C) {
    36  	err := s.config.Validate()
    37  	c.Assert(err, jc.ErrorIsNil)
    38  }
    39  
    40  func (s *ControllerSuite) TestConfigMissingChanges(c *gc.C) {
    41  	s.config.Changes = nil
    42  	err := s.config.Validate()
    43  	c.Check(err, gc.ErrorMatches, "nil Changes not valid")
    44  	c.Check(err, jc.Satisfies, errors.IsNotValid)
    45  }
    46  
    47  func (s *ControllerSuite) TestController(c *gc.C) {
    48  	controller, err := cache.NewController(s.config)
    49  	c.Assert(err, jc.ErrorIsNil)
    50  
    51  	c.Check(controller.ModelUUIDs(), gc.HasLen, 0)
    52  	c.Check(controller.Report(), gc.HasLen, 0)
    53  
    54  	workertest.CleanKill(c, controller)
    55  }
    56  
    57  func (s *ControllerSuite) TestAddModel(c *gc.C) {
    58  	controller, events := s.new(c)
    59  	s.processChange(c, modelChange, events)
    60  
    61  	c.Check(controller.ModelUUIDs(), jc.SameContents, []string{"model-uuid"})
    62  	c.Check(controller.Report(), gc.DeepEquals, map[string]interface{}{
    63  		"model-uuid": map[string]interface{}{
    64  			"name":              "model-owner/test-model",
    65  			"life":              life.Value("alive"),
    66  			"application-count": 0,
    67  		}})
    68  }
    69  
    70  func (s *ControllerSuite) TestRemoveModel(c *gc.C) {
    71  	controller, events := s.new(c)
    72  	s.processChange(c, modelChange, events)
    73  
    74  	remove := cache.RemoveModel{ModelUUID: "model-uuid"}
    75  	s.processChange(c, remove, events)
    76  
    77  	c.Check(controller.ModelUUIDs(), gc.HasLen, 0)
    78  	c.Check(controller.Report(), gc.HasLen, 0)
    79  }
    80  
    81  func (s *ControllerSuite) TestAddApplication(c *gc.C) {
    82  	controller, events := s.new(c)
    83  	s.processChange(c, modelChange, events)
    84  	s.processChange(c, appChange, events)
    85  
    86  	mod, err := controller.Model("model-uuid")
    87  	c.Assert(err, jc.ErrorIsNil)
    88  	c.Check(mod.Report()["application-count"], gc.Equals, 1)
    89  
    90  	app, err := mod.Application("application-name")
    91  	c.Assert(err, jc.ErrorIsNil)
    92  	c.Check(app, gc.NotNil)
    93  }
    94  
    95  func (s *ControllerSuite) TestRemoveApplication(c *gc.C) {
    96  	controller, events := s.new(c)
    97  	s.processChange(c, modelChange, events)
    98  	s.processChange(c, appChange, events)
    99  
   100  	remove := cache.RemoveApplication{
   101  		ModelUUID: "model-uuid",
   102  		Name:      "application-name",
   103  	}
   104  	s.processChange(c, remove, events)
   105  
   106  	mod, err := controller.Model("model-uuid")
   107  	c.Assert(err, jc.ErrorIsNil)
   108  	c.Check(mod.Report()["application-count"], gc.Equals, 0)
   109  }
   110  
   111  func (s *ControllerSuite) new(c *gc.C) (*cache.Controller, <-chan interface{}) {
   112  	events := s.captureEvents(c)
   113  	controller, err := cache.NewController(s.config)
   114  	c.Assert(err, jc.ErrorIsNil)
   115  	s.AddCleanup(func(c *gc.C) { workertest.CleanKill(c, controller) })
   116  	return controller, events
   117  }
   118  
   119  func (s *ControllerSuite) captureEvents(c *gc.C) <-chan interface{} {
   120  	events := make(chan interface{})
   121  	s.config.Notify = func(change interface{}) {
   122  		send := false
   123  		switch change.(type) {
   124  		case cache.ModelChange:
   125  			send = true
   126  		case cache.RemoveModel:
   127  			send = true
   128  		case cache.ApplicationChange:
   129  			send = true
   130  		case cache.RemoveApplication:
   131  			send = true
   132  		default:
   133  			// no-op
   134  		}
   135  		if send {
   136  			c.Logf("sending %#v", change)
   137  			select {
   138  			case events <- change:
   139  			case <-time.After(testing.LongWait):
   140  				c.Fatalf("change not processed by test")
   141  			}
   142  		}
   143  	}
   144  	return events
   145  }
   146  
   147  func (s *ControllerSuite) processChange(c *gc.C, change interface{}, notify <-chan interface{}) {
   148  	select {
   149  	case s.changes <- change:
   150  	case <-time.After(testing.LongWait):
   151  		c.Fatalf("controller did not read change")
   152  	}
   153  	select {
   154  	case obtained := <-notify:
   155  		c.Check(obtained, jc.DeepEquals, change)
   156  	case <-time.After(testing.LongWait):
   157  		c.Fatalf("controller did not handle change")
   158  	}
   159  }
   160  
   161  func (s *ControllerSuite) nextChange(c *gc.C, changes <-chan interface{}) interface{} {
   162  	var obtained interface{}
   163  	select {
   164  	case obtained = <-changes:
   165  	case <-time.After(testing.LongWait):
   166  		c.Fatalf("no change")
   167  	}
   168  	return obtained
   169  }