Files
virtual-kubelet/test/e2e/suite.go
Brian Goff 0c64171e85 Add v2 node provider for accepting status updates
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).
2020-09-17 13:52:58 -07:00

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,
}
}