github.com/IBM/fsgo@v0.0.0-20220920202152-e16fd2119d49/mem/file_test.go (about)

     1  // Copyright 2022 IBM Inc. All rights reserved
     2  // Copyright © 2014 Steve Francia <spf@spf13.com>
     3  //
     4  // SPDX-License-Identifier: Apache2.0
     5  package mem
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  	"testing"
    11  	"time"
    12  )
    13  
    14  func TestFileDataNameRace(t *testing.T) {
    15  	t.Parallel()
    16  	const someName = "someName"
    17  	const someOtherName = "someOtherName"
    18  	d := FileData{
    19  		name: someName,
    20  	}
    21  
    22  	if d.Name() != someName {
    23  		t.Errorf("Failed to read correct Name, was %v", d.Name())
    24  	}
    25  
    26  	ChangeFileName(&d, someOtherName)
    27  	if d.Name() != someOtherName {
    28  		t.Errorf("Failed to set Name, was %v", d.Name())
    29  	}
    30  
    31  	go func() {
    32  		ChangeFileName(&d, someName)
    33  	}()
    34  
    35  	if d.Name() != someName && d.Name() != someOtherName {
    36  		t.Errorf("Failed to read either Name, was %v", d.Name())
    37  	}
    38  }
    39  
    40  func TestFileDataModTimeRace(t *testing.T) {
    41  	t.Parallel()
    42  	someTime := time.Now()
    43  	someOtherTime := someTime.Add(1 * time.Minute)
    44  
    45  	d := FileData{
    46  		modtime: someTime,
    47  	}
    48  
    49  	s := FileInfo{
    50  		FileData: &d,
    51  	}
    52  
    53  	if s.ModTime() != someTime {
    54  		t.Errorf("Failed to read correct value, was %v", s.ModTime())
    55  	}
    56  
    57  	SetModTime(&d, someOtherTime)
    58  	if s.ModTime() != someOtherTime {
    59  		t.Errorf("Failed to set ModTime, was %v", s.ModTime())
    60  	}
    61  
    62  	go func() {
    63  		SetModTime(&d, someTime)
    64  	}()
    65  
    66  	if s.ModTime() != someTime && s.ModTime() != someOtherTime {
    67  		t.Errorf("Failed to read either modtime, was %v", s.ModTime())
    68  	}
    69  }
    70  
    71  func TestFileDataModeRace(t *testing.T) {
    72  	t.Parallel()
    73  	const someMode = 0777
    74  	const someOtherMode = 0660
    75  
    76  	d := FileData{
    77  		mode: someMode,
    78  	}
    79  
    80  	s := FileInfo{
    81  		FileData: &d,
    82  	}
    83  
    84  	if s.Mode() != someMode {
    85  		t.Errorf("Failed to read correct value, was %v", s.Mode())
    86  	}
    87  
    88  	SetMode(&d, someOtherMode)
    89  	if s.Mode() != someOtherMode {
    90  		t.Errorf("Failed to set Mode, was %v", s.Mode())
    91  	}
    92  
    93  	go func() {
    94  		SetMode(&d, someMode)
    95  	}()
    96  
    97  	if s.Mode() != someMode && s.Mode() != someOtherMode {
    98  		t.Errorf("Failed to read either mode, was %v", s.Mode())
    99  	}
   100  }
   101  
   102  func TestFileWriteAt(t *testing.T) {
   103  	t.Parallel()
   104  
   105  	data := CreateFile("abc.txt")
   106  	f := NewFileHandle(data)
   107  
   108  	testData := []byte{1, 2, 3, 4, 5}
   109  	offset := len(testData)
   110  
   111  	// 5 zeros + testdata
   112  	_, err := f.WriteAt(testData, int64(offset))
   113  	if err != nil {
   114  		t.Fatal(err)
   115  	}
   116  
   117  	// 2 * testdata
   118  	_, err = f.WriteAt(testData, 0)
   119  	if err != nil {
   120  		t.Fatal(err)
   121  	}
   122  
   123  	// 3 * testdata
   124  	_, err = f.WriteAt(testData, int64(offset*2))
   125  	if err != nil {
   126  		t.Fatal(err)
   127  	}
   128  
   129  	// 3 * testdata + 5 zeros + testdata
   130  	_, err = f.WriteAt(testData, int64(offset*4))
   131  	if err != nil {
   132  		t.Fatal(err)
   133  	}
   134  
   135  	// 5 * testdata
   136  	_, err = f.WriteAt(testData, int64(offset*3))
   137  	if err != nil {
   138  		t.Fatal(err)
   139  	}
   140  
   141  	err = f.Close()
   142  	if err != nil {
   143  		t.Fatal(err)
   144  	}
   145  
   146  	expected := bytes.Repeat(testData, 5)
   147  	if !bytes.Equal(expected, data.data) {
   148  		t.Fatalf("expected: %v, got: %v", expected, data.data)
   149  	}
   150  }
   151  
   152  func TestFileDataIsDirRace(t *testing.T) {
   153  	t.Parallel()
   154  
   155  	d := FileData{
   156  		dir: true,
   157  	}
   158  
   159  	s := FileInfo{
   160  		FileData: &d,
   161  	}
   162  
   163  	if s.IsDir() != true {
   164  		t.Errorf("Failed to read correct value, was %v", s.IsDir())
   165  	}
   166  
   167  	go func() {
   168  		s.Lock()
   169  		d.dir = false
   170  		s.Unlock()
   171  	}()
   172  
   173  	//just logging the value to trigger a read:
   174  	t.Logf("Value is %v", s.IsDir())
   175  }
   176  
   177  func TestFileDataSizeRace(t *testing.T) {
   178  	t.Parallel()
   179  
   180  	const someData = "Hello"
   181  	const someOtherDataSize = "Hello World"
   182  
   183  	d := FileData{
   184  		data: []byte(someData),
   185  		dir:  false,
   186  	}
   187  
   188  	s := FileInfo{
   189  		FileData: &d,
   190  	}
   191  
   192  	if s.Size() != int64(len(someData)) {
   193  		t.Errorf("Failed to read correct value, was %v", s.Size())
   194  	}
   195  
   196  	go func() {
   197  		s.Lock()
   198  		d.data = []byte(someOtherDataSize)
   199  		s.Unlock()
   200  	}()
   201  
   202  	//just logging the value to trigger a read:
   203  	t.Logf("Value is %v", s.Size())
   204  
   205  	//Testing the Dir size case
   206  	d.dir = true
   207  	if s.Size() != int64(42) {
   208  		t.Errorf("Failed to read correct value for dir, was %v", s.Size())
   209  	}
   210  }
   211  
   212  func TestFileReadAtSeekOffset(t *testing.T) {
   213  	t.Parallel()
   214  
   215  	fd := CreateFile("foo")
   216  	f := NewFileHandle(fd)
   217  
   218  	_, err := f.WriteString("TEST")
   219  	if err != nil {
   220  		t.Fatal(err)
   221  	}
   222  	offset, err := f.Seek(0, io.SeekStart)
   223  	if err != nil {
   224  		t.Fatal(err)
   225  	}
   226  	if offset != 0 {
   227  		t.Fail()
   228  	}
   229  
   230  	offsetBeforeReadAt, err := f.Seek(0, io.SeekCurrent)
   231  	if err != nil {
   232  		t.Fatal(err)
   233  	}
   234  	if offsetBeforeReadAt != 0 {
   235  		t.Fatal("expected 0")
   236  	}
   237  
   238  	b := make([]byte, 4)
   239  	n, err := f.ReadAt(b, 0)
   240  	if err != nil {
   241  		t.Fatal(err)
   242  	}
   243  	if n != 4 {
   244  		t.Fail()
   245  	}
   246  	if string(b) != "TEST" {
   247  		t.Fail()
   248  	}
   249  
   250  	offsetAfterReadAt, err := f.Seek(0, io.SeekCurrent)
   251  	if err != nil {
   252  		t.Fatal(err)
   253  	}
   254  	if offsetAfterReadAt != offsetBeforeReadAt {
   255  		t.Fatal("ReadAt should not affect offset")
   256  	}
   257  
   258  	err = f.Close()
   259  	if err != nil {
   260  		t.Fatal(err)
   261  	}
   262  }
   263  
   264  func TestFileWriteAndSeek(t *testing.T) {
   265  	fd := CreateFile("foo")
   266  	f := NewFileHandle(fd)
   267  
   268  	assert := func(expected bool, v ...interface{}) {
   269  		if !expected {
   270  			t.Helper()
   271  			t.Fatal(v...)
   272  		}
   273  	}
   274  
   275  	data4 := []byte{0, 1, 2, 3}
   276  	data20 := bytes.Repeat(data4, 5)
   277  	var off int64
   278  
   279  	for i := 0; i < 100; i++ {
   280  		// write 20 bytes
   281  		n, err := f.Write(data20)
   282  		assert(err == nil, err)
   283  		off += int64(n)
   284  		assert(n == len(data20), n)
   285  		assert(off == int64((i+1)*len(data20)), off)
   286  
   287  		// rewind to start and write 4 bytes there
   288  		cur, err := f.Seek(-off, io.SeekCurrent)
   289  		assert(err == nil, err)
   290  		assert(cur == 0, cur)
   291  
   292  		n, err = f.Write(data4)
   293  		assert(err == nil, err)
   294  		assert(n == len(data4), n)
   295  
   296  		// back at the end
   297  		cur, err = f.Seek(off-int64(n), io.SeekCurrent)
   298  		assert(err == nil, err)
   299  		assert(cur == off, cur, off)
   300  	}
   301  }