Skip to content

Commit

Permalink
test: adding more files testing (#97)
Browse files Browse the repository at this point in the history
* test(file): added fileSymlink tests

* fix(file): fixed bug in fileSymlink

- adds check if the symlink/file in name does not exist

* style(file): updated fileTouch to use types.Snprintf

* test(file): added the initial fileTouch tests

* fix(file): fixed incorrect variables, short-circuited test ops

- Synced mTime and aTime to use the same time.Now
- Fixed incorrectly named variable that caused unexpected behavior
- Addded checks for changes to when options were not provided
- Added case for when both times would be modified for test

* test(file): added longer and more in depth fileTouch tests

* test(file): initial fileContent testing

* test(file): validates case w/ two sources and one hash

- This case currently fails but should not

* test(file): initial testing for simple case of fileManaged

* test(file): added a multi-source skip-verify

- Adds a case where a skip_verify option is passed for multiple sources
- Logic for this currently does not exist so test case is simple

* test(file): added test for managed external source
  • Loading branch information
ethanholz authored Feb 22, 2024
1 parent b164180 commit c7d1ee1
Show file tree
Hide file tree
Showing 7 changed files with 927 additions and 16 deletions.
8 changes: 8 additions & 0 deletions ingredients/file/fileContent.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ func (f File) content(ctx context.Context, test bool) (types.Result, error) {
foundSource := false
_, _, _, _ = template, sources, sourceHashes, foundSource
var ok bool
err := f.validate()
if err != nil {
return types.Result{
Succeeded: false, Failed: true,
Changed: false, Notes: notes,
}, err
}
{
name, ok = f.params["name"].(string)
if !ok {
Expand Down Expand Up @@ -131,6 +138,7 @@ func (f File) content(ctx context.Context, test bool) (types.Result, error) {
var srces []interface{}
var srcHashes []interface{}
var ok bool
fmt.Printf("sources: %v\n", f.params["sources"])
if srces, ok = f.params["sources"].([]interface{}); ok && len(srces) > 0 {
if srcHashes, ok = f.params["source_hashes"].([]interface{}); ok {
foundSource = true
Expand Down
184 changes: 184 additions & 0 deletions ingredients/file/fileContent_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package file

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"testing"

"github.com/gogrlx/grlx/config"
"github.com/gogrlx/grlx/types"
)

func TestFileContent(t *testing.T) {
tempDir := t.TempDir()
cd := config.CacheDir
// Restore config.CacheDir after test
defer func() { config.CacheDir = cd }()
config.CacheDir = filepath.Join(tempDir, "cache")
newDir := filepath.Join(tempDir, "this/item")
dirEntry := filepath.Dir(newDir)
fmt.Println(newDir)
doesExist := filepath.Join(tempDir, "doesExist")
_, err := os.Create(doesExist)
if err != nil {
t.Fatal(err)
}
sourceExist := filepath.Join(tempDir, "sourceExist")
_, err = os.Create(sourceExist)
if err != nil {
t.Fatal(err)
}
tests := []struct {
name string
params map[string]interface{}
expected types.Result
error error
test bool
}{
{
name: "incorrect name",
params: map[string]interface{}{
"name": 1,
"text": "string",
},
expected: types.Result{
Succeeded: false,
Failed: true,
Notes: []fmt.Stringer{},
},
error: types.ErrMissingName,
},
{
name: "root",
params: map[string]interface{}{
"name": "/",
},
expected: types.Result{
Succeeded: false,
Failed: true,
Notes: []fmt.Stringer{},
},
error: types.ErrModifyRoot,
},
{
name: "makedirs",
params: map[string]interface{}{
"name": newDir,
"makedirs": true,
},
expected: types.Result{
Succeeded: false,
Failed: true,
Changed: true,
Notes: []fmt.Stringer{
types.Snprintf("created directory %s", dirEntry),
},
},
error: nil,
test: false,
},
{
name: "skip_verify file exists",
params: map[string]interface{}{
"name": doesExist,
"skip_verify": true,
},
expected: types.Result{
Succeeded: false,
Failed: true,
Changed: false,
Notes: []fmt.Stringer{},
},
error: nil,
test: false,
},
{
name: "source missing hash",
params: map[string]interface{}{
"name": doesExist,
"source": "nope",
},
expected: types.Result{
Succeeded: false,
Failed: true,
Changed: false,
Notes: []fmt.Stringer{},
},
error: types.ErrMissingHash,
test: false,
},
{
name: "sources missing hashes",
params: map[string]interface{}{
"name": "test",
"sources": []string{sourceExist, doesExist},
"source_hashes": []string{"thing1"},
},
expected: types.Result{
Succeeded: false,
Failed: true,
Changed: false,
Notes: []fmt.Stringer{
types.Snprintf("sources and source_hashes must be the same length"),
},
},
error: types.ErrMissingHash,
test: false,
},
// Expect this to match the single source case
{
name: "sources missing hashes w/ skip_verify",
params: map[string]interface{}{
"name": "test",
"sources": []string{sourceExist, doesExist},
"skip_verify": true,
},
expected: types.Result{
Succeeded: false,
Failed: true,
Changed: false,
Notes: []fmt.Stringer{},
},
error: nil,
test: false,
},
{
name: "source with hash",
params: map[string]interface{}{
"name": doesExist,
"source": sourceExist,
"source_hash": "test1",
},
expected: types.Result{
Succeeded: false,
Failed: true,
Changed: false,
Notes: []fmt.Stringer{},
},
// TODO: This should be a lot cleaner, relying on a stdblib error that we have little control over is difficult to test.
error: errors.Join(fmt.Errorf("open %s: no such file or directory", filepath.Join(config.CacheDir, "test1")), types.ErrCacheFailure),
test: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
f := File{
id: "",
method: "content",
params: test.params,
}
result, err := f.content(context.TODO(), test.test)
if err != nil {
if test.error == nil {
t.Errorf("expected error to be nil but got %v", err)
} else if err.Error() != test.error.Error() {
t.Errorf("expected error %v, got %v", test.error, err)
}
}
compareResults(t, result, test.expected)
})
}
}
166 changes: 166 additions & 0 deletions ingredients/file/fileManaged_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package file

import (
"context"
"crypto/md5"
"fmt"
"io"
"os"
"path/filepath"
"testing"

"github.com/gogrlx/grlx/types"
)

func TestManaged(t *testing.T) {
// TODO: Determine how to set up the farmer local file system path
tempDir := t.TempDir()
existingFile := filepath.Join(tempDir, "managed-file")
f, err := os.Create(existingFile)
if err != nil {
t.Fatal(err)
}
defer f.Close()
f.WriteString("This is the existing file content")
h := md5.New()
if _, err := io.Copy(h, f); err != nil {
t.Fatal(err)
}
existingFileHash := h.Sum(nil)
hashString := fmt.Sprintf("md5:%x", existingFileHash)
tests := []struct {
name string
params map[string]interface{}
expected types.Result
error error
test bool
}{
{
name: "incorrect name",
params: map[string]interface{}{
"name": 1,
"text": "string",
},
expected: types.Result{
Succeeded: false,
Failed: true,
Notes: []fmt.Stringer{},
},
error: types.ErrMissingName,
},
{
name: "root",
params: map[string]interface{}{
"name": "/",
},
expected: types.Result{
Succeeded: false,
Failed: true,
Notes: []fmt.Stringer{},
},
error: types.ErrModifyRoot,
},
{
name: "Simple case",
params: map[string]interface{}{
"name": existingFile,
"source": "grlx://test/managed-file",
"skip_verify": true,
},
expected: types.Result{
Succeeded: true,
Failed: false,
Changed: true,
// TODO: Notes not implemented yet for file.managed
Notes: []fmt.Stringer{},
},
error: nil,
test: false,
},
{
name: "Simple case with backup",
params: map[string]interface{}{
"name": existingFile,
"source": "grlx://test/managed-file",
"skip_verify": true,
"backup": true,
},
expected: types.Result{
Succeeded: true,
Failed: false,
Changed: true,
// TODO: Notes not implemented yet for file.managed
Notes: []fmt.Stringer{},
},
error: nil,
test: false,
},
{
name: "Simple case with source_hash",
params: map[string]interface{}{
"name": existingFile,
"source": "grlx://test/managed-file",
"source_hash": hashString,
},
expected: types.Result{
Succeeded: true,
Failed: false,
Changed: true,
// TODO: Notes not implemented yet for file.managed
Notes: []fmt.Stringer{},
},
error: nil,
test: false,
},
{
// TODO: Verify that this is the expected behavior
name: "Simple case no create",
params: map[string]interface{}{
"name": existingFile,
"source": "grlx://test/managed-file",
"source_hash": hashString,
"create": false,
},
expected: types.Result{
Succeeded: true,
Failed: false,
Changed: true,
// TODO: Notes not implemented yet for file.managed
Notes: []fmt.Stringer{},
},
error: nil,
test: false,
},
{
name: "External case",
params: map[string]interface{}{
"name": existingFile,
"source": "https://releases.grlx.dev/linux/amd64/v1.0.0/grlx",
"source_hash": "md5:0f9847d3b437488309329463b1454f40",
},
expected: types.Result{
Succeeded: true,
Failed: false,
Changed: true,
// TODO: Notes not implemented yet for file.managed
Notes: []fmt.Stringer{},
},
error: nil,
test: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
f := File{
id: "",
method: "managed",
params: test.params,
}
result, err := f.managed(context.TODO(), test.test)
if test.error != nil && err.Error() != test.error.Error() {
t.Errorf("expected error %v, got %v", test.error, err)
}
compareResults(t, result, test.expected)
})
}
}
2 changes: 1 addition & 1 deletion ingredients/file/fileSymlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (f File) symlink(ctx context.Context, test bool) (types.Result, error) {
}, nil
}
// check if it's not already a symlink
if nameStat.Mode()&os.ModeSymlink == 0 {
if nameStat == nil || nameStat.Mode()&os.ModeSymlink == 0 {
// create the symlink
err = os.Symlink(target, name)
if err != nil {
Expand Down
Loading

0 comments on commit c7d1ee1

Please sign in to comment.