This allows the use of a built-in provider to do things like mark a node as ready once all the controllers are spun up. The e2e tests now use this instead of waiting on the pod that the vk provider is deployed in to be marked ready (this was waiting on /stats/summary to be serving, which is racey).
123 lines
3.7 KiB
Go
123 lines
3.7 KiB
Go
package e2e
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/watch"
|
|
|
|
"github.com/virtual-kubelet/virtual-kubelet/internal/test/e2e/framework"
|
|
"github.com/virtual-kubelet/virtual-kubelet/internal/test/suite"
|
|
)
|
|
|
|
const defaultWatchTimeout = 2 * time.Minute
|
|
|
|
// f is a testing framework that is accessible across the e2e package
|
|
var f *framework.Framework
|
|
|
|
// EndToEndTestSuite holds the setup, teardown, and shouldSkipTest functions for a specific provider
|
|
type EndToEndTestSuite struct {
|
|
setup suite.SetUpFunc
|
|
teardown suite.TeardownFunc
|
|
shouldSkipTest suite.ShouldSkipTestFunc
|
|
}
|
|
|
|
// EndToEndTestSuiteConfig is the config passed to initialize the testing framework and test suite.
|
|
type EndToEndTestSuiteConfig struct {
|
|
// Kubeconfig is the path to the kubeconfig file to use when running the test suite outside a Kubernetes cluster.
|
|
Kubeconfig string
|
|
// Namespace is the name of the Kubernetes namespace to use for running the test suite (i.e. where to create pods).
|
|
Namespace string
|
|
// NodeName is the name of the virtual-kubelet node to test.
|
|
NodeName string
|
|
// WatchTimeout is the duration for which the framework watch a particular condition to be satisfied (e.g. watches a pod becoming ready)
|
|
WatchTimeout time.Duration
|
|
// Setup is a function that sets up provider-specific resource in the test suite
|
|
Setup suite.SetUpFunc
|
|
// Teardown is a function that tears down provider-specific resources from the test suite
|
|
Teardown suite.TeardownFunc
|
|
// ShouldSkipTest is a function that determines whether the test suite should skip certain tests
|
|
ShouldSkipTest suite.ShouldSkipTestFunc
|
|
}
|
|
|
|
// Setup runs the setup function from the provider and other
|
|
// procedures before running the test suite
|
|
func (ts *EndToEndTestSuite) Setup(t *testing.T) {
|
|
if err := ts.setup(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Wait for the virtual kubelet node resource to become fully ready
|
|
if err := f.WaitUntilNodeCondition(func(ev watch.Event) (bool, error) {
|
|
n := ev.Object.(*corev1.Node)
|
|
if n.Name != f.NodeName {
|
|
return false, nil
|
|
}
|
|
|
|
for _, c := range n.Status.Conditions {
|
|
if c.Type != "Ready" {
|
|
continue
|
|
}
|
|
t.Log(c.Status)
|
|
return c.Status == corev1.ConditionTrue, nil
|
|
}
|
|
|
|
return false, nil
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// Teardown runs the teardown function from the provider and other
|
|
// procedures after running the test suite
|
|
func (ts *EndToEndTestSuite) Teardown() {
|
|
if err := ts.teardown(); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// ShouldSkipTest returns true if a provider wants to skip running a particular test
|
|
func (ts *EndToEndTestSuite) ShouldSkipTest(testName string) bool {
|
|
return ts.shouldSkipTest(testName)
|
|
}
|
|
|
|
// Run runs tests registered in the test suite
|
|
func (ts *EndToEndTestSuite) Run(t *testing.T) {
|
|
suite.Run(t, ts)
|
|
}
|
|
|
|
// NewEndToEndTestSuite returns a new EndToEndTestSuite given a test suite configuration,
|
|
// setup, and teardown functions from provider
|
|
func NewEndToEndTestSuite(cfg EndToEndTestSuiteConfig) *EndToEndTestSuite {
|
|
if cfg.Namespace == "" {
|
|
panic("Empty namespace")
|
|
} else if cfg.NodeName == "" {
|
|
panic("Empty node name")
|
|
}
|
|
|
|
if cfg.WatchTimeout == time.Duration(0) {
|
|
cfg.WatchTimeout = defaultWatchTimeout
|
|
}
|
|
|
|
f = framework.NewTestingFramework(cfg.Kubeconfig, cfg.Namespace, cfg.NodeName, cfg.WatchTimeout)
|
|
|
|
emptyFunc := func() error { return nil }
|
|
if cfg.Setup == nil {
|
|
cfg.Setup = emptyFunc
|
|
}
|
|
if cfg.Teardown == nil {
|
|
cfg.Teardown = emptyFunc
|
|
}
|
|
if cfg.ShouldSkipTest == nil {
|
|
// This will not skip any test in the test suite
|
|
cfg.ShouldSkipTest = func(_ string) bool { return false }
|
|
}
|
|
|
|
return &EndToEndTestSuite{
|
|
setup: cfg.Setup,
|
|
teardown: cfg.Teardown,
|
|
shouldSkipTest: cfg.ShouldSkipTest,
|
|
}
|
|
}
|