156 lines
2.8 KiB
Go
156 lines
2.8 KiB
Go
|
package safefile
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"io/ioutil"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"testing"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func ensureFileContains(name, data string) error {
|
||
|
b, err := ioutil.ReadFile(name)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if string(b) != data {
|
||
|
return fmt.Errorf("wrong data in file: expected %s, got %s", data, string(b))
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func tempFileName(count int) string {
|
||
|
return filepath.Join(os.TempDir(), fmt.Sprintf("safefile-test-%d-%x", count, time.Now().UnixNano()))
|
||
|
}
|
||
|
|
||
|
var testData = "Hello, this is a test data"
|
||
|
|
||
|
func testInTempDir() error {
|
||
|
name := tempFileName(0)
|
||
|
defer os.Remove(name)
|
||
|
f, err := Create(name, 0666)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if name != f.OrigName() {
|
||
|
f.Close()
|
||
|
return fmt.Errorf("name %q differs from OrigName: %q", name, f.OrigName())
|
||
|
}
|
||
|
_, err = io.WriteString(f, testData)
|
||
|
if err != nil {
|
||
|
f.Close()
|
||
|
return err
|
||
|
}
|
||
|
err = f.Commit()
|
||
|
if err != nil {
|
||
|
f.Close()
|
||
|
return err
|
||
|
}
|
||
|
err = f.Close()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return ensureFileContains(name, testData)
|
||
|
}
|
||
|
|
||
|
func TestMakeTempName(t *testing.T) {
|
||
|
// Make sure temp name is random.
|
||
|
m := make(map[string]bool)
|
||
|
for i := 0; i < 100; i++ {
|
||
|
name, err := makeTempName("/tmp", "sf")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if m[name] {
|
||
|
t.Fatal("repeated file name")
|
||
|
}
|
||
|
m[name] = true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestFile(t *testing.T) {
|
||
|
err := testInTempDir()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestWriteFile(t *testing.T) {
|
||
|
name := tempFileName(1)
|
||
|
err := WriteFile(name, []byte(testData), 0666)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
err = ensureFileContains(name, testData)
|
||
|
if err != nil {
|
||
|
os.Remove(name)
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
os.Remove(name)
|
||
|
}
|
||
|
|
||
|
func TestAbandon(t *testing.T) {
|
||
|
name := tempFileName(2)
|
||
|
f, err := Create(name, 0666)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
err = f.Close()
|
||
|
if err != nil {
|
||
|
t.Fatalf("Abandon failed: %s", err)
|
||
|
}
|
||
|
// Make sure temporary file doesn't exist.
|
||
|
_, err = os.Stat(f.Name())
|
||
|
if err != nil && !os.IsNotExist(err) {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestDoubleCommit(t *testing.T) {
|
||
|
name := tempFileName(3)
|
||
|
f, err := Create(name, 0666)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
err = f.Commit()
|
||
|
if err != nil {
|
||
|
os.Remove(name)
|
||
|
t.Fatalf("First commit failed: %s", err)
|
||
|
}
|
||
|
err = f.Commit()
|
||
|
if err != ErrAlreadyCommitted {
|
||
|
os.Remove(name)
|
||
|
t.Fatalf("Second commit didn't fail: %s", err)
|
||
|
}
|
||
|
err = f.Close()
|
||
|
if err != nil {
|
||
|
os.Remove(name)
|
||
|
t.Fatalf("Close failed: %s", err)
|
||
|
}
|
||
|
os.Remove(name)
|
||
|
}
|
||
|
|
||
|
func TestOverwriting(t *testing.T) {
|
||
|
name := tempFileName(4)
|
||
|
defer os.Remove(name)
|
||
|
|
||
|
olddata := "This is old data"
|
||
|
err := ioutil.WriteFile(name, []byte(olddata), 0600)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
newdata := "This is new data"
|
||
|
err = WriteFile(name, []byte(newdata), 0600)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
err = ensureFileContains(name, newdata)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}
|