github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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 }