github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/state/endpoint_bindings_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state_test
     5  
     6  import (
     7  	jc "github.com/juju/testing/checkers"
     8  	gc "gopkg.in/check.v1"
     9  	"gopkg.in/juju/charm.v6-unstable"
    10  
    11  	"github.com/juju/juju/state"
    12  )
    13  
    14  type BindingsSuite struct {
    15  	ConnSuite
    16  
    17  	oldMeta     *charm.Meta
    18  	oldDefaults map[string]string
    19  	newMeta     *charm.Meta
    20  	newDefaults map[string]string
    21  }
    22  
    23  var _ = gc.Suite(&BindingsSuite{})
    24  
    25  func (s *BindingsSuite) SetUpTest(c *gc.C) {
    26  	s.ConnSuite.SetUpTest(c)
    27  
    28  	const dummyCharmWithOneOfEachRelationTypeAndExtraBindings = `
    29  name: dummy
    30  summary: "That's a dummy charm with one relation of each type and extra-bindings."
    31  description: "This is a longer description."
    32  provides:
    33    foo1:
    34      interface: phony
    35  requires:
    36    bar1:
    37      interface: fake
    38  peers:
    39    self:
    40      interface: dummy
    41  extra-bindings:
    42    one-extra:
    43  `
    44  	oldCharm := s.AddMetaCharm(c, "dummy", dummyCharmWithOneOfEachRelationTypeAndExtraBindings, 1)
    45  	s.oldMeta = oldCharm.Meta()
    46  	s.oldDefaults = map[string]string{
    47  		"foo1":      "",
    48  		"bar1":      "",
    49  		"self":      "",
    50  		"one-extra": "",
    51  	}
    52  
    53  	const dummyCharmWithTwoOfEachRelationTypeAndNoExtraBindings = `
    54  name: dummy
    55  summary: "That's a dummy charm with 2 relations for each type."
    56  description: "This is a longer description."
    57  provides:
    58    foo1:
    59      interface: phony
    60    foo2:
    61      interface: secret
    62  requires:
    63    bar2: real
    64    bar3:
    65      interface: cool
    66  peers:
    67    self:
    68      interface: dummy
    69    me: peer
    70  `
    71  	newCharm := s.AddMetaCharm(c, "dummy", dummyCharmWithTwoOfEachRelationTypeAndNoExtraBindings, 2)
    72  	s.newMeta = newCharm.Meta()
    73  	s.newDefaults = map[string]string{
    74  		"foo1": "",
    75  		"foo2": "",
    76  		"bar2": "",
    77  		"bar3": "",
    78  		"self": "",
    79  		"me":   "",
    80  	}
    81  
    82  	// Add some spaces to use in bindings, but notably NOT the default space, as
    83  	// it should be always allowed.
    84  	_, err := s.State.AddSpace("client", "", nil, true)
    85  	c.Assert(err, jc.ErrorIsNil)
    86  	_, err = s.State.AddSpace("apps", "", nil, false)
    87  	c.Assert(err, jc.ErrorIsNil)
    88  }
    89  
    90  func (s *BindingsSuite) TestMergeBindings(c *gc.C) {
    91  	// The test cases below are not exhaustive, but just check basic
    92  	// functionality. Most of the logic is tested by calling service.SetCharm()
    93  	// in various ways.
    94  
    95  	for i, test := range []struct {
    96  		about          string
    97  		newMap, oldMap map[string]string
    98  		meta           *charm.Meta
    99  		updated        map[string]string
   100  		removed        []string
   101  	}{{
   102  		about:   "defaults used when both newMap and oldMap are nil",
   103  		newMap:  nil,
   104  		oldMap:  nil,
   105  		meta:    s.oldMeta,
   106  		updated: s.copyMap(s.oldDefaults),
   107  		removed: nil,
   108  	}, {
   109  		about:  "oldMap overrides defaults, newMap is nil",
   110  		newMap: nil,
   111  		oldMap: map[string]string{
   112  			"foo1": "client",
   113  			"self": "db",
   114  		},
   115  		meta: s.oldMeta,
   116  		updated: map[string]string{
   117  			"foo1":      "client",
   118  			"bar1":      "",
   119  			"self":      "db",
   120  			"one-extra": "",
   121  		},
   122  		removed: nil,
   123  	}, {
   124  		about: "oldMap overrides defaults, newMap overrides oldMap",
   125  		newMap: map[string]string{
   126  			"foo1":      "",
   127  			"self":      "db",
   128  			"bar1":      "client",
   129  			"one-extra": "apps",
   130  		},
   131  		oldMap: map[string]string{
   132  			"foo1": "client",
   133  			"bar1": "db",
   134  		},
   135  		meta: s.oldMeta,
   136  		updated: map[string]string{
   137  			"foo1":      "",
   138  			"bar1":      "client",
   139  			"self":      "db",
   140  			"one-extra": "apps",
   141  		},
   142  		removed: nil,
   143  	}, {
   144  		about: "newMap overrides defaults, oldMap is nil",
   145  		newMap: map[string]string{
   146  			"self": "db",
   147  		},
   148  		oldMap: nil,
   149  		meta:   s.oldMeta,
   150  		updated: map[string]string{
   151  			"foo1":      "",
   152  			"bar1":      "",
   153  			"self":      "db",
   154  			"one-extra": "",
   155  		},
   156  		removed: nil,
   157  	}, {
   158  		about:  "obsolete entries in oldMap missing in defaults are removed",
   159  		newMap: nil,
   160  		oldMap: map[string]string{
   161  			"any-old-thing": "boo",
   162  			"self":          "db",
   163  			"one-extra":     "apps",
   164  		},
   165  		meta: s.oldMeta,
   166  		updated: map[string]string{
   167  			"foo1":      "",
   168  			"bar1":      "",
   169  			"self":      "db",
   170  			"one-extra": "apps",
   171  		},
   172  		removed: []string{"any-old-thing"},
   173  	}, {
   174  		about: "new endpoints use defaults unless specified in newMap, existing ones are kept",
   175  		newMap: map[string]string{
   176  			"foo2": "db",
   177  			"me":   "client",
   178  			"bar3": "db",
   179  		},
   180  		oldMap: s.copyMap(s.oldDefaults),
   181  		meta:   s.newMeta,
   182  		updated: map[string]string{
   183  			"foo1": "",
   184  			"foo2": "db",
   185  			"bar2": "",
   186  			"bar3": "db",
   187  			"self": "",
   188  			"me":   "client",
   189  		},
   190  		removed: []string{"bar1", "one-extra"},
   191  	}} {
   192  		c.Logf("test #%d: %s", i, test.about)
   193  
   194  		updated, removed, err := state.MergeBindings(test.newMap, test.oldMap, test.meta)
   195  		c.Check(err, jc.ErrorIsNil)
   196  		c.Check(updated, jc.DeepEquals, test.updated)
   197  		c.Check(removed, jc.DeepEquals, test.removed)
   198  	}
   199  }
   200  
   201  func (s *BindingsSuite) copyMap(input map[string]string) map[string]string {
   202  	output := make(map[string]string, len(input))
   203  	for key, value := range input {
   204  		output[key] = value
   205  	}
   206  	return output
   207  }