mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 16:29:21 +00:00
ktesting: add Run
This is useful in Go unit tests because it directly replaces the corresponding testing.T/B.Run.
This commit is contained in:
parent
c2ad724e9a
commit
f9e7b15c00
@ -86,6 +86,10 @@ func (cCtx clientContext) ExpectNoError(err error, explain ...interface{}) {
|
|||||||
expectNoError(cCtx, err, explain...)
|
expectNoError(cCtx, err, explain...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cCtx clientContext) Run(name string, cb func(tCtx TContext)) bool {
|
||||||
|
return run(cCtx, name, cb)
|
||||||
|
}
|
||||||
|
|
||||||
func (cCtx clientContext) Logger() klog.Logger {
|
func (cCtx clientContext) Logger() klog.Logger {
|
||||||
return klog.FromContext(cCtx)
|
return klog.FromContext(cCtx)
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,10 @@ func (eCtx *errorContext) ExpectNoError(err error, explain ...interface{}) {
|
|||||||
expectNoError(eCtx, err, explain...)
|
expectNoError(eCtx, err, explain...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cCtx *errorContext) Run(name string, cb func(tCtx TContext)) bool {
|
||||||
|
return run(cCtx, name, cb)
|
||||||
|
}
|
||||||
|
|
||||||
func (eCtx *errorContext) Logger() klog.Logger {
|
func (eCtx *errorContext) Logger() klog.Logger {
|
||||||
return klog.FromContext(eCtx)
|
return klog.FromContext(eCtx)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
@ -84,6 +85,13 @@ type TContext interface {
|
|||||||
// a single test never run in parallel with each other.
|
// a single test never run in parallel with each other.
|
||||||
Parallel()
|
Parallel()
|
||||||
|
|
||||||
|
// Run runs f as a subtest of t called name. It blocks until f returns or
|
||||||
|
// calls t.Parallel to become a parallel test.
|
||||||
|
//
|
||||||
|
// Only supported in Go unit tests or benchmarks. It fails the current
|
||||||
|
// test when called elsewhere.
|
||||||
|
Run(name string, f func(tCtx TContext)) bool
|
||||||
|
|
||||||
// Cancel can be invoked to cancel the context before the test is completed.
|
// Cancel can be invoked to cancel the context before the test is completed.
|
||||||
// Tests which use the context to control goroutines and then wait for
|
// Tests which use the context to control goroutines and then wait for
|
||||||
// termination of those goroutines must call Cancel to avoid a deadlock.
|
// termination of those goroutines must call Cancel to avoid a deadlock.
|
||||||
@ -174,6 +182,7 @@ type TContext interface {
|
|||||||
// - CleanupCtx
|
// - CleanupCtx
|
||||||
// - Expect
|
// - Expect
|
||||||
// - ExpectNoError
|
// - ExpectNoError
|
||||||
|
// - Run
|
||||||
// - Logger
|
// - Logger
|
||||||
//
|
//
|
||||||
// Usually these methods would be stand-alone functions with a TContext
|
// Usually these methods would be stand-alone functions with a TContext
|
||||||
@ -337,6 +346,9 @@ func InitCtx(ctx context.Context, tb TB, _ ...InitOption) TContext {
|
|||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// WithTB sets up cancellation for the sub-test.
|
// WithTB sets up cancellation for the sub-test.
|
||||||
|
//
|
||||||
|
// A simpler API is to use TContext.Run as replacement
|
||||||
|
// for [testing.T.Run].
|
||||||
func WithTB(parentCtx TContext, tb TB) TContext {
|
func WithTB(parentCtx TContext, tb TB) TContext {
|
||||||
tCtx := InitCtx(parentCtx, tb)
|
tCtx := InitCtx(parentCtx, tb)
|
||||||
tCtx = WithCancel(tCtx)
|
tCtx = WithCancel(tCtx)
|
||||||
@ -350,6 +362,27 @@ func WithTB(parentCtx TContext, tb TB) TContext {
|
|||||||
return tCtx
|
return tCtx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// run implements the different Run methods. It's not an exported
|
||||||
|
// method because tCtx.Run is more discoverable (same usage as
|
||||||
|
// with normal Go).
|
||||||
|
func run(tCtx TContext, name string, cb func(tCtx TContext)) bool {
|
||||||
|
tCtx.Helper()
|
||||||
|
switch tb := tCtx.TB().(type) {
|
||||||
|
case interface {
|
||||||
|
Run(string, func(t *testing.T)) bool
|
||||||
|
}:
|
||||||
|
return tb.Run(name, func(t *testing.T) { cb(WithTB(tCtx, t)) })
|
||||||
|
case interface {
|
||||||
|
Run(string, func(t *testing.B)) bool
|
||||||
|
}:
|
||||||
|
return tb.Run(name, func(b *testing.B) { cb(WithTB(tCtx, b)) })
|
||||||
|
default:
|
||||||
|
tCtx.Fatalf("Run not implemented, underlying %T does not support it", tCtx.TB())
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// WithContext constructs a new TContext with a different Context instance.
|
// WithContext constructs a new TContext with a different Context instance.
|
||||||
// This can be used in callbacks which receive a Context, for example
|
// This can be used in callbacks which receive a Context, for example
|
||||||
// from Gomega:
|
// from Gomega:
|
||||||
@ -439,6 +472,10 @@ func cleanupCtx(tCtx TContext, cb func(TContext)) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cCtx tContext) Run(name string, cb func(tCtx TContext)) bool {
|
||||||
|
return run(cCtx, name, cb)
|
||||||
|
}
|
||||||
|
|
||||||
func (tCtx tContext) Logger() klog.Logger {
|
func (tCtx tContext) Logger() klog.Logger {
|
||||||
return klog.FromContext(tCtx)
|
return klog.FromContext(tCtx)
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,33 @@ func TestWithTB(t *testing.T) {
|
|||||||
assert.Equal(t, apiextensions, tCtx.APIExtensions(), "APIExtensions")
|
assert.Equal(t, apiextensions, tCtx.APIExtensions(), "APIExtensions")
|
||||||
|
|
||||||
tCtx.Cancel("test is complete")
|
tCtx.Cancel("test is complete")
|
||||||
|
<-tCtx.Done()
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := tCtx.Err(); err != nil {
|
||||||
|
t.Errorf("parent TContext should not have been cancelled: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRun(t *testing.T) {
|
||||||
|
tCtx := ktesting.Init(t)
|
||||||
|
|
||||||
|
cfg := new(rest.Config)
|
||||||
|
mapper := new(restmapper.DeferredDiscoveryRESTMapper)
|
||||||
|
client := clientset.New(nil)
|
||||||
|
dynamic := dynamic.New(nil)
|
||||||
|
apiextensions := apiextensions.New(nil)
|
||||||
|
tCtx = ktesting.WithClients(tCtx, cfg, mapper, client, dynamic, apiextensions)
|
||||||
|
|
||||||
|
tCtx.Run("sub", func(tCtx ktesting.TContext) {
|
||||||
|
assert.Equal(t, cfg, tCtx.RESTConfig(), "RESTConfig")
|
||||||
|
assert.Equal(t, mapper, tCtx.RESTMapper(), "RESTMapper")
|
||||||
|
assert.Equal(t, client, tCtx.Client(), "Client")
|
||||||
|
assert.Equal(t, dynamic, tCtx.Dynamic(), "Dynamic")
|
||||||
|
assert.Equal(t, apiextensions, tCtx.APIExtensions(), "APIExtensions")
|
||||||
|
|
||||||
|
tCtx.Cancel("test is complete")
|
||||||
|
<-tCtx.Done()
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := tCtx.Err(); err != nil {
|
if err := tCtx.Err(); err != nil {
|
||||||
|
@ -102,6 +102,10 @@ func (wCtx withContext) ExpectNoError(err error, explain ...interface{}) {
|
|||||||
expectNoError(wCtx, err, explain...)
|
expectNoError(wCtx, err, explain...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cCtx withContext) Run(name string, cb func(tCtx TContext)) bool {
|
||||||
|
return run(cCtx, name, cb)
|
||||||
|
}
|
||||||
|
|
||||||
func (wCtx withContext) Logger() klog.Logger {
|
func (wCtx withContext) Logger() klog.Logger {
|
||||||
return klog.FromContext(wCtx)
|
return klog.FromContext(wCtx)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user