github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/apiserver/charms/client_test.go (about) 1 // Copyright 2012-2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package charms_test 5 6 import ( 7 jc "github.com/juju/testing/checkers" 8 gc "gopkg.in/check.v1" 9 10 "github.com/juju/juju/apiserver/charms" 11 "github.com/juju/juju/apiserver/common" 12 "github.com/juju/juju/apiserver/params" 13 "github.com/juju/juju/apiserver/testing" 14 jujutesting "github.com/juju/juju/juju/testing" 15 "github.com/juju/juju/testing/factory" 16 ) 17 18 type charmsSuite struct { 19 // TODO(anastasiamac) mock to remove JujuConnSuite 20 jujutesting.JujuConnSuite 21 api *charms.API 22 } 23 24 var _ = gc.Suite(&charmsSuite{}) 25 26 func (s *charmsSuite) SetUpTest(c *gc.C) { 27 s.JujuConnSuite.SetUpTest(c) 28 29 var err error 30 auth := testing.FakeAuthorizer{ 31 Tag: s.AdminUserTag(c), 32 EnvironManager: true, 33 } 34 s.api, err = charms.NewAPI(s.State, common.NewResources(), auth) 35 c.Assert(err, jc.ErrorIsNil) 36 } 37 38 func (s *charmsSuite) TestClientCharmInfo(c *gc.C) { 39 var clientCharmInfoTests = []struct { 40 about string 41 charm string 42 url string 43 expected params.CharmInfo 44 err string 45 }{ 46 { 47 about: "dummy charm which contains an expectedActions spec", 48 charm: "dummy", 49 url: "local:quantal/dummy-1", 50 expected: params.CharmInfo{ 51 Revision: 1, 52 URL: "local:quantal/dummy-1", 53 Config: map[string]params.CharmOption{ 54 "skill-level": params.CharmOption{ 55 Type: "int", 56 Description: "A number indicating skill."}, 57 "title": params.CharmOption{ 58 Type: "string", 59 Description: "A descriptive title used for the application.", 60 Default: "My Title"}, 61 "outlook": params.CharmOption{ 62 Type: "string", 63 Description: "No default outlook."}, 64 "username": params.CharmOption{ 65 Type: "string", 66 Description: "The name of the initial account (given admin permissions).", 67 Default: "admin001"}, 68 }, 69 Meta: ¶ms.CharmMeta{ 70 Name: "dummy", 71 Summary: "That's a dummy charm.", 72 Description: "This is a longer description which\npotentially contains multiple lines.\n", 73 Subordinate: false, 74 MinJujuVersion: "0.0.0", 75 }, 76 Actions: ¶ms.CharmActions{ 77 ActionSpecs: map[string]params.CharmActionSpec{ 78 "snapshot": params.CharmActionSpec{ 79 Description: "Take a snapshot of the database.", 80 Params: map[string]interface{}{ 81 "title": "snapshot", 82 "description": "Take a snapshot of the database.", 83 "type": "object", 84 "properties": map[string]interface{}{ 85 "outfile": map[string]interface{}{ 86 "type": "string", 87 "description": "The file to write out to.", 88 "default": "foo.bz2", 89 }, 90 }, 91 }, 92 }, 93 }, 94 }, 95 }, 96 }, 97 { 98 about: "retrieves charm info", 99 // Use wordpress for tests so that we can compare Provides and Requires. 100 charm: "wordpress", 101 url: "local:quantal/wordpress-3", 102 expected: params.CharmInfo{ 103 Revision: 3, 104 URL: "local:quantal/wordpress-3", 105 Config: map[string]params.CharmOption{ 106 "blog-title": params.CharmOption{Type: "string", Description: "A descriptive title used for the blog.", Default: "My Title"}}, 107 Meta: ¶ms.CharmMeta{ 108 Name: "wordpress", 109 Summary: "Blog engine", 110 Description: "A pretty popular blog engine", 111 Subordinate: false, 112 Provides: map[string]params.CharmRelation{ 113 "logging-dir": params.CharmRelation{ 114 Name: "logging-dir", 115 Role: "provider", 116 Interface: "logging", 117 Scope: "container", 118 }, 119 "monitoring-port": params.CharmRelation{ 120 Name: "monitoring-port", 121 Role: "provider", 122 Interface: "monitoring", 123 Scope: "container", 124 }, 125 "url": params.CharmRelation{ 126 Name: "url", 127 Role: "provider", 128 Interface: "http", 129 Scope: "global", 130 }, 131 }, 132 Requires: map[string]params.CharmRelation{ 133 "cache": params.CharmRelation{ 134 Name: "cache", 135 Role: "requirer", 136 Interface: "varnish", 137 Optional: true, 138 Limit: 2, 139 Scope: "global", 140 }, 141 "db": params.CharmRelation{ 142 Name: "db", 143 Role: "requirer", 144 Interface: "mysql", 145 Limit: 1, 146 Scope: "global", 147 }, 148 }, 149 ExtraBindings: map[string]string{ 150 "admin-api": "admin-api", 151 "foo-bar": "foo-bar", 152 "db-client": "db-client", 153 }, 154 MinJujuVersion: "0.0.0", 155 }, 156 Actions: ¶ms.CharmActions{ 157 ActionSpecs: map[string]params.CharmActionSpec{ 158 "fakeaction": params.CharmActionSpec{ 159 Description: "No description", 160 Params: map[string]interface{}{ 161 "properties": map[string]interface{}{}, 162 "description": "No description", 163 "type": "object", 164 "title": "fakeaction"}, 165 }, 166 }, 167 }, 168 }, 169 }, 170 { 171 about: "invalid URL", 172 charm: "wordpress", 173 url: "not-valid!", 174 err: `URL has invalid charm or bundle name: "not-valid!"`, 175 }, 176 { 177 about: "invalid schema", 178 charm: "wordpress", 179 url: "not-valid:your-arguments", 180 err: `charm or bundle URL has invalid schema: "not-valid:your-arguments"`, 181 }, 182 { 183 about: "unknown charm", 184 charm: "wordpress", 185 url: "cs:missing/one-1", 186 err: `charm "cs:missing/one-1" not found`, 187 }, 188 } 189 190 for i, t := range clientCharmInfoTests { 191 c.Logf("test %d. %s", i, t.about) 192 s.AddTestingCharm(c, t.charm) 193 info, err := s.api.CharmInfo(params.CharmURL{t.url}) 194 if t.err != "" { 195 c.Check(err, gc.ErrorMatches, t.err) 196 continue 197 } 198 c.Assert(err, jc.ErrorIsNil) 199 c.Check(info, jc.DeepEquals, t.expected) 200 } 201 } 202 203 func (s *charmsSuite) TestMeteredCharmInfo(c *gc.C) { 204 meteredCharm := s.Factory.MakeCharm( 205 c, &factory.CharmParams{Name: "metered", URL: "cs:xenial/metered"}) 206 info, err := s.api.CharmInfo(params.CharmURL{ 207 URL: meteredCharm.URL().String(), 208 }) 209 c.Assert(err, jc.ErrorIsNil) 210 expected := ¶ms.CharmMetrics{ 211 Plan: params.CharmPlan{ 212 Required: true, 213 }, 214 Metrics: map[string]params.CharmMetric{ 215 "pings": params.CharmMetric{ 216 Type: "gauge", 217 Description: "Description of the metric."}, 218 "juju-units": params.CharmMetric{ 219 Type: "", 220 Description: ""}}} 221 c.Assert(info.Metrics, jc.DeepEquals, expected) 222 } 223 224 func (s *charmsSuite) TestListCharmsNoFilter(c *gc.C) { 225 s.assertListCharms(c, []string{"dummy"}, []string{}, []string{"local:quantal/dummy-1"}) 226 } 227 228 func (s *charmsSuite) TestListCharmsWithFilterMatchingNone(c *gc.C) { 229 s.assertListCharms(c, []string{"dummy"}, []string{"notdummy"}, []string{}) 230 } 231 232 func (s *charmsSuite) TestListCharmsFilteredOnly(c *gc.C) { 233 s.assertListCharms(c, []string{"dummy", "wordpress"}, []string{"dummy"}, []string{"local:quantal/dummy-1"}) 234 } 235 236 func (s *charmsSuite) assertListCharms(c *gc.C, someCharms, args, expected []string) { 237 for _, aCharm := range someCharms { 238 s.AddTestingCharm(c, aCharm) 239 } 240 found, err := s.api.List(params.CharmsList{Names: args}) 241 c.Assert(err, jc.ErrorIsNil) 242 c.Check(found.CharmURLs, gc.HasLen, len(expected)) 243 c.Check(found.CharmURLs, jc.DeepEquals, expected) 244 } 245 246 func (s *charmsSuite) TestIsMeteredFalse(c *gc.C) { 247 charm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "wordpress"}) 248 metered, err := s.api.IsMetered(params.CharmURL{ 249 URL: charm.URL().String(), 250 }) 251 c.Assert(err, jc.ErrorIsNil) 252 c.Assert(metered.Metered, jc.IsFalse) 253 } 254 255 func (s *charmsSuite) TestIsMeteredTrue(c *gc.C) { 256 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "cs:quantal/metered"}) 257 metered, err := s.api.IsMetered(params.CharmURL{ 258 URL: meteredCharm.URL().String(), 259 }) 260 c.Assert(err, jc.ErrorIsNil) 261 c.Assert(metered.Metered, jc.IsTrue) 262 }