github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/btfhelpers/bpfhelpers_test.go (about)

     1  // Copyright 2024 The Inspektor Gadget authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package btfhelpers
    16  
    17  import (
    18  	"reflect"
    19  	"testing"
    20  
    21  	"github.com/cilium/ebpf/btf"
    22  	"github.com/stretchr/testify/assert"
    23  )
    24  
    25  var int32Type = &btf.Int{
    26  	Encoding: btf.Signed,
    27  	Size:     4,
    28  	Name:     "int32",
    29  }
    30  
    31  func TestGetType(t *testing.T) {
    32  	t.Parallel()
    33  
    34  	tests := []struct {
    35  		name          string
    36  		typ           btf.Type
    37  		expectedType  reflect.Type
    38  		expectedNames []string
    39  	}{
    40  		{
    41  			name: "int8",
    42  			typ: &btf.Int{
    43  				Encoding: btf.Signed,
    44  				Size:     1,
    45  				Name:     "int8",
    46  			},
    47  			expectedType:  reflect.TypeOf(int8(0)),
    48  			expectedNames: []string{"int8"},
    49  		},
    50  		{
    51  			name: "int16",
    52  			typ: &btf.Int{
    53  				Encoding: btf.Signed,
    54  				Size:     2,
    55  				Name:     "int16",
    56  			},
    57  			expectedType:  reflect.TypeOf(int16(0)),
    58  			expectedNames: []string{"int16"},
    59  		},
    60  		{
    61  			name: "int32",
    62  			typ: &btf.Int{
    63  				Encoding: btf.Signed,
    64  				Size:     4,
    65  				Name:     "int32",
    66  			},
    67  			expectedType:  reflect.TypeOf(int32(0)),
    68  			expectedNames: []string{"int32"},
    69  		},
    70  		{
    71  			name: "int64",
    72  			typ: &btf.Int{
    73  				Encoding: btf.Signed,
    74  				Size:     8,
    75  				Name:     "int64",
    76  			},
    77  			expectedType:  reflect.TypeOf(int64(0)),
    78  			expectedNames: []string{"int64"},
    79  		},
    80  		{
    81  			name: "uint8",
    82  			typ: &btf.Int{
    83  				Encoding: btf.Unsigned,
    84  				Size:     1,
    85  				Name:     "uint8",
    86  			},
    87  			expectedType:  reflect.TypeOf(uint8(0)),
    88  			expectedNames: []string{"uint8"},
    89  		},
    90  		{
    91  			name: "uint16",
    92  			typ: &btf.Int{
    93  				Encoding: btf.Unsigned,
    94  				Size:     2,
    95  				Name:     "uint16",
    96  			},
    97  			expectedType:  reflect.TypeOf(uint16(0)),
    98  			expectedNames: []string{"uint16"},
    99  		},
   100  		{
   101  			name: "uint32",
   102  			typ: &btf.Int{
   103  				Encoding: btf.Unsigned,
   104  				Size:     4,
   105  				Name:     "uint32",
   106  			},
   107  			expectedType:  reflect.TypeOf(uint32(0)),
   108  			expectedNames: []string{"uint32"},
   109  		},
   110  		{
   111  			name: "uint64",
   112  			typ: &btf.Int{
   113  				Encoding: btf.Unsigned,
   114  				Size:     8,
   115  				Name:     "uint64",
   116  			},
   117  			expectedType:  reflect.TypeOf(uint64(0)),
   118  			expectedNames: []string{"uint64"},
   119  		},
   120  		{
   121  			name: "bool",
   122  			typ: &btf.Int{
   123  				Encoding: btf.Bool,
   124  				Size:     1,
   125  				Name:     "bool",
   126  			},
   127  			expectedType:  reflect.TypeOf(false),
   128  			expectedNames: []string{"bool"},
   129  		},
   130  		{
   131  			name: "char",
   132  			typ: &btf.Int{
   133  				Encoding: btf.Char,
   134  				Size:     1,
   135  				Name:     "char",
   136  			},
   137  			expectedType:  reflect.TypeOf(uint8(0)),
   138  			expectedNames: []string{"char"},
   139  		},
   140  		{
   141  			name: "float32",
   142  			typ: &btf.Float{
   143  				Size: 4,
   144  				Name: "float32",
   145  			},
   146  			expectedType:  reflect.TypeOf(float32(0)),
   147  			expectedNames: []string{"float32"},
   148  		},
   149  		{
   150  			name: "float64",
   151  			typ: &btf.Float{
   152  				Size: 8,
   153  				Name: "float64",
   154  			},
   155  			expectedType:  reflect.TypeOf(float64(0)),
   156  			expectedNames: []string{"float64"},
   157  		},
   158  		{
   159  			name: "typedef",
   160  			typ: &btf.Typedef{
   161  				Type: &btf.Int{
   162  					Encoding: btf.Signed,
   163  					Size:     4,
   164  					Name:     "int32",
   165  				},
   166  				Name: "typedef",
   167  			},
   168  			expectedType:  reflect.TypeOf(int32(0)),
   169  			expectedNames: []string{"typedef", "int32"},
   170  		},
   171  		{
   172  			name: "typedef typedef",
   173  			typ: &btf.Typedef{
   174  				Type: &btf.Typedef{
   175  					Type: int32Type,
   176  					Name: "typedef2",
   177  				},
   178  				Name: "typedef1",
   179  			},
   180  			expectedType:  reflect.TypeOf(int32(0)),
   181  			expectedNames: []string{"typedef1", "typedef2", "int32"},
   182  		},
   183  		{
   184  			name: "array",
   185  			typ: &btf.Array{
   186  				Type:   int32Type,
   187  				Nelems: 10,
   188  			},
   189  			expectedType:  reflect.ArrayOf(10, reflect.TypeOf(int32(0))),
   190  			expectedNames: []string{"int32"},
   191  		},
   192  		{
   193  			name: "array of arrays",
   194  			typ: &btf.Array{
   195  				Type: &btf.Array{
   196  					Type:   int32Type,
   197  					Nelems: 10,
   198  				},
   199  				Nelems: 10,
   200  			},
   201  			expectedType:  nil,
   202  			expectedNames: nil,
   203  		},
   204  		{
   205  			name:          "unknown",
   206  			typ:           &btf.Void{},
   207  			expectedNames: []string{},
   208  		},
   209  		{
   210  			name: "unnamed",
   211  			typ: &btf.Int{
   212  				Encoding: btf.Unsigned,
   213  				Size:     2,
   214  			},
   215  			expectedType:  reflect.TypeOf(uint16(0)),
   216  			expectedNames: []string{},
   217  		},
   218  		// TODO: checks structures
   219  	}
   220  
   221  	for _, tt := range tests {
   222  		tt := tt
   223  
   224  		t.Run(tt.name, func(t *testing.T) {
   225  			t.Parallel()
   226  			retTyp, retNames := GetType(tt.typ)
   227  			assert.Equal(t, tt.expectedType, retTyp)
   228  			assert.Equal(t, tt.expectedNames, retNames)
   229  		})
   230  	}
   231  }
   232  
   233  func TestGetUnderlyingType(t *testing.T) {
   234  	t.Parallel()
   235  
   236  	tests := []struct {
   237  		name         string
   238  		typDef       *btf.Typedef
   239  		expectedType btf.Type
   240  	}{
   241  		{
   242  			name: "typedef",
   243  			typDef: &btf.Typedef{
   244  				Type: int32Type,
   245  				Name: "typedef",
   246  			},
   247  			expectedType: int32Type,
   248  		},
   249  		{
   250  			name: "typedef typedef",
   251  			typDef: &btf.Typedef{
   252  				Type: &btf.Typedef{
   253  					Type: int32Type,
   254  					Name: "typedef",
   255  				},
   256  				Name: "typedef",
   257  			},
   258  			expectedType: int32Type,
   259  		},
   260  	}
   261  
   262  	for _, tt := range tests {
   263  		tt := tt
   264  
   265  		t.Run(tt.name, func(t *testing.T) {
   266  			t.Parallel()
   267  			retTyp := GetUnderlyingType(tt.typDef)
   268  			assert.Equal(t, tt.expectedType, retTyp)
   269  		})
   270  	}
   271  }