github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/upgrades/charmstorage_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package upgrades_test 5 6 import ( 7 "io/ioutil" 8 "net/url" 9 "path/filepath" 10 "strings" 11 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 "gopkg.in/juju/charm.v4" 15 16 "github.com/juju/juju/agent" 17 "github.com/juju/juju/environs" 18 jujutesting "github.com/juju/juju/juju/testing" 19 "github.com/juju/juju/state" 20 "github.com/juju/juju/state/storage" 21 "github.com/juju/juju/upgrades" 22 ) 23 24 type migrateCharmStorageSuite struct { 25 jujutesting.JujuConnSuite 26 27 bundleURLs map[string]*url.URL 28 } 29 30 var _ = gc.Suite(&migrateCharmStorageSuite{}) 31 32 func (s *migrateCharmStorageSuite) SetUpTest(c *gc.C) { 33 s.JujuConnSuite.SetUpTest(c) 34 s.bundleURLs = make(map[string]*url.URL) 35 36 s.PatchValue(upgrades.CharmBundleURL, func(ch *state.Charm) *url.URL { 37 return s.bundleURLs[ch.URL().String()] 38 }) 39 s.PatchValue(upgrades.CharmStoragePath, func(ch *state.Charm) string { 40 // pretend none of the charms have storage paths 41 return "" 42 }) 43 } 44 45 func (s *migrateCharmStorageSuite) TestMigrateCharmStorage(c *gc.C) { 46 stor := s.Environ.(environs.EnvironStorage).Storage() 47 err := stor.Put("somewhere", strings.NewReader("abc"), 3) 48 c.Assert(err, jc.ErrorIsNil) 49 50 dummyCharm := s.AddTestingCharm(c, "dummy") 51 dummyCharmURL, err := stor.URL("somewhere") 52 c.Assert(err, jc.ErrorIsNil) 53 url, err := url.Parse(dummyCharmURL) 54 c.Assert(err, jc.ErrorIsNil) 55 s.bundleURLs[dummyCharm.URL().String()] = url 56 57 s.testMigrateCharmStorage(c, dummyCharm.URL(), &mockAgentConfig{}) 58 } 59 60 func (s *migrateCharmStorageSuite) TestMigrateCharmStorageLocalstorage(c *gc.C) { 61 storageDir := c.MkDir() 62 err := ioutil.WriteFile(filepath.Join(storageDir, "somewhere"), []byte("abc"), 0644) 63 c.Assert(err, jc.ErrorIsNil) 64 65 dummyCharm := s.AddTestingCharm(c, "dummy") 66 url := &url.URL{Scheme: "https", Host: "localhost:8040", Path: "/somewhere"} 67 c.Assert(err, jc.ErrorIsNil) 68 s.bundleURLs[dummyCharm.URL().String()] = url 69 70 s.testMigrateCharmStorage(c, dummyCharm.URL(), &mockAgentConfig{ 71 values: map[string]string{ 72 agent.ProviderType: "local", 73 agent.StorageDir: storageDir, 74 }, 75 }) 76 } 77 78 func (s *migrateCharmStorageSuite) testMigrateCharmStorage(c *gc.C, curl *charm.URL, agentConfig agent.Config) { 79 curlPlaceholder := charm.MustParseURL("cs:quantal/dummy-1") 80 err := s.State.AddStoreCharmPlaceholder(curlPlaceholder) 81 c.Assert(err, jc.ErrorIsNil) 82 83 curlPending := charm.MustParseURL("cs:quantal/missing-123") 84 _, err = s.State.PrepareStoreCharmUpload(curlPending) 85 c.Assert(err, jc.ErrorIsNil) 86 87 var storagePath string 88 var called bool 89 s.PatchValue(upgrades.StateAddCharmStoragePaths, func(st *state.State, storagePaths map[*charm.URL]string) error { 90 c.Assert(storagePaths, gc.HasLen, 1) 91 for k, v := range storagePaths { 92 c.Assert(k.String(), gc.Equals, curl.String()) 93 storagePath = v 94 } 95 called = true 96 return nil 97 }) 98 err = upgrades.MigrateCharmStorage(s.State, agentConfig) 99 c.Assert(err, jc.ErrorIsNil) 100 c.Assert(called, jc.IsTrue) 101 102 storage := storage.NewStorage(s.State.EnvironUUID(), s.State.MongoSession()) 103 r, length, err := storage.Get(storagePath) 104 c.Assert(err, jc.ErrorIsNil) 105 c.Assert(r, gc.NotNil) 106 defer r.Close() 107 c.Assert(length, gc.Equals, int64(3)) 108 data, err := ioutil.ReadAll(r) 109 c.Assert(err, jc.ErrorIsNil) 110 c.Assert(string(data), gc.Equals, "abc") 111 } 112 113 func (s *migrateCharmStorageSuite) TestMigrateCharmStorageIdempotency(c *gc.C) { 114 // If MigrateCharmStorage is called a second time, it will 115 // leave alone the charms that have already been migrated. 116 // The final step of migration is a transactional update 117 // of the charm document in state, which is what we base 118 // the decision on. 119 s.PatchValue(upgrades.CharmStoragePath, func(ch *state.Charm) string { 120 return "alreadyset" 121 }) 122 s.AddTestingCharm(c, "dummy") 123 var called bool 124 s.PatchValue(upgrades.StateAddCharmStoragePaths, func(st *state.State, storagePaths map[*charm.URL]string) error { 125 c.Assert(storagePaths, gc.HasLen, 0) 126 called = true 127 return nil 128 }) 129 err := upgrades.MigrateCharmStorage(s.State, &mockAgentConfig{}) 130 c.Assert(err, jc.ErrorIsNil) 131 c.Assert(called, jc.IsTrue) 132 }