Source file src/crypto/internal/cryptotest/implementations.go

     1  // Copyright 2024 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package cryptotest
     6  
     7  import (
     8  	"crypto/internal/boring"
     9  	"crypto/internal/impl"
    10  	"internal/goarch"
    11  	"internal/goos"
    12  	"internal/testenv"
    13  	"strings"
    14  	"testing"
    15  )
    16  
    17  // TestAllImplementations runs the provided test function with each available
    18  // implementation of the package registered with crypto/internal/impl. If there
    19  // are no alternative implementations for pkg, f is invoked directly once.
    20  func TestAllImplementations(t *testing.T, pkg string, f func(t *testing.T)) {
    21  	// BoringCrypto bypasses the multiple Go implementations.
    22  	if boring.Enabled {
    23  		f(t)
    24  		return
    25  	}
    26  
    27  	impls := impl.List(pkg)
    28  	if len(impls) == 0 {
    29  		f(t)
    30  		return
    31  	}
    32  
    33  	t.Cleanup(func() { impl.Reset(pkg) })
    34  
    35  	for _, name := range impls {
    36  		if available := impl.Select(pkg, name); available {
    37  			t.Run(name, f)
    38  		} else {
    39  			t.Run(name, func(t *testing.T) {
    40  				// Report an error if we're on the most capable builder for the
    41  				// architecture and the builder can't test this implementation.
    42  				if flagshipBuilder() {
    43  					t.Error("builder doesn't support CPU features needed to test this implementation")
    44  				} else {
    45  					t.Skip("implementation not supported")
    46  				}
    47  			})
    48  		}
    49  	}
    50  
    51  	// Test the generic implementation.
    52  	impl.Select(pkg, "")
    53  	t.Run("Base", f)
    54  }
    55  
    56  func flagshipBuilder() bool {
    57  	builder := testenv.Builder()
    58  	if builder == "" {
    59  		return false
    60  	}
    61  	switch goarch.GOARCH {
    62  	case "amd64":
    63  		return strings.Contains(builder, "_avx512")
    64  	case "arm64":
    65  		// Apple M chips support everything we use.
    66  		return goos.GOOS == "darwin"
    67  	default:
    68  		// Presumably the Linux builders are the most capable.
    69  		return goos.GOOS == "linux"
    70  	}
    71  }
    72  

View as plain text