mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-11 21:12:07 +00:00
Merge pull request #117108 from pohly/test-integration-race-detection-component-base-logs
component-base/logs: improve handling of re-applying a configuration
This commit is contained in:
commit
e5efa0a5ee
@ -42,6 +42,7 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/util/cert"
|
"k8s.io/client-go/util/cert"
|
||||||
|
logsapi "k8s.io/component-base/logs/api/v1"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"k8s.io/kube-aggregator/pkg/apiserver"
|
"k8s.io/kube-aggregator/pkg/apiserver"
|
||||||
|
|
||||||
@ -51,6 +52,13 @@ import (
|
|||||||
testutil "k8s.io/kubernetes/test/utils"
|
testutil "k8s.io/kubernetes/test/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// If instantiated more than once or together with other servers, the
|
||||||
|
// servers would try to modify the global logging state. This must get
|
||||||
|
// ignored during testing.
|
||||||
|
logsapi.ReapplyHandling = logsapi.ReapplyHandlingIgnoreUnchanged
|
||||||
|
}
|
||||||
|
|
||||||
// This key is for testing purposes only and is not considered secure.
|
// This key is for testing purposes only and is not considered secure.
|
||||||
const ecdsaPrivateKey = `-----BEGIN EC PRIVATE KEY-----
|
const ecdsaPrivateKey = `-----BEGIN EC PRIVATE KEY-----
|
||||||
MHcCAQEEIEZmTmUhuanLjPA2CLquXivuwBDHTt5XYwgIr/kA1LtRoAoGCCqGSM49
|
MHcCAQEEIEZmTmUhuanLjPA2CLquXivuwBDHTt5XYwgIr/kA1LtRoAoGCCqGSM49
|
||||||
|
@ -28,14 +28,21 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
|
logsapi "k8s.io/component-base/logs/api/v1"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app"
|
"k8s.io/kubernetes/cmd/kube-controller-manager/app"
|
||||||
kubecontrollerconfig "k8s.io/kubernetes/cmd/kube-controller-manager/app/config"
|
kubecontrollerconfig "k8s.io/kubernetes/cmd/kube-controller-manager/app/config"
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// If instantiated more than once or together with other servers, the
|
||||||
|
// servers would try to modify the global logging state. This must get
|
||||||
|
// ignored during testing.
|
||||||
|
logsapi.ReapplyHandling = logsapi.ReapplyHandlingIgnoreUnchanged
|
||||||
|
}
|
||||||
|
|
||||||
// TearDownFunc is to be called to tear down a test server.
|
// TearDownFunc is to be called to tear down a test server.
|
||||||
type TearDownFunc func()
|
type TearDownFunc func()
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/component-base/configz"
|
"k8s.io/component-base/configz"
|
||||||
|
logsapi "k8s.io/component-base/logs/api/v1"
|
||||||
"k8s.io/kubernetes/cmd/kube-scheduler/app"
|
"k8s.io/kubernetes/cmd/kube-scheduler/app"
|
||||||
kubeschedulerconfig "k8s.io/kubernetes/cmd/kube-scheduler/app/config"
|
kubeschedulerconfig "k8s.io/kubernetes/cmd/kube-scheduler/app/config"
|
||||||
"k8s.io/kubernetes/cmd/kube-scheduler/app/options"
|
"k8s.io/kubernetes/cmd/kube-scheduler/app/options"
|
||||||
@ -36,6 +37,13 @@ import (
|
|||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// If instantiated more than once or together with other servers, the
|
||||||
|
// servers would try to modify the global logging state. This must get
|
||||||
|
// ignored during testing.
|
||||||
|
logsapi.ReapplyHandling = logsapi.ReapplyHandlingIgnoreUnchanged
|
||||||
|
}
|
||||||
|
|
||||||
// TearDownFunc is to be called to tear down a test server.
|
// TearDownFunc is to be called to tear down a test server.
|
||||||
type TearDownFunc func()
|
type TearDownFunc func()
|
||||||
|
|
||||||
|
@ -34,9 +34,17 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
|
logsapi "k8s.io/component-base/logs/api/v1"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// If instantiated more than once or together with other servers, the
|
||||||
|
// servers would try to modify the global logging state. This must get
|
||||||
|
// ignored during testing.
|
||||||
|
logsapi.ReapplyHandling = logsapi.ReapplyHandlingIgnoreUnchanged
|
||||||
|
}
|
||||||
|
|
||||||
// TearDownFunc is to be called to tear down a test server.
|
// TearDownFunc is to be called to tear down a test server.
|
||||||
type TearDownFunc func()
|
type TearDownFunc func()
|
||||||
|
|
||||||
|
@ -34,9 +34,26 @@ import (
|
|||||||
"k8s.io/cloud-provider/names"
|
"k8s.io/cloud-provider/names"
|
||||||
"k8s.io/cloud-provider/options"
|
"k8s.io/cloud-provider/options"
|
||||||
cliflag "k8s.io/component-base/cli/flag"
|
cliflag "k8s.io/component-base/cli/flag"
|
||||||
|
logsapi "k8s.io/component-base/logs/api/v1"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// If instantiated more than once or together with other servers, the
|
||||||
|
// servers would try to modify the global logging state. This must get
|
||||||
|
// ignored during testing.
|
||||||
|
logsapi.ReapplyHandling = logsapi.ReapplyHandlingIgnoreUnchanged
|
||||||
|
|
||||||
|
// Because the test server gets started after other goroutines are
|
||||||
|
// running already, we also have to initialize logging here when
|
||||||
|
// those goroutines are not running yet. This works because the
|
||||||
|
// test server uses the default config.
|
||||||
|
config := logsapi.NewLoggingConfiguration()
|
||||||
|
if err := logsapi.ValidateAndApply(config, nil); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TearDownFunc is to be called to tear down a test server.
|
// TearDownFunc is to be called to tear down a test server.
|
||||||
type TearDownFunc func()
|
type TearDownFunc func()
|
||||||
|
|
||||||
|
@ -17,14 +17,17 @@ limitations under the License.
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
@ -57,6 +60,24 @@ func NewLoggingConfiguration() *LoggingConfiguration {
|
|||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Applying configurations multiple times is not safe unless it's guaranteed that there
|
||||||
|
// are no goroutines which might call logging functions. The default for ValidateAndApply
|
||||||
|
// and ValidateAndApplyWithOptions is to return an error when called more than once.
|
||||||
|
// Binaries and unit tests can override that behavior.
|
||||||
|
var ReapplyHandling = ReapplyHandlingError
|
||||||
|
|
||||||
|
type ReapplyHandlingType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ReapplyHandlingError is the default: calling ValidateAndApply or
|
||||||
|
// ValidateAndApplyWithOptions again returns an error.
|
||||||
|
ReapplyHandlingError ReapplyHandlingType = iota
|
||||||
|
// ReapplyHandlingIgnoreUnchanged silently ignores any additional calls of
|
||||||
|
// ValidateAndApply or ValidateAndApplyWithOptions if the configuration
|
||||||
|
// is unchanged, otherwise they return an error.
|
||||||
|
ReapplyHandlingIgnoreUnchanged
|
||||||
|
)
|
||||||
|
|
||||||
// ValidateAndApply combines validation and application of the logging configuration.
|
// ValidateAndApply combines validation and application of the logging configuration.
|
||||||
// This should be invoked as early as possible because then the rest of the program
|
// This should be invoked as early as possible because then the rest of the program
|
||||||
// startup (including validation of other options) will already run with the final
|
// startup (including validation of other options) will already run with the final
|
||||||
@ -64,6 +85,10 @@ func NewLoggingConfiguration() *LoggingConfiguration {
|
|||||||
//
|
//
|
||||||
// The optional FeatureGate controls logging features. If nil, the default for
|
// The optional FeatureGate controls logging features. If nil, the default for
|
||||||
// these features is used.
|
// these features is used.
|
||||||
|
//
|
||||||
|
// Logging options must be applied as early as possible during the program
|
||||||
|
// startup. Some changes are global and cannot be done safely when there are
|
||||||
|
// already goroutines running.
|
||||||
func ValidateAndApply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error {
|
func ValidateAndApply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error {
|
||||||
return validateAndApply(c, nil, featureGate, nil)
|
return validateAndApply(c, nil, featureGate, nil)
|
||||||
}
|
}
|
||||||
@ -71,6 +96,10 @@ func ValidateAndApply(c *LoggingConfiguration, featureGate featuregate.FeatureGa
|
|||||||
// ValidateAndApplyWithOptions is a variant of ValidateAndApply which accepts
|
// ValidateAndApplyWithOptions is a variant of ValidateAndApply which accepts
|
||||||
// additional options beyond those that can be configured through the API. This
|
// additional options beyond those that can be configured through the API. This
|
||||||
// is meant for testing.
|
// is meant for testing.
|
||||||
|
//
|
||||||
|
// Logging options must be applied as early as possible during the program
|
||||||
|
// startup. Some changes are global and cannot be done safely when there are
|
||||||
|
// already goroutines running.
|
||||||
func ValidateAndApplyWithOptions(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate) error {
|
func ValidateAndApplyWithOptions(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate) error {
|
||||||
return validateAndApply(c, options, featureGate, nil)
|
return validateAndApply(c, options, featureGate, nil)
|
||||||
}
|
}
|
||||||
@ -183,10 +212,30 @@ func featureEnabled(featureGate featuregate.FeatureGate, feature featuregate.Fea
|
|||||||
}
|
}
|
||||||
|
|
||||||
func apply(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate) error {
|
func apply(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate) error {
|
||||||
contextualLoggingEnabled := contextualLoggingDefault
|
p := ¶meters{
|
||||||
if featureGate != nil {
|
C: c,
|
||||||
contextualLoggingEnabled = featureGate.Enabled(ContextualLogging)
|
Options: options,
|
||||||
|
ContextualLoggingEnabled: contextualLoggingDefault,
|
||||||
}
|
}
|
||||||
|
if featureGate != nil {
|
||||||
|
p.ContextualLoggingEnabled = featureGate.Enabled(ContextualLogging)
|
||||||
|
}
|
||||||
|
|
||||||
|
oldP := applyParameters.Load()
|
||||||
|
if oldP != nil {
|
||||||
|
switch ReapplyHandling {
|
||||||
|
case ReapplyHandlingError:
|
||||||
|
return errors.New("logging configuration was already applied earlier, changing it is not allowed")
|
||||||
|
case ReapplyHandlingIgnoreUnchanged:
|
||||||
|
if diff := cmp.Diff(oldP, p); diff != "" {
|
||||||
|
return fmt.Errorf("the logging configuration should not be changed after setting it once (- old setting, + new setting):\n%s", diff)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid value %d for ReapplyHandling", ReapplyHandling)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
applyParameters.Store(p)
|
||||||
|
|
||||||
// if log format not exists, use nil loggr
|
// if log format not exists, use nil loggr
|
||||||
format, _ := logRegistry.get(c.Format)
|
format, _ := logRegistry.get(c.Format)
|
||||||
@ -205,7 +254,7 @@ func apply(c *LoggingConfiguration, options *LoggingOptions, featureGate feature
|
|||||||
defer setverbositylevel.Mutex.Unlock()
|
defer setverbositylevel.Mutex.Unlock()
|
||||||
setverbositylevel.Callbacks = append(setverbositylevel.Callbacks, control.SetVerbosityLevel)
|
setverbositylevel.Callbacks = append(setverbositylevel.Callbacks, control.SetVerbosityLevel)
|
||||||
}
|
}
|
||||||
klog.SetLoggerWithOptions(log, klog.ContextualLogger(contextualLoggingEnabled), klog.FlushLogger(control.Flush))
|
klog.SetLoggerWithOptions(log, klog.ContextualLogger(p.ContextualLoggingEnabled), klog.FlushLogger(control.Flush))
|
||||||
}
|
}
|
||||||
if err := loggingFlags.Lookup("v").Value.Set(VerbosityLevelPflag(&c.Verbosity).String()); err != nil {
|
if err := loggingFlags.Lookup("v").Value.Set(VerbosityLevelPflag(&c.Verbosity).String()); err != nil {
|
||||||
return fmt.Errorf("internal error while setting klog verbosity: %v", err)
|
return fmt.Errorf("internal error while setting klog verbosity: %v", err)
|
||||||
@ -214,7 +263,40 @@ func apply(c *LoggingConfiguration, options *LoggingOptions, featureGate feature
|
|||||||
return fmt.Errorf("internal error while setting klog vmodule: %v", err)
|
return fmt.Errorf("internal error while setting klog vmodule: %v", err)
|
||||||
}
|
}
|
||||||
klog.StartFlushDaemon(c.FlushFrequency)
|
klog.StartFlushDaemon(c.FlushFrequency)
|
||||||
klog.EnableContextualLogging(contextualLoggingEnabled)
|
klog.EnableContextualLogging(p.ContextualLoggingEnabled)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type parameters struct {
|
||||||
|
C *LoggingConfiguration
|
||||||
|
Options *LoggingOptions
|
||||||
|
ContextualLoggingEnabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var applyParameters atomic.Pointer[parameters]
|
||||||
|
|
||||||
|
// ResetForTest restores the default settings. This is not thread-safe and should only
|
||||||
|
// be used when there are no goroutines running. The intended users are unit
|
||||||
|
// tests in other packages.
|
||||||
|
func ResetForTest(featureGate featuregate.FeatureGate) error {
|
||||||
|
oldP := applyParameters.Load()
|
||||||
|
if oldP == nil {
|
||||||
|
// Nothing to do.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// This makes it possible to call apply again without triggering errors.
|
||||||
|
applyParameters.Store(nil)
|
||||||
|
|
||||||
|
// Restore defaults. Shouldn't fail, but check anyway.
|
||||||
|
config := NewLoggingConfiguration()
|
||||||
|
if err := ValidateAndApply(config, featureGate); err != nil {
|
||||||
|
return fmt.Errorf("apply default configuration: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// And again...
|
||||||
|
applyParameters.Store(nil)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,34 @@ import (
|
|||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestReapply(t *testing.T) {
|
||||||
|
oldReapplyHandling := ReapplyHandling
|
||||||
|
defer func() {
|
||||||
|
ReapplyHandling = oldReapplyHandling
|
||||||
|
if err := ResetForTest(nil /* feature gates */); err != nil {
|
||||||
|
t.Errorf("Unexpected error resetting the logging configuration: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
newOptions := NewLoggingConfiguration()
|
||||||
|
if err := ValidateAndApply(newOptions, nil); err != nil {
|
||||||
|
t.Errorf("unexpected error for first ValidateAndApply: %v", err)
|
||||||
|
}
|
||||||
|
ReapplyHandling = ReapplyHandlingError
|
||||||
|
if err := ValidateAndApply(newOptions, nil); err == nil {
|
||||||
|
t.Error("did not get expected error for second ValidateAndApply")
|
||||||
|
}
|
||||||
|
ReapplyHandling = ReapplyHandlingIgnoreUnchanged
|
||||||
|
if err := ValidateAndApply(newOptions, nil); err != nil {
|
||||||
|
t.Errorf("unexpected error for third ValidateAndApply: %v", err)
|
||||||
|
}
|
||||||
|
modifiedOptions := newOptions.DeepCopy()
|
||||||
|
modifiedOptions.Verbosity = 100
|
||||||
|
if err := ValidateAndApply(modifiedOptions, nil); err == nil {
|
||||||
|
t.Errorf("unexpected success for forth ValidateAndApply, should have complained about modified config")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestOptions(t *testing.T) {
|
func TestOptions(t *testing.T) {
|
||||||
newOptions := NewLoggingConfiguration()
|
newOptions := NewLoggingConfiguration()
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
@ -75,6 +103,11 @@ func TestOptions(t *testing.T) {
|
|||||||
if !assert.Equal(t, tc.want, c) {
|
if !assert.Equal(t, tc.want, c) {
|
||||||
t.Errorf("Wrong Validate() result for %q. expect %v, got %v", tc.name, tc.want, c)
|
t.Errorf("Wrong Validate() result for %q. expect %v, got %v", tc.name, tc.want, c)
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := ResetForTest(nil /* feature gates */); err != nil {
|
||||||
|
t.Errorf("Unexpected error resetting the logging configuration: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
errs := ValidateAndApply(c, nil /* We don't care about feature gates here. */)
|
errs := ValidateAndApply(c, nil /* We don't care about feature gates here. */)
|
||||||
defer klog.StopFlushDaemon()
|
defer klog.StopFlushDaemon()
|
||||||
if !assert.ElementsMatch(t, tc.errs, errs) {
|
if !assert.ElementsMatch(t, tc.errs, errs) {
|
||||||
@ -182,6 +215,11 @@ func testContextualLogging(t *testing.T, enabled bool) {
|
|||||||
AddFeatureGates(featureGate)
|
AddFeatureGates(featureGate)
|
||||||
err = featureGate.SetFromMap(map[string]bool{string(ContextualLogging): enabled})
|
err = featureGate.SetFromMap(map[string]bool{string(ContextualLogging): enabled})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
defer func() {
|
||||||
|
if err := ResetForTest(nil /* feature gates */); err != nil {
|
||||||
|
t.Errorf("Unexpected error resetting the logging configuration: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
err = ValidateAndApply(c, featureGate)
|
err = ValidateAndApply(c, featureGate)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer klog.StopFlushDaemon()
|
defer klog.StopFlushDaemon()
|
||||||
|
@ -155,8 +155,12 @@ func TestJSONFormatRegister(t *testing.T) {
|
|||||||
err := mutable.SetFromMap(map[string]bool{string(logsapi.ContextualLogging): tc.contextualLogging})
|
err := mutable.SetFromMap(map[string]bool{string(logsapi.ContextualLogging): tc.contextualLogging})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
featureGate = mutable
|
featureGate = mutable
|
||||||
|
defer func() {
|
||||||
|
if err := logsapi.ResetForTest(featureGate); err != nil {
|
||||||
|
t.Errorf("Unexpected error while resetting the logging configuration: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
errs := logsapi.ValidateAndApply(c, featureGate)
|
errs := logsapi.ValidateAndApply(c, featureGate)
|
||||||
defer klog.ClearLogger()
|
|
||||||
if !assert.ElementsMatch(t, tc.errs, errs) {
|
if !assert.ElementsMatch(t, tc.errs, errs) {
|
||||||
t.Errorf("Wrong Validate() result for %q.\n expect:\t%+v\n got:\t%+v", tc.name, tc.errs, errs)
|
t.Errorf("Wrong Validate() result for %q.\n expect:\t%+v\n got:\t%+v", tc.name, tc.errs, errs)
|
||||||
|
|
||||||
|
@ -81,6 +81,11 @@ func TestGlogSetter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
os.Stderr = newStderr
|
os.Stderr = newStderr
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err := logsapi.ResetForTest(nil /* feature gates */); err != nil {
|
||||||
|
t.Errorf("Unexpected error resetting the logging configuration: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
tc.init(t)
|
tc.init(t)
|
||||||
|
|
||||||
// First write with default verbosity level of 0 -> no output.
|
// First write with default verbosity level of 0 -> no output.
|
||||||
|
@ -194,6 +194,11 @@ func TestData(t *testing.T) {
|
|||||||
InfoStream: &buffer,
|
InfoStream: &buffer,
|
||||||
}
|
}
|
||||||
klog.SetOutput(&buffer)
|
klog.SetOutput(&buffer)
|
||||||
|
defer func() {
|
||||||
|
if err := logsapi.ResetForTest(nil); err != nil {
|
||||||
|
t.Errorf("Unexpected error resetting the logging configuration: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
if err := logsapi.ValidateAndApplyWithOptions(c, &o, nil); err != nil {
|
if err := logsapi.ValidateAndApplyWithOptions(c, &o, nil); err != nil {
|
||||||
t.Fatalf("Unexpected error configuring logging: %v", err)
|
t.Fatalf("Unexpected error configuring logging: %v", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user