github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/agent/tools/symlinks_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package tools_test 5 6 import ( 7 "os" 8 "path/filepath" 9 "time" 10 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils/v3" 13 "github.com/juju/utils/v3/symlink" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/juju/agent/tools" 17 "github.com/juju/juju/juju/names" 18 "github.com/juju/juju/testing" 19 ) 20 21 type SymlinksSuite struct { 22 dataDir, toolsDir string 23 } 24 25 var _ = gc.Suite(&SymlinksSuite{}) 26 27 func (s *SymlinksSuite) SetUpTest(c *gc.C) { 28 s.dataDir = c.MkDir() 29 s.toolsDir = tools.SharedToolsDir(s.dataDir, testing.CurrentVersion()) 30 err := os.MkdirAll(s.toolsDir, 0755) 31 c.Assert(err, jc.ErrorIsNil) 32 c.Logf("created %s", s.toolsDir) 33 unitDir := tools.ToolsDir(s.dataDir, "unit-u-123") 34 err = symlink.New(s.toolsDir, unitDir) 35 c.Assert(err, jc.ErrorIsNil) 36 c.Logf("created %s => %s", unitDir, s.toolsDir) 37 } 38 39 func (s *SymlinksSuite) TestEnsureSymlinks(c *gc.C) { 40 s.testEnsureSymlinks(c, s.toolsDir) 41 } 42 43 func (s *SymlinksSuite) TestEnsureSymlinksSymlinkedDir(c *gc.C) { 44 dirSymlink := filepath.Join(c.MkDir(), "commands") 45 err := symlink.New(s.toolsDir, dirSymlink) 46 c.Assert(err, jc.ErrorIsNil) 47 c.Logf("created %s => %s", dirSymlink, s.toolsDir) 48 s.testEnsureSymlinks(c, dirSymlink) 49 } 50 51 func (s *SymlinksSuite) testEnsureSymlinks(c *gc.C, dir string) { 52 // If we have both 'jujuc' and 'jujud' prefer 'jujuc' 53 jujucPath := filepath.Join(s.toolsDir, names.Jujuc) 54 jujudPath := filepath.Join(s.toolsDir, names.Jujud) 55 err := os.WriteFile(jujucPath, []byte("first pick"), 0755) 56 c.Assert(err, jc.ErrorIsNil) 57 err = os.WriteFile(jujudPath, []byte("assume sane"), 0755) 58 c.Assert(err, jc.ErrorIsNil) 59 60 assertLink := func(path string) time.Time { 61 target, err := symlink.Read(path) 62 c.Assert(err, jc.ErrorIsNil) 63 c.Check(target, jc.SamePath, jujucPath) 64 c.Check(filepath.Dir(target), gc.Equals, filepath.Dir(jujucPath)) 65 fi, err := os.Lstat(path) 66 c.Assert(err, jc.ErrorIsNil) 67 return fi.ModTime() 68 } 69 70 commands := []string{"foo", "bar"} 71 72 // Check that EnsureSymlinks writes appropriate symlinks. 73 err = tools.EnsureSymlinks(dir, dir, commands) 74 c.Assert(err, jc.ErrorIsNil) 75 mtimes := map[string]time.Time{} 76 for _, name := range commands { 77 tool := filepath.Join(s.toolsDir, name) 78 mtimes[tool] = assertLink(tool) 79 } 80 81 // Check that EnsureSymlinks doesn't overwrite things that don't need to be. 82 err = tools.EnsureSymlinks(s.toolsDir, s.toolsDir, commands) 83 c.Assert(err, jc.ErrorIsNil) 84 for tool, mtime := range mtimes { 85 c.Assert(assertLink(tool), gc.Equals, mtime) 86 } 87 } 88 89 func (s *SymlinksSuite) TestEnsureSymlinksBadDir(c *gc.C) { 90 dir := filepath.Join(c.MkDir(), "noexist") 91 err := tools.EnsureSymlinks(dir, dir, []string{"foo"}) 92 c.Assert(err, gc.ErrorMatches, "cannot initialize commands in .*: "+utils.NoSuchFileErrRegexp) 93 }