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 }