1// Copyright 2014 Canonical Ltd.
2// Licensed under the LGPLv3, see LICENCE file for details.
3
4package testing
5
6import (
7	"io/ioutil"
8	"os"
9	"path/filepath"
10
11	"github.com/juju/utils/v2"
12	gc "gopkg.in/check.v1"
13
14	jc "github.com/juju/testing/checkers"
15)
16
17type TestFile struct {
18	Name, Data string
19}
20
21// FakeHome stores information about the user's home
22// environment so it can be cast aside for tests and
23// restored afterwards.
24type FakeHome struct {
25	files []TestFile
26}
27
28func MakeFakeHome(c *gc.C) *FakeHome {
29	fakeHome := c.MkDir()
30	err := utils.SetHome(fakeHome)
31	c.Assert(err, jc.ErrorIsNil)
32
33	sshPath := filepath.Join(fakeHome, ".ssh")
34	err = os.Mkdir(sshPath, 0777)
35	c.Assert(err, gc.IsNil)
36	err = ioutil.WriteFile(filepath.Join(sshPath, "id_rsa"), []byte("private auth key\n"), 0600)
37	c.Assert(err, gc.IsNil)
38	err = ioutil.WriteFile(filepath.Join(sshPath, "id_rsa.pub"), []byte("public auth key\n"), 0666)
39	c.Assert(err, gc.IsNil)
40
41	return &FakeHome{
42		files: []TestFile{},
43	}
44}
45
46func (h *FakeHome) AddFiles(c *gc.C, files ...TestFile) {
47	for _, f := range files {
48		path := filepath.Join(utils.Home(), f.Name)
49		err := os.MkdirAll(filepath.Dir(path), 0700)
50		c.Assert(err, gc.IsNil)
51		err = ioutil.WriteFile(path, []byte(f.Data), 0666)
52		c.Assert(err, gc.IsNil)
53		h.files = append(h.files, f)
54	}
55}
56
57// FileContents returns the test file contents for the
58// given specified path (which may be relative, so
59// we compare with the base filename only).
60func (h *FakeHome) FileContents(c *gc.C, path string) string {
61	for _, f := range h.files {
62		if filepath.Base(f.Name) == filepath.Base(path) {
63			return f.Data
64		}
65	}
66	c.Fatalf("path attribute holds unknown test file: %q", path)
67	panic("unreachable")
68}
69
70// FileExists returns if the given relative file path exists
71// in the fake home.
72func (h *FakeHome) FileExists(path string) bool {
73	for _, f := range h.files {
74		if f.Name == path {
75			return true
76		}
77	}
78	return false
79}
80
81// HomePath joins the specified path snippets and returns
82// an absolute path under Juju home.
83func HomePath(names ...string) string {
84	all := append([]string{utils.Home()}, names...)
85	return filepath.Join(all...)
86}
87
88// JujuXDGDataHomePath returns the test home path, it is just a convenience
89// for tests, if extra path snippets are passed they will be
90// joined to juju home.
91// This tool assumes ~/.config/juju as the juju home.
92func JujuXDGDataHomePath(names ...string) string {
93	all := append([]string{".local", "share", "juju"}, names...)
94	return HomePath(all...)
95}
96
97// FakeHomeSuite sets up a fake home directory before running tests.
98type FakeHomeSuite struct {
99	CleanupSuite
100	LoggingSuite
101	Home *FakeHome
102}
103
104func (s *FakeHomeSuite) SetUpSuite(c *gc.C) {
105	s.CleanupSuite.SetUpSuite(c)
106	s.LoggingSuite.SetUpSuite(c)
107}
108
109func (s *FakeHomeSuite) TearDownSuite(c *gc.C) {
110	s.LoggingSuite.TearDownSuite(c)
111	s.CleanupSuite.TearDownSuite(c)
112}
113
114func (s *FakeHomeSuite) SetUpTest(c *gc.C) {
115	s.CleanupSuite.SetUpTest(c)
116	s.LoggingSuite.SetUpTest(c)
117	home := utils.Home()
118	s.Home = MakeFakeHome(c)
119	s.AddCleanup(func(*gc.C) {
120		err := utils.SetHome(home)
121		c.Assert(err, jc.ErrorIsNil)
122	})
123}
124
125func (s *FakeHomeSuite) TearDownTest(c *gc.C) {
126	s.LoggingSuite.TearDownTest(c)
127	s.CleanupSuite.TearDownTest(c)
128}
129