github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/storage/provider/tmpfs_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package provider_test
     5  
     6  import (
     7  	"errors"
     8  	"runtime"
     9  
    10  	"github.com/juju/names"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/storage"
    15  	"github.com/juju/juju/storage/provider"
    16  	"github.com/juju/juju/testing"
    17  )
    18  
    19  var _ = gc.Suite(&tmpfsSuite{})
    20  
    21  type tmpfsSuite struct {
    22  	testing.BaseSuite
    23  	storageDir string
    24  	commands   *mockRunCommand
    25  }
    26  
    27  func (s *tmpfsSuite) SetUpTest(c *gc.C) {
    28  	if runtime.GOOS == "windows" {
    29  		c.Skip("Tests relevant only on *nix systems")
    30  	}
    31  	s.BaseSuite.SetUpTest(c)
    32  	s.storageDir = c.MkDir()
    33  }
    34  
    35  func (s *tmpfsSuite) TearDownTest(c *gc.C) {
    36  	if s.commands != nil {
    37  		s.commands.assertDrained()
    38  	}
    39  	s.BaseSuite.TearDownTest(c)
    40  }
    41  
    42  func (s *tmpfsSuite) tmpfsProvider(c *gc.C) storage.Provider {
    43  	s.commands = &mockRunCommand{c: c}
    44  	return provider.TmpfsProvider(s.commands.run)
    45  }
    46  
    47  func (s *tmpfsSuite) TestFilesystemSource(c *gc.C) {
    48  	p := s.tmpfsProvider(c)
    49  	cfg, err := storage.NewConfig("name", provider.TmpfsProviderType, map[string]interface{}{})
    50  	c.Assert(err, jc.ErrorIsNil)
    51  	_, err = p.FilesystemSource(nil, cfg)
    52  	c.Assert(err, gc.ErrorMatches, "storage directory not specified")
    53  	cfg, err = storage.NewConfig("name", provider.TmpfsProviderType, map[string]interface{}{
    54  		"storage-dir": c.MkDir(),
    55  	})
    56  	c.Assert(err, jc.ErrorIsNil)
    57  	_, err = p.FilesystemSource(nil, cfg)
    58  	c.Assert(err, jc.ErrorIsNil)
    59  }
    60  
    61  func (s *tmpfsSuite) TestValidateConfig(c *gc.C) {
    62  	p := s.tmpfsProvider(c)
    63  	cfg, err := storage.NewConfig("name", provider.TmpfsProviderType, map[string]interface{}{})
    64  	c.Assert(err, jc.ErrorIsNil)
    65  	err = p.ValidateConfig(cfg)
    66  	// The tmpfs provider does not have any user
    67  	// configuration, so an empty map will pass.
    68  	c.Assert(err, jc.ErrorIsNil)
    69  }
    70  
    71  func (s *tmpfsSuite) TestSupports(c *gc.C) {
    72  	p := s.tmpfsProvider(c)
    73  	c.Assert(p.Supports(storage.StorageKindBlock), jc.IsFalse)
    74  	c.Assert(p.Supports(storage.StorageKindFilesystem), jc.IsTrue)
    75  }
    76  
    77  func (s *tmpfsSuite) TestScope(c *gc.C) {
    78  	p := s.tmpfsProvider(c)
    79  	c.Assert(p.Scope(), gc.Equals, storage.ScopeMachine)
    80  }
    81  
    82  func (s *tmpfsSuite) tmpfsFilesystemSource(c *gc.C) storage.FilesystemSource {
    83  	s.commands = &mockRunCommand{c: c}
    84  	return provider.TmpfsFilesystemSource(
    85  		s.storageDir,
    86  		s.commands.run,
    87  	)
    88  }
    89  
    90  func (s *tmpfsSuite) TestCreateFilesystems(c *gc.C) {
    91  	source := s.tmpfsFilesystemSource(c)
    92  
    93  	filesystems, err := source.CreateFilesystems([]storage.FilesystemParams{{
    94  		Tag:  names.NewFilesystemTag("6"),
    95  		Size: 2,
    96  	}})
    97  	c.Assert(err, jc.ErrorIsNil)
    98  	c.Assert(filesystems, jc.DeepEquals, []storage.Filesystem{{
    99  		Tag: names.NewFilesystemTag("6"),
   100  		FilesystemInfo: storage.FilesystemInfo{
   101  			FilesystemId: "filesystem-6",
   102  			Size:         2,
   103  		},
   104  	}})
   105  }
   106  
   107  func (s *tmpfsSuite) TestCreateFilesystemsHugePages(c *gc.C) {
   108  	source := s.tmpfsFilesystemSource(c)
   109  
   110  	// Set page size to 16MiB.
   111  	s.PatchValue(provider.Getpagesize, func() int { return 16 * 1024 * 1024 })
   112  
   113  	filesystems, err := source.CreateFilesystems([]storage.FilesystemParams{{
   114  		Tag:  names.NewFilesystemTag("1"),
   115  		Size: 17,
   116  	}, {
   117  		Tag:  names.NewFilesystemTag("2"),
   118  		Size: 16,
   119  	}})
   120  	c.Assert(err, jc.ErrorIsNil)
   121  	c.Assert(filesystems, jc.DeepEquals, []storage.Filesystem{{
   122  		Tag: names.NewFilesystemTag("1"),
   123  		FilesystemInfo: storage.FilesystemInfo{
   124  			FilesystemId: "filesystem-1",
   125  			Size:         32,
   126  		},
   127  	}, {
   128  		Tag: names.NewFilesystemTag("2"),
   129  		FilesystemInfo: storage.FilesystemInfo{
   130  			FilesystemId: "filesystem-2",
   131  			Size:         16,
   132  		},
   133  	}})
   134  }
   135  
   136  func (s *tmpfsSuite) TestCreateFilesystemsIsUse(c *gc.C) {
   137  	source := s.tmpfsFilesystemSource(c)
   138  	_, err := source.CreateFilesystems([]storage.FilesystemParams{{
   139  		Tag:  names.NewFilesystemTag("1"),
   140  		Size: 1,
   141  	}, {
   142  		Tag:  names.NewFilesystemTag("1"),
   143  		Size: 2,
   144  	}})
   145  	c.Assert(err, gc.ErrorMatches, "creating filesystem: filesystem 1 already exists")
   146  }
   147  
   148  func (s *tmpfsSuite) TestAttachFilesystemsPathNotDir(c *gc.C) {
   149  	source := s.tmpfsFilesystemSource(c)
   150  	_, err := source.CreateFilesystems([]storage.FilesystemParams{{
   151  		Tag:  names.NewFilesystemTag("1"),
   152  		Size: 1,
   153  	}})
   154  	c.Assert(err, jc.ErrorIsNil)
   155  	_, err = source.AttachFilesystems([]storage.FilesystemAttachmentParams{{
   156  		Filesystem: names.NewFilesystemTag("1"),
   157  		Path:       "file",
   158  	}})
   159  	c.Assert(err, gc.ErrorMatches, `.* path "file" must be a directory`)
   160  }
   161  
   162  func (s *tmpfsSuite) TestAttachFilesystemsAlreadyMounted(c *gc.C) {
   163  	source := s.tmpfsFilesystemSource(c)
   164  	cmd := s.commands.expect("df", "--output=source", "exists")
   165  	cmd.respond("header\nfilesystem-123", nil)
   166  	_, err := source.CreateFilesystems([]storage.FilesystemParams{{
   167  		Tag:  names.NewFilesystemTag("123"),
   168  		Size: 1,
   169  	}})
   170  	c.Assert(err, jc.ErrorIsNil)
   171  	attachments, err := source.AttachFilesystems([]storage.FilesystemAttachmentParams{{
   172  		Filesystem: names.NewFilesystemTag("123"),
   173  		Path:       "exists",
   174  	}})
   175  	c.Assert(attachments, jc.DeepEquals, []storage.FilesystemAttachment{{
   176  		Filesystem: names.NewFilesystemTag("123"),
   177  		FilesystemAttachmentInfo: storage.FilesystemAttachmentInfo{
   178  			Path: "exists",
   179  		},
   180  	}})
   181  }
   182  
   183  func (s *tmpfsSuite) TestAttachFilesystemsMountReadOnly(c *gc.C) {
   184  	source := s.tmpfsFilesystemSource(c)
   185  	_, err := source.CreateFilesystems([]storage.FilesystemParams{{
   186  		Tag:  names.NewFilesystemTag("1"),
   187  		Size: 1024,
   188  	}})
   189  	c.Assert(err, jc.ErrorIsNil)
   190  
   191  	cmd := s.commands.expect("df", "--output=source", "/var/lib/juju/storage/fs/foo")
   192  	cmd.respond("header\nvalue", nil)
   193  	s.commands.expect("mount", "-t", "tmpfs", "filesystem-1", "/var/lib/juju/storage/fs/foo", "-o", "size=1024m,ro")
   194  
   195  	attachments, err := source.AttachFilesystems([]storage.FilesystemAttachmentParams{{
   196  		Filesystem: names.NewFilesystemTag("1"),
   197  		Path:       "/var/lib/juju/storage/fs/foo",
   198  		AttachmentParams: storage.AttachmentParams{
   199  			Machine:  names.NewMachineTag("2"),
   200  			ReadOnly: true,
   201  		},
   202  	}})
   203  	c.Assert(err, jc.ErrorIsNil)
   204  	c.Assert(attachments, jc.DeepEquals, []storage.FilesystemAttachment{{
   205  		Filesystem: names.NewFilesystemTag("1"),
   206  		Machine:    names.NewMachineTag("2"),
   207  		FilesystemAttachmentInfo: storage.FilesystemAttachmentInfo{
   208  			Path:     "/var/lib/juju/storage/fs/foo",
   209  			ReadOnly: true,
   210  		},
   211  	}})
   212  }
   213  
   214  func (s *tmpfsSuite) TestAttachFilesystemsMountFails(c *gc.C) {
   215  	source := s.tmpfsFilesystemSource(c)
   216  	_, err := source.CreateFilesystems([]storage.FilesystemParams{{
   217  		Tag:  names.NewFilesystemTag("1"),
   218  		Size: 1024,
   219  	}})
   220  	c.Assert(err, jc.ErrorIsNil)
   221  
   222  	cmd := s.commands.expect("df", "--output=source", "/var/lib/juju/storage/fs/foo")
   223  	cmd.respond("header\nvalue", nil)
   224  	cmd = s.commands.expect("mount", "-t", "tmpfs", "filesystem-1", "/var/lib/juju/storage/fs/foo", "-o", "size=1024m")
   225  	cmd.respond("", errors.New("mount failed"))
   226  
   227  	_, err = source.AttachFilesystems([]storage.FilesystemAttachmentParams{{
   228  		Filesystem: names.NewFilesystemTag("1"),
   229  		Path:       "/var/lib/juju/storage/fs/foo",
   230  	}})
   231  	c.Assert(err, gc.ErrorMatches, "attaching filesystem 1: cannot mount tmpfs: mount failed")
   232  }
   233  
   234  func (s *tmpfsSuite) TestAttachFilesystemsNoPathSpecified(c *gc.C) {
   235  	source := s.tmpfsFilesystemSource(c)
   236  	_, err := source.CreateFilesystems([]storage.FilesystemParams{{
   237  		Tag:  names.NewFilesystemTag("1"),
   238  		Size: 1024,
   239  	}})
   240  	c.Assert(err, jc.ErrorIsNil)
   241  	_, err = source.AttachFilesystems([]storage.FilesystemAttachmentParams{{
   242  		Filesystem: names.NewFilesystemTag("6"),
   243  	}})
   244  	c.Assert(err, gc.ErrorMatches, "attaching filesystem 6: filesystem mount point not specified")
   245  }
   246  
   247  func (s *tmpfsSuite) TestAttachFilesystemsNoFilesystem(c *gc.C) {
   248  	source := s.tmpfsFilesystemSource(c)
   249  	_, err := source.AttachFilesystems([]storage.FilesystemAttachmentParams{{
   250  		Filesystem: names.NewFilesystemTag("6"),
   251  		Path:       "/mnt",
   252  	}})
   253  	c.Assert(err, gc.ErrorMatches, "attaching filesystem 6: reading filesystem info from disk: open .*/6.info: no such file or directory")
   254  }
   255  
   256  func (s *tmpfsSuite) TestDetachFilesystems(c *gc.C) {
   257  	source := s.tmpfsFilesystemSource(c)
   258  	testDetachFilesystems(c, s.commands, source, true)
   259  }
   260  
   261  func (s *tmpfsSuite) TestDetachFilesystemsUnattached(c *gc.C) {
   262  	source := s.tmpfsFilesystemSource(c)
   263  	testDetachFilesystems(c, s.commands, source, false)
   264  }