
In particular ExpectNoError needed testing, as it was unused so far and not functional in its initial implementation.
102 lines
3.0 KiB
Go
102 lines
3.0 KiB
Go
/*
|
|
Copyright 2024 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package ktesting
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"k8s.io/klog/v2"
|
|
)
|
|
|
|
// WithStep creates a context where a prefix is added to all errors and log
|
|
// messages, similar to how errors are wrapped. This can be nested, leaving a
|
|
// trail of "bread crumbs" that help figure out where in a test some problem
|
|
// occurred or why some log output gets written:
|
|
//
|
|
// ERROR: bake cake: set heat for baking: oven not found
|
|
//
|
|
// The string should describe the operation that is about to happen ("starting
|
|
// the controller", "list items") or what is being operated on ("HTTP server").
|
|
// Multiple different prefixes get concatenated with a colon.
|
|
func WithStep(tCtx TContext, what string) TContext {
|
|
sCtx := &stepContext{
|
|
TContext: tCtx,
|
|
what: what,
|
|
}
|
|
return WithLogger(sCtx, klog.LoggerWithName(sCtx.Logger(), what))
|
|
}
|
|
|
|
type stepContext struct {
|
|
TContext
|
|
what string
|
|
}
|
|
|
|
func (sCtx *stepContext) Log(args ...any) {
|
|
sCtx.Helper()
|
|
sCtx.TContext.Log(sCtx.what + ": " + strings.TrimSpace(fmt.Sprintln(args...)))
|
|
}
|
|
|
|
func (sCtx *stepContext) Logf(format string, args ...any) {
|
|
sCtx.Helper()
|
|
sCtx.TContext.Log(sCtx.what + ": " + strings.TrimSpace(fmt.Sprintf(format, args...)))
|
|
}
|
|
|
|
func (sCtx *stepContext) Error(args ...any) {
|
|
sCtx.Helper()
|
|
sCtx.TContext.Error(sCtx.what + ": " + strings.TrimSpace(fmt.Sprintln(args...)))
|
|
}
|
|
|
|
func (sCtx *stepContext) Errorf(format string, args ...any) {
|
|
sCtx.Helper()
|
|
sCtx.TContext.Error(sCtx.what + ": " + strings.TrimSpace(fmt.Sprintf(format, args...)))
|
|
}
|
|
|
|
func (sCtx *stepContext) Fatal(args ...any) {
|
|
sCtx.Helper()
|
|
sCtx.TContext.Fatal(sCtx.what + ": " + strings.TrimSpace(fmt.Sprintln(args...)))
|
|
}
|
|
|
|
func (sCtx *stepContext) Fatalf(format string, args ...any) {
|
|
sCtx.Helper()
|
|
sCtx.TContext.Fatal(sCtx.what + ": " + strings.TrimSpace(fmt.Sprintf(format, args...)))
|
|
}
|
|
|
|
// Value intercepts a search for the special "GINKGO_SPEC_CONTEXT".
|
|
func (sCtx *stepContext) Value(key any) any {
|
|
if s, ok := key.(string); ok && s == ginkgoSpecContextKey {
|
|
if reporter, ok := sCtx.TContext.Value(key).(ginkgoReporter); ok {
|
|
return ginkgoReporter(&stepReporter{reporter: reporter, what: sCtx.what})
|
|
}
|
|
}
|
|
return sCtx.TContext.Value(key)
|
|
}
|
|
|
|
type stepReporter struct {
|
|
reporter ginkgoReporter
|
|
what string
|
|
}
|
|
|
|
var _ ginkgoReporter = &stepReporter{}
|
|
|
|
func (s *stepReporter) AttachProgressReporter(reporter func() string) func() {
|
|
return s.reporter.AttachProgressReporter(func() string {
|
|
report := reporter()
|
|
return s.what + ": " + report
|
|
})
|
|
}
|