github.com/cilium/cilium@v1.16.2/pkg/alignchecker/alignchecker_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package alignchecker
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestAlignChecker(t *testing.T) {
    13  	type foo struct {
    14  		_ [4]uint32 `align:"$union0"`
    15  		_ uint32    `align:"$union1"`
    16  		_ uint8     `align:"family"`
    17  		_ uint8     `align:"pad4"`
    18  		_ uint16    `align:"pad5"`
    19  	}
    20  
    21  	type foo2 struct {
    22  		_ foo
    23  	}
    24  
    25  	type foo3 struct {
    26  		_ [4]uint32 `align:"$union0.ip6"`
    27  		_ uint32    `align:"$union1.p2"`
    28  		_ uint8     `align:"family"`
    29  		_ uint8     `align:"pad4"`
    30  		_ uint16    `align:"pad5"`
    31  	}
    32  
    33  	type foo4 struct {
    34  		_ uint32 `align:"$union0.$struct0.ip4"`
    35  		_ uint32 `align:"$union0.$struct0.pad1"`
    36  		_ uint32 `align:"$union0.$struct0.pad2"`
    37  		_ uint32 `align:"$union0.$struct0.pad3"`
    38  		_ uint32 `align:"$union1.p1"`
    39  		_ uint8  `align:"family"`
    40  		_ uint8  `align:"pad4"`
    41  		_ uint16 `align:"pad5"`
    42  	}
    43  
    44  	type invalidSize struct {
    45  		_ uint32
    46  	}
    47  
    48  	type invalidOffset struct {
    49  		_ [4]uint32 `align:"$union0"`
    50  		_ uint32    `align:"$union1"`
    51  		_ uint16    `align:"family"`
    52  		_ uint8     `align:"pad4"`
    53  		_ uint8     `align:"pad5"`
    54  	}
    55  
    56  	// Struct alignment value is 16 bits, so this will carry 8 bits of trailing
    57  	// padding.
    58  	type trailingPadding struct {
    59  		_ uint16
    60  		_ uint8
    61  		// _ uint8 implicit padding
    62  	}
    63  
    64  	type toCheck map[string][]any
    65  
    66  	testCases := []struct {
    67  		cName   string
    68  		goTypes []any
    69  		err     string
    70  	}{
    71  		{
    72  			"foo",
    73  			[]any{foo{}},
    74  			"",
    75  		},
    76  		{
    77  			"foo",
    78  			[]any{foo2{}},
    79  			"",
    80  		},
    81  		{
    82  			"foo",
    83  			[]any{foo{}, foo2{}},
    84  			"",
    85  		},
    86  		{
    87  			"foo",
    88  			[]any{foo3{}},
    89  			"",
    90  		},
    91  		{
    92  			"foo",
    93  			[]any{foo4{}},
    94  			"",
    95  		},
    96  		{
    97  			"foo",
    98  			[]any{invalidSize{}},
    99  			"invalidSize(4) size does not match foo(24)",
   100  		},
   101  		{
   102  			"foo",
   103  			[]any{invalidOffset{}},
   104  			"offset(22) does not match foo.pad4(21)",
   105  		},
   106  		{
   107  			"bar",
   108  			[]any{foo{}},
   109  			"not found",
   110  		},
   111  		{
   112  			"foo",
   113  			[]any{trailingPadding{}},
   114  			"implicit trailing padding",
   115  		},
   116  	}
   117  
   118  	for _, tt := range testCases {
   119  		err := CheckStructAlignments("testdata/bpf_foo.o", toCheck{tt.cName: tt.goTypes}, true)
   120  		if tt.err != "" {
   121  			assert.NotNil(t, err)
   122  			assert.Contains(t, err.Error(), tt.err)
   123  			continue
   124  		}
   125  
   126  		assert.Nil(t, err)
   127  	}
   128  }