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  }