launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/environs/storage/storage_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package storage_test
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"io"
    10  	"io/ioutil"
    11  	stdtesting "testing"
    12  
    13  	gc "launchpad.net/gocheck"
    14  
    15  	"launchpad.net/juju-core/environs"
    16  	"launchpad.net/juju-core/environs/configstore"
    17  	"launchpad.net/juju-core/environs/storage"
    18  	"launchpad.net/juju-core/provider/dummy"
    19  	"launchpad.net/juju-core/testing"
    20  	"launchpad.net/juju-core/utils"
    21  )
    22  
    23  func TestPackage(t *stdtesting.T) {
    24  	gc.TestingT(t)
    25  }
    26  
    27  var _ = gc.Suite(&datasourceSuite{})
    28  
    29  type datasourceSuite struct {
    30  	home    *testing.FakeHome
    31  	stor    storage.Storage
    32  	baseURL string
    33  }
    34  
    35  const existingEnv = `
    36  environments:
    37      test:
    38          type: dummy
    39          state-server: false
    40          authorized-keys: i-am-a-key
    41  `
    42  
    43  func (s *datasourceSuite) SetUpTest(c *gc.C) {
    44  	s.home = testing.MakeFakeHome(c, existingEnv, "existing")
    45  	environ, err := environs.PrepareFromName("test", configstore.NewMem())
    46  	c.Assert(err, gc.IsNil)
    47  	s.stor = environ.Storage()
    48  	s.baseURL, err = s.stor.URL("")
    49  	c.Assert(err, gc.IsNil)
    50  }
    51  
    52  func (s *datasourceSuite) TearDownTest(c *gc.C) {
    53  	dummy.Reset()
    54  	s.home.Restore()
    55  }
    56  
    57  func (s *datasourceSuite) TestFetch(c *gc.C) {
    58  	sampleData := "hello world"
    59  	s.stor.Put("foo/bar/data.txt", bytes.NewReader([]byte(sampleData)), int64(len(sampleData)))
    60  	ds := storage.NewStorageSimpleStreamsDataSource(s.stor, "")
    61  	rc, url, err := ds.Fetch("foo/bar/data.txt")
    62  	c.Assert(err, gc.IsNil)
    63  	defer rc.Close()
    64  	c.Assert(url, gc.Equals, s.baseURL+"foo/bar/data.txt")
    65  	data, err := ioutil.ReadAll(rc)
    66  	c.Assert(data, gc.DeepEquals, []byte(sampleData))
    67  }
    68  
    69  func (s *datasourceSuite) TestFetchWithBasePath(c *gc.C) {
    70  	sampleData := "hello world"
    71  	s.stor.Put("base/foo/bar/data.txt", bytes.NewReader([]byte(sampleData)), int64(len(sampleData)))
    72  	ds := storage.NewStorageSimpleStreamsDataSource(s.stor, "base")
    73  	rc, url, err := ds.Fetch("foo/bar/data.txt")
    74  	c.Assert(err, gc.IsNil)
    75  	defer rc.Close()
    76  	c.Assert(url, gc.Equals, s.baseURL+"base/foo/bar/data.txt")
    77  	data, err := ioutil.ReadAll(rc)
    78  	c.Assert(data, gc.DeepEquals, []byte(sampleData))
    79  }
    80  
    81  func (s *datasourceSuite) TestFetchWithRetry(c *gc.C) {
    82  	stor := &fakeStorage{shouldRetry: true}
    83  	ds := storage.NewStorageSimpleStreamsDataSource(stor, "base")
    84  	ds.SetAllowRetry(true)
    85  	_, _, err := ds.Fetch("foo/bar/data.txt")
    86  	c.Assert(err, gc.ErrorMatches, "an error")
    87  	c.Assert(stor.getName, gc.Equals, "base/foo/bar/data.txt")
    88  	c.Assert(stor.invokeCount, gc.Equals, 10)
    89  }
    90  
    91  func (s *datasourceSuite) TestFetchWithNoRetry(c *gc.C) {
    92  	// NB shouldRetry below is true indicating the fake storage is capable of
    93  	// retrying, not that it will retry.
    94  	stor := &fakeStorage{shouldRetry: true}
    95  	ds := storage.NewStorageSimpleStreamsDataSource(stor, "base")
    96  	_, _, err := ds.Fetch("foo/bar/data.txt")
    97  	c.Assert(err, gc.ErrorMatches, "an error")
    98  	c.Assert(stor.getName, gc.Equals, "base/foo/bar/data.txt")
    99  	c.Assert(stor.invokeCount, gc.Equals, 1)
   100  }
   101  
   102  func (s *datasourceSuite) TestURL(c *gc.C) {
   103  	sampleData := "hello world"
   104  	s.stor.Put("bar/data.txt", bytes.NewReader([]byte(sampleData)), int64(len(sampleData)))
   105  	ds := storage.NewStorageSimpleStreamsDataSource(s.stor, "")
   106  	url, err := ds.URL("bar")
   107  	c.Assert(err, gc.IsNil)
   108  	expectedURL, _ := s.stor.URL("bar")
   109  	c.Assert(url, gc.Equals, expectedURL)
   110  }
   111  
   112  func (s *datasourceSuite) TestURLWithBasePath(c *gc.C) {
   113  	sampleData := "hello world"
   114  	s.stor.Put("base/bar/data.txt", bytes.NewReader([]byte(sampleData)), int64(len(sampleData)))
   115  	ds := storage.NewStorageSimpleStreamsDataSource(s.stor, "base")
   116  	url, err := ds.URL("bar")
   117  	c.Assert(err, gc.IsNil)
   118  	expectedURL, _ := s.stor.URL("base/bar")
   119  	c.Assert(url, gc.Equals, expectedURL)
   120  }
   121  
   122  var _ = gc.Suite(&storageSuite{})
   123  
   124  type storageSuite struct{}
   125  
   126  type fakeStorage struct {
   127  	getName     string
   128  	listPrefix  string
   129  	invokeCount int
   130  	shouldRetry bool
   131  }
   132  
   133  func (s *fakeStorage) Get(name string) (io.ReadCloser, error) {
   134  	s.getName = name
   135  	s.invokeCount++
   136  	return nil, fmt.Errorf("an error")
   137  }
   138  
   139  func (s *fakeStorage) List(prefix string) ([]string, error) {
   140  	s.listPrefix = prefix
   141  	s.invokeCount++
   142  	return nil, fmt.Errorf("an error")
   143  }
   144  
   145  func (s *fakeStorage) URL(name string) (string, error) {
   146  	return "", nil
   147  }
   148  
   149  func (s *fakeStorage) DefaultConsistencyStrategy() utils.AttemptStrategy {
   150  	return utils.AttemptStrategy{Min: 10}
   151  }
   152  
   153  func (s *fakeStorage) ShouldRetry(error) bool {
   154  	return s.shouldRetry
   155  }
   156  
   157  func (s *storageSuite) TestGetWithRetry(c *gc.C) {
   158  	stor := &fakeStorage{shouldRetry: true}
   159  	attempt := utils.AttemptStrategy{Min: 5}
   160  	storage.GetWithRetry(stor, "foo", attempt)
   161  	c.Assert(stor.getName, gc.Equals, "foo")
   162  	c.Assert(stor.invokeCount, gc.Equals, 5)
   163  }
   164  
   165  func (s *storageSuite) TestGet(c *gc.C) {
   166  	stor := &fakeStorage{shouldRetry: true}
   167  	storage.Get(stor, "foo")
   168  	c.Assert(stor.getName, gc.Equals, "foo")
   169  	c.Assert(stor.invokeCount, gc.Equals, 10)
   170  }
   171  
   172  func (s *storageSuite) TestGetNoRetryAllowed(c *gc.C) {
   173  	stor := &fakeStorage{}
   174  	storage.Get(stor, "foo")
   175  	c.Assert(stor.getName, gc.Equals, "foo")
   176  	c.Assert(stor.invokeCount, gc.Equals, 1)
   177  }
   178  
   179  func (s *storageSuite) TestListWithRetry(c *gc.C) {
   180  	stor := &fakeStorage{shouldRetry: true}
   181  	attempt := utils.AttemptStrategy{Min: 5}
   182  	storage.ListWithRetry(stor, "foo", attempt)
   183  	c.Assert(stor.listPrefix, gc.Equals, "foo")
   184  	c.Assert(stor.invokeCount, gc.Equals, 5)
   185  }
   186  
   187  func (s *storageSuite) TestList(c *gc.C) {
   188  	stor := &fakeStorage{shouldRetry: true}
   189  	storage.List(stor, "foo")
   190  	c.Assert(stor.listPrefix, gc.Equals, "foo")
   191  	c.Assert(stor.invokeCount, gc.Equals, 10)
   192  }
   193  
   194  func (s *storageSuite) TestListNoRetryAllowed(c *gc.C) {
   195  	stor := &fakeStorage{}
   196  	storage.List(stor, "foo")
   197  	c.Assert(stor.listPrefix, gc.Equals, "foo")
   198  	c.Assert(stor.invokeCount, gc.Equals, 1)
   199  }