github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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: &params.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: &params.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: &params.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: &params.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:   `cannot parse URL "not-valid!": name "not-valid!" not valid`,
   175  		},
   176  		{
   177  			about: "invalid schema",
   178  			charm: "wordpress",
   179  			url:   "not-valid:your-arguments",
   180  			err:   `cannot parse URL "not-valid:your-arguments": schema "not-valid" not valid`,
   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  		if c.Check(err, jc.ErrorIsNil) == false {
   199  			continue
   200  		}
   201  		c.Check(info, jc.DeepEquals, t.expected)
   202  	}
   203  }
   204  
   205  func (s *charmsSuite) TestMeteredCharmInfo(c *gc.C) {
   206  	meteredCharm := s.Factory.MakeCharm(
   207  		c, &factory.CharmParams{Name: "metered", URL: "cs:xenial/metered"})
   208  	info, err := s.api.CharmInfo(params.CharmURL{
   209  		URL: meteredCharm.URL().String(),
   210  	})
   211  	c.Assert(err, jc.ErrorIsNil)
   212  	expected := &params.CharmMetrics{
   213  		Plan: params.CharmPlan{
   214  			Required: true,
   215  		},
   216  		Metrics: map[string]params.CharmMetric{
   217  			"pings": params.CharmMetric{
   218  				Type:        "gauge",
   219  				Description: "Description of the metric."},
   220  			"juju-units": params.CharmMetric{
   221  				Type:        "",
   222  				Description: ""}}}
   223  	c.Assert(info.Metrics, jc.DeepEquals, expected)
   224  }
   225  
   226  func (s *charmsSuite) TestListCharmsNoFilter(c *gc.C) {
   227  	s.assertListCharms(c, []string{"dummy"}, []string{}, []string{"local:quantal/dummy-1"})
   228  }
   229  
   230  func (s *charmsSuite) TestListCharmsWithFilterMatchingNone(c *gc.C) {
   231  	s.assertListCharms(c, []string{"dummy"}, []string{"notdummy"}, []string{})
   232  }
   233  
   234  func (s *charmsSuite) TestListCharmsFilteredOnly(c *gc.C) {
   235  	s.assertListCharms(c, []string{"dummy", "wordpress"}, []string{"dummy"}, []string{"local:quantal/dummy-1"})
   236  }
   237  
   238  func (s *charmsSuite) assertListCharms(c *gc.C, someCharms, args, expected []string) {
   239  	for _, aCharm := range someCharms {
   240  		s.AddTestingCharm(c, aCharm)
   241  	}
   242  	found, err := s.api.List(params.CharmsList{Names: args})
   243  	c.Assert(err, jc.ErrorIsNil)
   244  	c.Check(found.CharmURLs, gc.HasLen, len(expected))
   245  	c.Check(found.CharmURLs, jc.DeepEquals, expected)
   246  }
   247  
   248  func (s *charmsSuite) TestIsMeteredFalse(c *gc.C) {
   249  	charm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "wordpress"})
   250  	metered, err := s.api.IsMetered(params.CharmURL{
   251  		URL: charm.URL().String(),
   252  	})
   253  	c.Assert(err, jc.ErrorIsNil)
   254  	c.Assert(metered.Metered, jc.IsFalse)
   255  }
   256  
   257  func (s *charmsSuite) TestIsMeteredTrue(c *gc.C) {
   258  	meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "cs:quantal/metered"})
   259  	metered, err := s.api.IsMetered(params.CharmURL{
   260  		URL: meteredCharm.URL().String(),
   261  	})
   262  	c.Assert(err, jc.ErrorIsNil)
   263  	c.Assert(metered.Metered, jc.IsTrue)
   264  }