cloudinit/system/env_file_test.go
Michael Marineau a270c4c737 env_file: fix broken test cases
TestWriteEnvFileDos2Unix had a copy/paste bug, it shouldn't have
asserted that mtime doesn't change because the file is actually being
modified in this test. This didn't come up earlier because the actual
comparison wasn't using Time.Equal as it should have.

Instead switch to comparing inode numbers which is the actual thing I
wanted to test for in the first place, just accessing them is much more
awkard. Now all tests where it is relevant check the inode in addition
to the contents.
2014-07-11 13:35:10 -07:00

427 lines
9.0 KiB
Go

package system
import (
"io/ioutil"
"os"
"path"
"strings"
"syscall"
"testing"
)
const (
base = "# a file\nFOO=base\n\nBAR= hi there\n"
baseNoNewline = "# a file\nFOO=base\n\nBAR= hi there"
baseDos = "# a file\r\nFOO=base\r\n\r\nBAR= hi there\r\n"
expectUpdate = "# a file\nFOO=test\n\nBAR= hi there\nNEW=a value\n"
expectCreate = "FOO=test\nNEW=a value\n"
)
var (
valueUpdate = map[string]string{
"FOO": "test",
"NEW": "a value",
}
valueNoop = map[string]string{
"FOO": "base",
}
valueEmpty = map[string]string{}
valueInvalid = map[string]string{
"FOO-X": "test",
}
)
func TestWriteEnvFileUpdate(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
if err != nil {
t.Fatalf("Unable to create tempdir: %v", err)
}
defer os.RemoveAll(dir)
name := "foo.conf"
fullPath := path.Join(dir, name)
ioutil.WriteFile(fullPath, []byte(base), 0644)
oldStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
ef := EnvFile{
File: &File{
Path: name,
},
Vars: valueUpdate,
}
err = WriteEnvFile(&ef, dir)
if err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
contents, err := ioutil.ReadFile(fullPath)
if err != nil {
t.Fatalf("Unable to read expected file: %v", err)
}
if string(contents) != expectUpdate {
t.Fatalf("File has incorrect contents: %q", contents)
}
newStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
if oldStat.Sys().(*syscall.Stat_t).Ino == newStat.Sys().(*syscall.Stat_t).Ino {
t.Fatal("File was not replaced: %s", fullPath)
}
}
func TestWriteEnvFileUpdateNoNewline(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
if err != nil {
t.Fatalf("Unable to create tempdir: %v", err)
}
defer os.RemoveAll(dir)
name := "foo.conf"
fullPath := path.Join(dir, name)
ioutil.WriteFile(fullPath, []byte(baseNoNewline), 0644)
oldStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
ef := EnvFile{
File: &File{
Path: name,
},
Vars: valueUpdate,
}
err = WriteEnvFile(&ef, dir)
if err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
contents, err := ioutil.ReadFile(fullPath)
if err != nil {
t.Fatalf("Unable to read expected file: %v", err)
}
if string(contents) != expectUpdate {
t.Fatalf("File has incorrect contents: %q", contents)
}
newStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
if oldStat.Sys().(*syscall.Stat_t).Ino == newStat.Sys().(*syscall.Stat_t).Ino {
t.Fatal("File was not replaced: %s", fullPath)
}
}
func TestWriteEnvFileCreate(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
if err != nil {
t.Fatalf("Unable to create tempdir: %v", err)
}
defer os.RemoveAll(dir)
name := "foo.conf"
fullPath := path.Join(dir, name)
ef := EnvFile{
File: &File{
Path: name,
},
Vars: valueUpdate,
}
err = WriteEnvFile(&ef, dir)
if err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
contents, err := ioutil.ReadFile(fullPath)
if err != nil {
t.Fatalf("Unable to read expected file: %v", err)
}
if string(contents) != expectCreate {
t.Fatalf("File has incorrect contents: %q", contents)
}
}
func TestWriteEnvFileNoop(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
if err != nil {
t.Fatalf("Unable to create tempdir: %v", err)
}
defer os.RemoveAll(dir)
name := "foo.conf"
fullPath := path.Join(dir, name)
ioutil.WriteFile(fullPath, []byte(base), 0644)
oldStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
ef := EnvFile{
File: &File{
Path: name,
},
Vars: valueNoop,
}
err = WriteEnvFile(&ef, dir)
if err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
contents, err := ioutil.ReadFile(fullPath)
if err != nil {
t.Fatalf("Unable to read expected file: %v", err)
}
if string(contents) != base {
t.Fatalf("File has incorrect contents: %q", contents)
}
newStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
if oldStat.Sys().(*syscall.Stat_t).Ino != newStat.Sys().(*syscall.Stat_t).Ino {
t.Fatal("File was replaced: %s", fullPath)
}
}
func TestWriteEnvFileUpdateDos(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
if err != nil {
t.Fatalf("Unable to create tempdir: %v", err)
}
defer os.RemoveAll(dir)
name := "foo.conf"
fullPath := path.Join(dir, name)
ioutil.WriteFile(fullPath, []byte(baseDos), 0644)
oldStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
ef := EnvFile{
File: &File{
Path: name,
},
Vars: valueUpdate,
}
err = WriteEnvFile(&ef, dir)
if err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
contents, err := ioutil.ReadFile(fullPath)
if err != nil {
t.Fatalf("Unable to read expected file: %v", err)
}
if string(contents) != expectUpdate {
t.Fatalf("File has incorrect contents: %q", contents)
}
newStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
if oldStat.Sys().(*syscall.Stat_t).Ino == newStat.Sys().(*syscall.Stat_t).Ino {
t.Fatal("File was not replaced: %s", fullPath)
}
}
// A middle ground noop, values are unchanged but we did have a value.
// Seems reasonable to rewrite the file in Unix format anyway.
func TestWriteEnvFileDos2Unix(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
if err != nil {
t.Fatalf("Unable to create tempdir: %v", err)
}
defer os.RemoveAll(dir)
name := "foo.conf"
fullPath := path.Join(dir, name)
ioutil.WriteFile(fullPath, []byte(baseDos), 0644)
oldStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
ef := EnvFile{
File: &File{
Path: name,
},
Vars: valueNoop,
}
err = WriteEnvFile(&ef, dir)
if err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
contents, err := ioutil.ReadFile(fullPath)
if err != nil {
t.Fatalf("Unable to read expected file: %v", err)
}
if string(contents) != base {
t.Fatalf("File has incorrect contents: %q", contents)
}
newStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
if oldStat.Sys().(*syscall.Stat_t).Ino == newStat.Sys().(*syscall.Stat_t).Ino {
t.Fatal("File was not replaced: %s", fullPath)
}
}
// If it really is a noop (structure is empty) don't even do dos2unix
func TestWriteEnvFileEmpty(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
if err != nil {
t.Fatalf("Unable to create tempdir: %v", err)
}
defer os.RemoveAll(dir)
name := "foo.conf"
fullPath := path.Join(dir, name)
ioutil.WriteFile(fullPath, []byte(baseDos), 0644)
oldStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
ef := EnvFile{
File: &File{
Path: name,
},
Vars: valueEmpty,
}
err = WriteEnvFile(&ef, dir)
if err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
contents, err := ioutil.ReadFile(fullPath)
if err != nil {
t.Fatalf("Unable to read expected file: %v", err)
}
if string(contents) != baseDos {
t.Fatalf("File has incorrect contents: %q", contents)
}
newStat, err := os.Stat(fullPath)
if err != nil {
t.Fatal("Unable to stat file: %v", err)
}
if oldStat.Sys().(*syscall.Stat_t).Ino != newStat.Sys().(*syscall.Stat_t).Ino {
t.Fatal("File was replaced: %s", fullPath)
}
}
// no point in creating empty files
func TestWriteEnvFileEmptyNoCreate(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
if err != nil {
t.Fatalf("Unable to create tempdir: %v", err)
}
defer os.RemoveAll(dir)
name := "foo.conf"
fullPath := path.Join(dir, name)
ef := EnvFile{
File: &File{
Path: name,
},
Vars: valueEmpty,
}
err = WriteEnvFile(&ef, dir)
if err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
contents, err := ioutil.ReadFile(fullPath)
if err == nil {
t.Fatalf("File has incorrect contents: %q", contents)
} else if !os.IsNotExist(err) {
t.Fatalf("Unexpected error while reading file: %v", err)
}
}
func TestWriteEnvFilePermFailure(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
if err != nil {
t.Fatalf("Unable to create tempdir: %v", err)
}
defer os.RemoveAll(dir)
name := "foo.conf"
fullPath := path.Join(dir, name)
ioutil.WriteFile(fullPath, []byte(base), 0000)
ef := EnvFile{
File: &File{
Path: name,
},
Vars: valueUpdate,
}
err = WriteEnvFile(&ef, dir)
if !os.IsPermission(err) {
t.Fatalf("Not a pemission denied error: %v", err)
}
}
func TestWriteEnvFileNameFailure(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
if err != nil {
t.Fatalf("Unable to create tempdir: %v", err)
}
defer os.RemoveAll(dir)
name := "foo.conf"
ef := EnvFile{
File: &File{
Path: name,
},
Vars: valueInvalid,
}
err = WriteEnvFile(&ef, dir)
if err == nil || !strings.HasPrefix(err.Error(), "Invalid name") {
t.Fatalf("Not an invalid name error: %v", err)
}
}