github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/inode/file_stress_test.go (about)

     1  // Copyright (c) 2015-2021, NVIDIA CORPORATION.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package inode
     5  
     6  import (
     7  	"crypto/rand"
     8  	"sync"
     9  	"testing"
    10  )
    11  
    12  type testStressFileWritesGlobalsStruct struct {
    13  	testStressNumWorkers        uint64
    14  	testStressNumFlushesPerFile uint64
    15  	testStressNumBlocksPerFlush uint64
    16  	testStressNumBytesPerBlock  uint64
    17  	volumeHandle                VolumeHandle
    18  	writeBlock                  []byte
    19  	childrenStart               sync.WaitGroup
    20  	childrenDone                sync.WaitGroup
    21  }
    22  
    23  var testStressFileWritesGlobals testStressFileWritesGlobalsStruct
    24  
    25  func TestStressFileWritesWhileStarved(t *testing.T) {
    26  	testStressFileWritesGlobals.testStressNumWorkers = 100
    27  	testStressFileWritesGlobals.testStressNumFlushesPerFile = 4 // Currently, each triggers a checkpoint as well
    28  	testStressFileWritesGlobals.testStressNumBlocksPerFlush = 20
    29  	testStressFileWritesGlobals.testStressNumBytesPerBlock = 1
    30  
    31  	testStressFileWrites(t, true)
    32  }
    33  
    34  func TestStressFileWritesWhileNotStarved(t *testing.T) {
    35  	testStressFileWritesGlobals.testStressNumWorkers = 100
    36  	testStressFileWritesGlobals.testStressNumFlushesPerFile = 10 // Currently, each triggers a checkpoint as well
    37  	testStressFileWritesGlobals.testStressNumBlocksPerFlush = 20
    38  	testStressFileWritesGlobals.testStressNumBytesPerBlock = 1
    39  
    40  	testStressFileWrites(t, false)
    41  }
    42  
    43  func testStressFileWrites(t *testing.T, starvationMode bool) {
    44  	var (
    45  		err         error
    46  		workerIndex uint64
    47  	)
    48  
    49  	testSetup(t, starvationMode)
    50  
    51  	testStressFileWritesGlobals.volumeHandle, err = FetchVolumeHandle("TestVolume")
    52  	if nil != err {
    53  		t.Fatalf("FetchVolumeHandle(\"TestVolume\") failed: %v", err)
    54  	}
    55  
    56  	testStressFileWritesGlobals.writeBlock = make([]byte, testStressFileWritesGlobals.testStressNumBytesPerBlock)
    57  	rand.Read(testStressFileWritesGlobals.writeBlock)
    58  
    59  	testStressFileWritesGlobals.childrenStart.Add(1)
    60  	testStressFileWritesGlobals.childrenDone.Add(int(testStressFileWritesGlobals.testStressNumWorkers))
    61  
    62  	for workerIndex = 0; workerIndex < testStressFileWritesGlobals.testStressNumWorkers; workerIndex++ {
    63  		go testStressFileWritesWorker(t, workerIndex)
    64  	}
    65  
    66  	testStressFileWritesGlobals.childrenStart.Done()
    67  
    68  	testStressFileWritesGlobals.childrenDone.Wait()
    69  
    70  	testTeardown(t)
    71  }
    72  
    73  func testStressFileWritesWorker(t *testing.T, workerIndex uint64) {
    74  	var (
    75  		err             error
    76  		fileBlockNumber uint64
    77  		fileFlushNumber uint64
    78  		fileInodeNumber InodeNumber
    79  	)
    80  
    81  	fileInodeNumber, err = testStressFileWritesGlobals.volumeHandle.CreateFile(InodeMode(0000), InodeRootUserID, InodeGroupID(0))
    82  	if nil != err {
    83  		t.Fatalf("testStressFileWritesGlobals.volumeHandle.CreateFile() failed: %v", err)
    84  	}
    85  
    86  	testStressFileWritesGlobals.childrenStart.Wait()
    87  
    88  	for fileFlushNumber = 0; fileFlushNumber < testStressFileWritesGlobals.testStressNumFlushesPerFile; fileFlushNumber++ {
    89  		for fileBlockNumber = 0; fileBlockNumber < testStressFileWritesGlobals.testStressNumBlocksPerFlush; fileBlockNumber++ {
    90  			err = testStressFileWritesGlobals.volumeHandle.Write(
    91  				fileInodeNumber,
    92  				fileBlockNumber*testStressFileWritesGlobals.testStressNumBytesPerBlock,
    93  				testStressFileWritesGlobals.writeBlock,
    94  				nil)
    95  			if nil != err {
    96  				t.Fatalf("Write() failed: %v", err)
    97  			}
    98  		}
    99  
   100  		err = testStressFileWritesGlobals.volumeHandle.Flush(fileInodeNumber, false)
   101  		if nil != err {
   102  			t.Fatalf("Flush() failed: %v", err)
   103  		}
   104  	}
   105  
   106  	err = testStressFileWritesGlobals.volumeHandle.Flush(fileInodeNumber, true)
   107  	if nil != err {
   108  		t.Fatalf("Flush() failed: %v", err)
   109  	}
   110  
   111  	err = testStressFileWritesGlobals.volumeHandle.Destroy(fileInodeNumber)
   112  	if nil != err {
   113  		t.Fatalf("Destroy() failed: %v", err)
   114  	}
   115  
   116  	testStressFileWritesGlobals.childrenDone.Done()
   117  }