github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/environs/filestorage/filestorage_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package filestorage_test
     5  
     6  // The filestorage structs are used as stubs in tests.
     7  // The tests defined herein are simple smoke tests for the
     8  // required reader and writer functionality.
     9  
    10  import (
    11  	"bytes"
    12  	"io/ioutil"
    13  	"os"
    14  	"path/filepath"
    15  	"strings"
    16  	"testing"
    17  
    18  	"github.com/juju/errors"
    19  	jc "github.com/juju/testing/checkers"
    20  	"github.com/juju/utils"
    21  	gc "gopkg.in/check.v1"
    22  
    23  	"github.com/juju/juju/environs/filestorage"
    24  	"github.com/juju/juju/environs/storage"
    25  )
    26  
    27  func TestPackage(t *testing.T) {
    28  	gc.TestingT(t)
    29  }
    30  
    31  type filestorageSuite struct {
    32  	dir    string
    33  	reader storage.StorageReader
    34  	writer storage.StorageWriter
    35  }
    36  
    37  var _ = gc.Suite(&filestorageSuite{})
    38  
    39  func (s *filestorageSuite) SetUpTest(c *gc.C) {
    40  	s.dir = c.MkDir()
    41  	var err error
    42  	s.reader, err = filestorage.NewFileStorageReader(s.dir)
    43  	c.Assert(err, jc.ErrorIsNil)
    44  	s.writer, err = filestorage.NewFileStorageWriter(s.dir)
    45  	c.Assert(err, jc.ErrorIsNil)
    46  }
    47  
    48  func (s *filestorageSuite) createFile(c *gc.C, name string) (fullpath string, data []byte) {
    49  	fullpath = filepath.Join(s.dir, name)
    50  	dir := filepath.Dir(fullpath)
    51  	c.Assert(os.MkdirAll(dir, 0755), gc.IsNil)
    52  	data = []byte{1, 2, 3, 4, 5}
    53  	err := ioutil.WriteFile(fullpath, data, 0644)
    54  	c.Assert(err, jc.ErrorIsNil)
    55  	return fullpath, data
    56  }
    57  
    58  func (s *filestorageSuite) TestList(c *gc.C) {
    59  	names := []string{
    60  		"a/b/c",
    61  		"a/bb",
    62  		"a/c",
    63  		"aa",
    64  		"b/c/d",
    65  	}
    66  	for _, name := range names {
    67  		s.createFile(c, name)
    68  	}
    69  	type test struct {
    70  		prefix   string
    71  		expected []string
    72  	}
    73  	for i, test := range []test{
    74  		{"a", []string{"a/b/c", "a/bb", "a/c", "aa"}},
    75  		{"a/b", []string{"a/b/c", "a/bb"}},
    76  		{"a/b/c", []string{"a/b/c"}},
    77  		{"", names},
    78  	} {
    79  		c.Logf("test %d: prefix=%q", i, test.prefix)
    80  		files, err := storage.List(s.reader, test.prefix)
    81  		c.Assert(err, jc.ErrorIsNil)
    82  		i := len(files)
    83  		j := len(test.expected)
    84  		c.Assert(i, gc.Equals, j)
    85  		for i := range files {
    86  			c.Assert(files[i], jc.SamePath, test.expected[i])
    87  		}
    88  	}
    89  }
    90  
    91  func (s *filestorageSuite) TestListHidesTempDir(c *gc.C) {
    92  	err := s.writer.Put("test-write", bytes.NewReader(nil), 0)
    93  	c.Assert(err, jc.ErrorIsNil)
    94  	files, err := storage.List(s.reader, "")
    95  	c.Assert(err, jc.ErrorIsNil)
    96  	c.Check(files, gc.DeepEquals, []string{"test-write"})
    97  	files, err = storage.List(s.reader, "no-such-directory")
    98  	c.Assert(err, jc.ErrorIsNil)
    99  	c.Check(files, gc.DeepEquals, []string(nil))
   100  	// We also pretend the .tmp directory doesn't exist. If you call a
   101  	// directory that doesn't exist, we just return an empty list of
   102  	// strings, so we force the same behavior for '.tmp'
   103  	// we poke in a file so it would have something to return
   104  	s.createFile(c, ".tmp/test-file")
   105  	files, err = storage.List(s.reader, ".tmp")
   106  	c.Assert(err, jc.ErrorIsNil)
   107  	c.Check(files, gc.DeepEquals, []string(nil))
   108  	// For consistency, we refuse all other possibilities as well
   109  	s.createFile(c, ".tmp/foo/bar")
   110  	files, err = storage.List(s.reader, ".tmp/foo")
   111  	c.Assert(err, jc.ErrorIsNil)
   112  	c.Check(files, gc.DeepEquals, []string(nil))
   113  	s.createFile(c, ".tmpother/foo")
   114  	files, err = storage.List(s.reader, ".tmpother")
   115  	c.Assert(err, jc.ErrorIsNil)
   116  	c.Check(files, gc.DeepEquals, []string(nil))
   117  }
   118  
   119  func (s *filestorageSuite) TestURL(c *gc.C) {
   120  	expectedpath, _ := s.createFile(c, "test-file")
   121  	_, file := filepath.Split(expectedpath)
   122  	url, err := s.reader.URL(file)
   123  	c.Assert(err, jc.ErrorIsNil)
   124  	c.Assert(url, gc.Equals, utils.MakeFileURL(expectedpath))
   125  }
   126  
   127  func (s *filestorageSuite) TestGet(c *gc.C) {
   128  	expectedpath, data := s.createFile(c, "test-file")
   129  	_, file := filepath.Split(expectedpath)
   130  	rc, err := storage.Get(s.reader, file)
   131  	c.Assert(err, jc.ErrorIsNil)
   132  	defer rc.Close()
   133  	c.Assert(err, jc.ErrorIsNil)
   134  	b, err := ioutil.ReadAll(rc)
   135  	c.Assert(err, jc.ErrorIsNil)
   136  	c.Assert(b, gc.DeepEquals, data)
   137  
   138  	// Get on a non-existant path returns errors.NotFound
   139  	_, err = s.reader.Get("nowhere")
   140  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   141  
   142  	// Get on a directory returns errors.NotFound
   143  	s.createFile(c, "dir/file")
   144  	_, err = s.reader.Get("dir")
   145  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   146  }
   147  
   148  func (s *filestorageSuite) TestGetRefusesTemp(c *gc.C) {
   149  	s.createFile(c, ".tmp/test-file")
   150  	_, err := storage.Get(s.reader, ".tmp/test-file")
   151  	c.Check(err, gc.NotNil)
   152  	c.Check(err, jc.Satisfies, os.IsNotExist)
   153  	s.createFile(c, ".tmp/foo/test-file")
   154  	_, err = storage.Get(s.reader, ".tmp/foo/test-file")
   155  	c.Check(err, gc.NotNil)
   156  	c.Check(err, jc.Satisfies, os.IsNotExist)
   157  }
   158  
   159  func (s *filestorageSuite) TestPut(c *gc.C) {
   160  	data := []byte{1, 2, 3, 4, 5}
   161  	err := s.writer.Put("test-write", bytes.NewReader(data), int64(len(data)))
   162  	c.Assert(err, jc.ErrorIsNil)
   163  	b, err := ioutil.ReadFile(filepath.Join(s.dir, "test-write"))
   164  	c.Assert(err, jc.ErrorIsNil)
   165  	c.Assert(b, gc.DeepEquals, data)
   166  }
   167  
   168  func (s *filestorageSuite) TestPutRefusesTmp(c *gc.C) {
   169  	data := []byte{1, 2, 3, 4, 5}
   170  	err := s.writer.Put(".tmp/test-write", bytes.NewReader(data), int64(len(data)))
   171  	c.Assert(err, gc.NotNil)
   172  	c.Check(err, jc.Satisfies, os.IsPermission)
   173  	c.Check(*err.(*os.PathError), gc.Equals, os.PathError{
   174  		Op:   "Put",
   175  		Path: ".tmp/test-write",
   176  		Err:  os.ErrPermission,
   177  	})
   178  	_, err = ioutil.ReadFile(filepath.Join(s.dir, ".tmp", "test-write"))
   179  	c.Assert(err, jc.Satisfies, os.IsNotExist)
   180  }
   181  
   182  func (s *filestorageSuite) TestRemove(c *gc.C) {
   183  	expectedpath, _ := s.createFile(c, "test-file")
   184  	_, file := filepath.Split(expectedpath)
   185  	err := s.writer.Remove(file)
   186  	c.Assert(err, jc.ErrorIsNil)
   187  	_, err = ioutil.ReadFile(expectedpath)
   188  	c.Assert(err, gc.Not(gc.IsNil))
   189  }
   190  
   191  func (s *filestorageSuite) TestRemoveAll(c *gc.C) {
   192  	expectedpath, _ := s.createFile(c, "test-file")
   193  	err := s.writer.RemoveAll()
   194  	c.Assert(err, jc.ErrorIsNil)
   195  	_, err = ioutil.ReadFile(expectedpath)
   196  	c.Assert(err, gc.Not(gc.IsNil))
   197  }
   198  
   199  func (s *filestorageSuite) TestPutTmpDir(c *gc.C) {
   200  	// Put should create and clean up the temporary directory
   201  	err := s.writer.Put("test-write", bytes.NewReader(nil), 0)
   202  	c.Assert(err, jc.ErrorIsNil)
   203  	_, err = os.Stat(s.dir + "/.tmp")
   204  	c.Assert(err, jc.Satisfies, os.IsNotExist)
   205  
   206  	// To deal with recovering from hard failure, we
   207  	// don't care if the temporary directory already exists. It
   208  	// still removes it, though.
   209  	err = os.Mkdir(s.dir+"/.tmp", 0755)
   210  	c.Assert(err, jc.ErrorIsNil)
   211  	err = s.writer.Put("test-write", bytes.NewReader(nil), 0)
   212  	c.Assert(err, jc.ErrorIsNil)
   213  	_, err = os.Stat(s.dir + "/.tmp")
   214  	c.Assert(err, jc.Satisfies, os.IsNotExist)
   215  }
   216  
   217  func (s *filestorageSuite) TestPathRelativeToHome(c *gc.C) {
   218  	homeDir := utils.Home()
   219  	tempDir, err := ioutil.TempDir(homeDir, "")
   220  	c.Assert(err, jc.ErrorIsNil)
   221  	defer os.RemoveAll(tempDir)
   222  	dirName := strings.Replace(tempDir, homeDir, "", -1)
   223  	reader, err := filestorage.NewFileStorageReader(filepath.Join(utils.Home(), dirName))
   224  	c.Assert(err, jc.ErrorIsNil)
   225  	url, err := reader.URL("")
   226  	c.Assert(err, jc.ErrorIsNil)
   227  	c.Assert(url, gc.Equals, utils.MakeFileURL(filepath.Join(homeDir, dirName)))
   228  }
   229  
   230  func (s *filestorageSuite) TestRelativePath(c *gc.C) {
   231  	dir := c.MkDir()
   232  	err := os.MkdirAll(filepath.Join(dir, "a", "b", "c"), os.ModePerm)
   233  	c.Assert(err, jc.ErrorIsNil)
   234  	cwd, err := os.Getwd()
   235  	c.Assert(err, jc.ErrorIsNil)
   236  	err = os.Chdir(filepath.Join(dir, "a", "b", "c"))
   237  	c.Assert(err, jc.ErrorIsNil)
   238  	defer os.Chdir(cwd)
   239  	reader, err := filestorage.NewFileStorageReader("../..")
   240  	c.Assert(err, jc.ErrorIsNil)
   241  	url, err := reader.URL("")
   242  	c.Assert(err, jc.ErrorIsNil)
   243  	c.Assert(url, gc.Equals, utils.MakeFileURL(dir)+"/a")
   244  }