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 }