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  }