github.com/cilium/ebpf@v0.15.0/internal/testutils/feature.go (about) 1 package testutils 2 3 import ( 4 "errors" 5 "os" 6 "strings" 7 "testing" 8 9 "github.com/cilium/ebpf/internal" 10 ) 11 12 const ( 13 ignoreKernelVersionEnvVar = "EBPF_TEST_IGNORE_KERNEL_VERSION" 14 ) 15 16 func CheckFeatureTest(t *testing.T, fn func() error) { 17 checkFeatureTestError(t, fn()) 18 } 19 20 func checkFeatureTestError(t *testing.T, err error) { 21 if err == nil { 22 return 23 } 24 25 var ufe *internal.UnsupportedFeatureError 26 if errors.As(err, &ufe) { 27 if ignoreKernelVersionCheck(t.Name()) { 28 t.Skipf("Ignoring error due to %s: %s", ignoreKernelVersionEnvVar, ufe.Error()) 29 } else { 30 checkKernelVersion(t, ufe) 31 } 32 } else { 33 t.Error("Feature test failed:", err) 34 } 35 } 36 37 func CheckFeatureMatrix[K comparable](t *testing.T, fm internal.FeatureMatrix[K]) { 38 t.Helper() 39 40 for key, ft := range fm { 41 t.Run(ft.Name, func(t *testing.T) { 42 checkFeatureTestError(t, fm.Result(key)) 43 }) 44 } 45 } 46 47 func SkipIfNotSupported(tb testing.TB, err error) { 48 tb.Helper() 49 50 if err == internal.ErrNotSupported { 51 tb.Fatal("Unwrapped ErrNotSupported") 52 } 53 54 var ufe *internal.UnsupportedFeatureError 55 if errors.As(err, &ufe) { 56 checkKernelVersion(tb, ufe) 57 tb.Skip(ufe.Error()) 58 } 59 if errors.Is(err, internal.ErrNotSupported) { 60 tb.Skip(err.Error()) 61 } 62 } 63 64 func checkKernelVersion(tb testing.TB, ufe *internal.UnsupportedFeatureError) { 65 if ufe.MinimumVersion.Unspecified() { 66 return 67 } 68 69 if !isKernelLessThan(tb, ufe.MinimumVersion) { 70 tb.Helper() 71 tb.Fatalf("Feature '%s' isn't supported even though kernel is newer than %s", 72 ufe.Name, ufe.MinimumVersion) 73 } 74 } 75 76 func SkipOnOldKernel(tb testing.TB, minVersion, feature string) { 77 tb.Helper() 78 79 if IsKernelLessThan(tb, minVersion) { 80 tb.Skipf("Test requires at least kernel %s (due to missing %s)", minVersion, feature) 81 } 82 } 83 84 func IsKernelLessThan(tb testing.TB, minVersion string) bool { 85 tb.Helper() 86 87 minv, err := internal.NewVersion(minVersion) 88 if err != nil { 89 tb.Fatalf("Invalid version %s: %s", minVersion, err) 90 } 91 92 return isKernelLessThan(tb, minv) 93 } 94 95 func isKernelLessThan(tb testing.TB, minv internal.Version) bool { 96 tb.Helper() 97 98 if max := os.Getenv("CI_MAX_KERNEL_VERSION"); max != "" { 99 maxv, err := internal.NewVersion(max) 100 if err != nil { 101 tb.Fatalf("Invalid version %q in CI_MAX_KERNEL_VERSION: %s", max, err) 102 } 103 104 if maxv.Less(minv) { 105 tb.Fatalf("Test for %s will never execute on CI since %s is the most recent kernel", minv, maxv) 106 } 107 } 108 109 return kernelVersion(tb).Less(minv) 110 } 111 112 func kernelVersion(tb testing.TB) internal.Version { 113 tb.Helper() 114 115 v, err := internal.KernelVersion() 116 if err != nil { 117 tb.Fatal(err) 118 } 119 return v 120 } 121 122 // ignoreKernelVersionCheck checks if test name should be ignored for kernel version check by checking against environment var EBPF_TEST_IGNORE_KERNEL_VERSION. 123 // EBPF_TEST_IGNORE_KERNEL_VERSION is a comma (,) separated list of test names for which kernel version check should be ignored. 124 // 125 // eg: EBPF_TEST_IGNORE_KERNEL_VERSION=TestABC,TestXYZ 126 func ignoreKernelVersionCheck(tName string) bool { 127 tNames := os.Getenv(ignoreKernelVersionEnvVar) 128 if tNames == "" { 129 return false 130 } 131 132 ignored := strings.Split(tNames, ",") 133 for _, n := range ignored { 134 if strings.TrimSpace(n) == tName { 135 return true 136 } 137 } 138 return false 139 }