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 }