github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/charmrevisionupdater/updater_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package charmrevisionupdater_test
     5  
     6  import (
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"net/url"
    10  
    11  	"github.com/juju/errors"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  	"gopkg.in/juju/charm.v6-unstable"
    15  	"gopkg.in/juju/charmrepo.v2-unstable"
    16  
    17  	"github.com/juju/juju/apiserver/charmrevisionupdater"
    18  	"github.com/juju/juju/apiserver/charmrevisionupdater/testing"
    19  	"github.com/juju/juju/apiserver/common"
    20  	apiservertesting "github.com/juju/juju/apiserver/testing"
    21  	"github.com/juju/juju/charmstore"
    22  	jujutesting "github.com/juju/juju/juju/testing"
    23  	"github.com/juju/juju/state"
    24  	"github.com/juju/juju/version"
    25  )
    26  
    27  type charmVersionSuite struct {
    28  	testing.CharmSuite
    29  	jujutesting.JujuConnSuite
    30  
    31  	charmrevisionupdater *charmrevisionupdater.CharmRevisionUpdaterAPI
    32  	resources            *common.Resources
    33  	authoriser           apiservertesting.FakeAuthorizer
    34  }
    35  
    36  var _ = gc.Suite(&charmVersionSuite{})
    37  
    38  func (s *charmVersionSuite) SetUpSuite(c *gc.C) {
    39  	s.JujuConnSuite.SetUpSuite(c)
    40  	s.CharmSuite.SetUpSuite(c, &s.JujuConnSuite)
    41  }
    42  
    43  func (s *charmVersionSuite) TearDownSuite(c *gc.C) {
    44  	s.CharmSuite.TearDownSuite(c)
    45  	s.JujuConnSuite.TearDownSuite(c)
    46  }
    47  
    48  func (s *charmVersionSuite) SetUpTest(c *gc.C) {
    49  	s.JujuConnSuite.SetUpTest(c)
    50  	s.CharmSuite.SetUpTest(c)
    51  	s.resources = common.NewResources()
    52  	s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() })
    53  	s.authoriser = apiservertesting.FakeAuthorizer{
    54  		EnvironManager: true,
    55  	}
    56  	var err error
    57  	s.charmrevisionupdater, err = charmrevisionupdater.NewCharmRevisionUpdaterAPI(s.State, s.resources, s.authoriser)
    58  	c.Assert(err, jc.ErrorIsNil)
    59  }
    60  
    61  func (s *charmVersionSuite) TearDownTest(c *gc.C) {
    62  	s.CharmSuite.TearDownTest(c)
    63  	s.JujuConnSuite.TearDownTest(c)
    64  }
    65  
    66  func (s *charmVersionSuite) TestNewCharmRevisionUpdaterAPIAcceptsStateManager(c *gc.C) {
    67  	endPoint, err := charmrevisionupdater.NewCharmRevisionUpdaterAPI(s.State, s.resources, s.authoriser)
    68  	c.Assert(err, jc.ErrorIsNil)
    69  	c.Assert(endPoint, gc.NotNil)
    70  }
    71  
    72  func (s *charmVersionSuite) TestNewCharmRevisionUpdaterAPIRefusesNonStateManager(c *gc.C) {
    73  	anAuthoriser := s.authoriser
    74  	anAuthoriser.EnvironManager = false
    75  	endPoint, err := charmrevisionupdater.NewCharmRevisionUpdaterAPI(s.State, s.resources, anAuthoriser)
    76  	c.Assert(endPoint, gc.IsNil)
    77  	c.Assert(err, gc.ErrorMatches, "permission denied")
    78  }
    79  
    80  func (s *charmVersionSuite) TestUpdateRevisions(c *gc.C) {
    81  	s.AddMachine(c, "0", state.JobManageModel)
    82  	s.SetupScenario(c)
    83  
    84  	curl := charm.MustParseURL("cs:quantal/mysql")
    85  	_, err := s.State.LatestPlaceholderCharm(curl)
    86  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
    87  
    88  	curl = charm.MustParseURL("cs:quantal/wordpress")
    89  	_, err = s.State.LatestPlaceholderCharm(curl)
    90  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
    91  
    92  	result, err := s.charmrevisionupdater.UpdateLatestRevisions()
    93  	c.Assert(err, jc.ErrorIsNil)
    94  	c.Assert(result.Error, gc.IsNil)
    95  
    96  	curl = charm.MustParseURL("cs:quantal/mysql")
    97  	pending, err := s.State.LatestPlaceholderCharm(curl)
    98  	c.Assert(err, jc.ErrorIsNil)
    99  	c.Assert(pending.String(), gc.Equals, "cs:quantal/mysql-23")
   100  
   101  	// Latest wordpress is already deployed, so no pending charm.
   102  	curl = charm.MustParseURL("cs:quantal/wordpress")
   103  	_, err = s.State.LatestPlaceholderCharm(curl)
   104  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   105  
   106  	// Varnish has an error when updating, so no pending charm.
   107  	curl = charm.MustParseURL("cs:quantal/varnish")
   108  	_, err = s.State.LatestPlaceholderCharm(curl)
   109  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   110  
   111  	// Update mysql version and run update again.
   112  	svc, err := s.State.Application("mysql")
   113  	c.Assert(err, jc.ErrorIsNil)
   114  	ch := s.AddCharmWithRevision(c, "mysql", 23)
   115  	cfg := state.SetCharmConfig{
   116  		Charm:      ch,
   117  		ForceUnits: true,
   118  	}
   119  	err = svc.SetCharm(cfg)
   120  	c.Assert(err, jc.ErrorIsNil)
   121  
   122  	result, err = s.charmrevisionupdater.UpdateLatestRevisions()
   123  	c.Assert(err, jc.ErrorIsNil)
   124  	c.Assert(result.Error, gc.IsNil)
   125  
   126  	// Latest mysql is now deployed, so no pending charm.
   127  	curl = charm.MustParseURL("cs:quantal/mysql")
   128  	_, err = s.State.LatestPlaceholderCharm(curl)
   129  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   130  }
   131  
   132  func (s *charmVersionSuite) TestWordpressCharmNoReadAccessIsntVisible(c *gc.C) {
   133  	s.AddMachine(c, "0", state.JobManageModel)
   134  	s.SetupScenario(c)
   135  
   136  	// Disallow read access to the wordpress charm in the charm store.
   137  	err := s.Client.Put("/quantal/wordpress/meta/perm/read", nil)
   138  	c.Assert(err, jc.ErrorIsNil)
   139  
   140  	// Run the revision updater and check that the public charm updates are
   141  	// still properly notified.
   142  	result, err := s.charmrevisionupdater.UpdateLatestRevisions()
   143  	c.Assert(err, jc.ErrorIsNil)
   144  	c.Assert(result.Error, gc.IsNil)
   145  
   146  	curl := charm.MustParseURL("cs:quantal/mysql")
   147  	pending, err := s.State.LatestPlaceholderCharm(curl)
   148  	c.Assert(err, jc.ErrorIsNil)
   149  	c.Assert(pending.String(), gc.Equals, "cs:quantal/mysql-23")
   150  
   151  	// No pending charm for wordpress.
   152  	curl = charm.MustParseURL("cs:quantal/wordpress")
   153  	_, err = s.State.LatestPlaceholderCharm(curl)
   154  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   155  }
   156  
   157  func (s *charmVersionSuite) TestJujuMetadataHeaderIsSent(c *gc.C) {
   158  	s.AddMachine(c, "0", state.JobManageModel)
   159  	s.SetupScenario(c)
   160  
   161  	// Set up a charm store server that stores the request header.
   162  	var header http.Header
   163  	received := false
   164  	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   165  		// the first request is the one with the UUID.
   166  		if !received {
   167  			header = r.Header
   168  			received = true
   169  		}
   170  		s.Handler.ServeHTTP(w, r)
   171  	}))
   172  	defer srv.Close()
   173  
   174  	// Point the charm repo initializer to the testing server.
   175  	s.PatchValue(&charmrevisionupdater.NewCharmStoreClient, func(st *state.State) (charmstore.Client, error) {
   176  		csURL, err := url.Parse(srv.URL)
   177  		c.Assert(err, jc.ErrorIsNil)
   178  		return charmstore.NewCachingClient(state.MacaroonCache{st}, csURL)
   179  	})
   180  
   181  	result, err := s.charmrevisionupdater.UpdateLatestRevisions()
   182  	c.Assert(err, jc.ErrorIsNil)
   183  	c.Assert(result.Error, gc.IsNil)
   184  
   185  	env, err := s.State.Model()
   186  	c.Assert(err, jc.ErrorIsNil)
   187  	cloud, err := s.State.Cloud(env.Cloud())
   188  	c.Assert(err, jc.ErrorIsNil)
   189  	expected_header := []string{
   190  		"environment_uuid=" + env.UUID(),
   191  		"cloud=" + env.Cloud(),
   192  		"cloud_region=" + env.CloudRegion(),
   193  		"provider=" + cloud.Type,
   194  		"controller_version=" + version.Current.String(),
   195  	}
   196  	for i, expected := range expected_header {
   197  		c.Assert(header[charmrepo.JujuMetadataHTTPHeader][i], gc.Equals, expected)
   198  	}
   199  }