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 }