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