This function is no longer used by any code. Instead, its copy in the `osbuild/images` repository is used by distro definitions to validate the customization. Signed-off-by: Tomáš Hozza <thozza@redhat.com>
977 lines
18 KiB
Go
977 lines
18 KiB
Go
package blueprint
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
"github.com/osbuild/osbuild-composer/internal/common"
|
|
"github.com/osbuild/osbuild-composer/internal/fsnode"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestDirectoryCustomizationToFsNodeDirectory(t *testing.T) {
|
|
ensureDirCreation := func(dir *fsnode.Directory, err error) *fsnode.Directory {
|
|
t.Helper()
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, dir)
|
|
return dir
|
|
}
|
|
|
|
testCases := []struct {
|
|
Name string
|
|
Dir DirectoryCustomization
|
|
WantDir *fsnode.Directory
|
|
Error bool
|
|
}{
|
|
{
|
|
Name: "empty",
|
|
Dir: DirectoryCustomization{},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-only",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
},
|
|
WantDir: ensureDirCreation(fsnode.NewDirectory("/etc/dir", nil, nil, nil, false)),
|
|
},
|
|
{
|
|
Name: "path-invalid",
|
|
Dir: DirectoryCustomization{
|
|
Path: "etc/dir",
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-and-mode",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
Mode: "0700",
|
|
},
|
|
WantDir: ensureDirCreation(fsnode.NewDirectory("/etc/dir", common.ToPtr(os.FileMode(0700)), nil, nil, false)),
|
|
},
|
|
{
|
|
Name: "path-and-mode-no-leading-zero",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
Mode: "700",
|
|
},
|
|
WantDir: ensureDirCreation(fsnode.NewDirectory("/etc/dir", common.ToPtr(os.FileMode(0700)), nil, nil, false)),
|
|
},
|
|
{
|
|
Name: "path-and-mode-invalid",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
Mode: "12345",
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-user-group-string",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
User: "root",
|
|
Group: "root",
|
|
},
|
|
WantDir: ensureDirCreation(fsnode.NewDirectory("/etc/dir", nil, "root", "root", false)),
|
|
},
|
|
{
|
|
Name: "path-user-group-int64",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
User: int64(0),
|
|
Group: int64(0),
|
|
},
|
|
WantDir: ensureDirCreation(fsnode.NewDirectory("/etc/dir", nil, int64(0), int64(0), false)),
|
|
},
|
|
{
|
|
Name: "path-and-user-invalid-string",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
User: "r@@t",
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-and-user-invalid-int64",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
User: -1,
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-and-group-invalid-string",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
Group: "r@@t",
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-and-group-invalid-int64",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
Group: -1,
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-and-ensure-parent-dirs",
|
|
Dir: DirectoryCustomization{
|
|
Path: "/etc/dir",
|
|
EnsureParents: true,
|
|
},
|
|
WantDir: ensureDirCreation(fsnode.NewDirectory("/etc/dir", nil, nil, nil, true)),
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
dir, err := tc.Dir.ToFsNodeDirectory()
|
|
if tc.Error {
|
|
assert.Error(t, err)
|
|
assert.Nil(t, dir)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, tc.WantDir, dir)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDirectoryCustomizationsToFsNodeDirectories(t *testing.T) {
|
|
ensureDirCreation := func(dir *fsnode.Directory, err error) *fsnode.Directory {
|
|
t.Helper()
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, dir)
|
|
return dir
|
|
}
|
|
|
|
testCases := []struct {
|
|
Name string
|
|
Dirs []DirectoryCustomization
|
|
WantDirs []*fsnode.Directory
|
|
Error bool
|
|
}{
|
|
{
|
|
Name: "empty",
|
|
Dirs: []DirectoryCustomization{},
|
|
WantDirs: nil,
|
|
},
|
|
{
|
|
Name: "single-directory",
|
|
Dirs: []DirectoryCustomization{
|
|
{
|
|
Path: "/etc/dir",
|
|
User: "root",
|
|
Group: "root",
|
|
Mode: "0700",
|
|
EnsureParents: true,
|
|
},
|
|
},
|
|
WantDirs: []*fsnode.Directory{
|
|
ensureDirCreation(fsnode.NewDirectory(
|
|
"/etc/dir",
|
|
common.ToPtr(os.FileMode(0700)),
|
|
"root",
|
|
"root",
|
|
true,
|
|
)),
|
|
},
|
|
},
|
|
{
|
|
Name: "multiple-directories",
|
|
Dirs: []DirectoryCustomization{
|
|
{
|
|
Path: "/etc/dir",
|
|
User: "root",
|
|
Group: "root",
|
|
},
|
|
{
|
|
Path: "/etc/dir2",
|
|
User: int64(0),
|
|
Group: int64(0),
|
|
},
|
|
},
|
|
WantDirs: []*fsnode.Directory{
|
|
ensureDirCreation(fsnode.NewDirectory("/etc/dir", nil, "root", "root", false)),
|
|
ensureDirCreation(fsnode.NewDirectory("/etc/dir2", nil, int64(0), int64(0), false)),
|
|
},
|
|
},
|
|
{
|
|
Name: "multiple-directories-with-errors",
|
|
Dirs: []DirectoryCustomization{
|
|
{
|
|
Path: "/etc/../dir",
|
|
},
|
|
{
|
|
Path: "/etc/dir2",
|
|
User: "r@@t",
|
|
},
|
|
},
|
|
Error: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
dirs, err := DirectoryCustomizationsToFsNodeDirectories(tc.Dirs)
|
|
if tc.Error {
|
|
assert.Error(t, err)
|
|
assert.Nil(t, dirs)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, tc.WantDirs, dirs)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDirectoryCustomizationUnmarshalTOML(t *testing.T) {
|
|
testCases := []struct {
|
|
Name string
|
|
TOML string
|
|
Want []DirectoryCustomization
|
|
Error bool
|
|
}{
|
|
{
|
|
Name: "directory-with-path",
|
|
TOML: `
|
|
name = "test"
|
|
description = "Test"
|
|
version = "0.0.0"
|
|
|
|
[[customizations.directories]]
|
|
path = "/etc/dir"
|
|
`,
|
|
Want: []DirectoryCustomization{
|
|
{
|
|
Path: "/etc/dir",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "multiple-directories",
|
|
TOML: `
|
|
name = "test"
|
|
description = "Test"
|
|
version = "0.0.0"
|
|
|
|
[[customizations.directories]]
|
|
path = "/etc/dir1"
|
|
mode = "0700"
|
|
user = "root"
|
|
group = "root"
|
|
ensure_parents = true
|
|
|
|
[[customizations.directories]]
|
|
path = "/etc/dir2"
|
|
mode = "0755"
|
|
user = 0
|
|
group = 0
|
|
ensure_parents = true
|
|
|
|
[[customizations.directories]]
|
|
path = "/etc/dir3"
|
|
`,
|
|
Want: []DirectoryCustomization{
|
|
{
|
|
Path: "/etc/dir1",
|
|
Mode: "0700",
|
|
User: "root",
|
|
Group: "root",
|
|
EnsureParents: true,
|
|
},
|
|
{
|
|
Path: "/etc/dir2",
|
|
Mode: "0755",
|
|
User: int64(0),
|
|
Group: int64(0),
|
|
EnsureParents: true,
|
|
},
|
|
{
|
|
Path: "/etc/dir3",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "invalid-directories",
|
|
TOML: `
|
|
name = "test"
|
|
description = "Test"
|
|
version = "0.0.0"
|
|
|
|
[[customizations.directories]]
|
|
path = "/etc/../dir1"
|
|
|
|
[[customizations.directories]]
|
|
path = "/etc/dir2"
|
|
mode = "12345"
|
|
|
|
[[customizations.directories]]
|
|
path = "/etc/dir3"
|
|
user = "r@@t"
|
|
|
|
[[customizations.directories]]
|
|
path = "/etc/dir4"
|
|
group = "r@@t"
|
|
|
|
[[customizations.directories]]
|
|
path = "/etc/dir5"
|
|
user = -1
|
|
|
|
[[customizations.directories]]
|
|
path = "/etc/dir6"
|
|
group = -1
|
|
|
|
|
|
[[customizations.directories]]
|
|
`,
|
|
Error: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
var blueprint Blueprint
|
|
err := toml.Unmarshal([]byte(tc.TOML), &blueprint)
|
|
if tc.Error {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, blueprint.Customizations)
|
|
assert.Len(t, blueprint.Customizations.Directories, len(tc.Want))
|
|
assert.EqualValues(t, tc.Want, blueprint.Customizations.GetDirectories())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDirectoryCustomizationUnmarshalJSON(t *testing.T) {
|
|
testCases := []struct {
|
|
Name string
|
|
JSON string
|
|
Want []DirectoryCustomization
|
|
Error bool
|
|
}{
|
|
{
|
|
Name: "directory-with-path",
|
|
JSON: `
|
|
{
|
|
"name": "test",
|
|
"description": "Test",
|
|
"version": "0.0.0",
|
|
"customizations": {
|
|
"directories": [
|
|
{
|
|
"path": "/etc/dir"
|
|
}
|
|
]
|
|
}
|
|
}`,
|
|
Want: []DirectoryCustomization{
|
|
{
|
|
Path: "/etc/dir",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "multiple-directories",
|
|
JSON: `
|
|
{
|
|
"name": "test",
|
|
"description": "Test",
|
|
"version": "0.0.0",
|
|
"customizations": {
|
|
"directories": [
|
|
{
|
|
"path": "/etc/dir1",
|
|
"mode": "0700",
|
|
"user": "root",
|
|
"group": "root",
|
|
"ensure_parents": true
|
|
},
|
|
{
|
|
"path": "/etc/dir2",
|
|
"mode": "0755",
|
|
"user": 0,
|
|
"group": 0,
|
|
"ensure_parents": true
|
|
},
|
|
{
|
|
"path": "/etc/dir3"
|
|
}
|
|
]
|
|
}
|
|
}`,
|
|
Want: []DirectoryCustomization{
|
|
{
|
|
Path: "/etc/dir1",
|
|
Mode: "0700",
|
|
User: "root",
|
|
Group: "root",
|
|
EnsureParents: true,
|
|
},
|
|
{
|
|
Path: "/etc/dir2",
|
|
Mode: "0755",
|
|
User: int64(0),
|
|
Group: int64(0),
|
|
EnsureParents: true,
|
|
},
|
|
{
|
|
Path: "/etc/dir3",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "invalid-directories",
|
|
JSON: `
|
|
{
|
|
"name": "test",
|
|
"description": "Test",
|
|
"version": "0.0.0",
|
|
"customizations": {
|
|
"directories": [
|
|
{
|
|
"path": "/etc/../dir1"
|
|
},
|
|
{
|
|
"path": "/etc/dir2",
|
|
"mode": "12345"
|
|
},
|
|
{
|
|
"path": "/etc/dir3",
|
|
"user": "r@@t"
|
|
},
|
|
{
|
|
"path": "/etc/dir4",
|
|
"group": "r@@t"
|
|
},
|
|
{
|
|
"path": "/etc/dir5",
|
|
"user": -1
|
|
},
|
|
{
|
|
"path": "/etc/dir6",
|
|
"group": -1
|
|
}
|
|
{}
|
|
]
|
|
}
|
|
}`,
|
|
Error: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
var blueprint Blueprint
|
|
err := json.Unmarshal([]byte(tc.JSON), &blueprint)
|
|
if tc.Error {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, blueprint.Customizations)
|
|
assert.Len(t, blueprint.Customizations.Directories, len(tc.Want))
|
|
assert.EqualValues(t, tc.Want, blueprint.Customizations.GetDirectories())
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestFileCustomizationToFsNodeFile(t *testing.T) {
|
|
ensureFileCreation := func(file *fsnode.File, err error) *fsnode.File {
|
|
t.Helper()
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, file)
|
|
return file
|
|
}
|
|
|
|
testCases := []struct {
|
|
Name string
|
|
File FileCustomization
|
|
Want *fsnode.File
|
|
Error bool
|
|
}{
|
|
{
|
|
Name: "empty",
|
|
File: FileCustomization{},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-only",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
},
|
|
Want: ensureFileCreation(fsnode.NewFile("/etc/file", nil, nil, nil, nil)),
|
|
},
|
|
{
|
|
Name: "path-invalid",
|
|
File: FileCustomization{
|
|
Path: "../etc/file",
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-and-mode",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
Mode: "0700",
|
|
},
|
|
Want: ensureFileCreation(fsnode.NewFile("/etc/file", common.ToPtr(os.FileMode(0700)), nil, nil, nil)),
|
|
},
|
|
{
|
|
Name: "path-and-mode-no-leading-zero",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
Mode: "700",
|
|
},
|
|
Want: ensureFileCreation(fsnode.NewFile("/etc/file", common.ToPtr(os.FileMode(0700)), nil, nil, nil)),
|
|
},
|
|
{
|
|
Name: "path-and-mode-invalid",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
Mode: "12345",
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-user-group-string",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
User: "root",
|
|
Group: "root",
|
|
},
|
|
Want: ensureFileCreation(fsnode.NewFile("/etc/file", nil, "root", "root", nil)),
|
|
},
|
|
{
|
|
Name: "path-user-group-int64",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
User: int64(0),
|
|
Group: int64(0),
|
|
},
|
|
Want: ensureFileCreation(fsnode.NewFile("/etc/file", nil, int64(0), int64(0), nil)),
|
|
},
|
|
{
|
|
Name: "path-and-user-invalid-string",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
User: "r@@t",
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-and-user-invalid-int64",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
User: int64(-1),
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-and-group-string",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
Group: "root",
|
|
},
|
|
Want: ensureFileCreation(fsnode.NewFile("/etc/file", nil, nil, "root", nil)),
|
|
},
|
|
{
|
|
Name: "path-and-group-int64",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
Group: int64(0),
|
|
},
|
|
Want: ensureFileCreation(fsnode.NewFile("/etc/file", nil, nil, int64(0), nil)),
|
|
},
|
|
{
|
|
Name: "path-and-group-invalid-string",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
Group: "r@@t",
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-and-group-invalid-int64",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
Group: int64(-1),
|
|
},
|
|
Error: true,
|
|
},
|
|
{
|
|
Name: "path-and-data",
|
|
File: FileCustomization{
|
|
Path: "/etc/file",
|
|
Data: "hello world",
|
|
},
|
|
Want: ensureFileCreation(fsnode.NewFile("/etc/file", nil, nil, nil, []byte("hello world"))),
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
file, err := tc.File.ToFsNodeFile()
|
|
if tc.Error {
|
|
assert.Error(t, err)
|
|
assert.Nil(t, file)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, tc.Want, file)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFileCustomizationsToFsNodeFiles(t *testing.T) {
|
|
ensureFileCreation := func(file *fsnode.File, err error) *fsnode.File {
|
|
t.Helper()
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, file)
|
|
return file
|
|
}
|
|
|
|
testCases := []struct {
|
|
Name string
|
|
Files []FileCustomization
|
|
Want []*fsnode.File
|
|
Error bool
|
|
}{
|
|
{
|
|
Name: "empty",
|
|
Files: []FileCustomization{},
|
|
Want: nil,
|
|
},
|
|
{
|
|
Name: "single-file",
|
|
Files: []FileCustomization{
|
|
{
|
|
Path: "/etc/file",
|
|
User: "root",
|
|
Group: "root",
|
|
Mode: "0700",
|
|
Data: "hello world",
|
|
},
|
|
},
|
|
Want: []*fsnode.File{
|
|
ensureFileCreation(fsnode.NewFile(
|
|
"/etc/file",
|
|
common.ToPtr(os.FileMode(0700)),
|
|
"root",
|
|
"root",
|
|
[]byte("hello world"),
|
|
)),
|
|
},
|
|
},
|
|
{
|
|
Name: "multiple-files",
|
|
Files: []FileCustomization{
|
|
{
|
|
Path: "/etc/file",
|
|
Data: "hello world",
|
|
User: "root",
|
|
Group: "root",
|
|
},
|
|
{
|
|
Path: "/etc/file2",
|
|
Data: "hello world",
|
|
User: int64(0),
|
|
Group: int64(0),
|
|
},
|
|
},
|
|
Want: []*fsnode.File{
|
|
ensureFileCreation(fsnode.NewFile("/etc/file", nil, "root", "root", []byte("hello world"))),
|
|
ensureFileCreation(fsnode.NewFile("/etc/file2", nil, int64(0), int64(0), []byte("hello world"))),
|
|
},
|
|
},
|
|
{
|
|
Name: "multiple-files-with-errors",
|
|
Files: []FileCustomization{
|
|
{
|
|
Path: "/etc/../file",
|
|
Data: "hello world",
|
|
},
|
|
{
|
|
Path: "/etc/file2",
|
|
Data: "hello world",
|
|
User: "r@@t",
|
|
},
|
|
},
|
|
Error: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
files, err := FileCustomizationsToFsNodeFiles(tc.Files)
|
|
if tc.Error {
|
|
assert.Error(t, err)
|
|
assert.Nil(t, files)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, tc.Want, files)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFileCustomizationUnmarshalTOML(t *testing.T) {
|
|
testCases := []struct {
|
|
Name string
|
|
TOML string
|
|
Want []FileCustomization
|
|
Error bool
|
|
}{
|
|
{
|
|
Name: "file-with-path",
|
|
TOML: `
|
|
name = "test"
|
|
description = "Test"
|
|
version = "0.0.0"
|
|
|
|
[[customizations.files]]
|
|
path = "/etc/file"
|
|
`,
|
|
Want: []FileCustomization{
|
|
{
|
|
Path: "/etc/file",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "multiple-files",
|
|
TOML: `
|
|
name = "test"
|
|
description = "Test"
|
|
version = "0.0.0"
|
|
|
|
[[customizations.files]]
|
|
path = "/etc/file1"
|
|
mode = "0600"
|
|
user = "root"
|
|
group = "root"
|
|
data = "hello world"
|
|
|
|
[[customizations.files]]
|
|
path = "/etc/file2"
|
|
mode = "0644"
|
|
data = "hello world 2"
|
|
|
|
[[customizations.files]]
|
|
path = "/etc/file3"
|
|
user = 0
|
|
group = 0
|
|
data = "hello world 3"
|
|
`,
|
|
Want: []FileCustomization{
|
|
{
|
|
Path: "/etc/file1",
|
|
Mode: "0600",
|
|
User: "root",
|
|
Group: "root",
|
|
Data: "hello world",
|
|
},
|
|
{
|
|
Path: "/etc/file2",
|
|
Mode: "0644",
|
|
Data: "hello world 2",
|
|
},
|
|
{
|
|
Path: "/etc/file3",
|
|
User: int64(0),
|
|
Group: int64(0),
|
|
Data: "hello world 3",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "invalid-files",
|
|
TOML: `
|
|
name = "test"
|
|
description = "Test"
|
|
version = "0.0.0"
|
|
|
|
[[customizations.files]]
|
|
path = "/etc/../file1"
|
|
|
|
[[customizations.files]]
|
|
path = "/etc/file2"
|
|
mode = "12345"
|
|
|
|
[[customizations.files]]
|
|
path = "/etc/file3"
|
|
user = "r@@t"
|
|
|
|
[[customizations.files]]
|
|
path = "/etc/file4"
|
|
group = "r@@t"
|
|
|
|
[[customizations.files]]
|
|
path = "/etc/file5"
|
|
user = -1
|
|
|
|
[[customizations.files]]
|
|
path = "/etc/file6"
|
|
group = -1
|
|
`,
|
|
Error: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
var blueprint Blueprint
|
|
err := toml.Unmarshal([]byte(tc.TOML), &blueprint)
|
|
if tc.Error {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, blueprint.Customizations)
|
|
assert.Len(t, blueprint.Customizations.Files, len(tc.Want))
|
|
assert.EqualValues(t, tc.Want, blueprint.Customizations.Files)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFileCustomizationUnmarshalJSON(t *testing.T) {
|
|
testCases := []struct {
|
|
Name string
|
|
JSON string
|
|
Want []FileCustomization
|
|
Error bool
|
|
}{
|
|
{
|
|
Name: "file-with-path",
|
|
JSON: `
|
|
{
|
|
"name": "test",
|
|
"description": "Test",
|
|
"version": "0.0.0",
|
|
"customizations": {
|
|
"files": [
|
|
{
|
|
"path": "/etc/file"
|
|
}
|
|
]
|
|
}
|
|
}`,
|
|
Want: []FileCustomization{
|
|
{
|
|
Path: "/etc/file",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "multiple-files",
|
|
JSON: `
|
|
{
|
|
"name": "test",
|
|
"description": "Test",
|
|
"version": "0.0.0",
|
|
"customizations": {
|
|
"files": [
|
|
{
|
|
"path": "/etc/file1",
|
|
"mode": "0600",
|
|
"user": "root",
|
|
"group": "root",
|
|
"data": "hello world"
|
|
},
|
|
{
|
|
"path": "/etc/file2",
|
|
"mode": "0644",
|
|
"data": "hello world 2"
|
|
},
|
|
{
|
|
"path": "/etc/file3",
|
|
"user": 0,
|
|
"group": 0,
|
|
"data": "hello world 3"
|
|
}
|
|
]
|
|
}
|
|
}`,
|
|
Want: []FileCustomization{
|
|
{
|
|
Path: "/etc/file1",
|
|
Mode: "0600",
|
|
User: "root",
|
|
Group: "root",
|
|
Data: "hello world",
|
|
},
|
|
{
|
|
Path: "/etc/file2",
|
|
Mode: "0644",
|
|
Data: "hello world 2",
|
|
},
|
|
{
|
|
Path: "/etc/file3",
|
|
User: int64(0),
|
|
Group: int64(0),
|
|
Data: "hello world 3",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "invalid-files",
|
|
JSON: `
|
|
{
|
|
"name": "test",
|
|
"description": "Test",
|
|
"version": "0.0.0",
|
|
"customizations": {
|
|
"files": [
|
|
{
|
|
"path": "/etc/../file1"
|
|
},
|
|
{
|
|
"path": "/etc/file2",
|
|
"mode": "12345"
|
|
},
|
|
{
|
|
"path": "/etc/file3",
|
|
"user": "r@@t"
|
|
},
|
|
{
|
|
"path": "/etc/file4",
|
|
"group": "r@@t"
|
|
},
|
|
{
|
|
"path": "/etc/file5",
|
|
"user": -1
|
|
},
|
|
{
|
|
"path": "/etc/file6",
|
|
"group": -1
|
|
}
|
|
]
|
|
}
|
|
}`,
|
|
Error: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
var blueprint Blueprint
|
|
err := json.Unmarshal([]byte(tc.JSON), &blueprint)
|
|
if tc.Error {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, blueprint.Customizations)
|
|
assert.Len(t, blueprint.Customizations.Files, len(tc.Want))
|
|
assert.EqualValues(t, tc.Want, blueprint.Customizations.Files)
|
|
}
|
|
})
|
|
}
|
|
}
|