github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/marshalers_test.go (about) 1 package ebpf 2 3 import ( 4 "testing" 5 6 "github.com/cilium/ebpf/internal" 7 8 "github.com/go-quicktest/qt" 9 ) 10 11 func TestMarshalUnmarshalBatchPerCPUValue(t *testing.T) { 12 const ( 13 batchLen = 3 14 elemLength = 4 15 ) 16 possibleCPU := MustPossibleCPU() 17 sliceLen := batchLen * possibleCPU 18 slice := makeFilledSlice(sliceLen) 19 buf, err := marshalBatchPerCPUValue(slice, batchLen, elemLength) 20 if err != nil { 21 t.Fatal(err) 22 } 23 output := make([]uint32, sliceLen) 24 err = unmarshalBatchPerCPUValue(output, batchLen, elemLength, buf) 25 if err != nil { 26 t.Fatal(err) 27 } 28 qt.Assert(t, qt.DeepEquals(output, slice)) 29 } 30 31 func TestMarshalBatchPerCPUValue(t *testing.T) { 32 const ( 33 batchLen = 3 34 elemLength = 4 35 ) 36 possibleCPU := MustPossibleCPU() 37 sliceLen := batchLen * possibleCPU 38 slice := makeFilledSlice(sliceLen) 39 expected := make([]byte, sliceLen*internal.Align(elemLength, 8)) 40 b := expected 41 for _, elem := range slice { 42 internal.NativeEndian.PutUint32(b, elem) 43 b = b[8:] 44 } 45 buf, err := marshalBatchPerCPUValue(slice, batchLen, elemLength) 46 qt.Assert(t, qt.IsNil(err)) 47 qt.Assert(t, qt.DeepEquals(buf, expected)) 48 49 tooSmall := slice[:len(slice)-1] 50 buf, err = marshalBatchPerCPUValue(tooSmall, batchLen, elemLength) 51 qt.Assert(t, qt.IsNotNil(err)) 52 qt.Assert(t, qt.HasLen(buf, 0)) 53 54 tooBig := append(slice, 0) 55 buf, err = marshalBatchPerCPUValue(tooBig, batchLen, elemLength) 56 qt.Assert(t, qt.IsNotNil(err)) 57 qt.Assert(t, qt.HasLen(buf, 0)) 58 } 59 60 func TestUnmarshalBatchPerCPUValue(t *testing.T) { 61 const ( 62 batchLen = 3 63 elemLength = 4 64 ) 65 possibleCPU := MustPossibleCPU() 66 outputLen := batchLen * possibleCPU 67 output := make([]uint32, outputLen) 68 expected := makeFilledSlice(batchLen * possibleCPU) 69 70 buf := make([]byte, batchLen*possibleCPU*internal.Align(elemLength, 8)) 71 b := buf 72 for _, elem := range expected { 73 internal.NativeEndian.PutUint32(b, elem) 74 b = b[8:] 75 } 76 err := unmarshalBatchPerCPUValue(output, batchLen, elemLength, buf) 77 qt.Assert(t, qt.IsNil(err)) 78 qt.Assert(t, qt.DeepEquals(output, expected)) 79 80 tooSmall := make([]uint32, outputLen-1) 81 err = unmarshalBatchPerCPUValue(tooSmall, batchLen, elemLength, buf) 82 qt.Assert(t, qt.IsNotNil(err)) 83 84 tooBig := make([]uint32, outputLen+1) 85 err = unmarshalBatchPerCPUValue(tooBig, batchLen, elemLength, buf) 86 qt.Assert(t, qt.IsNotNil(err)) 87 88 empty := make([]uint32, outputLen) 89 tooSmallBuf := buf[:len(buf)-1] 90 err = unmarshalBatchPerCPUValue(empty, batchLen, elemLength, tooSmallBuf) 91 qt.Assert(t, qt.IsNotNil(err)) 92 93 tooBigBuf := append(buf, 0) 94 err = unmarshalBatchPerCPUValue(empty, batchLen, elemLength, tooBigBuf) 95 qt.Assert(t, qt.IsNotNil(err)) 96 } 97 98 func TestUnmarshalPerCPUValue(t *testing.T) { 99 possibleCPUs := MustPossibleCPU() 100 expected := make([]uint32, possibleCPUs) 101 for i := 0; i < possibleCPUs; i++ { 102 expected[i] = uint32(1021 * (i + 1)) 103 } 104 elemLength := 4 105 106 buf := make([]byte, possibleCPUs*internal.Align(elemLength, 8)) 107 b := buf 108 for _, elem := range expected { 109 internal.NativeEndian.PutUint32(b, elem) 110 b = b[8:] 111 } 112 slice := make([]uint32, possibleCPUs) 113 err := unmarshalPerCPUValue(slice, elemLength, buf) 114 if err != nil { 115 t.Fatal(err) 116 } 117 qt.Assert(t, qt.DeepEquals(slice, expected)) 118 119 smallSlice := make([]uint32, possibleCPUs-1) 120 qt.Assert(t, qt.IsNotNil(unmarshalPerCPUValue(smallSlice, elemLength, buf))) 121 122 nilElemSlice := make([]*uint32, possibleCPUs) 123 qt.Assert(t, qt.IsNotNil(unmarshalPerCPUValue(nilElemSlice, elemLength, buf))) 124 } 125 126 func makeFilledSlice(len int) []uint32 { 127 slice := make([]uint32, len) 128 for i := range slice { 129 slice[i] = uint32(1021 * (i + 1)) 130 } 131 return slice 132 }