github.com/pawelgaczynski/giouring@v0.0.0-20230826085535-69588b89acb9/msg_ring_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  	"syscall"
    29  	"testing"
    30  
    31  	. "github.com/stretchr/testify/require"
    32  )
    33  
    34  func TestMsgRingItself(t *testing.T) {
    35  	ring, err := CreateRing(16)
    36  	Nil(t, err)
    37  
    38  	defer ring.QueueExit()
    39  
    40  	entry := ring.GetSQE()
    41  	NotNil(t, entry)
    42  	entry.PrepareMsgRing(ring.ringFd, 100, 200, 0)
    43  	entry.UserData = 123
    44  
    45  	entry = ring.GetSQE()
    46  	NotNil(t, entry)
    47  	entry.PrepareMsgRing(ring.ringFd, 300, 400, 0)
    48  	entry.UserData = 234
    49  
    50  	entry = ring.GetSQE()
    51  	NotNil(t, entry)
    52  	entry.PrepareMsgRing(ring.ringFd, 500, 600, 0)
    53  	entry.UserData = 345
    54  
    55  	numberOfCQEsSubmitted, err := ring.Submit()
    56  	Nil(t, err)
    57  
    58  	if numberOfCQEsSubmitted == 1 {
    59  		cqe, cqeErr := ring.WaitCQE()
    60  		Nil(t, cqeErr)
    61  
    62  		if cqe.Res == -int32(syscall.EINVAL) || cqe.Res == -int32(syscall.EOPNOTSUPP) {
    63  			//nolint
    64  			fmt.Println("Skipping test because of no msg support")
    65  
    66  			return
    67  		}
    68  	}
    69  
    70  	Equal(t, uint(3), numberOfCQEsSubmitted)
    71  
    72  	cqes := make([]*CompletionQueueEvent, 128)
    73  
    74  	numberOfCQEs := ring.PeekBatchCQE(cqes)
    75  	Equal(t, uint32(6), numberOfCQEs)
    76  
    77  	cqe := cqes[0]
    78  	Equal(t, uint64(200), cqe.UserData)
    79  	Equal(t, int32(100), cqe.Res)
    80  
    81  	cqe = cqes[1]
    82  	Equal(t, uint64(400), cqe.UserData)
    83  	Equal(t, int32(300), cqe.Res)
    84  
    85  	cqe = cqes[2]
    86  	Equal(t, uint64(600), cqe.UserData)
    87  	Equal(t, int32(500), cqe.Res)
    88  
    89  	cqe = cqes[3]
    90  	Equal(t, uint64(123), cqe.UserData)
    91  	Equal(t, int32(0), cqe.Res)
    92  
    93  	cqe = cqes[4]
    94  	Equal(t, uint64(234), cqe.UserData)
    95  	Equal(t, int32(0), cqe.Res)
    96  
    97  	cqe = cqes[5]
    98  	Equal(t, uint64(345), cqe.UserData)
    99  	Equal(t, int32(0), cqe.Res)
   100  
   101  	ring.CQAdvance(numberOfCQEs)
   102  }
   103  
   104  func TestMsgRing(t *testing.T) {
   105  	senderRing, err := CreateRing(16)
   106  	Nil(t, err)
   107  
   108  	defer senderRing.QueueExit()
   109  
   110  	receiverRing, err := CreateRing(16)
   111  	Nil(t, err)
   112  
   113  	defer receiverRing.QueueExit()
   114  
   115  	entry := senderRing.GetSQE()
   116  	NotNil(t, entry)
   117  	entry.PrepareMsgRing(receiverRing.ringFd, 100, 200, 0)
   118  
   119  	entry = senderRing.GetSQE()
   120  	NotNil(t, entry)
   121  	entry.PrepareMsgRing(receiverRing.ringFd, 300, 400, 0)
   122  
   123  	entry = senderRing.GetSQE()
   124  	NotNil(t, entry)
   125  	entry.PrepareMsgRing(receiverRing.ringFd, 500, 600, 0)
   126  
   127  	cqeNr, err := senderRing.Submit()
   128  	Nil(t, err)
   129  
   130  	if cqeNr == 1 {
   131  		cqe, cqeErr := senderRing.WaitCQE()
   132  		Nil(t, cqeErr)
   133  
   134  		if cqe.Res == -int32(syscall.EINVAL) || cqe.Res == -int32(syscall.EOPNOTSUPP) {
   135  			//nolint
   136  			fmt.Println("Skipping test because of no msg support")
   137  
   138  			return
   139  		}
   140  	}
   141  
   142  	Equal(t, uint(3), cqeNr)
   143  
   144  	cqes := make([]*CompletionQueueEvent, 128)
   145  
   146  	numberOfCQEs := receiverRing.PeekBatchCQE(cqes)
   147  	Equal(t, uint32(3), numberOfCQEs)
   148  
   149  	cqe := cqes[0]
   150  	Equal(t, uint64(200), cqe.UserData)
   151  	Equal(t, int32(100), cqe.Res)
   152  
   153  	cqe = cqes[1]
   154  	Equal(t, uint64(400), cqe.UserData)
   155  	Equal(t, int32(300), cqe.Res)
   156  
   157  	cqe = cqes[2]
   158  	Equal(t, uint64(600), cqe.UserData)
   159  	Equal(t, int32(500), cqe.Res)
   160  	receiverRing.CQAdvance(numberOfCQEs)
   161  }