github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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  )
    25  
    26  type charmVersionSuite struct {
    27  	testing.CharmSuite
    28  	jujutesting.JujuConnSuite
    29  
    30  	charmrevisionupdater *charmrevisionupdater.CharmRevisionUpdaterAPI
    31  	resources            *common.Resources
    32  	authoriser           apiservertesting.FakeAuthorizer
    33  }
    34  
    35  var _ = gc.Suite(&charmVersionSuite{})
    36  
    37  func (s *charmVersionSuite) SetUpSuite(c *gc.C) {
    38  	s.JujuConnSuite.SetUpSuite(c)
    39  	s.CharmSuite.SetUpSuite(c, &s.JujuConnSuite)
    40  }
    41  
    42  func (s *charmVersionSuite) TearDownSuite(c *gc.C) {
    43  	s.CharmSuite.TearDownSuite(c)
    44  	s.JujuConnSuite.TearDownSuite(c)
    45  }
    46  
    47  func (s *charmVersionSuite) SetUpTest(c *gc.C) {
    48  	s.JujuConnSuite.SetUpTest(c)
    49  	s.CharmSuite.SetUpTest(c)
    50  	s.resources = common.NewResources()
    51  	s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() })
    52  	s.authoriser = apiservertesting.FakeAuthorizer{
    53  		EnvironManager: true,
    54  	}
    55  	var err error
    56  	s.charmrevisionupdater, err = charmrevisionupdater.NewCharmRevisionUpdaterAPI(s.State, s.resources, s.authoriser)
    57  	c.Assert(err, jc.ErrorIsNil)
    58  }
    59  
    60  func (s *charmVersionSuite) TearDownTest(c *gc.C) {
    61  	s.CharmSuite.TearDownTest(c)
    62  	s.JujuConnSuite.TearDownTest(c)
    63  }
    64  
    65  func (s *charmVersionSuite) TestNewCharmRevisionUpdaterAPIAcceptsStateManager(c *gc.C) {
    66  	endPoint, err := charmrevisionupdater.NewCharmRevisionUpdaterAPI(s.State, s.resources, s.authoriser)
    67  	c.Assert(err, jc.ErrorIsNil)
    68  	c.Assert(endPoint, gc.NotNil)
    69  }
    70  
    71  func (s *charmVersionSuite) TestNewCharmRevisionUpdaterAPIRefusesNonStateManager(c *gc.C) {
    72  	anAuthoriser := s.authoriser
    73  	anAuthoriser.EnvironManager = false
    74  	endPoint, err := charmrevisionupdater.NewCharmRevisionUpdaterAPI(s.State, s.resources, anAuthoriser)
    75  	c.Assert(endPoint, gc.IsNil)
    76  	c.Assert(err, gc.ErrorMatches, "permission denied")
    77  }
    78  
    79  func (s *charmVersionSuite) TestUpdateRevisions(c *gc.C) {
    80  	s.AddMachine(c, "0", state.JobManageModel)
    81  	s.SetupScenario(c)
    82  
    83  	curl := charm.MustParseURL("cs:quantal/mysql")
    84  	_, err := s.State.LatestPlaceholderCharm(curl)
    85  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
    86  
    87  	curl = charm.MustParseURL("cs:quantal/wordpress")
    88  	_, err = s.State.LatestPlaceholderCharm(curl)
    89  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
    90  
    91  	result, err := s.charmrevisionupdater.UpdateLatestRevisions()
    92  	c.Assert(err, jc.ErrorIsNil)
    93  	c.Assert(result.Error, gc.IsNil)
    94  
    95  	curl = charm.MustParseURL("cs:quantal/mysql")
    96  	pending, err := s.State.LatestPlaceholderCharm(curl)
    97  	c.Assert(err, jc.ErrorIsNil)
    98  	c.Assert(pending.String(), gc.Equals, "cs:quantal/mysql-23")
    99  
   100  	// Latest wordpress is already deployed, so no pending charm.
   101  	curl = charm.MustParseURL("cs:quantal/wordpress")
   102  	_, err = s.State.LatestPlaceholderCharm(curl)
   103  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   104  
   105  	// Varnish has an error when updating, so no pending charm.
   106  	curl = charm.MustParseURL("cs:quantal/varnish")
   107  	_, err = s.State.LatestPlaceholderCharm(curl)
   108  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   109  
   110  	// Update mysql version and run update again.
   111  	svc, err := s.State.Service("mysql")
   112  	c.Assert(err, jc.ErrorIsNil)
   113  	ch := s.AddCharmWithRevision(c, "mysql", 23)
   114  	cfg := state.SetCharmConfig{
   115  		Charm:      ch,
   116  		ForceUnits: true,
   117  	}
   118  	err = svc.SetCharm(cfg)
   119  	c.Assert(err, jc.ErrorIsNil)
   120  
   121  	result, err = s.charmrevisionupdater.UpdateLatestRevisions()
   122  	c.Assert(err, jc.ErrorIsNil)
   123  	c.Assert(result.Error, gc.IsNil)
   124  
   125  	// Latest mysql is now deployed, so no pending charm.
   126  	curl = charm.MustParseURL("cs:quantal/mysql")
   127  	_, err = s.State.LatestPlaceholderCharm(curl)
   128  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   129  }
   130  
   131  func (s *charmVersionSuite) TestWordpressCharmNoReadAccessIsntVisible(c *gc.C) {
   132  	s.AddMachine(c, "0", state.JobManageModel)
   133  	s.SetupScenario(c)
   134  
   135  	// Disallow read access to the wordpress charm in the charm store.
   136  	err := s.Client.Put("/quantal/wordpress/meta/perm/read", nil)
   137  	c.Assert(err, jc.ErrorIsNil)
   138  
   139  	// Run the revision updater and check that the public charm updates are
   140  	// still properly notified.
   141  	result, err := s.charmrevisionupdater.UpdateLatestRevisions()
   142  	c.Assert(err, jc.ErrorIsNil)
   143  	c.Assert(result.Error, gc.IsNil)
   144  
   145  	curl := charm.MustParseURL("cs:quantal/mysql")
   146  	pending, err := s.State.LatestPlaceholderCharm(curl)
   147  	c.Assert(err, jc.ErrorIsNil)
   148  	c.Assert(pending.String(), gc.Equals, "cs:quantal/mysql-23")
   149  
   150  	// No pending charm for wordpress.
   151  	curl = charm.MustParseURL("cs:quantal/wordpress")
   152  	_, err = s.State.LatestPlaceholderCharm(curl)
   153  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   154  }
   155  
   156  func (s *charmVersionSuite) TestEnvironmentUUIDUsed(c *gc.C) {
   157  	s.AddMachine(c, "0", state.JobManageModel)
   158  	s.SetupScenario(c)
   159  
   160  	// Set up a charm store server that stores the request header.
   161  	var header http.Header
   162  	received := false
   163  	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   164  		// the first request is the one with the UUID.
   165  		if !received {
   166  			header = r.Header
   167  			received = true
   168  		}
   169  		s.Handler.ServeHTTP(w, r)
   170  	}))
   171  	defer srv.Close()
   172  
   173  	// Point the charm repo initializer to the testing server.
   174  	s.PatchValue(&charmrevisionupdater.NewCharmStoreClient, func(st *state.State) (charmstore.Client, error) {
   175  		csURL, err := url.Parse(srv.URL)
   176  		c.Assert(err, jc.ErrorIsNil)
   177  		return charmstore.NewCachingClient(state.MacaroonCache{st}, csURL)
   178  	})
   179  
   180  	result, err := s.charmrevisionupdater.UpdateLatestRevisions()
   181  	c.Assert(err, jc.ErrorIsNil)
   182  	c.Assert(result.Error, gc.IsNil)
   183  
   184  	env, err := s.State.Model()
   185  	c.Assert(err, jc.ErrorIsNil)
   186  	c.Assert(header.Get(charmrepo.JujuMetadataHTTPHeader), gc.Equals, "environment_uuid="+env.UUID())
   187  }