github.com/pawelgaczynski/giouring@v0.0.0-20230826085535-69588b89acb9/completion_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  	"testing"
    28  
    29  	. "github.com/stretchr/testify/require"
    30  )
    31  
    32  func queueNOPs(t *testing.T, ring *Ring, number int, offset int) error {
    33  	t.Helper()
    34  
    35  	for i := 0; i < number; i++ {
    36  		entry := ring.GetSQE()
    37  		NotNil(t, entry)
    38  
    39  		entry.PrepareNop()
    40  		entry.UserData = uint64(i + offset)
    41  	}
    42  	submitted, err := ring.Submit()
    43  	Equal(t, int(submitted), number)
    44  
    45  	return err
    46  }
    47  
    48  func TestPeekBatchCQE(t *testing.T) {
    49  	ring, err := CreateRing(16)
    50  	NoError(t, err)
    51  
    52  	defer ring.QueueExit()
    53  
    54  	cqeBuff := make([]*CompletionQueueEvent, 4)
    55  
    56  	cnt := ring.PeekBatchCQE(cqeBuff)
    57  	Equal(t, uint32(0), cnt)
    58  	NoError(t, queueNOPs(t, ring, 4, 0))
    59  
    60  	cnt = ring.PeekBatchCQE(cqeBuff)
    61  	Equal(t, uint32(4), cnt)
    62  
    63  	ring.CQAdvance(4)
    64  
    65  	for i := 0; i < 4; i++ {
    66  		Equal(t, uint64(i), cqeBuff[i].UserData)
    67  	}
    68  }
    69  
    70  func TestRingCqRingNeedsEnter(t *testing.T) {
    71  	ring := NewRing()
    72  	ring.sqRing = &SubmissionQueue{}
    73  
    74  	var flags uint32
    75  	ring.sqRing.flags = &flags
    76  
    77  	False(t, ring.cqRingNeedsEnter())
    78  
    79  	ring.flags |= SetupIOPoll
    80  
    81  	True(t, ring.cqRingNeedsEnter())
    82  
    83  	ring.flags = 0
    84  
    85  	False(t, ring.cqRingNeedsEnter())
    86  
    87  	flags |= SQCQOverflow
    88  
    89  	True(t, ring.cqRingNeedsEnter())
    90  }
    91  
    92  func TestRingForEachCQE(t *testing.T) {
    93  	entries := 16
    94  	ring, err := CreateRing(uint32(entries))
    95  	NoError(t, err)
    96  	NotNil(t, ring)
    97  	defer ring.QueueExit()
    98  
    99  	// Add some events to the submission queue
   100  	for i := 0; i < entries; i++ {
   101  		sqe := ring.GetSQE()
   102  		sqe.PrepareNop()
   103  		sqe.UserData = uint64(i + 1000)
   104  		var submitted uint
   105  		submitted, err = ring.Submit()
   106  		NoError(t, err)
   107  		Equal(t, 1, int(submitted))
   108  	}
   109  
   110  	// Wait for the events to complete
   111  	_, err = ring.WaitCQENr(16)
   112  	NoError(t, err)
   113  
   114  	// Verify that all events were completed
   115  	count := 0
   116  	ring.ForEachCQE(func(cqe *CompletionQueueEvent) {
   117  		count++
   118  		GreaterOrEqual(t, int(cqe.UserData), 1000)
   119  	})
   120  	Equal(t, entries, count)
   121  }