github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/wrench/wrench_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package wrench_test
     5  
     6  import (
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  	"runtime"
    11  	stdtesting "testing"
    12  
    13  	"github.com/juju/loggo"
    14  	jc "github.com/juju/testing/checkers"
    15  	gc "gopkg.in/check.v1"
    16  
    17  	coretesting "github.com/juju/juju/testing"
    18  	"github.com/juju/juju/wrench"
    19  )
    20  
    21  func TestPackage(t *stdtesting.T) {
    22  	gc.TestingT(t)
    23  }
    24  
    25  type wrenchSuite struct {
    26  	coretesting.BaseSuite
    27  	wrenchDir string
    28  	logWriter loggo.TestWriter
    29  }
    30  
    31  var _ = gc.Suite(&wrenchSuite{})
    32  
    33  func (s *wrenchSuite) SetUpTest(c *gc.C) {
    34  	s.BaseSuite.SetUpTest(c)
    35  	// BaseSuite turns off wrench so restore the non-testing default.
    36  	wrench.SetEnabled(true)
    37  	c.Assert(loggo.RegisterWriter("wrench-tests", &s.logWriter, loggo.TRACE), gc.IsNil)
    38  	s.AddCleanup(func(*gc.C) {
    39  		s.logWriter.Clear()
    40  		loggo.RemoveWriter("wrench-tests")
    41  	})
    42  }
    43  
    44  func (s *wrenchSuite) TearDownSuite(c *gc.C) {
    45  	s.BaseSuite.TearDownSuite(c)
    46  	// Ensure the wrench is turned off when these tests are done.
    47  	wrench.SetEnabled(false)
    48  }
    49  
    50  func (s *wrenchSuite) createWrenchDir(c *gc.C) {
    51  	s.wrenchDir = c.MkDir()
    52  	s.PatchValue(wrench.WrenchDir, s.wrenchDir)
    53  }
    54  
    55  func (s *wrenchSuite) createWrenchFile(c *gc.C, name, content string) string {
    56  	filename := filepath.Join(s.wrenchDir, name)
    57  	err := ioutil.WriteFile(filename, []byte(content), 0700)
    58  	c.Assert(err, jc.ErrorIsNil)
    59  	return filename
    60  }
    61  
    62  func (s *wrenchSuite) TestIsActive(c *gc.C) {
    63  	s.createWrenchDir(c)
    64  	s.createWrenchFile(c, "foo", "bar")
    65  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsTrue)
    66  	s.AssertActivationLogged(c)
    67  }
    68  
    69  func (s *wrenchSuite) TestIsActiveWithWhitespace(c *gc.C) {
    70  	s.createWrenchDir(c)
    71  	s.createWrenchFile(c, "foo", "\tbar  ")
    72  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsTrue)
    73  	s.AssertActivationLogged(c)
    74  }
    75  
    76  func (s *wrenchSuite) TestIsActiveMultiFeatures(c *gc.C) {
    77  	s.createWrenchDir(c)
    78  	s.createWrenchFile(c, "foo", "one\ntwo\nbar\n")
    79  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsTrue)
    80  	s.AssertActivationLogged(c)
    81  }
    82  
    83  func (s *wrenchSuite) TestIsActiveMultiFeaturesWithMixedNewlines(c *gc.C) {
    84  	s.createWrenchDir(c)
    85  	s.createWrenchFile(c, "foo", "one\ntwo\r\nthree\nbar\n")
    86  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsTrue)
    87  	s.AssertActivationLogged(c)
    88  }
    89  
    90  func (s *wrenchSuite) TestNotActive(c *gc.C) {
    91  	s.createWrenchDir(c)
    92  	s.createWrenchFile(c, "foo", "abc")
    93  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsFalse)
    94  	s.AssertNothingLogged(c)
    95  }
    96  
    97  func (s *wrenchSuite) TestNoFile(c *gc.C) {
    98  	s.createWrenchDir(c)
    99  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsFalse)
   100  	s.AssertFileErrorLogged(c)
   101  }
   102  
   103  func (s *wrenchSuite) TestMatchInOtherCategory(c *gc.C) {
   104  	s.createWrenchDir(c)
   105  	s.createWrenchFile(c, "other", "bar")
   106  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsFalse)
   107  	s.AssertFileErrorLogged(c)
   108  }
   109  
   110  func (s *wrenchSuite) TestNoDirectory(c *gc.C) {
   111  	s.PatchValue(wrench.WrenchDir, "/does/not/exist")
   112  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsFalse)
   113  	s.AssertDirErrorLogged(c)
   114  }
   115  
   116  func (s *wrenchSuite) TestFileNotOwnedByJujuUser(c *gc.C) {
   117  	s.createWrenchDir(c)
   118  	filename := s.createWrenchFile(c, "foo", "bar")
   119  	s.tweakOwner(c, filename)
   120  
   121  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsFalse)
   122  
   123  	c.Assert(s.logWriter.Log(), jc.LogMatches, []jc.SimpleMessage{{
   124  		loggo.ERROR,
   125  		`wrench file for foo/bar has incorrect ownership - ignoring ` + filename,
   126  	}})
   127  }
   128  
   129  func (s *wrenchSuite) TestFilePermsTooLoose(c *gc.C) {
   130  	if runtime.GOOS == "windows" {
   131  		c.Skip("Windows is not fully POSIX compliant")
   132  	}
   133  	s.createWrenchDir(c)
   134  	filename := s.createWrenchFile(c, "foo", "bar")
   135  	err := os.Chmod(filename, 0666)
   136  	c.Assert(err, jc.ErrorIsNil)
   137  
   138  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsFalse)
   139  
   140  	c.Assert(s.logWriter.Log(), jc.LogMatches, []jc.SimpleMessage{{
   141  		loggo.ERROR,
   142  		`wrench file for foo/bar should only be writable by owner - ignoring ` + filename,
   143  	}})
   144  }
   145  
   146  func (s *wrenchSuite) TestDirectoryNotOwnedByJujuUser(c *gc.C) {
   147  	s.createWrenchDir(c)
   148  	s.tweakOwner(c, s.wrenchDir)
   149  
   150  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsFalse)
   151  
   152  	c.Assert(s.logWriter.Log(), jc.LogMatches, []jc.SimpleMessage{{
   153  		loggo.ERROR,
   154  		`wrench directory has incorrect ownership - wrench functionality disabled \(.+\)`,
   155  	}})
   156  }
   157  
   158  func (s *wrenchSuite) TestSetEnabled(c *gc.C) {
   159  	s.createWrenchDir(c)
   160  	s.createWrenchFile(c, "foo", "bar")
   161  
   162  	// Starts enabled.
   163  	c.Assert(wrench.IsEnabled(), jc.IsTrue)
   164  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsTrue)
   165  
   166  	// Disable.
   167  	c.Assert(wrench.SetEnabled(false), jc.IsTrue)
   168  	c.Assert(wrench.IsEnabled(), jc.IsFalse)
   169  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsFalse)
   170  
   171  	// Enable again.
   172  	c.Assert(wrench.SetEnabled(true), jc.IsFalse)
   173  	c.Assert(wrench.IsEnabled(), jc.IsTrue)
   174  	c.Assert(wrench.IsActive("foo", "bar"), jc.IsTrue)
   175  }
   176  
   177  var notJujuUid = uint32(os.Getuid() + 1)
   178  
   179  func (s *wrenchSuite) AssertActivationLogged(c *gc.C) {
   180  	c.Assert(s.logWriter.Log(), jc.LogMatches, []jc.SimpleMessage{
   181  		{loggo.WARNING, `wrench for foo/bar is active`}})
   182  }
   183  
   184  func (s *wrenchSuite) AssertNothingLogged(c *gc.C) {
   185  	c.Assert(len(s.logWriter.Log()), gc.Equals, 0)
   186  }
   187  
   188  func (s *wrenchSuite) AssertFileErrorLogged(c *gc.C) {
   189  	c.Assert(s.logWriter.Log(), jc.LogMatches, []jc.SimpleMessage{
   190  		{loggo.DEBUG, `no wrench data for foo/bar \(ignored\): ` + fileNotFound}})
   191  }
   192  
   193  func (s *wrenchSuite) AssertDirErrorLogged(c *gc.C) {
   194  	c.Assert(s.logWriter.Log(), jc.LogMatches, []jc.SimpleMessage{
   195  		{loggo.DEBUG, `couldn't read wrench directory: ` + fileNotFound}})
   196  }