123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- package winio
- import (
- "io"
- "io/ioutil"
- "os"
- "syscall"
- "testing"
- )
- var testFileName string
- func TestMain(m *testing.M) {
- f, err := ioutil.TempFile("", "tmp")
- if err != nil {
- panic(err)
- }
- testFileName = f.Name()
- f.Close()
- defer os.Remove(testFileName)
- os.Exit(m.Run())
- }
- func makeTestFile(makeADS bool) error {
- os.Remove(testFileName)
- f, err := os.Create(testFileName)
- if err != nil {
- return err
- }
- defer f.Close()
- _, err = f.Write([]byte("testing 1 2 3\n"))
- if err != nil {
- return err
- }
- if makeADS {
- a, err := os.Create(testFileName + ":ads.txt")
- if err != nil {
- return err
- }
- defer a.Close()
- _, err = a.Write([]byte("alternate data stream\n"))
- if err != nil {
- return err
- }
- }
- return nil
- }
- func TestBackupRead(t *testing.T) {
- err := makeTestFile(true)
- if err != nil {
- t.Fatal(err)
- }
- f, err := os.Open(testFileName)
- if err != nil {
- t.Fatal(err)
- }
- defer f.Close()
- r := NewBackupFileReader(f, false)
- defer r.Close()
- b, err := ioutil.ReadAll(r)
- if err != nil {
- t.Fatal(err)
- }
- if len(b) == 0 {
- t.Fatal("no data")
- }
- }
- func TestBackupStreamRead(t *testing.T) {
- err := makeTestFile(true)
- if err != nil {
- t.Fatal(err)
- }
- f, err := os.Open(testFileName)
- if err != nil {
- t.Fatal(err)
- }
- defer f.Close()
- r := NewBackupFileReader(f, false)
- defer r.Close()
- br := NewBackupStreamReader(r)
- gotData := false
- gotAltData := false
- for {
- hdr, err := br.Next()
- if err == io.EOF {
- break
- }
- if err != nil {
- t.Fatal(err)
- }
- switch hdr.Id {
- case BackupData:
- if gotData {
- t.Fatal("duplicate data")
- }
- if hdr.Name != "" {
- t.Fatalf("unexpected name %s", hdr.Name)
- }
- b, err := ioutil.ReadAll(br)
- if err != nil {
- t.Fatal(err)
- }
- if string(b) != "testing 1 2 3\n" {
- t.Fatalf("incorrect data %v", b)
- }
- gotData = true
- case BackupAlternateData:
- if gotAltData {
- t.Fatal("duplicate alt data")
- }
- if hdr.Name != ":ads.txt:$DATA" {
- t.Fatalf("incorrect name %s", hdr.Name)
- }
- b, err := ioutil.ReadAll(br)
- if err != nil {
- t.Fatal(err)
- }
- if string(b) != "alternate data stream\n" {
- t.Fatalf("incorrect data %v", b)
- }
- gotAltData = true
- default:
- t.Fatalf("unknown stream ID %d", hdr.Id)
- }
- }
- if !gotData || !gotAltData {
- t.Fatal("missing stream")
- }
- }
- func TestBackupStreamWrite(t *testing.T) {
- f, err := os.Create(testFileName)
- if err != nil {
- t.Fatal(err)
- }
- defer f.Close()
- w := NewBackupFileWriter(f, false)
- defer w.Close()
- data := "testing 1 2 3\n"
- altData := "alternate stream\n"
- br := NewBackupStreamWriter(w)
- err = br.WriteHeader(&BackupHeader{Id: BackupData, Size: int64(len(data))})
- if err != nil {
- t.Fatal(err)
- }
- n, err := br.Write([]byte(data))
- if err != nil {
- t.Fatal(err)
- }
- if n != len(data) {
- t.Fatal("short write")
- }
- err = br.WriteHeader(&BackupHeader{Id: BackupAlternateData, Size: int64(len(altData)), Name: ":ads.txt:$DATA"})
- if err != nil {
- t.Fatal(err)
- }
- n, err = br.Write([]byte(altData))
- if err != nil {
- t.Fatal(err)
- }
- if n != len(altData) {
- t.Fatal("short write")
- }
- f.Close()
- b, err := ioutil.ReadFile(testFileName)
- if err != nil {
- t.Fatal(err)
- }
- if string(b) != data {
- t.Fatalf("wrong data %v", b)
- }
- b, err = ioutil.ReadFile(testFileName + ":ads.txt")
- if err != nil {
- t.Fatal(err)
- }
- if string(b) != altData {
- t.Fatalf("wrong data %v", b)
- }
- }
- func makeSparseFile() error {
- os.Remove(testFileName)
- f, err := os.Create(testFileName)
- if err != nil {
- return err
- }
- defer f.Close()
- const (
- FSCTL_SET_SPARSE = 0x000900c4
- FSCTL_SET_ZERO_DATA = 0x000980c8
- )
- err = syscall.DeviceIoControl(syscall.Handle(f.Fd()), FSCTL_SET_SPARSE, nil, 0, nil, 0, nil, nil)
- if err != nil {
- return err
- }
- _, err = f.Write([]byte("testing 1 2 3\n"))
- if err != nil {
- return err
- }
- _, err = f.Seek(1000000, 0)
- if err != nil {
- return err
- }
- _, err = f.Write([]byte("more data later\n"))
- if err != nil {
- return err
- }
- return nil
- }
- func TestBackupSparseFile(t *testing.T) {
- err := makeSparseFile()
- if err != nil {
- t.Fatal(err)
- }
- f, err := os.Open(testFileName)
- if err != nil {
- t.Fatal(err)
- }
- defer f.Close()
- r := NewBackupFileReader(f, false)
- defer r.Close()
- br := NewBackupStreamReader(r)
- for {
- hdr, err := br.Next()
- if err == io.EOF {
- break
- }
- if err != nil {
- t.Fatal(err)
- }
- t.Log(hdr)
- }
- }
|