func pkgPath(t Logger) (string, error) {
	_, thisFile, _, ok := runtime.Caller(0)
	if !ok {
		return "", fmt.Errorf("failed to get current file")
	}
	pkgPath := filepath.Dir(thisFile)
	if testSrcdir, testWorkspace := os.Getenv("TEST_SRCDIR"), os.Getenv("TEST_WORKSPACE"); testSrcdir != "" && testWorkspace != "" {
		t.Logf("Detected bazel env varaiables: TEST_SRCDIR=%q TEST_WORKSPACE=%q", testSrcdir, testWorkspace)
		pkgPath = filepath.Join(testSrcdir, testWorkspace, pkgPath)
	}
	if !filepath.IsAbs(pkgPath) {
		return "", fmt.Errorf("can't construct an absolute path from %q", pkgPath)
	}
	t.Logf("Resolved testserver package path to: %q", pkgPath)
	return pkgPath, nil
}
pkgPath returns the absolute file path to this package's directory. With go
test, we can just look at the runtime call stack. However, bazel compiles go
binaries with the -trimpath option so the simple approach fails however we
can consult environment variables to derive the path.

The approach taken here works for both go test and bazel on the assumption
that if and only if trimpath is passed, we are running under bazel.
package testing
import (
	"context"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"runtime"
	"time"
	"github.com/spf13/pflag"
	"k8s.io/apiextensions-apiserver/pkg/cmd/server/options"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/apiserver/pkg/registry/generic/registry"
	genericapiserver "k8s.io/apiserver/pkg/server"
	"k8s.io/apiserver/pkg/storage/storagebackend"
	"k8s.io/client-go/kubernetes"
	restclient "k8s.io/client-go/rest"
)
type TearDownFunc func()
type TestServerInstanceOptions struct {
	DisableStorageCleanup bool
}
type TestServer struct {
	ClientConfig *restclient.Config                               
	ServerOpts   *options.CustomResourceDefinitionsServerOptions  
	TearDownFn   TearDownFunc                                     
	TmpDir       string                                           
}
type Logger interface {
	Errorf(format string, args ...interface{})
	Fatalf(format string, args ...interface{})
	Logf(format string, args ...interface{})
}
func NewDefaultTestServerOptions() *TestServerInstanceOptions {
	return &TestServerInstanceOptions{
		DisableStorageCleanup: false,
	}
}
func StartTestServer(t Logger, instanceOptions *TestServerInstanceOptions, customFlags []string, storageConfig *storagebackend.Config) (result TestServer, err error) {
	if instanceOptions == nil {
		instanceOptions = NewDefaultTestServerOptions()
	}
	if !instanceOptions.DisableStorageCleanup {
		registry.TrackStorageCleanup()
	}
	stopCh := make(chan struct{})
	tearDown := func() {
		if !instanceOptions.DisableStorageCleanup {
			registry.CleanupStorage()
		}
		close(stopCh)
		if len(result.TmpDir) != 0 {
			os.RemoveAll(result.TmpDir)
		}
	}
	defer func() {
		if result.TearDownFn == nil {
			tearDown()
		}
	}()
	result.TmpDir, err = ioutil.TempDir("", "apiextensions-apiserver")
	if err != nil {
		return result, fmt.Errorf("failed to create temp dir: %v", err)
	}
	fs := pflag.NewFlagSet("test", pflag.PanicOnError)
	s := options.NewCustomResourceDefinitionsServerOptions(os.Stdout, os.Stderr)
	s.AddFlags(fs)
	s.RecommendedOptions.SecureServing.Listener, s.RecommendedOptions.SecureServing.BindPort, err = createLocalhostListenerOnFreePort()
	if err != nil {
		return result, fmt.Errorf("failed to create listener: %v", err)
	}
	s.RecommendedOptions.SecureServing.ServerCert.CertDirectory = result.TmpDir
	s.RecommendedOptions.SecureServing.ExternalAddress = s.RecommendedOptions.SecureServing.Listener.Addr().(*net.TCPAddr).IP  
	pkgPath, err := pkgPath(t)
	if err != nil {
		return result, err
	}
	s.RecommendedOptions.SecureServing.ServerCert.FixtureDirectory = filepath.Join(pkgPath, "testdata")
	if storageConfig != nil {
		s.RecommendedOptions.Etcd.StorageConfig = *storageConfig
	}
	s.APIEnablement.RuntimeConfig.Set("api/all=true")
	fs.Parse(customFlags)
	if err := s.Complete(); err != nil {
		return result, fmt.Errorf("failed to set default options: %v", err)
	}
	if err := s.Validate(); err != nil {
		return result, fmt.Errorf("failed to validate options: %v", err)
	}
	t.Logf("runtime-config=%v", s.APIEnablement.RuntimeConfig)
	t.Logf("Starting apiextensions-apiserver on port %d...", s.RecommendedOptions.SecureServing.BindPort)
	config, err := s.Config()
	if err != nil {
		return result, fmt.Errorf("failed to create config from options: %v", err)
	}
	server, err := config.Complete().New(genericapiserver.NewEmptyDelegate())
	if err != nil {
		return result, fmt.Errorf("failed to create server: %v", err)
	}
	errCh := make(chan error)
	go func(stopCh <-chan struct{}) {
		if err := server.GenericAPIServer.PrepareRun().Run(stopCh); err != nil {
			errCh <- err
		}
	}(stopCh)
	t.Logf("Waiting for /healthz to be ok...")
	client, err := kubernetes.NewForConfig(server.GenericAPIServer.LoopbackClientConfig)
	if err != nil {
		return result, fmt.Errorf("failed to create a client: %v", err)
	}
	err = wait.Poll(100*time.Millisecond, time.Minute, func() (bool, error) {
		select {
		case err := <-errCh:
			return false, err
		default:
		}
		result := client.CoreV1().RESTClient().Get().AbsPath("/healthz").Do(context.TODO())
		status := 0
		result.StatusCode(&status)
		if status == 200 {
			return true, nil
		}
		return false, nil
	})
	if err != nil {
		return result, fmt.Errorf("failed to wait for /healthz to return ok: %v", err)
	}
	result.ClientConfig = server.GenericAPIServer.LoopbackClientConfig
	result.ServerOpts = s
	result.TearDownFn = tearDown
	return result, nil
}
func StartTestServerOrDie(t Logger, instanceOptions *TestServerInstanceOptions, flags []string, storageConfig *storagebackend.Config) *TestServer {
	result, err := StartTestServer(t, instanceOptions, flags, storageConfig)
	if err == nil {
		return &result
	}
	t.Fatalf("failed to launch server: %v", err)
	return nil
}
func createLocalhostListenerOnFreePort() (net.Listener, int, error) {
	ln, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return nil, 0, err
	}
	tcpAddr, ok := ln.Addr().(*net.TCPAddr)
	if !ok {
		ln.Close()
		return nil, 0, fmt.Errorf("invalid listen address: %q", ln.Addr().String())
	}
	return ln, tcpAddr.Port, nil
}