github.com/pawelgaczynski/giouring@v0.0.0-20230826085535-69588b89acb9/splice_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 "io" 28 "os" 29 "testing" 30 31 . "github.com/stretchr/testify/require" 32 ) 33 34 func TestSplice(t *testing.T) { 35 testNewFramework(t, ringInitParams{}, testScenario{ 36 setup: func(ctx testContext) { 37 file1, err := os.CreateTemp("", "splice_1") 38 NoError(t, err) 39 ctx["file1"] = file1 40 err = os.WriteFile(file1.Name(), []byte("test"), 0o600) 41 NoError(t, err) 42 43 file2, err := os.CreateTemp("", "splice_1") 44 NoError(t, err) 45 ctx["file2"] = file2 46 47 pipeR, pipeW, err := os.Pipe() 48 NoError(t, err) 49 ctx["pipeR"] = pipeR 50 ctx["pipeW"] = pipeW 51 }, 52 53 prepares: []func(*testing.T, testContext, *SubmissionQueueEntry){ 54 func(t *testing.T, ctx testContext, sqe *SubmissionQueueEntry) { 55 file1, ok := ctx["file1"].(*os.File) 56 True(t, ok) 57 pipeW, ok := ctx["pipeW"].(*os.File) 58 True(t, ok) 59 sqe.PrepareSplice(int(file1.Fd()), -1, int(pipeW.Fd()), -1, 4, 0) 60 sqe.UserData = 1 61 }, 62 func(t *testing.T, ctx testContext, sqe *SubmissionQueueEntry) { 63 file2, ok := ctx["file2"].(*os.File) 64 True(t, ok) 65 pipeR, ok := ctx["pipeR"].(*os.File) 66 True(t, ok) 67 sqe.PrepareSplice(int(pipeR.Fd()), -1, int(file2.Fd()), -1, 4, 0) 68 sqe.UserData = 2 69 }, 70 }, 71 72 result: func(t *testing.T, ctx testContext, cqes []*CompletionQueueEvent) { 73 for _, cqe := range cqes { 74 Contains(t, []uint64{1, 2}, cqe.UserData) 75 Equal(t, cqe.Res, int32(4)) 76 } 77 }, 78 79 assert: func(t *testing.T, ctx testContext) { 80 val, ok := ctx["file2"] 81 True(t, ok) 82 file, ok := val.(*os.File) 83 True(t, ok) 84 data, err := os.ReadFile(file.Name()) 85 Error(t, io.EOF, err) 86 Equal(t, 4, len(data)) 87 }, 88 89 cleanup: func(ctx testContext) { 90 files := []string{"file1", "file2"} 91 for i := 0; i < len(files); i++ { 92 if val, ok := ctx[files[i]]; ok { 93 file, fileOk := val.(*os.File) 94 True(t, fileOk) 95 file.Close() 96 os.Remove(file.Name()) 97 } 98 } 99 }, 100 }) 101 } 102 103 func TestTee(t *testing.T) { 104 testNewFramework(t, ringInitParams{}, testScenario{ 105 setup: func(ctx testContext) { 106 pipe1R, pipe1W, err := os.Pipe() 107 NoError(t, err) 108 ctx["pipe1R"] = pipe1R 109 ctx["pipe1W"] = pipe1W 110 111 pipe2R, pipe2W, err := os.Pipe() 112 NoError(t, err) 113 ctx["pipe2R"] = pipe2R 114 ctx["pipe2W"] = pipe2W 115 116 n, err := pipe1W.WriteString("data") 117 NoError(t, err) 118 Equal(t, 4, n) 119 }, 120 121 prepares: []func(*testing.T, testContext, *SubmissionQueueEntry){ 122 func(t *testing.T, ctx testContext, sqe *SubmissionQueueEntry) { 123 pipe1R, ok := ctx["pipe1R"].(*os.File) 124 True(t, ok) 125 pipe2W, ok := ctx["pipe2W"].(*os.File) 126 True(t, ok) 127 sqe.PrepareTee(int(pipe1R.Fd()), int(pipe2W.Fd()), 4, 0) 128 sqe.UserData = 1 129 }, 130 }, 131 132 result: func(t *testing.T, ctx testContext, cqes []*CompletionQueueEvent) { 133 for _, cqe := range cqes { 134 Equal(t, cqe.UserData, uint64(1)) 135 Equal(t, cqe.Res, int32(4)) 136 } 137 }, 138 139 assert: func(t *testing.T, ctx testContext) { 140 val, ok := ctx["pipe2R"] 141 True(t, ok) 142 file, ok := val.(*os.File) 143 True(t, ok) 144 145 data := make([]byte, 4) 146 n, err := file.Read(data) 147 Error(t, io.EOF, err) 148 Equal(t, 4, n) 149 Equal(t, "data", string(data)) 150 }, 151 152 cleanup: func(ctx testContext) { 153 files := []string{"file1", "file2"} 154 for i := 0; i < len(files); i++ { 155 if val, ok := ctx[files[i]]; ok { 156 file, fileOk := val.(*os.File) 157 True(t, fileOk) 158 file.Close() 159 os.Remove(file.Name()) 160 } 161 } 162 }, 163 }) 164 }