jx/internal/resource/file_test.go

451 lines
9.9 KiB
Go
Raw Normal View History

2024-03-20 19:23:31 +00:00
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
2024-04-23 22:35:08 +00:00
2024-03-20 16:15:27 +00:00
package resource
import (
2024-03-20 19:23:31 +00:00
"context"
_ "encoding/json"
"fmt"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
_ "io"
_ "log"
_ "net/http"
_ "net/http/httptest"
_ "net/url"
"os"
"path/filepath"
_ "strings"
2024-03-25 20:31:06 +00:00
"syscall"
2024-03-20 19:23:31 +00:00
"testing"
"time"
2024-05-06 00:48:54 +00:00
"os/user"
2024-03-20 16:15:27 +00:00
)
func TestNewFileResource(t *testing.T) {
2024-03-20 19:23:31 +00:00
f := NewFile()
assert.NotEqual(t, nil, f)
2024-03-20 16:15:27 +00:00
}
2024-05-06 00:48:54 +00:00
func TestNewFileNormalized(t *testing.T) {
file := fmt.Sprintf("%s/%s", TempDir, "bar/../fooread.txt")
absFilePath,_ := filepath.Abs(file)
f := NewNormalizedFile()
assert.NotNil(t, f)
2024-05-06 04:40:34 +00:00
assert.Nil(t, f.SetURI("file://" + file))
2024-05-06 00:48:54 +00:00
assert.NotEqual(t, file, f.Path)
assert.Equal(t, absFilePath, f.Path)
assert.NotEqual(t, "file://" + file, f.URI())
assert.Equal(t, "file://" + absFilePath, f.URI())
}
2024-03-20 16:15:27 +00:00
func TestApplyResourceTransformation(t *testing.T) {
2024-03-20 19:23:31 +00:00
f := NewFile()
assert.NotEqual(t, nil, f)
2024-03-20 16:15:27 +00:00
2024-03-20 19:23:31 +00:00
//e := f.Apply()
//assert.Equal(t, nil, e)
2024-03-20 16:15:27 +00:00
}
func TestReadFile(t *testing.T) {
2024-03-20 19:23:31 +00:00
ctx := context.Background()
file, _ := filepath.Abs(filepath.Join(TempDir, "fooread.txt"))
2024-03-20 16:15:27 +00:00
2024-05-24 05:11:51 +00:00
expectedTime, timeErr := time.Parse(time.RFC3339Nano, "2001-12-15T01:01:01.000000001Z")
assert.Nil(t, timeErr)
expectedTimestamp := expectedTime.Local().Format(time.RFC3339Nano)
declarationAttributes := `
2024-03-20 16:15:27 +00:00
path: "%s"
2024-05-24 05:11:51 +00:00
owner: "%s"
group: "%s"
2024-03-20 16:15:27 +00:00
mode: "0600"
2024-05-24 05:11:51 +00:00
atime: %s
ctime: %s
2024-05-24 05:11:51 +00:00
mtime: %s
2024-03-20 16:15:27 +00:00
content: |-
test line 1
test line 2
2024-04-21 18:06:53 +00:00
sha256: f2082f984f1bf1a7886e2af32ccc9ca474fbff3553d131204b070c438114dd51
2024-04-23 22:35:08 +00:00
size: 23
2024-03-20 19:23:31 +00:00
filetype: "regular"
2024-03-20 16:15:27 +00:00
state: present
`
2024-05-24 05:11:51 +00:00
decl := fmt.Sprintf(declarationAttributes, file, ProcessTestUserName, ProcessTestGroupName, expectedTimestamp, expectedTimestamp, expectedTimestamp)
2024-03-20 16:15:27 +00:00
2024-03-20 19:23:31 +00:00
testFile := NewFile()
e := testFile.LoadDecl(decl)
2024-05-24 05:11:51 +00:00
assert.Nil(t, e)
2024-04-03 19:27:16 +00:00
applyErr := testFile.Apply()
assert.Nil(t, applyErr)
2024-03-20 16:15:27 +00:00
2024-03-20 19:23:31 +00:00
f := NewFile()
assert.NotEqual(t, nil, f)
2024-03-20 16:15:27 +00:00
2024-03-20 19:23:31 +00:00
f.Path = file
r, e := f.Read(ctx)
2024-05-24 05:11:51 +00:00
assert.Nil(t, e)
assert.Equal(t, ProcessTestUserName, f.Owner)
2024-03-25 20:31:06 +00:00
info, statErr := os.Stat(file)
assert.Nil(t, statErr)
stat, ok := info.Sys().(*syscall.Stat_t)
assert.True(t, ok)
cTime := time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec))
2024-05-24 05:11:51 +00:00
expected := fmt.Sprintf(declarationAttributes, file, ProcessTestUserName, ProcessTestGroupName, expectedTimestamp, cTime.Local().Format(time.RFC3339Nano), expectedTimestamp)
assert.YAMLEq(t, expected, string(r))
2024-03-20 16:15:27 +00:00
}
2024-03-25 05:06:08 +00:00
func TestReadFileError(t *testing.T) {
2024-03-25 20:31:06 +00:00
ctx := context.Background()
file, _ := filepath.Abs(filepath.Join(TempDir, "missingfile.txt"))
f := NewFile()
assert.NotEqual(t, nil, f)
f.Path = file
_, e := f.Read(ctx)
assert.True(t, os.IsNotExist(e))
assert.Equal(t, "absent", f.State)
2024-03-25 05:06:08 +00:00
}
2024-03-20 16:15:27 +00:00
func TestCreateFile(t *testing.T) {
2024-03-20 19:23:31 +00:00
file, _ := filepath.Abs(filepath.Join(TempDir, "foo.txt"))
2024-03-20 16:15:27 +00:00
2024-03-20 19:23:31 +00:00
decl := fmt.Sprintf(`
2024-03-20 16:15:27 +00:00
path: "%s"
2024-05-24 05:11:51 +00:00
owner: "%s"
group: "%s"
2024-03-20 16:15:27 +00:00
mode: "0600"
content: |-
test line 1
test line 2
state: present
2024-05-24 05:11:51 +00:00
`, file, ProcessTestUserName, ProcessTestGroupName)
2024-03-20 16:15:27 +00:00
2024-03-20 19:23:31 +00:00
f := NewFile()
e := f.LoadDecl(decl)
assert.Equal(t, nil, e)
2024-05-24 05:11:51 +00:00
assert.Equal(t, ProcessTestUserName, f.Owner)
2024-03-20 16:15:27 +00:00
2024-03-20 19:23:31 +00:00
applyErr := f.Apply()
assert.Equal(t, nil, applyErr)
assert.FileExists(t, file, nil)
s, e := os.Stat(file)
assert.Equal(t, nil, e)
2024-03-20 16:15:27 +00:00
2024-03-20 19:23:31 +00:00
assert.Greater(t, s.Size(), int64(0))
2024-03-20 16:15:27 +00:00
2024-03-20 19:23:31 +00:00
f.State = "absent"
assert.Equal(t, nil, f.Apply())
assert.NoFileExists(t, file, nil)
}
func TestFileType(t *testing.T) {
fileType := []byte(`
filetype: "directory"
`)
var testFile File
err := yaml.Unmarshal(fileType, &testFile)
assert.Nil(t, err)
}
func TestFileDirectory(t *testing.T) {
file, _ := filepath.Abs(filepath.Join(TempDir, "testdir"))
decl := fmt.Sprintf(`
path: "%s"
2024-05-24 05:11:51 +00:00
owner: "%s"
group: "%s"
2024-03-20 19:23:31 +00:00
mode: "0700"
filetype: "directory"
state: present
2024-05-24 05:11:51 +00:00
`, file, ProcessTestUserName, ProcessTestGroupName)
2024-03-20 19:23:31 +00:00
f := NewFile()
e := f.LoadDecl(decl)
assert.Equal(t, nil, e)
2024-05-24 05:11:51 +00:00
assert.Equal(t, ProcessTestUserName, f.Owner)
2024-03-20 19:23:31 +00:00
applyErr := f.Apply()
assert.Equal(t, nil, applyErr)
assert.DirExists(t, file)
f.State = "absent"
deleteErr := f.Apply()
assert.Nil(t, deleteErr)
assert.NoDirExists(t, file)
2024-03-20 16:15:27 +00:00
}
func TestFileTimes(t *testing.T) {
2024-03-25 20:31:06 +00:00
file, _ := filepath.Abs(filepath.Join(TempDir, "testtimes.txt"))
decl := fmt.Sprintf(`
path: "%s"
2024-05-24 05:11:51 +00:00
owner: "%s"
group: "%s"
mtime: 2001-12-15T01:01:01.1Z
mode: "0600"
filtetype: "regular"
state: "present"
2024-05-24 05:11:51 +00:00
`, file, ProcessTestUserName, ProcessTestGroupName)
2024-03-25 20:31:06 +00:00
expectedTime, timeErr := time.Parse(time.RFC3339, "2001-12-15T01:01:01.1Z")
assert.Nil(t, timeErr)
2024-03-25 20:31:06 +00:00
f := NewFile()
e := f.LoadDecl(decl)
assert.Nil(t, e)
2024-05-24 05:11:51 +00:00
assert.Equal(t, ProcessTestUserName, f.Owner)
2024-03-25 20:31:06 +00:00
assert.True(t, f.Mtime.Equal(expectedTime))
}
2024-03-25 20:27:30 +00:00
func TestFileSetURI(t *testing.T) {
2024-03-25 20:31:06 +00:00
file, _ := filepath.Abs(filepath.Join(TempDir, "testuri.txt"))
f := NewFile()
assert.NotNil(t, f)
2024-04-03 19:27:16 +00:00
e := f.SetURI("file://" + file)
assert.Nil(t, e)
2024-03-25 20:31:06 +00:00
assert.Equal(t, "file", f.Type())
assert.Equal(t, file, f.Path)
2024-03-25 20:27:30 +00:00
}
func TestFileNormalizePath(t *testing.T) {
absFile, absFilePathErr := filepath.Abs(filepath.Join(TempDir, "./testuri.txt"))
assert.Nil(t, absFilePathErr)
file := filepath.Join(TempDir, "./testuri.txt")
f := NewFile()
assert.NotNil(t, f)
f.Path = file
e := f.NormalizePath()
assert.Nil(t, e)
assert.Equal(t, absFile, f.Path)
}
2024-04-19 07:52:10 +00:00
func TestFileUpdateAttributesFromFileInfo(t *testing.T) {
f := NewFile()
assert.NotNil(t, f)
info, e := os.Lstat(TempDir)
assert.Nil(t, e)
2024-04-22 06:11:17 +00:00
updateAttributesErr := f.UpdateAttributesFromFileInfo(info)
assert.Nil(t, updateAttributesErr)
2024-04-19 07:52:10 +00:00
assert.Equal(t, DirectoryFile, f.FileType)
}
func TestFileReadStat(t *testing.T) {
ctx := context.Background()
link := filepath.Join(TempDir, "link.txt")
linkTargetFile := filepath.Join(TempDir, "testuri.txt")
f := NewFile()
assert.NotNil(t, f)
f.Path = linkTargetFile
e := f.NormalizePath()
assert.Nil(t, e)
statErr := f.ReadStat()
assert.Error(t, statErr)
2024-05-24 05:11:51 +00:00
f.Owner = ProcessTestUserName
f.Group = ProcessTestGroupName
f.State = "present"
assert.Nil(t, f.Apply())
assert.Nil(t, f.ReadStat())
l := NewFile()
assert.NotNil(t, l)
l.FileType = SymbolicLinkFile
l.Path = link
l.Target = linkTargetFile
l.State = "present"
2024-04-03 19:27:16 +00:00
applyErr := l.Apply()
assert.Nil(t, applyErr)
readStatErr := l.ReadStat()
assert.Nil(t, readStatErr)
testRead := NewFile()
testRead.Path = link
2024-04-03 19:27:16 +00:00
_,testReadErr := testRead.Read(ctx)
assert.Nil(t, testReadErr)
assert.Equal(t, linkTargetFile, testRead.Target)
}
2024-04-23 22:35:08 +00:00
func TestFileResourceFileInfo(t *testing.T) {
testFile := filepath.Join(TempDir, "testuri.txt")
f := NewFile()
assert.NotNil(t, f)
f.Path = testFile
f.Mode = "0600"
f.State = "present"
assert.Nil(t, f.Apply())
2024-05-06 04:40:34 +00:00
_, readErr := f.Read(context.Background())
assert.Nil(t, readErr)
2024-04-23 22:35:08 +00:00
fi := f.FileInfo()
assert.Equal(t, os.FileMode(0600), fi.Mode().Perm())
}
2024-05-06 00:48:54 +00:00
func TestFileClone(t *testing.T) {
ctx := context.Background()
testFile := filepath.Join(TempDir, "testorig.txt")
testCloneFile := filepath.Join(TempDir, "testclone.txt")
f := NewFile()
assert.NotNil(t, f)
f.Path = testFile
f.Mode = "0600"
f.State = "present"
assert.Nil(t, f.Apply())
2024-05-06 20:26:38 +00:00
_,readErr := f.Read(ctx)
2024-05-06 04:40:34 +00:00
assert.Nil(t, readErr)
2024-05-06 00:48:54 +00:00
time.Sleep(100 * time.Millisecond)
clone := f.Clone().(*File)
assert.Equal(t, f, clone)
clone.Mtime = time.Time{}
clone.Path = testCloneFile
assert.Nil(t, clone.Apply())
2024-05-06 20:26:38 +00:00
_,updateReadErr := f.Read(ctx)
assert.Nil(t, updateReadErr)
2024-05-06 04:40:34 +00:00
2024-05-06 21:11:41 +00:00
_, cloneReadErr := clone.Read(ctx)
assert.Nil(t, cloneReadErr)
2024-05-06 00:48:54 +00:00
fmt.Printf("file %#v\nclone %#v\n", f, clone)
assert.NotEqual(t, f.Mtime, clone.Mtime)
}
func TestFileErrors(t *testing.T) {
2024-05-24 05:11:51 +00:00
//ctx := context.Background()
2024-05-06 00:48:54 +00:00
testFile := filepath.Join(TempDir, "testerr.txt")
f := NewFile()
assert.NotNil(t, f)
2024-05-24 05:11:51 +00:00
stater := f.StateMachine()
2024-05-06 00:48:54 +00:00
f.Path = testFile
f.Mode = "631"
2024-05-24 05:11:51 +00:00
assert.Nil(t, stater.Trigger("create"))
2024-05-06 00:48:54 +00:00
read := NewFile()
2024-05-24 05:11:51 +00:00
readStater := read.StateMachine()
2024-05-06 00:48:54 +00:00
read.Path = testFile
2024-05-24 05:11:51 +00:00
assert.Nil(t, readStater.Trigger("read"))
2024-05-06 00:48:54 +00:00
assert.Equal(t, "0631", read.Mode)
f.Mode = "900"
2024-05-24 05:11:51 +00:00
assert.ErrorAs(t, stater.Trigger("create"), &ErrInvalidFileMode, "Apply should fail with NumError when converting invalid octal")
2024-05-06 00:48:54 +00:00
2024-05-24 05:11:51 +00:00
assert.Nil(t, readStater.Trigger("read"))
2024-05-06 00:48:54 +00:00
assert.Equal(t, "0631", read.Mode)
f.Mode = "0631"
f.Owner = "bar"
uidErr := f.Apply()
var UnknownUser user.UnknownUserError
assert.Error(t, uidErr, UnknownUser)
}
2024-05-24 05:11:51 +00:00
func TestFileDelete(t *testing.T) {
file, _ := filepath.Abs(filepath.Join(TempDir, "foo.txt"))
decl := fmt.Sprintf(`
path: "%s"
owner: "%s"
group: "%s"
mode: "0600"
content: |-
test line 1
test line 2
state: present
`, file, ProcessTestUserName, ProcessTestGroupName)
f := NewFile()
stater := f.StateMachine()
e := f.LoadDecl(decl)
assert.Nil(t, e)
assert.Equal(t, ProcessTestUserName, f.Owner)
assert.Nil(t, stater.Trigger("create"))
assert.FileExists(t, file, nil)
s, e := os.Stat(file)
assert.Nil(t, e)
assert.Greater(t, s.Size(), int64(0))
assert.Nil(t, stater.Trigger("delete"))
assert.NoFileExists(t, file, nil)
}
func TestFileContentRef(t *testing.T) {
file, _ := filepath.Abs(filepath.Join(TempDir, "src.txt"))
copyFile, _ := filepath.Abs(filepath.Join(TempDir, "copy.txt"))
decl := fmt.Sprintf(`
path: "%s"
owner: "%s"
group: "%s"
mode: "0600"
content: |-
test line 1
test line 2
state: present
`, file, ProcessTestUserName, ProcessTestGroupName)
contentRef := fmt.Sprintf(`
path: "%s"
owner: "%s"
group: "%s"
mode: "0600"
sourceref: "file://%s"
state: present
`, file, ProcessTestUserName, ProcessTestGroupName, copyFile)
f := NewFile()
stater := f.StateMachine()
e := f.LoadDecl(decl)
assert.Nil(t, e)
assert.Equal(t, ProcessTestUserName, f.Owner)
assert.Nil(t, stater.Trigger("create"))
assert.FileExists(t, file, nil)
s, e := os.Stat(file)
assert.Nil(t, e)
assert.Greater(t, s.Size(), int64(0))
fr := NewFile()
loadErr := fr.LoadDecl(contentRef)
assert.Nil(t, loadErr)
assert.Equal(t, ProcessTestUserName, fr.Owner)
assert.Nil(t, fr.StateMachine().Trigger("create"))
assert.FileExists(t, file, nil)
_, statErr := os.Stat(file)
assert.Nil(t, statErr)
assert.Nil(t, stater.Trigger("delete"))
assert.NoFileExists(t, file, nil)
}