| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package file |
| |
| import ( |
| "bytes" |
| "io/ioutil" |
| "math/rand" |
| "os" |
| "testing" |
| "time" |
| |
| "thinfs/block/blocktest" |
| ) |
| |
| const ( |
| numBlocks = 4096 |
| |
| defaultBlockSize int64 = 1024 |
| fileSize = numBlocks * defaultBlockSize |
| ) |
| |
| func setUp(t *testing.T) (string, []byte, *rand.Rand) { |
| seed := time.Now().UTC().UnixNano() |
| t.Log("Seed is", seed) |
| r := rand.New(rand.NewSource(seed)) |
| |
| buf := make([]byte, fileSize) |
| r.Read(buf) |
| |
| tmpFile, err := ioutil.TempFile("", "file_test") |
| if err != nil { |
| t.Fatal("Error creating temp file: ", err) |
| } |
| |
| name := tmpFile.Name() |
| |
| if _, err := tmpFile.Write(buf); err != nil { |
| t.Fatal("Error writing random data to temp file: ", err) |
| } |
| |
| if err := tmpFile.Close(); err != nil { |
| t.Fatal("Error closing temp file: ", err) |
| } |
| |
| return name, buf, r |
| } |
| |
| func TestReadAt(t *testing.T) { |
| name, buf, r := setUp(t) |
| defer os.Remove(name) |
| |
| f, err := os.OpenFile(name, os.O_RDWR, 0666) |
| if err != nil { |
| t.Fatal("Error opening TempFile: ", err) |
| } |
| file, err := New(f, defaultBlockSize) |
| if err != nil { |
| f.Close() |
| t.Fatal("Error creating File: ", err) |
| } |
| defer func() { |
| if err := file.Close(); err != nil { |
| t.Error("Error closing file: ", err) |
| } |
| }() |
| |
| blocktest.ReadAt(t, file, r, buf) |
| } |
| |
| func TestWriteAt(t *testing.T) { |
| name, buf, r := setUp(t) |
| defer os.Remove(name) |
| |
| f, err := os.OpenFile(name, os.O_RDWR, 0666) |
| if err != nil { |
| t.Fatal("Error opening TempFile: ", err) |
| } |
| file, err := New(f, defaultBlockSize) |
| if err != nil { |
| f.Close() |
| t.Fatal("Error creating File: ", err) |
| } |
| defer func() { |
| if err := file.Close(); err != nil { |
| t.Error("Error closing file: ", err) |
| } |
| }() |
| |
| blocktest.WriteAt(t, file, r, buf) |
| } |
| |
| func TestErrorPaths(t *testing.T) { |
| name, _, _ := setUp(t) |
| defer os.Remove(name) |
| |
| f, err := os.OpenFile(name, os.O_RDWR, 0666) |
| if err != nil { |
| t.Fatal("Error opening TempFile: ", err) |
| } |
| file, err := New(f, defaultBlockSize) |
| if err != nil { |
| f.Close() |
| t.Fatal("Error creating File: ", err) |
| } |
| defer func() { |
| if err := file.Close(); err != nil { |
| t.Error("Error closing File: ", err) |
| } |
| }() |
| |
| blocktest.ErrorPaths(t, file) |
| } |
| |
| func TestRangeReadWrite(t *testing.T) { |
| name, _, _ := setUp(t) |
| defer os.Remove(name) |
| |
| f, err := os.OpenFile(name, os.O_RDWR, 0666) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| file, err := NewRange(f, 512, 1024, 10240) |
| if err != nil { |
| f.Close() |
| t.Fatal(err) |
| } |
| defer func() { |
| if err := file.Close(); err != nil { |
| t.Error("Error closing File: ", err) |
| } |
| }() |
| |
| want := make([]byte, 512) |
| copy(want, []byte("hello world")) |
| if _, err := file.WriteAt(want, 0); err != nil { |
| t.Fatal(err) |
| } |
| |
| b := make([]byte, len(want)) |
| if _, err := f.ReadAt(b, 1024); err != nil { |
| t.Fatal(err) |
| } |
| if !bytes.Equal(b, want) { |
| t.Errorf("Range WriteAt: got %x, want %x", b, want) |
| } |
| |
| b = make([]byte, len(want)) |
| if _, err := file.ReadAt(b, 0); err != nil { |
| t.Fatal(err) |
| } |
| if !bytes.Equal(b, want) { |
| t.Errorf("Range ReadAt: got %x, want %x", b, want) |
| } |
| |
| // TODO(raggi): I'm not aware of a portable / good way to test discard here. |
| } |