github.com/pawelgaczynski/giouring@v0.0.0-20230826085535-69588b89acb9/common_test.go (about) 1 // MIT License 2 // 3 // Copyright (c) 2023 Paweł Gaczyński 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a 6 // copy of this software and associated documentation files (the 7 // "Software"), to deal in the Software without restriction, including 8 // without limitation the rights to use, copy, modify, merge, publish, 9 // distribute, sublicense, and/or sell copies of the Software, and to 10 // permit persons to whom the Software is furnished to do so, subject to 11 // the following conditions: 12 // 13 // The above copyright notice and this permission notice shall be included 14 // in all copies or substantial portions of the Software. 15 // 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24 package giouring 25 26 import ( 27 "fmt" 28 "sync/atomic" 29 "testing" 30 31 . "github.com/stretchr/testify/require" 32 ) 33 34 var port int32 = 8000 35 36 func getTestPort() int { 37 return int(atomic.AddInt32(&port, 1)) 38 } 39 40 type ringInitParams struct { 41 entries uint32 42 flags uint32 43 } 44 45 type testScenario struct { 46 prepares []func(*testing.T, testContext, *SubmissionQueueEntry) 47 setup func(testContext) 48 cleanup func(testContext) 49 result func(*testing.T, testContext, []*CompletionQueueEvent) 50 assert func(*testing.T, testContext) 51 debug bool 52 } 53 54 type testContext map[string]interface{} 55 56 func testNewFramework(t *testing.T, params ringInitParams, scenario testScenario) { 57 ring := NewRing() 58 NotNil(t, ring) 59 60 var entries uint32 = 16 61 if params.entries != 0 { 62 entries = params.entries 63 } 64 65 err := ring.QueueInit(entries, params.flags) 66 NoError(t, err) 67 68 defer ring.QueueExit() 69 70 context := make(map[string]interface{}) 71 if scenario.setup != nil { 72 scenario.setup(context) 73 } 74 75 defer func() { 76 if scenario.cleanup != nil { 77 scenario.cleanup(context) 78 } 79 }() 80 81 for i := 0; i < len(scenario.prepares); i++ { 82 sqe := ring.GetSQE() 83 NotNil(t, sqe) 84 85 scenario.prepares[i](t, context, sqe) 86 87 if scenario.debug { 88 // nolint: forbidigo 89 fmt.Printf(">>> %s # Prepared SQE[%d] = %+v\n", t.Name(), i, sqe) 90 } 91 } 92 93 numberOfSQEs := uint32(len(scenario.prepares)) 94 95 submitted, err := ring.SubmitAndWait(numberOfSQEs) 96 NoError(t, err) 97 Equal(t, uint(numberOfSQEs), submitted) 98 99 cqes := make([]*CompletionQueueEvent, numberOfSQEs) 100 101 numberOfCQEs := ring.PeekBatchCQE(cqes) 102 Equal(t, numberOfSQEs, numberOfCQEs) 103 104 for i, cqe := range cqes { 105 if scenario.debug { 106 // nolint: forbidigo 107 fmt.Printf("<<< %s # Received CQE[%d] = %+v\n", t.Name(), i, cqe) 108 } 109 } 110 111 scenario.result(t, context, cqes) 112 113 if scenario.assert != nil { 114 scenario.assert(t, context) 115 } 116 117 ring.CQAdvance(uint32(submitted)) 118 }