...

Source file src/github.com/Microsoft/go-winio/backup_test.go

Documentation: github.com/Microsoft/go-winio

     1  //go:build windows
     2  // +build windows
     3  
     4  package winio
     5  
     6  import (
     7  	"io"
     8  	"os"
     9  	"syscall"
    10  	"testing"
    11  
    12  	"golang.org/x/sys/windows"
    13  )
    14  
    15  var testFileName string
    16  
    17  func TestMain(m *testing.M) {
    18  	f, err := os.CreateTemp("", "tmp")
    19  	if err != nil {
    20  		panic(err)
    21  	}
    22  	testFileName = f.Name()
    23  	f.Close()
    24  	defer os.Remove(testFileName)
    25  	os.Exit(m.Run())
    26  }
    27  
    28  func makeTestFile(makeADS bool) error {
    29  	os.Remove(testFileName)
    30  	f, err := os.Create(testFileName)
    31  	if err != nil {
    32  		return err
    33  	}
    34  	defer f.Close()
    35  	_, err = f.Write([]byte("testing 1 2 3\n"))
    36  	if err != nil {
    37  		return err
    38  	}
    39  	if makeADS {
    40  		a, err := os.Create(testFileName + ":ads.txt")
    41  		if err != nil {
    42  			return err
    43  		}
    44  		defer a.Close()
    45  		_, err = a.Write([]byte("alternate data stream\n"))
    46  		if err != nil {
    47  			return err
    48  		}
    49  	}
    50  	return nil
    51  }
    52  
    53  func TestBackupRead(t *testing.T) {
    54  	err := makeTestFile(true)
    55  	if err != nil {
    56  		t.Fatal(err)
    57  	}
    58  
    59  	f, err := os.Open(testFileName)
    60  	if err != nil {
    61  		t.Fatal(err)
    62  	}
    63  	defer f.Close()
    64  	r := NewBackupFileReader(f, false)
    65  	defer r.Close()
    66  	b, err := io.ReadAll(r)
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  	if len(b) == 0 {
    71  		t.Fatal("no data")
    72  	}
    73  }
    74  
    75  func TestBackupStreamRead(t *testing.T) {
    76  	err := makeTestFile(true)
    77  	if err != nil {
    78  		t.Fatal(err)
    79  	}
    80  
    81  	f, err := os.Open(testFileName)
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  	defer f.Close()
    86  	r := NewBackupFileReader(f, false)
    87  	defer r.Close()
    88  
    89  	br := NewBackupStreamReader(r)
    90  	gotData := false
    91  	gotAltData := false
    92  	for {
    93  		hdr, err := br.Next()
    94  		if err == io.EOF { //nolint:errorlint
    95  			break
    96  		}
    97  		if err != nil {
    98  			t.Fatal(err)
    99  		}
   100  
   101  		switch hdr.Id {
   102  		case BackupData:
   103  			if gotData {
   104  				t.Fatal("duplicate data")
   105  			}
   106  			if hdr.Name != "" {
   107  				t.Fatalf("unexpected name %s", hdr.Name)
   108  			}
   109  			b, err := io.ReadAll(br)
   110  			if err != nil {
   111  				t.Fatal(err)
   112  			}
   113  			if string(b) != "testing 1 2 3\n" {
   114  				t.Fatalf("incorrect data %v", b)
   115  			}
   116  			gotData = true
   117  		case BackupAlternateData:
   118  			if gotAltData {
   119  				t.Fatal("duplicate alt data")
   120  			}
   121  			if hdr.Name != ":ads.txt:$DATA" {
   122  				t.Fatalf("incorrect name %s", hdr.Name)
   123  			}
   124  			b, err := io.ReadAll(br)
   125  			if err != nil {
   126  				t.Fatal(err)
   127  			}
   128  			if string(b) != "alternate data stream\n" {
   129  				t.Fatalf("incorrect data %v", b)
   130  			}
   131  			gotAltData = true
   132  		default:
   133  			t.Fatalf("unknown stream ID %d", hdr.Id)
   134  		}
   135  	}
   136  	if !gotData || !gotAltData {
   137  		t.Fatal("missing stream")
   138  	}
   139  }
   140  
   141  func TestBackupStreamWrite(t *testing.T) {
   142  	f, err := os.Create(testFileName)
   143  	if err != nil {
   144  		t.Fatal(err)
   145  	}
   146  	defer f.Close()
   147  	w := NewBackupFileWriter(f, false)
   148  	defer w.Close()
   149  
   150  	data := "testing 1 2 3\n"
   151  	altData := "alternate stream\n"
   152  
   153  	br := NewBackupStreamWriter(w)
   154  	err = br.WriteHeader(&BackupHeader{Id: BackupData, Size: int64(len(data))})
   155  	if err != nil {
   156  		t.Fatal(err)
   157  	}
   158  	n, err := br.Write([]byte(data))
   159  	if err != nil {
   160  		t.Fatal(err)
   161  	}
   162  	if n != len(data) {
   163  		t.Fatal("short write")
   164  	}
   165  
   166  	err = br.WriteHeader(&BackupHeader{Id: BackupAlternateData, Size: int64(len(altData)), Name: ":ads.txt:$DATA"})
   167  	if err != nil {
   168  		t.Fatal(err)
   169  	}
   170  	n, err = br.Write([]byte(altData))
   171  	if err != nil {
   172  		t.Fatal(err)
   173  	}
   174  	if n != len(altData) {
   175  		t.Fatal("short write")
   176  	}
   177  
   178  	f.Close()
   179  
   180  	b, err := os.ReadFile(testFileName)
   181  	if err != nil {
   182  		t.Fatal(err)
   183  	}
   184  	if string(b) != data {
   185  		t.Fatalf("wrong data %v", b)
   186  	}
   187  
   188  	b, err = os.ReadFile(testFileName + ":ads.txt")
   189  	if err != nil {
   190  		t.Fatal(err)
   191  	}
   192  	if string(b) != altData {
   193  		t.Fatalf("wrong data %v", b)
   194  	}
   195  }
   196  
   197  func makeSparseFile() error {
   198  	os.Remove(testFileName)
   199  	f, err := os.Create(testFileName)
   200  	if err != nil {
   201  		return err
   202  	}
   203  	defer f.Close()
   204  
   205  	err = syscall.DeviceIoControl(syscall.Handle(f.Fd()), windows.FSCTL_SET_SPARSE, nil, 0, nil, 0, nil, nil)
   206  	if err != nil {
   207  		return err
   208  	}
   209  
   210  	_, err = f.Write([]byte("testing 1 2 3\n"))
   211  	if err != nil {
   212  		return err
   213  	}
   214  
   215  	_, err = f.Seek(1000000, 0)
   216  	if err != nil {
   217  		return err
   218  	}
   219  
   220  	_, err = f.Write([]byte("more data later\n"))
   221  	if err != nil {
   222  		return err
   223  	}
   224  
   225  	return nil
   226  }
   227  
   228  func TestBackupSparseFile(t *testing.T) {
   229  	err := makeSparseFile()
   230  	if err != nil {
   231  		t.Fatal(err)
   232  	}
   233  
   234  	f, err := os.Open(testFileName)
   235  	if err != nil {
   236  		t.Fatal(err)
   237  	}
   238  	defer f.Close()
   239  	r := NewBackupFileReader(f, false)
   240  	defer r.Close()
   241  
   242  	br := NewBackupStreamReader(r)
   243  	for {
   244  		hdr, err := br.Next()
   245  		if err == io.EOF { //nolint:errorlint
   246  			break
   247  		}
   248  		if err != nil {
   249  			t.Fatal(err)
   250  		}
   251  
   252  		t.Log(hdr)
   253  	}
   254  }
   255  

View as plain text